diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-05-18 08:48:13 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-05-18 08:48:13 +0200 |
| commit | 8b94d135429a9f3253cc7f25a1453b412065c4a0 (patch) | |
| tree | 4a31d6def5421e95fb98505a2bc2653c18fca330 /src/nissy.c | |
| parent | 30b43f08955158d4f2066f4b50fe8d1241b3177b (diff) | |
| download | nissy-core-8b94d135429a9f3253cc7f25a1453b412065c4a0.tar.gz nissy-core-8b94d135429a9f3253cc7f25a1453b412065c4a0.zip | |
Refactor solver dispatch and checkdata
Diffstat (limited to 'src/nissy.c')
| -rw-r--r-- | src/nissy.c | 143 |
1 files changed, 31 insertions, 112 deletions
diff --git a/src/nissy.c b/src/nissy.c index acf6ebe..1f929c0 100644 --- a/src/nissy.c +++ b/src/nissy.c | |||
| @@ -12,13 +12,10 @@ | |||
| 12 | #include "core/core.h" | 12 | #include "core/core.h" |
| 13 | #include "solvers/solvers.h" | 13 | #include "solvers/solvers.h" |
| 14 | 14 | ||
| 15 | long long parse_h48_solver( | ||
| 16 | const char *, uint8_t [static 1], uint8_t [static 1]); | ||
| 17 | STATIC bool checkdata(const unsigned char *, const tableinfo_t [static 1]); | 15 | STATIC bool checkdata(const unsigned char *, const tableinfo_t [static 1]); |
| 18 | STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN], | 16 | STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN], |
| 19 | const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t); | 17 | const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t); |
| 20 | STATIC long long write_result(oriented_cube_t, char [static NISSY_SIZE_CUBE]); | 18 | STATIC long long write_result(oriented_cube_t, char [static NISSY_SIZE_CUBE]); |
| 21 | STATIC size_t my_strnlen(const char *, size_t); | ||
| 22 | STATIC long long nissy_dataid(const char *, char [static NISSY_SIZE_DATAID]); | 19 | STATIC long long nissy_dataid(const char *, char [static NISSY_SIZE_DATAID]); |
| 23 | STATIC long long nissy_gendata_unsafe( | 20 | STATIC long long nissy_gendata_unsafe( |
| 24 | const char *, unsigned long long, unsigned char *); | 21 | const char *, unsigned long long, unsigned char *); |
| @@ -33,67 +30,20 @@ struct { | |||
| 33 | GETCUBE_OPTIONS(NULL, NULL) | 30 | GETCUBE_OPTIONS(NULL, NULL) |
| 34 | }; | 31 | }; |
| 35 | 32 | ||
| 36 | long long | ||
| 37 | parse_h48_solver(const char *buf, uint8_t h[static 1], uint8_t k[static 1]) | ||
| 38 | { | ||
| 39 | const char *fullbuf = buf; | ||
| 40 | |||
| 41 | buf += 3; | ||
| 42 | |||
| 43 | if (*buf != 'h') | ||
| 44 | goto parse_h48_solver_error; | ||
| 45 | buf++; | ||
| 46 | |||
| 47 | *h = atoi(buf); | ||
| 48 | |||
| 49 | for ( ; *buf >= 0 + '0' && *buf <= 9 + '0'; buf++) | ||
| 50 | if (*buf == 0) | ||
| 51 | goto parse_h48_solver_error; | ||
| 52 | |||
| 53 | if (*buf != 'k') | ||
| 54 | goto parse_h48_solver_error; | ||
| 55 | buf++; | ||
| 56 | |||
| 57 | *k = atoi(buf); | ||
| 58 | |||
| 59 | return *h < 12 && (*k == 2 || (*k == 4 && *h == 0)) ? 0 : 1; | ||
| 60 | |||
| 61 | parse_h48_solver_error: | ||
| 62 | *h = 0; | ||
| 63 | *k = 0; | ||
| 64 | LOG("Error parsing H48 solver: must be in \"h48h*k*\" format," | ||
| 65 | " but got %s\n", fullbuf); | ||
| 66 | return NISSY_ERROR_INVALID_SOLVER; | ||
| 67 | } | ||
| 68 | |||
| 69 | STATIC bool | 33 | STATIC bool |
| 70 | checkdata(const unsigned char *buf, const tableinfo_t info[static 1]) | 34 | checkdata(const unsigned char *buf, const tableinfo_t info[static 1]) |
| 71 | { | 35 | { |
| 72 | uint64_t distr[INFO_DISTRIBUTION_LEN]; | 36 | uint64_t distr[INFO_DISTRIBUTION_LEN]; |
| 73 | 37 | ||
| 74 | if (my_strnlen(info->solver, INFO_SOLVER_STRLEN) | 38 | if (info->type == TABLETYPE_PRUNING) { |
| 75 | == INFO_SOLVER_STRLEN) { | 39 | getdistribution(buf + INFOSIZE, distr, info); |
| 76 | LOG("[checkdata] Error reading table info\n"); | 40 | LOG("\n[checkdata] Checking distribution for %s\n", info->solver); |
| 77 | return false; | 41 | return distribution_equal(info->distribution, distr, info->maxvalue); |
| 78 | } else if (!strncmp(info->solver, "cocsep", 6)) { | ||
| 79 | getdistribution_cocsep( | ||
| 80 | (uint32_t *)((char *)buf + INFOSIZE), distr); | ||
| 81 | } else if (!strncmp(info->solver, "h48", 3)) { | ||
| 82 | getdistribution_h48(buf + INFOSIZE, distr, | ||
| 83 | info->h48h, info->bits); | ||
| 84 | } else if (!strncmp(info->solver, "coordinate solver for ", 22)) { | ||
| 85 | getdistribution_coord(buf + INFOSIZE, | ||
| 86 | info->solver + 22, distr); | ||
| 87 | } else if (!strncmp(info->solver, "eoesep data for h48", 19)) { | ||
| 88 | return true; | ||
| 89 | } else if (!strncmp(info->solver, "coord helper table for ", 23)) { | ||
| 90 | return true; | ||
| 91 | } else { | 42 | } else { |
| 92 | LOG("[checkdata] unknown solver %s\n", info->solver); | 43 | LOG("\n[checkdata] Skipping distribution check for " |
| 93 | return false; | 44 | "special table %s\n", info->solver); |
| 45 | return true; | ||
| 94 | } | 46 | } |
| 95 | |||
| 96 | return distribution_equal(info->distribution, distr, info->maxvalue); | ||
| 97 | } | 47 | } |
| 98 | 48 | ||
| 99 | STATIC bool | 49 | STATIC bool |
| @@ -109,8 +59,12 @@ distribution_equal( | |||
| 109 | for (i = 0, wrong = 0; i <= MIN(maxvalue, 20); i++) { | 59 | for (i = 0, wrong = 0; i <= MIN(maxvalue, 20); i++) { |
| 110 | if (expected[i] != actual[i]) { | 60 | if (expected[i] != actual[i]) { |
| 111 | wrong++; | 61 | wrong++; |
| 112 | LOG("Value %" PRIu8 ": expected %" PRIu64 ", found %" | 62 | LOG("[checkdata] Value for depth %" PRIu8 |
| 113 | PRIu64 "\n", i, expected[i], actual[i]); | 63 | ": expected %" PRIu64 ", found %" PRIu64 "\n", |
| 64 | i, expected[i], actual[i]); | ||
| 65 | } else { | ||
| 66 | LOG("[checkdata] Value for depth %" PRIu8 | ||
| 67 | " is correct (%" PRIu64 ")\n", i, actual[i]); | ||
| 114 | } | 68 | } |
| 115 | } | 69 | } |
| 116 | 70 | ||
| @@ -130,18 +84,6 @@ write_result(oriented_cube_t cube, char result[static NISSY_SIZE_CUBE]) | |||
| 130 | return NISSY_OK; | 84 | return NISSY_OK; |
| 131 | } | 85 | } |
| 132 | 86 | ||
| 133 | STATIC size_t | ||
| 134 | my_strnlen(const char *str, size_t maxlen) | ||
| 135 | { | ||
| 136 | size_t i; | ||
| 137 | |||
| 138 | for (i = 0; i < maxlen; i++) | ||
| 139 | if (str[i] == '\0') | ||
| 140 | return i; | ||
| 141 | |||
| 142 | return maxlen; | ||
| 143 | } | ||
| 144 | |||
| 145 | long long | 87 | long long |
| 146 | nissy_inverse( | 88 | nissy_inverse( |
| 147 | const char cube[static NISSY_SIZE_CUBE], | 89 | const char cube[static NISSY_SIZE_CUBE], |
| @@ -337,22 +279,15 @@ nissy_datainfo( | |||
| 337 | STATIC long long | 279 | STATIC long long |
| 338 | nissy_dataid(const char *solver, char dataid[static NISSY_SIZE_DATAID]) | 280 | nissy_dataid(const char *solver, char dataid[static NISSY_SIZE_DATAID]) |
| 339 | { | 281 | { |
| 340 | if (!strncmp(solver, "h48", 3)) { | 282 | solver_dispatch_t *dispatch; |
| 341 | uint8_t h, k; | 283 | |
| 342 | long long err; | 284 | dispatch = match_solver(solver); |
| 343 | if ((err = parse_h48_solver(solver, &h, &k)) != NISSY_OK) | 285 | if (dispatch == NULL) { |
| 344 | return err; | 286 | LOG("[dataid] Unknown solver %s\n", solver); |
| 345 | /* TODO: also check that h and k are admissible */ | ||
| 346 | else strcpy(dataid, solver); | ||
| 347 | return err; | ||
| 348 | /* TODO: do this when moved parser */ | ||
| 349 | /* return dataid_h48(solver, dataid); */ | ||
| 350 | } else if (!strncmp(solver, "coord_", 6)) { | ||
| 351 | return dataid_coord(solver+6, dataid); | ||
| 352 | } else { | ||
| 353 | LOG("[gendata] Unknown solver %s\n", solver); | ||
| 354 | return NISSY_ERROR_INVALID_SOLVER; | 287 | return NISSY_ERROR_INVALID_SOLVER; |
| 355 | } | 288 | } |
| 289 | |||
| 290 | return dispatch->dataid(solver, dataid); | ||
| 356 | } | 291 | } |
| 357 | 292 | ||
| 358 | long long | 293 | long long |
| @@ -386,8 +321,7 @@ nissy_gendata_unsafe( | |||
| 386 | unsigned char *data | 321 | unsigned char *data |
| 387 | ) | 322 | ) |
| 388 | { | 323 | { |
| 389 | long long parse_ret; | 324 | solver_dispatch_t *dispatch; |
| 390 | gendata_h48_arg_t arg; | ||
| 391 | 325 | ||
| 392 | if (solver == NULL) { | 326 | if (solver == NULL) { |
| 393 | LOG("[gendata] Error: 'solver' argument is NULL\n"); | 327 | LOG("[gendata] Error: 'solver' argument is NULL\n"); |
| @@ -399,20 +333,13 @@ nissy_gendata_unsafe( | |||
| 399 | return NISSY_ERROR_DATA; | 333 | return NISSY_ERROR_DATA; |
| 400 | } | 334 | } |
| 401 | 335 | ||
| 402 | if (!strncmp(solver, "h48", 3)) { | 336 | dispatch = match_solver(solver); |
| 403 | arg.buf_size = data_size; | 337 | if (dispatch == NULL) { |
| 404 | arg.buf = data; | ||
| 405 | parse_ret = parse_h48_solver(solver, &arg.h, &arg.k); | ||
| 406 | arg.maxdepth = 20; | ||
| 407 | if (parse_ret != NISSY_OK) | ||
| 408 | return parse_ret; | ||
| 409 | return gendata_h48(&arg); | ||
| 410 | } else if (!strncmp(solver, "coord_", 6)) { | ||
| 411 | return gendata_coord_dispatch(solver+6, data); | ||
| 412 | } else { | ||
| 413 | LOG("[gendata] Unknown solver %s\n", solver); | 338 | LOG("[gendata] Unknown solver %s\n", solver); |
| 414 | return NISSY_ERROR_INVALID_SOLVER; | 339 | return NISSY_ERROR_INVALID_SOLVER; |
| 415 | } | 340 | } |
| 341 | |||
| 342 | return dispatch->gendata(solver, data_size, data); | ||
| 416 | } | 343 | } |
| 417 | 344 | ||
| 418 | long long | 345 | long long |
| @@ -466,9 +393,8 @@ nissy_solve( | |||
| 466 | ) | 393 | ) |
| 467 | { | 394 | { |
| 468 | oriented_cube_t oc; | 395 | oriented_cube_t oc; |
| 469 | long long parse_ret; | ||
| 470 | uint8_t h, k; | ||
| 471 | int t; | 396 | int t; |
| 397 | solver_dispatch_t *dispatch; | ||
| 472 | 398 | ||
| 473 | if (solver == NULL) { | 399 | if (solver == NULL) { |
| 474 | LOG("[solve] Error: 'solver' argument is NULL\n"); | 400 | LOG("[solve] Error: 'solver' argument is NULL\n"); |
| @@ -511,21 +437,14 @@ nissy_solve( | |||
| 511 | return NISSY_ERROR_DATA; | 437 | return NISSY_ERROR_DATA; |
| 512 | } | 438 | } |
| 513 | 439 | ||
| 514 | if (!strncmp(solver, "h48", 3)) { | 440 | dispatch = match_solver(solver); |
| 515 | parse_ret = parse_h48_solver(solver, &h, &k); | 441 | if (dispatch == NULL) { |
| 516 | if (parse_ret != NISSY_OK) | ||
| 517 | return parse_ret; | ||
| 518 | return solve_h48(oc, minmoves, maxmoves, maxsols, | ||
| 519 | optimal, t, data_size, data, sols_size, sols, stats, | ||
| 520 | poll_status, poll_status_data); | ||
| 521 | } else if (!strncmp(solver, "coord_", 6)) { | ||
| 522 | return solve_coord_dispatch(oc, solver + 6, nissflag, | ||
| 523 | minmoves, maxmoves, maxsols, optimal, t, data_size, data, | ||
| 524 | sols_size, sols, poll_status, poll_status_data); | ||
| 525 | } else { | ||
| 526 | LOG("[solve] Error: unknown solver '%s'\n", solver); | 442 | LOG("[solve] Error: unknown solver '%s'\n", solver); |
| 527 | return NISSY_ERROR_INVALID_SOLVER; | 443 | return NISSY_ERROR_INVALID_SOLVER; |
| 528 | } | 444 | } |
| 445 | return dispatch->solve(oc, solver, nissflag, minmoves, maxmoves, | ||
| 446 | maxsols, optimal, t, data_size, data, sols_size, sols, stats, | ||
| 447 | poll_status, poll_status_data); | ||
| 529 | } | 448 | } |
| 530 | 449 | ||
| 531 | long long | 450 | long long |
