aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48/gendata_cocsep.h
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-08-25 10:27:21 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-08-25 10:27:21 +0200
commitdd44adceed44bec3dc313b77ec6f69123dc59016 (patch)
treebef73833770b191e113f90c4aa3d6b1683b35ba2 /src/solvers/h48/gendata_cocsep.h
parent9c5bdcb09dc56104f7ea34c71a9418c7908ed227 (diff)
downloadnissy-core-dd44adceed44bec3dc313b77ec6f69123dc59016.tar.gz
nissy-core-dd44adceed44bec3dc313b77ec6f69123dc59016.zip
Started work on k=2 tables; further split h48 gendata
Diffstat (limited to 'src/solvers/h48/gendata_cocsep.h')
-rw-r--r--src/solvers/h48/gendata_cocsep.h169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/solvers/h48/gendata_cocsep.h b/src/solvers/h48/gendata_cocsep.h
new file mode 100644
index 0000000..13ce68b
--- /dev/null
+++ b/src/solvers/h48/gendata_cocsep.h
@@ -0,0 +1,169 @@
1#define COCSEP_CLASSES ((size_t)3393)
2#define COCSEP_TABLESIZE ((size_t)_3p7 << (size_t)7)
3#define COCSEP_VISITEDSIZE ((COCSEP_TABLESIZE + (size_t)7) / (size_t)8)
4#define COCSEP_FULLSIZE ((size_t)4 * (COCSEP_TABLESIZE + (size_t)12))
5
6#define VISITED_IND(i) ((uint32_t)(i) / UINT32_C(8))
7#define VISITED_MASK(i) (UINT32_C(1) << ((uint32_t)(i) % UINT32_C(8)))
8
9#define CBOUND_MASK UINT32_C(0xFF)
10#define CBOUND(x) ((x) & CBOUND_MASK)
11
12typedef struct {
13 cube_t cube;
14 uint8_t depth;
15 uint8_t maxdepth;
16 uint16_t *n;
17 uint32_t *buf32;
18 uint8_t *visited;
19 uint64_t *selfsim;
20 cube_t *rep;
21} dfsarg_cocsep_t;
22
23_static_inline bool get_visited(const uint8_t *, int64_t);
24_static_inline void set_visited(uint8_t *, int64_t);
25
26_static size_t gendata_cocsep(void *, uint64_t *, cube_t *);
27_static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *);
28
29_static_inline int8_t get_h48_cdata(cube_t, uint32_t *, uint32_t *);
30
31/*
32Each element of the cocsep table is a uint32_t used as follows:
33 - Lowest 8-bit block: pruning value
34 - Second-lowest 8-bit block: "ttrep" (transformation to representative)
35 - Top 16-bit block: symcoord value
36After the data as described above, more auxiliary information is appended:
37 - A uint32_t representing the number of symmetry classes
38 - A uint32_t representing the highest value of the pruning table
39 - One uint32_t for each "line" of the pruning table, representing the number
40 of positions having that pruning value.
41*/
42_static size_t
43gendata_cocsep(void *buf, uint64_t *selfsim, cube_t *rep)
44{
45 uint32_t *buf32, *info, cc;
46 uint16_t n;
47 uint8_t i, j, visited[COCSEP_VISITEDSIZE];
48 dfsarg_cocsep_t arg;
49
50 if (buf == NULL)
51 goto gendata_cocsep_return_size;
52
53 buf32 = (uint32_t *)buf;
54 info = buf32 + COCSEP_TABLESIZE;
55 memset(buf32, 0xFF, sizeof(uint32_t) * COCSEP_TABLESIZE);
56 if (selfsim != NULL)
57 memset(selfsim, 0, sizeof(uint64_t) * COCSEP_CLASSES);
58
59 arg = (dfsarg_cocsep_t) {
60 .cube = solved,
61 .n = &n,
62 .buf32 = buf32,
63 .visited = visited,
64 .selfsim = selfsim,
65 .rep = rep
66 };
67 for (i = 0, n = 0, cc = 0; i < 10; i++) {
68 LOG("cocsep: generating depth %" PRIu8 "\n", i);
69 memset(visited, 0, COCSEP_VISITEDSIZE);
70 arg.depth = 0;
71 arg.maxdepth = i;
72 cc = gendata_cocsep_dfs(&arg);
73 info[i+2] = cc;
74 LOG("found %" PRIu32 "\n", cc);
75 }
76
77 info[0] = (uint32_t)n;
78 info[1] = 9; /* Known max pruning value */
79 DBG_ASSERT(n == COCSEP_CLASSES, 0,
80 "cocsep: computed %" PRIu16 " symmetry classes, "
81 "expected %zu\n", n, COCSEP_CLASSES);
82
83 LOG("cocsep data computed\n");
84 LOG("Symmetry classes: %" PRIu32 "\n", info[0]);
85 LOG("Maximum pruning value: %" PRIu32 "\n", info[1]);
86 LOG("Pruning value distribution:\n");
87 for (j = 0; j < 10; j++)
88 LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, info[j+2]);
89
90gendata_cocsep_return_size:
91 return COCSEP_FULLSIZE;
92}
93
94_static uint32_t
95gendata_cocsep_dfs(dfsarg_cocsep_t *arg)
96{
97 uint8_t m;
98 uint32_t cc, class, ttrep, depth, olddepth, tinv;
99 uint64_t t;
100 int64_t i, j;
101 cube_t d;
102 dfsarg_cocsep_t nextarg;
103
104 i = coord_cocsep(arg->cube);
105 olddepth = (uint8_t)(arg->buf32[i] & 0xFF);
106 if (olddepth < arg->depth || get_visited(arg->visited, i))
107 return 0;
108 set_visited(arg->visited, i);
109
110 if (arg->depth == arg->maxdepth) {
111 if ((arg->buf32[i] & 0xFF) != 0xFF)
112 return 0;
113
114 if (arg->rep != NULL)
115 arg->rep[*arg->n] = arg->cube;
116 for (t = 0, cc = 0; t < 48; t++) {
117 d = transform_corners(arg->cube, t);
118 j = coord_cocsep(d);
119 if (i == j && arg->selfsim != NULL)
120 arg->selfsim[*arg->n] |= UINT64_C(1) << t;
121 if (COCLASS(arg->buf32[j]) != UINT32_C(0xFFFF))
122 continue;
123 set_visited(arg->visited, j);
124 tinv = inverse_trans(t);
125 olddepth = arg->buf32[j] & 0xFF;
126 cc += olddepth == 0xFF;
127
128 class = (uint32_t)(*arg->n) << UINT32_C(16);
129 ttrep = (uint32_t)tinv << UINT32_C(8);
130 depth = (uint32_t)arg->depth;
131 arg->buf32[j] = class | ttrep | depth;
132 }
133 (*arg->n)++;
134
135 return cc;
136 }
137
138 memcpy(&nextarg, arg, sizeof(dfsarg_cocsep_t));
139 nextarg.depth++;
140 for (m = 0, cc = 0; m < 18; m++) {
141 nextarg.cube = move(arg->cube, m);
142 cc += gendata_cocsep_dfs(&nextarg);
143 }
144
145 return cc;
146}
147
148_static_inline bool
149get_visited(const uint8_t *a, int64_t i)
150{
151 return a[VISITED_IND(i)] & VISITED_MASK(i);
152}
153
154_static_inline void
155set_visited(uint8_t *a, int64_t i)
156{
157 a[VISITED_IND(i)] |= VISITED_MASK(i);
158}
159
160_static_inline int8_t
161get_h48_cdata(cube_t cube, uint32_t *cocsepdata, uint32_t *cdata)
162{
163 int64_t coord;
164
165 coord = coord_cocsep(cube);
166 *cdata = cocsepdata[coord];
167
168 return CBOUND(*cdata);
169}

Generated with cgit - Back to sebastiano.tronto.net