aboutsummaryrefslogtreecommitdiff
path: root/src/solver_step.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/solver_step.c')
-rw-r--r--src/solver_step.c296
1 files changed, 296 insertions, 0 deletions
diff --git a/src/solver_step.c b/src/solver_step.c
new file mode 100644
index 0000000..5c9d149
--- /dev/null
+++ b/src/solver_step.c
@@ -0,0 +1,296 @@
1#include "solver_step.h"
2
3typedef struct {
4 Cube * cube;
5 uint64_t * val;
6 Trans * t;
7} CubeData;
8
9static void apply_alg_cubedata(void *, void *, Alg *);
10static void init_indexes(Step *, CubeData *);
11static void * prepare_cube(void *, Cube *);
12static bool move_check_stop_eager(void *, DfsArg *, Threader *);
13static bool move_check_stop_lazy(void *, DfsArg *, Threader *);
14static bool move_check_stop_nonsol(void *, DfsArg *, Threader *);
15static bool is_solved_step(void *, void *);
16static Alg * validate_solution(void *, Alg *);
17static void * alloc_cubedata(void *);
18static void copy_cubedata(void *, void *, void *);
19static void free_cubedata(void *, void *);
20static void invert_cubedata(void *, void *);
21static bool niss_makes_sense(void *, void *, Alg *);
22static Solver * new_stepsolver_nocheckstop(Step *step);
23
24static void
25apply_alg_cubedata(void *param, void *cubedata, Alg *alg)
26{
27 Step *s = (Step *)param;
28 CubeData *data = (CubeData *)cubedata;
29
30 apply_alg(alg, data->cube);
31 init_indexes(s, data);
32}
33
34static void
35init_indexes(Step *step, CubeData *data)
36{
37 int i;
38 Cube moved;
39 Trans t, tt;
40
41 for (i = 0; i < step->n_coord; i++) {
42 t = step->coord_trans[i];
43 copy_cube(data->cube, &moved);
44 apply_trans(t, &moved);
45 data->val[i] = index_coord(step->coord[i], &moved, &tt);
46 data->t[i] = transform_trans(tt, t);
47 }
48}
49
50static void *
51prepare_cube(void *param, Cube *cube)
52{
53 int i;
54 Step *s;
55 CubeData *data;
56
57 s = (Step *)param;
58
59 for (i = 0; i < s->n_coord; i++) {
60 s->pd[i] = malloc(sizeof(PruneData));
61 s->pd[i]->moveset = s->moveset;
62/* TODO: check if moveset initialization works fine,
63 e.g. if there is a variable to save the initialized status
64 or if it gets initialized multiple times */
65 init_moveset(s->moveset);
66 s->pd[i]->coord = s->coord[i];
67 gen_coord(s->coord[i]);
68 s->pd[i]->compact = s->pd_compact[i];
69 s->pd[i] = genptable(s->pd[i], 4); /* TODO: threads */
70 }
71
72 data = alloc_cubedata(param);
73 data->cube = malloc(sizeof(Cube));
74 copy_cube(cube, data->cube);
75 init_indexes(s, data);
76
77 return data;
78}
79
80static bool
81move_check_stop_eager(void *param, DfsArg *arg, Threader *threader)
82{
83 int nsol;
84
85 if (move_check_stop_nonsol(param, arg, threader))
86 return true;
87
88 nsol = threader->get_nsol(arg->threaddata);
89 return nsol >= arg->opts->max_solutions;
90}
91
92static bool
93move_check_stop_lazy(void *param, DfsArg *arg, Threader *threader)
94{
95 int nsol;
96
97 nsol = threader->get_nsol(arg->threaddata);
98 if (nsol >= arg->opts->max_solutions)
99 return true;
100
101 return move_check_stop_nonsol(param, arg, threader);
102}
103
104static bool
105move_check_stop_nonsol(void *param, DfsArg *arg, Threader *threader)
106{
107 int i, goal, bound;
108 Move mm, lastmove;
109 Trans tt = uf;
110 CubeData *data;
111 Step *s;
112
113 s = (Step *)param;
114 data = (CubeData *)arg->cubedata;
115
116 bound = 0;
117 goal = arg->d - arg->current_alg->len;
118/* TODO: check if len is 0 */
119 lastmove = arg->current_alg->move[arg->current_alg->len-1];
120 for (i = 0; i < s->n_coord; i++) {
121 mm = transform_move(data->t[i], lastmove);
122 data->val[i] = move_coord(s->coord[i], mm, data->val[i], &tt);
123 data->t[i] = transform_trans(tt, data->t[i]);
124
125 bound = MAX(bound, ptableval(s->pd[i], data->val[i]));
126 if (arg->opts->can_niss && !arg->niss)
127 bound = MIN(1, bound);
128
129 if (bound > goal) {
130 return true;
131 }
132 }
133
134 return false;
135}
136
137static bool
138is_solved_step(void *param, void *cubedata)
139{
140 int i;
141 Step *s;
142 CubeData *data;
143
144 s = (Step *)param;
145 data = (CubeData *)cubedata;
146
147 for (i = 0; i < s->n_coord; i++)
148 if (data->val[i] != 0)
149 return false;
150
151 return true;
152}
153
154static Alg *
155validate_solution(void *param, Alg *alg)
156{
157 return ((Step *)param)->is_valid(alg);
158}
159
160static void *
161alloc_cubedata(void *param)
162{
163 Step *s;
164 CubeData *data;
165
166 s = (Step *)param;
167
168 data = malloc(sizeof(CubeData));
169 /* We do not need to allocate a cube */
170 data->val = malloc(s->n_coord * sizeof(uint64_t));
171 data->t = malloc(s->n_coord * sizeof(Trans));
172
173 return data;
174}
175
176static void
177copy_cubedata(void *param, void *src, void *dst)
178{
179 int i;
180 Step *s;
181 CubeData *newdata, *olddata;
182
183 s = (Step *)param;
184 olddata = (CubeData *)src;
185 newdata = (CubeData *)dst;
186
187 /* Copy reference: we never move the cube */
188 newdata->cube = olddata->cube;
189 for (i = 0; i < s->n_coord; i++) {
190 newdata->val[i] = olddata->val[i];
191 newdata->t[i] = olddata->t[i];
192 }
193}
194
195static void
196free_cubedata(void *param, void *cubedata)
197{
198 CubeData *data;
199
200 data = (CubeData *)cubedata;
201
202 free(data->t);
203 free(data->val);
204 /* We do not free the cube */
205 free(data);
206}
207
208static void
209invert_cubedata(void *param, void *cubedata)
210{
211 Step *s;
212 CubeData *data;
213
214 s = (Step *)param;
215 data = (CubeData *)cubedata;
216
217 invert_cube(data->cube);
218 init_indexes(s, data);
219}
220
221static bool
222niss_makes_sense(void *param, void *cubedata, Alg *alg)
223{
224 Step *s;
225 CubeData *data;
226
227 s = (Step *)param;
228 data = (CubeData *)cubedata;
229
230 if (s->final)
231 return false;
232
233 if (alg->len_normal == 0)
234 return true;
235
236 Move m = inverse_move(alg->move_normal[alg->len_normal-1]);
237 for (int i = 0; i < s->n_coord; i++) {
238 Move mm = transform_move(data->t[i], m);
239 uint64_t u = move_coord(s->coord[i], mm, 0, NULL);
240 if (ptableval(s->pd[i], u) > 0)
241 return true;
242 }
243
244 return false;
245}
246
247static Solver *
248new_stepsolver_nocheckstop(Step *step)
249{
250 Solver *solver;
251
252 solver = malloc(sizeof(Solver));
253
254 solver->moveset = step->moveset;
255 solver->param = step;
256
257 solver->apply_alg = apply_alg_cubedata;
258 solver->prepare_cube = prepare_cube;
259 solver->is_solved = is_solved_step;
260 solver->validate_solution = validate_solution;
261 solver->alloc_cubedata = alloc_cubedata;
262 solver->copy_cubedata = copy_cubedata;
263 solver->free_cubedata = free_cubedata;
264 solver->invert_cube = invert_cubedata;
265 solver->niss_makes_sense = niss_makes_sense;
266
267 return solver;
268}
269
270Solver *
271new_stepsolver_eager(Step *step)
272{
273 Solver *solver;
274
275 solver = new_stepsolver_nocheckstop(step);
276 solver->move_check_stop = move_check_stop_eager;
277
278 return solver;
279}
280
281Solver *
282new_stepsolver_lazy(Step *step)
283{
284 Solver *solver;
285
286 solver = new_stepsolver_nocheckstop(step);
287 solver->move_check_stop = move_check_stop_lazy;
288
289 return solver;
290}
291
292void
293free_stepsolver(Solver *solver)
294{
295 free(solver);
296}

Generated with cgit - Back to sebastiano.tronto.net