aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48/gendata_h48.h
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-08-25 14:36:11 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-08-25 15:40:08 +0200
commit25c16cc4350a659ede2a2503c4c5be36264e853d (patch)
tree97af17c9497817959909e0a17bc1286c7c0feccd /src/solvers/h48/gendata_h48.h
parentcdf311166da0171c2787fb1745072cd14569ff4f (diff)
downloadnissy-core-25c16cc4350a659ede2a2503c4c5be36264e853d.tar.gz
nissy-core-25c16cc4350a659ede2a2503c4c5be36264e853d.zip
Renamed file
Diffstat (limited to 'src/solvers/h48/gendata_h48.h')
-rw-r--r--src/solvers/h48/gendata_h48.h351
1 files changed, 351 insertions, 0 deletions
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h
new file mode 100644
index 0000000..2b1347f
--- /dev/null
+++ b/src/solvers/h48/gendata_h48.h
@@ -0,0 +1,351 @@
1#define H48_COORDMAX_NOEO (COCSEP_CLASSES * (size_t)_12c4 * (size_t)_8c4)
2#define H48_COORDMAX(h) (H48_COORDMAX_NOEO << (size_t)(h))
3#define H48_TABLESIZE(h, k) (H48_COORDMAX((h)) / ((size_t)8 / (size_t)(k)))
4
5#define H48_COEFF(k) (UINT32_C(32) / (uint32_t)(k))
6#define H48_INDEX(i, k) ((uint32_t)(i) / H48_COEFF(k))
7#define H48_SHIFT(i, k) ((uint32_t)(k) * ((uint32_t)(i) % H48_COEFF(k)))
8#define H48_MASK(i, k) ((_bit_u32(k) - (uint32_t)(1)) << H48_SHIFT(i, k))
9
10#define MAXLEN 20
11
12/*
13TODO: This loop over similar h48 coordinates can be improved by only
14transforming edges, but we need to compose transformations (i.e. conjugate
15_t by _ttrep).
16*/
17#define _foreach_h48sim(_cube, _cocsepdata, _selfsim, _h, _action) \
18 int64_t _cocsep = coord_cocsep(_cube); \
19 uint8_t _ttrep = TTREP(_cocsepdata[_cocsep]); \
20 uint8_t _inverse_ttrep = inverse_trans(_ttrep); \
21 int64_t _coclass = COCLASS(_cocsepdata[_cocsep]); \
22 cube_t _rep = transform(_cube, _ttrep); \
23 uint64_t _sim = _selfsim[_coclass]; \
24 for (uint8_t _t = 0; _t < 48 && _sim; _t++, _sim >>= 1) { \
25 if (!(_sim & 1)) continue; \
26 _cube = transform(_rep, _t); \
27 _cube = transform(_cube, _inverse_ttrep); \
28 _action \
29 }
30
31typedef struct {
32 uint8_t h;
33 uint8_t k;
34 uint8_t maxdepth;
35 void *buf;
36 uint32_t *info;
37 uint32_t *cocsepdata;
38 uint32_t *h48data;
39 uint64_t selfsim[COCSEP_CLASSES];
40 cube_t crep[COCSEP_CLASSES];
41} gendata_h48_arg_t;
42
43typedef struct {
44 uint8_t maxdepth;
45 const uint32_t *cocsepdata;
46 const cube_t *crep;
47 const uint64_t *selfsim;
48 h48map_t *map;
49} gendata_h48short_arg_t;
50
51typedef struct {
52 uint8_t depth;
53 uint32_t *cocsepdata;
54 uint32_t *buf32;
55 uint64_t *selfsim;
56 int64_t done;
57 cube_t *crep;
58} bfsarg_esep_t;
59
60_static_inline uint8_t get_esep_pval(const uint32_t *, int64_t, uint8_t);
61_static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t, uint8_t);
62
63_static uint64_t gen_h48short(gendata_h48short_arg_t *);
64_static size_t gendata_h48(gendata_h48_arg_t *);
65_static size_t gendata_h48h0k4(gendata_h48_arg_t *);
66_static int64_t gendata_h48h0k4_bfs(bfsarg_esep_t *);
67_static int64_t gendata_h48h0k4_bfs_fromdone(bfsarg_esep_t *);
68_static int64_t gendata_h48h0k4_bfs_fromnew(bfsarg_esep_t *);
69_static size_t gendata_h48k2(gendata_h48_arg_t *);
70
71_static_inline int8_t get_h48_bound(cube_t, uint32_t, uint8_t, uint8_t, uint32_t *);
72
73_static uint64_t
74gen_h48short(gendata_h48short_arg_t *arg)
75{
76 uint8_t i, m;
77 int64_t coord;
78 uint64_t j, oldn;
79 kvpair_t kv;
80 cube_t cube, d;
81
82 cube = solvedcube();
83 coord = coord_h48(cube, arg->cocsepdata, 11);
84 h48map_insertmin(arg->map, coord, 0);
85 oldn = 0;
86 LOG("Short h48: depth 0\nfound %" PRIu8 "\n", arg->map->n-oldn);
87 for (i = 0; i < arg->maxdepth; i++) {
88 LOG("Short h48: depth %" PRIu8 "\n", i+1);
89 j = 0;
90 oldn = arg->map->n;
91 for (kv = h48map_nextkvpair(arg->map, &j);
92 j != arg->map->capacity;
93 kv = h48map_nextkvpair(arg->map, &j)
94 ) {
95 if (kv.val != i)
96 continue;
97 cube = invcoord_h48(kv.key, arg->crep, 11);
98 for (m = 0; m < 18; m++) {
99 d = move(cube, m);
100 _foreach_h48sim(
101 d, arg->cocsepdata, arg->selfsim, 11,
102 coord = coord_h48(d, arg->cocsepdata, 11);
103 h48map_insertmin(arg->map, coord, i+1);
104 )
105 }
106 }
107 LOG("found %" PRIu8 "\n", arg->map->n-oldn);
108 }
109
110 return arg->map->n;
111}
112
113/* Generic function that dispatches to the data generators */
114_static size_t
115gendata_h48(gendata_h48_arg_t *arg)
116{
117 static const size_t infosize = 88; /* TODO: change to e.g. 1024 */
118
119 size_t cocsepsize, h48size;
120
121 /* TODO: move info at the start */
122 arg->cocsepdata = (uint32_t *)arg->buf;
123 cocsepsize = gendata_cocsep(
124 (void *)arg->cocsepdata, arg->selfsim, arg->crep);
125 arg->h48data = arg->cocsepdata + (cocsepsize / sizeof(uint32_t));
126 arg->info = arg->h48data +
127 (H48_TABLESIZE(arg->h, arg->k) / sizeof(uint32_t));
128
129 if (arg->buf != NULL)
130 memset(arg->h48data, 0xFF, H48_TABLESIZE(arg->h, arg->k));
131
132 if (arg->h == 0 && arg->k == 4) {
133 h48size = gendata_h48h0k4(arg);
134 } else if (arg->k == 2) {
135 h48size = gendata_h48k2(arg);
136 } else {
137 h48size = 0;
138 LOG("Cannot generate data for h = %" PRIu8 " and k = %" PRIu8
139 " (not implemented yet)\n", arg->h, arg->k);
140 }
141
142 return infosize + cocsepsize + h48size;
143}
144
145/*
146TODO description
147generating fixed table with h=0, k=4
148*/
149_static size_t
150gendata_h48h0k4(gendata_h48_arg_t *arg)
151{
152 uint32_t j;
153 bfsarg_esep_t bfsarg;
154 int64_t sc, cc, esep_max;
155/*
156 uint64_t selfsim[COCSEP_CLASSES];
157 cube_t crep[COCSEP_CLASSES];
158 size_t cocsepsize, infosize;
159*/
160
161 if (arg->buf == NULL)
162 goto gendata_h48h0k4_return_size;
163/*
164 cocsepsize = gendata_cocsep(buf, selfsim, crep);
165 infosize = 88;
166
167 cocsepdata = (uint32_t *)buf;
168 buf32 = cocsepdata + cocsepsize / 4;
169 info = buf32 + (H48_TABLESIZE(0, 4) / sizeof(uint32_t));
170 memset(buf32, 0xFF, H48_TABLESIZE(0, 4));
171*/
172
173 esep_max = (int64_t)H48_COORDMAX(0);
174 sc = coord_h48(solved, arg->cocsepdata, 0);
175 set_esep_pval(arg->h48data, sc, 4, 0);
176 arg->info[1] = 1;
177 bfsarg = (bfsarg_esep_t) {
178 .cocsepdata = arg->cocsepdata,
179 .buf32 = arg->h48data,
180 .selfsim = arg->selfsim,
181 .crep = arg->crep
182 };
183 for (
184 bfsarg.done = 1, bfsarg.depth = 1, cc = 0;
185 bfsarg.done < esep_max && bfsarg.depth <= arg->maxdepth;
186 bfsarg.depth++
187 ) {
188 LOG("esep: generating depth %" PRIu8 "\n", bfsarg.depth);
189 cc = gendata_h48h0k4_bfs(&bfsarg);
190 bfsarg.done += cc;
191 arg->info[bfsarg.depth+1] = cc;
192 LOG("found %" PRId64 "\n", cc);
193 }
194
195 arg->info[0] = bfsarg.depth-1;
196
197 LOG("h48 pruning table computed\n");
198 LOG("Maximum pruning value: %" PRIu32 "\n", arg->info[0]);
199 LOG("Pruning value distribution:\n");
200 for (j = 0; j <= arg->info[0]; j++)
201 LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, arg->info[j+1]);
202
203gendata_h48h0k4_return_size:
204 return H48_TABLESIZE(0, 4);
205}
206
207_static int64_t
208gendata_h48h0k4_bfs(bfsarg_esep_t *arg)
209{
210 const uint8_t breakpoint = 10; /* Hand-picked optimal */
211
212 if (arg->depth < breakpoint)
213 return gendata_h48h0k4_bfs_fromdone(arg);
214 else
215 return gendata_h48h0k4_bfs_fromnew(arg);
216}
217
218_static int64_t
219gendata_h48h0k4_bfs_fromdone(bfsarg_esep_t *arg)
220{
221 uint8_t c, m, x;
222 uint32_t cc;
223 int64_t i, j, k;
224 cube_t cube, moved;
225
226 for (i = 0, cc = 0; i < (int64_t)H48_COORDMAX(0); i++) {
227 c = get_esep_pval(arg->buf32, i, 4);
228 if (c != arg->depth - 1)
229 continue;
230 cube = invcoord_h48(i, arg->crep, 0);
231 for (m = 0; m < 18; m++) {
232 moved = move(cube, m);
233 j = coord_h48(moved, arg->cocsepdata, 0);
234 if (get_esep_pval(arg->buf32, j, 4) <= arg->depth)
235 continue;
236 _foreach_h48sim(moved, arg->cocsepdata, arg->selfsim, 0,
237 k = coord_h48(moved, arg->cocsepdata, 0);
238 x = get_esep_pval(arg->buf32, k, 4);
239 set_esep_pval(arg->buf32, k, 4, arg->depth);
240 cc += x != arg->depth;
241 )
242 }
243 }
244
245 return cc;
246}
247
248_static int64_t
249gendata_h48h0k4_bfs_fromnew(bfsarg_esep_t *arg)
250{
251 uint8_t c, m, x;
252 uint32_t cc;
253 int64_t i, j;
254 cube_t cube, moved;
255
256 for (i = 0, cc = 0; i < (int64_t)H48_COORDMAX(0); i++) {
257 c = get_esep_pval(arg->buf32, i, 4);
258 if (c != 0xF)
259 continue;
260 cube = invcoord_h48(i, arg->crep, 0);
261 for (m = 0; m < 18; m++) {
262 moved = move(cube, m);
263 j = coord_h48(moved, arg->cocsepdata, 0);
264 x = get_esep_pval(arg->buf32, j, 4);
265 if (x >= arg->depth)
266 continue;
267 _foreach_h48sim(cube, arg->cocsepdata, arg->selfsim, 0,
268 j = coord_h48(cube, arg->cocsepdata, 0);
269 x = get_esep_pval(arg->buf32, j, 4);
270 set_esep_pval(arg->buf32, j, 4, arg->depth);
271 cc += x == 0xF;
272 )
273 break; /* Enough to find one, skip the rest */
274 }
275 }
276
277 return cc;
278}
279
280_static size_t
281gendata_h48k2(gendata_h48_arg_t *arg)
282{
283 static const uint8_t shortdepth = 8;
284 static const uint64_t capacity = 10000019;
285 static const uint64_t randomizer = 10000079;
286 static const uint8_t base[] = {
287 [0] = 8,
288 [1] = 8,
289 [2] = 8,
290 [3] = 8,
291 [4] = 9,
292 [5] = 9,
293 [6] = 9,
294 [7] = 9,
295 [8] = 10,
296 [9] = 10,
297 [10] = 10,
298 [11] = 10
299 };
300
301 uint64_t nshort;
302 h48map_t shortcubes;
303 gendata_h48short_arg_t shortarg;
304
305 DBG_ASSERT(base[arg->h] == 8, 0, "Only implemented for h <= 3 (base 8)\n");
306
307 if (arg->buf == NULL)
308 goto gendata_h48k2_return_size;
309
310 LOG("Computing depth <=%" PRIu8 "\n", shortdepth)
311 h48map_create(&shortcubes, capacity, randomizer);
312 shortarg = (gendata_h48short_arg_t) {
313 .maxdepth = shortdepth,
314 .cocsepdata = arg->cocsepdata,
315 .crep = arg->crep,
316 .selfsim = arg->selfsim,
317 .map = &shortcubes
318 };
319 nshort = gen_h48short(&shortarg);
320 LOG("Found %" PRIu64 "\n", nshort);
321
322 /* TODO: loop over map, set all found to 0, do 2 moves each */
323 LOG("The rest is not implemented yet\n");
324
325 h48map_destroy(&shortcubes);
326
327gendata_h48k2_return_size:
328 return H48_TABLESIZE(arg->h, 2);
329}
330
331_static_inline uint8_t
332get_esep_pval(const uint32_t *buf32, int64_t i, uint8_t k)
333{
334 return (buf32[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k);
335}
336
337_static_inline void
338set_esep_pval(uint32_t *buf32, int64_t i, uint8_t k, uint8_t val)
339{
340 buf32[H48_INDEX(i, k)] = (buf32[H48_INDEX(i, k)] & (~H48_MASK(i, k)))
341 | (val << H48_SHIFT(i, k));
342}
343
344_static_inline int8_t
345get_h48_bound(cube_t cube, uint32_t cdata, uint8_t h, uint8_t k, uint32_t *h48data)
346{
347 int64_t coord;
348
349 coord = coord_h48_edges(cube, COCLASS(cdata), TTREP(cdata), h);
350 return get_esep_pval(h48data, coord, k);
351}

Generated with cgit - Back to sebastiano.tronto.net