aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--README.md5
-rw-r--r--src/coord.c8
-rw-r--r--src/cubetypes.h1
-rw-r--r--src/pruning.c157
-rw-r--r--src/symcoord.c9
6 files changed, 155 insertions, 26 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d9168a4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
nissy.o
diff --git a/README.md b/README.md
index fc71f2d..de56f9d 100644
--- a/README.md
+++ b/README.md
@@ -109,8 +109,9 @@ table to solving EO with HTM moveset and this coordinate would have values 0 (fo
109There is one caveat: each coordinates also needs an inverse function that takes a 109There is one caveat: each coordinates also needs an inverse function that takes a
110coordinate value and returns a cube which has that coordinate. This is in general 110coordinate value and returns a cube which has that coordinate. This is in general
111more complicated, but luckily the cube does not need to be fully built or consistent. 111more complicated, but luckily the cube does not need to be fully built or consistent.
112This inverse-coordinate is used only in one specific step when building pruning tables 112This inverse-coordinate is used only in one specific step when generating symmetry
113to avoid using up hundreds of Gb of memory. 113data, and I don't know if it is possible to avoid it (maybe it is). It is also used
114when building pruning tables, but in that case it is avoidable.
114 115
115Note: this part is different from what Cube Explorer does. Overall I think it is 116Note: this part is different from what Cube Explorer does. Overall I think it is
116conceptually easier, although in practice it was still hard to implement. 117conceptually easier, although in practice it was still hard to implement.
diff --git a/src/coord.c b/src/coord.c
index 7e691ef..059a7a2 100644
--- a/src/coord.c
+++ b/src/coord.c
@@ -171,7 +171,7 @@ antindex_eofbepos(uint64_t ind)
171 171
172 /* We need eorl for sym16 coordinate */ 172 /* We need eorl for sym16 coordinate */
173 static int initialized = false; 173 static int initialized = false;
174 static uint64_t eorl_aux[POW2TO11][BINOM12ON4]; 174 static uint64_t eorl_a[POW2TO11][BINOM12ON4];
175 static int eo_aux[12], ep_aux[12]; 175 static int eo_aux[12], ep_aux[12];
176 unsigned int i, j, k; 176 unsigned int i, j, k;
177 177
@@ -181,8 +181,10 @@ antindex_eofbepos(uint64_t ind)
181 int_to_sum_zero_array(i, 2, 12, eo_aux); 181 int_to_sum_zero_array(i, 2, 12, eo_aux);
182 index_to_subset(j, 12, 4, ep_aux); 182 index_to_subset(j, 12, 4, ep_aux);
183 for (k = 0; k < 12; k++) 183 for (k = 0; k < 12; k++)
184 if (ep_aux[k]) 184 if ((ep_aux[k] && k < FR) ||
185 (!ep_aux[k] && k >= FR))
185 eo_aux[k] = 1 - eo_aux[k]; 186 eo_aux[k] = 1 - eo_aux[k];
187 eorl_a[i][j] = digit_array_to_int(eo_aux,11,2);
186 } 188 }
187 } 189 }
188 190
@@ -191,7 +193,7 @@ antindex_eofbepos(uint64_t ind)
191 193
192 ret.eofb = ind % POW2TO11; 194 ret.eofb = ind % POW2TO11;
193 ret.epose = (ind / POW2TO11) * 24; 195 ret.epose = (ind / POW2TO11) * 24;
194 ret.eorl = eorl_aux[ret.eofb][ret.epose/24]; 196 ret.eorl = eorl_a[ret.eofb][ret.epose/24];
195 197
196 return ret; 198 return ret;
197} 199}
diff --git a/src/cubetypes.h b/src/cubetypes.h
index 6602a68..da8ab6b 100644
--- a/src/cubetypes.h
+++ b/src/cubetypes.h
@@ -213,6 +213,7 @@ dfsdata
213 Alg * current_alg; 213 Alg * current_alg;
214 Move sorted_moves[NMOVES]; 214 Move sorted_moves[NMOVES];
215 int move_position[NMOVES]; 215 int move_position[NMOVES];
216 uint8_t * visited;
216}; 217};
217 218
218struct 219struct
diff --git a/src/pruning.c b/src/pruning.c
index b7fedd4..ca6f57a 100644
--- a/src/pruning.c
+++ b/src/pruning.c
@@ -1,7 +1,20 @@
1#include "pruning.h" 1#include "pruning.h"
2 2
3/*
4 * The commented functions are a way to generate a pruning table
5 * without using anti-indexes. It does not matter too much because
6 * we still need anti-indexes in gensym.
7 */
8/*
9static bool dfs_get_visited(PruneData *pd, DfsData *dd, Cube c);
10static bool dfs_get_visited_index(DfsData *dd, uint64_t ind);
11static void dfs_set_visited(PruneData *pd, DfsData *dd, Cube c, bool b);
12static void dfs_set_visited_index(DfsData *dd, uint64_t ind, bool b);
13static void genptable_dfs(Cube c, PruneData *pd, DfsData *dd);
14*/
15
3static void genptable_bfs(PruneData *pd, int d, Move *ms); 16static void genptable_bfs(PruneData *pd, int d, Move *ms);
4static void genptable_branch(PruneData *pd, uint64_t i, int d, Move *m); 17static void genptable_branch(PruneData *pd,uint64_t ind,int d,Move *ms);
5static void ptable_update(PruneData *pd, Cube cube, int m); 18static void ptable_update(PruneData *pd, Cube cube, int m);
6static void ptable_update_index(PruneData *pd, uint64_t ind, int m); 19static void ptable_update_index(PruneData *pd, uint64_t ind, int m);
7static int ptableval_index(PruneData *pd, uint64_t ind); 20static int ptableval_index(PruneData *pd, uint64_t ind);
@@ -78,6 +91,54 @@ pd_khuge_HTM = {
78 .moveset = moveset_HTM, 91 .moveset = moveset_HTM,
79}; 92};
80 93
94/*
95void
96genptable(PruneData *pd)
97{
98 Move ms[NMOVES];
99 uint64_t j, oldn;
100 DfsData dd;
101
102 if (pd->generated)
103 return;
104
105 pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t));
106
107 if (read_ptable_file(pd)) {
108 pd->generated = true;
109 return;
110 }
111 pd->generated = true;
112
113 fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
114
115 moveset_to_list(pd->moveset, ms);
116
117 for (j = 0; j < pd->coord->max; j++)
118 ptable_update_index(pd, j, 15);
119
120 dd = (DfsData) { .m = 0 };
121 dd.visited = malloc((ptablesize(pd)/4 + 1) * sizeof(uint8_t));
122 moveset_to_list(pd->moveset, dd.sorted_moves);
123 oldn = 0;
124 pd->n = 0;
125
126 for (dd.d = 0; dd.d < 15 && pd->n < pd->coord->max; dd.d++) {
127 for (j = 0; j < pd->coord->max; j++)
128 dfs_set_visited_index(&dd, j, false);
129 genptable_dfs((Cube){0}, pd, &dd);
130 fprintf(stderr, "Depth %d done, generated %lu\t(%lu/%lu)\n",
131 dd.d+1, pd->n - oldn, pd->n, pd->coord->max);
132 oldn = pd->n;
133 }
134
135 if (!write_ptable_file(pd))
136 fprintf(stderr, "Error writing ptable file\n");
137
138 free(dd.visited);
139}
140*/
141
81void 142void
82genptable(PruneData *pd) 143genptable(PruneData *pd)
83{ 144{
@@ -105,13 +166,6 @@ genptable(PruneData *pd)
105 for (j = 0; j < pd->coord->max; j++) 166 for (j = 0; j < pd->coord->max; j++)
106 ptable_update_index(pd, j, 15); 167 ptable_update_index(pd, j, 15);
107 168
108 for (j = 0; j < pd->coord->max; j++)
109 if (ptableval_index(pd, j) != 15) {
110 printf("Error, non-max value at index %lu!\n", j);
111 break;
112 }
113 printf("Table set, ready to start\n");
114
115 ptable_update(pd, (Cube){0}, 0); 169 ptable_update(pd, (Cube){0}, 0);
116 pd->n = 1; 170 pd->n = 1;
117 oldn = 0; 171 oldn = 0;
@@ -127,7 +181,81 @@ genptable(PruneData *pd)
127 181
128 if (!write_ptable_file(pd)) 182 if (!write_ptable_file(pd))
129 fprintf(stderr, "Error writing ptable file\n"); 183 fprintf(stderr, "Error writing ptable file\n");
184
185}
186
187/*
188static void
189genptable_dfs(Cube c, PruneData *pd, DfsData *dd)
190{
191 int i, j, pv;
192 Move mm;
193 Cube cc;
194
195 if (pd->coord->index(c) > 2*ptablesize(pd)) {
196 printf("error! %lu > %lu\n", pd->coord->index(c), 2*ptablesize(pd));
197 print_cube(c);
198 exit(1);
199 }
200 pv = ptableval(pd, c);
201
202 if (pv < dd->m || dd->m > dd->d)
203 return;
204
205 if (dfs_get_visited(pd, dd, c))
206 return;
207 dfs_set_visited(pd, dd, c, true);
208
209 if (pv != dd->m)
210 ptable_update(pd, c, dd->m);
211
212 for (i = 0; i < pd->coord->ntrans; i++) {
213 cc = i == 0 ? c :
214 apply_trans(pd->coord->trans[i], c);
215 for (j = 0; dd->sorted_moves[j] != NULLMOVE; j++) {
216 mm = dd->sorted_moves[j];
217 dd->m++;
218 genptable_dfs(apply_move(mm, cc), pd, dd);
219 dd->m--;
220 }
221 }
222}
223*/
224
225/*
226static bool
227dfs_get_visited(PruneData *pd, DfsData *dd, Cube c)
228{
229 return dfs_get_visited_index(dd, pd->coord->index(c));
230}
231*/
232
233/*
234static bool
235dfs_get_visited_index(DfsData *dd, uint64_t ind)
236{
237 return dd->visited[ind/8] & ((uint8_t)1 << (ind % 8));
238}
239*/
240
241/*
242static void
243dfs_set_visited(PruneData *pd, DfsData *dd, Cube c, bool b)
244{
245 dfs_set_visited_index(dd, pd->coord->index(c), b);
246}
247*/
248
249/*
250static void
251dfs_set_visited_index(DfsData *dd, uint64_t ind, bool b)
252{
253 if (b)
254 dd->visited[ind/8] |= ((uint8_t)1 << (ind % 8));
255 else
256 dd->visited[ind/8] &= ~((uint8_t)1 << (ind % 8));
130} 257}
258*/
131 259
132static void 260static void
133genptable_bfs(PruneData *pd, int d, Move *ms) 261genptable_bfs(PruneData *pd, int d, Move *ms)
@@ -145,22 +273,9 @@ genptable_branch(PruneData *pd, uint64_t ind, int d, Move *ms)
145 int i, j; 273 int i, j;
146 Cube ci, cc, c; 274 Cube ci, cc, c;
147 275
148 /*
149 * This is the only line of the whole program where we REALLY need an
150 * anti-indexer function. We could get rid of it if only we could save
151 * a cube object for each index value as we go, but then we would need
152 * an incredible amount of memory to generate each ptable: assuming
153 * fields in struct cube are 32 bit ints that would take 88 times the
154 * memory of the table to be generated, more than 120Gb for
155 * ptable_khuge for example!
156 *
157 * TODO: it would be nice to get rid of this...
158 *
159 */
160 ci = pd->coord->cube(ind); 276 ci = pd->coord->cube(ind);
161 277
162 for (i = 0; i < pd->coord->ntrans; i++) { 278 for (i = 0; i < pd->coord->ntrans; i++) {
163 /* For simplicity trans[] is NULL when ntrans = 1 */
164 c = i == 0 ? ci : 279 c = i == 0 ? ci :
165 apply_trans(pd->coord->trans[i], ci); 280 apply_trans(pd->coord->trans[i], ci);
166 for (j = 0; ms[j] != NULLMOVE; j++) { 281 for (j = 0; ms[j] != NULLMOVE; j++) {
diff --git a/src/symcoord.c b/src/symcoord.c
index 97a8d9a..e9374d7 100644
--- a/src/symcoord.c
+++ b/src/symcoord.c
@@ -257,7 +257,16 @@ gensym(SymData *sd)
257 257
258 for (i = 0; i < sd->coord->max; i++) { 258 for (i = 0; i < sd->coord->max; i++) {
259 if (sd->class[i] == sd->coord->max + 1) { 259 if (sd->class[i] == sd->coord->max + 1) {
260
261 /*
262 * TODO: this is the only unavoidable use of
263 * antindexes. I also use them in genptable() (see
264 * pruning.c), but there I can do without (see
265 * commented functions in that file.
266 * Removing this would allow for a great simplification
267 */
260 c = sd->coord->cube(i); 268 c = sd->coord->cube(i);
269
261 sd->rep[nreps] = c; 270 sd->rep[nreps] = c;
262 for (j = 0; j < sd->ntrans; j++) { 271 for (j = 0; j < sd->ntrans; j++) {
263 d = apply_trans(sd->trans[j], c); 272 d = apply_trans(sd->trans[j], c);

Generated with cgit - Back to sebastiano.tronto.net