diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-03-07 17:08:28 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-03-07 17:08:28 +0100 |
| commit | 4d8465a3a791ebcf4bc74bdcc21eff7341ebc30f (patch) | |
| tree | 227eb3fa6189b8e4e422d47cfa3f503aa99db5cf | |
| parent | 7defd8041e6050a9adf7927b43fd249d75d6389f (diff) | |
| download | nissy-core-4d8465a3a791ebcf4bc74bdcc21eff7341ebc30f.tar.gz nissy-core-4d8465a3a791ebcf4bc74bdcc21eff7341ebc30f.zip | |
More progress on coordinate solver
Diffstat (limited to '')
| -rw-r--r-- | TODO_COORDINATES | 4 | ||||
| -rw-r--r-- | src/solvers/coord/common.h | 28 | ||||
| -rw-r--r-- | src/solvers/coord/coord_solve.h | 225 | ||||
| -rw-r--r-- | src/solvers/coord/coord_types_macros.h | 1 | ||||
| -rw-r--r-- | src/solvers/coord/eo.h | 5 | ||||
| -rw-r--r-- | src/solvers/coord/gendata_coord.h | 14 | ||||
| -rw-r--r-- | src/solvers/h48/solve.h | 2 | ||||
| -rw-r--r-- | src/utils/constants.h | 4 |
8 files changed, 274 insertions, 9 deletions
diff --git a/TODO_COORDINATES b/TODO_COORDINATES index 7e5628b..0202f49 100644 --- a/TODO_COORDINATES +++ b/TODO_COORDINATES | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | - solver | 1 | - solver (from TODOs in appending solution) |
| 2 | - include NISS | ||
| 3 | - test solver for EO | 2 | - test solver for EO |
| 3 | - add NISS (and add tests for NISS EO) | ||
| 4 | - make solve parallelized | 4 | - make solve parallelized |
| 5 | - other coordinates | 5 | - other coordinates |
| 6 | - gendata must handle symmetry | 6 | - gendata must handle symmetry |
diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h index b54e5e2..1d6e622 100644 --- a/src/solvers/coord/common.h +++ b/src/solvers/coord/common.h | |||
| @@ -6,6 +6,8 @@ coord_t *all_coordinates[] = { | |||
| 6 | }; | 6 | }; |
| 7 | 7 | ||
| 8 | STATIC void append_coord_name(const coord_t *, char *); | 8 | STATIC void append_coord_name(const coord_t *, char *); |
| 9 | STATIC coord_t *parse_coord(const char *, int); | ||
| 10 | STATIC uint8_t parse_axis(const char *, int); | ||
| 9 | 11 | ||
| 10 | STATIC void | 12 | STATIC void |
| 11 | append_coord_name(const coord_t *coord, char *str) | 13 | append_coord_name(const coord_t *coord, char *str) |
| @@ -18,3 +20,29 @@ append_coord_name(const coord_t *coord, char *str) | |||
| 18 | 20 | ||
| 19 | str[j] = '\0'; | 21 | str[j] = '\0'; |
| 20 | } | 22 | } |
| 23 | |||
| 24 | STATIC coord_t * | ||
| 25 | parse_coord(const char *coord, int n) | ||
| 26 | { | ||
| 27 | int i; | ||
| 28 | |||
| 29 | for (i = 0; all_coordinates[i] != NULL; i++) | ||
| 30 | if (!strncmp(all_coordinates[i]->name, coord, n)) | ||
| 31 | return all_coordinates[i]; | ||
| 32 | |||
| 33 | return NULL; | ||
| 34 | } | ||
| 35 | |||
| 36 | STATIC uint8_t | ||
| 37 | parse_axis(const char *axis, int n) | ||
| 38 | { | ||
| 39 | if (!strncmp(axis, "UD", n) || !strncmp(axis, "DU", n)) { | ||
| 40 | return AXIS_UD; | ||
| 41 | } else if (!strncmp(axis, "RL", n) || !strncmp(axis, "LR", n)) { | ||
| 42 | return AXIS_RL; | ||
| 43 | } else if (!strncmp(axis, "FB", n) || !strncmp(axis, "BF", n)) { | ||
| 44 | return AXIS_FB; | ||
| 45 | } | ||
| 46 | |||
| 47 | return UINT8_ERROR; | ||
| 48 | } | ||
diff --git a/src/solvers/coord/coord_solve.h b/src/solvers/coord/coord_solve.h index 1d7c036..317cb33 100644 --- a/src/solvers/coord/coord_solve.h +++ b/src/solvers/coord/coord_solve.h | |||
| @@ -1,3 +1,228 @@ | |||
| 1 | #include "coord_types_macros.h" | 1 | #include "coord_types_macros.h" |
| 2 | #include "common.h" | 2 | #include "common.h" |
| 3 | #include "gendata_coord.h" | 3 | #include "gendata_coord.h" |
| 4 | |||
| 5 | #define MAXLEN_COORDSOL 20 | ||
| 6 | |||
| 7 | typedef struct { | ||
| 8 | cube_t cube; | ||
| 9 | uint8_t depth; | ||
| 10 | uint8_t nmoves; | ||
| 11 | uint8_t moves[MAXLEN_COORDSOL]; | ||
| 12 | coord_t *coord; | ||
| 13 | const void *coord_data; | ||
| 14 | const uint8_t *ptable; | ||
| 15 | uint8_t trans; | ||
| 16 | int64_t *nsols; | ||
| 17 | int64_t maxsolutions; | ||
| 18 | int optimal; | ||
| 19 | uint8_t *shortest_sol; | ||
| 20 | uint64_t solutions_size; | ||
| 21 | uint64_t *solutions_used; | ||
| 22 | char **solutions; | ||
| 23 | } dfsarg_solve_coord_t; | ||
| 24 | |||
| 25 | STATIC int64_t solve_coord(cube_t, coord_t *, uint8_t, uint8_t, uint8_t, | ||
| 26 | uint8_t, uint64_t, int, int, uint64_t, const void, uint64_t, char); | ||
| 27 | STATIC int64_t solve_coord_dispatch(cube_t, const char *, uint8_t, uint8_t, | ||
| 28 | uint8_t, uint64_t, int, int, uint64_t, const void, uint64_t, char); | ||
| 29 | STATIC bool solve_coord_appendchar(char *, uint64_t, uint64_t *, char); | ||
| 30 | STATIC int64_t solve_coord_appendsolution(dfsarg_solve_coord_t *); | ||
| 31 | STATIC int64_t solve_coord_dfs(dfsarg_solve_coord_t *); | ||
| 32 | |||
| 33 | STATIC int64_t | ||
| 34 | solve_coord_appendsolution(dfsarg_solve_coord_t *arg) | ||
| 35 | { | ||
| 36 | uint8_t i, t, tmoves[MAXLEN_COORDSOL]; | ||
| 37 | |||
| 38 | if (*arg->nsols >= arg->maxsolutions || | ||
| 39 | arg->nmoves > *arg->shortest_sol + arg->optimal) | ||
| 40 | return 0; | ||
| 41 | |||
| 42 | sortparallel(arg->moves, arg->nmoves); | ||
| 43 | |||
| 44 | t = inverse_trans(arg->trans); | ||
| 45 | for (i = 0; i < arg->nmoves; i++) | ||
| 46 | tmoves[i] = transform_move(arg->moves[i], t); | ||
| 47 | |||
| 48 | /* TODO append tmoves[] */ | ||
| 49 | |||
| 50 | return 1; | ||
| 51 | } | ||
| 52 | |||
| 53 | STATIC bool | ||
| 54 | solve_coord_appendchar(char *s, uint64_t s_size, uint64_t *s_used, char c) | ||
| 55 | { | ||
| 56 | if (s_size == *s_used) | ||
| 57 | return false; | ||
| 58 | |||
| 59 | s[*s_used] = c; | ||
| 60 | (*s_used)++; | ||
| 61 | |||
| 62 | return true; | ||
| 63 | } | ||
| 64 | |||
| 65 | STATIC int64_t | ||
| 66 | solve_coord_dfs(dfsarg_solve_coord_t *arg) | ||
| 67 | { | ||
| 68 | uint64_t coord; | ||
| 69 | uint8_t pval; | ||
| 70 | |||
| 71 | coord = arg->coord->coord(arg->cube, arg->coord_data); | ||
| 72 | |||
| 73 | if (coord == 0) { | ||
| 74 | if (arg->nmoves != arg->depth) | ||
| 75 | return 0; | ||
| 76 | return solve_coord_appendsolution(arg); | ||
| 77 | } | ||
| 78 | |||
| 79 | pval = get_coord_pval(arg->coord, arg->ptable, coord); | ||
| 80 | if (arg->nmoves + pval > arg->depth) | ||
| 81 | return 0; | ||
| 82 | |||
| 83 | /* TODO recursive call */ | ||
| 84 | /* Is allowednextmove available here? */ | ||
| 85 | |||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | STATIC int64_t | ||
| 90 | solve_coord_dispatch( | ||
| 91 | cube_t cube, | ||
| 92 | const char *coord_axis, | ||
| 93 | uint8_t nissflag, | ||
| 94 | uint8_t minmoves, | ||
| 95 | uint8_t maxmoves, | ||
| 96 | uint64_t maxsolutions, | ||
| 97 | int optimal, | ||
| 98 | int threads, | ||
| 99 | uint64_t data_size, | ||
| 100 | const void *data, | ||
| 101 | uint64_t sols_size, | ||
| 102 | char *sols | ||
| 103 | ) | ||
| 104 | { | ||
| 105 | int i, n; | ||
| 106 | coord_t *coord; | ||
| 107 | uint8_t axis; | ||
| 108 | |||
| 109 | n = strlen(coord_axis); | ||
| 110 | for (i = 0; coord_axis[i] != ' ' && coord_axis[i] != '\0'; i++) ; | ||
| 111 | |||
| 112 | coord = parse_coord(coord_axis, i); | ||
| 113 | axis = parse_axis(coord_axis + i + 1, n - i - 1); | ||
| 114 | |||
| 115 | if (coord == NULL) { | ||
| 116 | LOG("Could not parse coordinate '%s'\n", coord_axis); | ||
| 117 | return NISSY_ERROR_INVALID_SOLVER; | ||
| 118 | } | ||
| 119 | |||
| 120 | if (axis == UINT8_ERROR) { | ||
| 121 | LOG("Could not parse axis from '%s'\n", coord_axis); | ||
| 122 | return NISSY_ERROR_INVALID_SOLVER; | ||
| 123 | } | ||
| 124 | |||
| 125 | return solve_coord(cube, coord, axis, nissflag, minmoves, maxmoves, | ||
| 126 | maxsolutions, optimal, threads, data_size, data, sols_size, sols); | ||
| 127 | } | ||
| 128 | |||
| 129 | STATIC int64_t | ||
| 130 | solve_coord( | ||
| 131 | cube_t cube, | ||
| 132 | coord_t *coord, | ||
| 133 | uint8_t axis, | ||
| 134 | uint8_t nissflag, | ||
| 135 | uint8_t minmoves, | ||
| 136 | uint8_t maxmoves, | ||
| 137 | uint64_t maxsolutions, | ||
| 138 | int optimal, | ||
| 139 | int threads, | ||
| 140 | uint64_t data_size, | ||
| 141 | const void data, | ||
| 142 | uint64_t sols_size, | ||
| 143 | char *sols | ||
| 144 | ) | ||
| 145 | { | ||
| 146 | int8_t d; | ||
| 147 | uint8_t t, shortest_sol; | ||
| 148 | int64_t nsols; | ||
| 149 | uint64_t sols_used; | ||
| 150 | cube_t c; | ||
| 151 | const void *coord_data; | ||
| 152 | const uint8_t *ptable; | ||
| 153 | dfsarg_solve_coord_t arg; | ||
| 154 | tableinfo_t info; | ||
| 155 | |||
| 156 | if (readtableinfo(data_size, data, &info) != NISSY_OK) | ||
| 157 | goto solve_coord_error_data; | ||
| 158 | |||
| 159 | if (info.type == TABLETYPE_PRUNING) { | ||
| 160 | /* Only the pruning table */ | ||
| 161 | coord_data = NULL; | ||
| 162 | ptable = (uint8_t *)data + INFOSIZE; | ||
| 163 | } else { | ||
| 164 | /* Coordinate has extra data */ | ||
| 165 | coord_data = data + INFOSIZE; | ||
| 166 | ptable = (uint8_t *)data + info.next + INFOSIZE; | ||
| 167 | } | ||
| 168 | |||
| 169 | nsols = 0; | ||
| 170 | sols_used = 0; | ||
| 171 | shortest_sol = MAXLEN_COORDSOL + 1; | ||
| 172 | c = transform(cube, t); | ||
| 173 | t = coord->axistrans[axis]; | ||
| 174 | |||
| 175 | arg = (dfsarg_solve_coord_t) { | ||
| 176 | .cube = c, | ||
| 177 | .coord = coord, | ||
| 178 | .coord_data = coord_data, | ||
| 179 | .ptable = ptable, | ||
| 180 | .trans = t, | ||
| 181 | .nsols = &nsols, | ||
| 182 | .maxsolutions = (int64_t)maxsolutions, | ||
| 183 | .optimal = optimal, | ||
| 184 | .shortest_sol = &shortest_sol, | ||
| 185 | .solutions_size = sols_size, | ||
| 186 | .solutions_used = &sols_used, | ||
| 187 | .solutions = &sols, | ||
| 188 | }; | ||
| 189 | |||
| 190 | if (coord->coord(c, coord_data) == 0) { | ||
| 191 | if (minmoves == 0) { | ||
| 192 | nsols = 1; | ||
| 193 | if (!solve_coord_appendchar( | ||
| 194 | sols, sols_size, &sols_used, '\n')) | ||
| 195 | goto solve_coord_error_buffer; | ||
| 196 | } | ||
| 197 | goto solve_coord_done; | ||
| 198 | } | ||
| 199 | |||
| 200 | for ( | ||
| 201 | d = MAX(minmoves, 1); | ||
| 202 | d <= maxmoves && nsols < (int64_t)maxsolutions | ||
| 203 | && !(nsols != 0 && d > shortest_sol + optimal); | ||
| 204 | d++ | ||
| 205 | ) { | ||
| 206 | if (d >= 10) | ||
| 207 | LOG("Found %" PRId64 " solutions, searching at depth %" | ||
| 208 | PRId8 "\n", nsols, d); | ||
| 209 | |||
| 210 | arg.depth = d; | ||
| 211 | arg.nmoves = 0; | ||
| 212 | nsols += solve_coord_dfs(&arg); | ||
| 213 | } | ||
| 214 | |||
| 215 | solve_coord_done: | ||
| 216 | if (!solve_coord_appendchar(sols, sols_size, &sols_used, '\0')) | ||
| 217 | goto solve_coord_error_buffer; | ||
| 218 | |||
| 219 | return nsols; | ||
| 220 | |||
| 221 | solve_coord_error_data: | ||
| 222 | LOG("solve_coord: error reading table\n"); | ||
| 223 | return NISSY_ERROR_DATA; | ||
| 224 | |||
| 225 | solve_coord_error_buffer: | ||
| 226 | LOG("Could not append solution to buffer: size too small\n"); | ||
| 227 | return NISSY_ERROR_BUFFER_SIZE; | ||
| 228 | } | ||
diff --git a/src/solvers/coord/coord_types_macros.h b/src/solvers/coord/coord_types_macros.h index 4f2877c..594f594 100644 --- a/src/solvers/coord/coord_types_macros.h +++ b/src/solvers/coord/coord_types_macros.h | |||
| @@ -10,4 +10,5 @@ typedef struct { | |||
| 10 | uint64_t max; | 10 | uint64_t max; |
| 11 | uint32_t moves_mask; | 11 | uint32_t moves_mask; |
| 12 | uint64_t trans_mask; | 12 | uint64_t trans_mask; |
| 13 | uint8_t axistrans[3]; | ||
| 13 | } coord_t; | 14 | } coord_t; |
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h index d6604d9..449397f 100644 --- a/src/solvers/coord/eo.h +++ b/src/solvers/coord/eo.h | |||
| @@ -10,6 +10,11 @@ STATIC coord_t coordinate_eo = { | |||
| 10 | .max = POW_2_11, | 10 | .max = POW_2_11, |
| 11 | .trans_mask = TM_ALLTRANS, | 11 | .trans_mask = TM_ALLTRANS, |
| 12 | .moves_mask = MM_ALLMOVES, | 12 | .moves_mask = MM_ALLMOVES, |
| 13 | .axistrans = { | ||
| 14 | [AXIS_UD] = TRANS_FDr, | ||
| 15 | [AXIS_RL] = TRANS_URr, | ||
| 16 | [AXIS_FB] = TRANS_UFr, | ||
| 17 | }, | ||
| 13 | }; | 18 | }; |
| 14 | 19 | ||
| 15 | STATIC uint64_t | 20 | STATIC uint64_t |
diff --git a/src/solvers/coord/gendata_coord.h b/src/solvers/coord/gendata_coord.h index b3932cd..3d385e9 100644 --- a/src/solvers/coord/gendata_coord.h +++ b/src/solvers/coord/gendata_coord.h | |||
| @@ -7,14 +7,16 @@ STATIC void set_coord_pval(const coord_t *, uint8_t *, uint64_t, uint8_t); | |||
| 7 | STATIC size_t | 7 | STATIC size_t |
| 8 | gendata_coordinate_name(const char *name, void *buf) | 8 | gendata_coordinate_name(const char *name, void *buf) |
| 9 | { | 9 | { |
| 10 | int i; | 10 | coord_t *coord; |
| 11 | 11 | ||
| 12 | for (i = 0; all_coordinates[i] != NULL; i++) | 12 | coord = parse_coord(name, strlen(name)); |
| 13 | if (strcmp(all_coordinates[i]->name, name) == 0) | 13 | if (coord == NULL) { |
| 14 | return gendata_coordinate(all_coordinates[i], buf); | 14 | LOG("Cannot generate data for coordinate '%s': not found\n", |
| 15 | name); | ||
| 16 | return 0; | ||
| 17 | } | ||
| 15 | 18 | ||
| 16 | LOG("Cannot generate data for coordinate '%s': not found\n", name); | 19 | return gendata_coordinate(coord, buf); |
| 17 | return 0; | ||
| 18 | } | 20 | } |
| 19 | 21 | ||
| 20 | STATIC size_t | 22 | STATIC size_t |
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index 6277082..44f6a89 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -457,7 +457,7 @@ solve_h48( | |||
| 457 | pthread_t thread[THREADS]; | 457 | pthread_t thread[THREADS]; |
| 458 | pthread_mutex_t solutions_mutex; | 458 | pthread_mutex_t solutions_mutex; |
| 459 | 459 | ||
| 460 | if(readtableinfo_n(data_size, data, 2, &info) != NISSY_OK) | 460 | if (readtableinfo_n(data_size, data, 2, &info) != NISSY_OK) |
| 461 | goto solve_h48_error_data; | 461 | goto solve_h48_error_data; |
| 462 | 462 | ||
| 463 | cocsepdata = (uint32_t *)((char *)data + INFOSIZE); | 463 | cocsepdata = (uint32_t *)((char *)data + INFOSIZE); |
diff --git a/src/utils/constants.h b/src/utils/constants.h index 3d8bf5e..1db1940 100644 --- a/src/utils/constants.h +++ b/src/utils/constants.h | |||
| @@ -93,6 +93,10 @@ STATIC int64_t binomial[12][12] = { | |||
| 93 | #define TRANS_BDm UINT8_C(46) | 93 | #define TRANS_BDm UINT8_C(46) |
| 94 | #define TRANS_BLm UINT8_C(47) | 94 | #define TRANS_BLm UINT8_C(47) |
| 95 | 95 | ||
| 96 | #define AXIS_UD UINT8_C(0) | ||
| 97 | #define AXIS_RL UINT8_C(1) | ||
| 98 | #define AXIS_FB UINT8_C(2) | ||
| 99 | |||
| 96 | #define NMOVES (1+MOVE_B3) | 100 | #define NMOVES (1+MOVE_B3) |
| 97 | #define NTRANS (1+TRANS_BLm) | 101 | #define NTRANS (1+TRANS_BLm) |
| 98 | 102 | ||
