f6e22340bb2e0ebde55d3b223d25c73b0d1798e5
[mc1516pa.git] / modelchecker / coord.c
1 #include <argp.h>
2 #include <inttypes.h>
3 #include <locale.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/time.h>
8
9 #ifdef HAVE_PROFILER
10 #include <gperftools/profiler.h>
11 #endif
12
13 #include <sylvan.h>
14 #include <llmsset.h>
15 #include <lace.h>
16
17 #include "coord.h"
18 #include "sokoban.h"
19
20 /*
21 * Global TODOs for now:
22 * - update the helper maps so it is a single bimap
23 * - make a data structure for relations
24 * - encode relations as a set of four relations for each move
25 */
26
27 typedef struct {
28 int x;
29 int y;
30 } xy;
31
32 typedef struct {
33 int var[3];
34 } bddvar;
35
36 typedef struct {
37 xy key;
38 bddvar value;
39 UT_hash_handle hh;
40 } xy_bddvar_map;
41
42 typedef struct {
43 int key;
44 xy value;
45 UT_hash_handle hh;
46 } bddvar_xy_map;
47
48 typedef struct {
49 xy_bddvar_map f;
50 bddvar_xy_map t;
51 } bimap;
52
53 xy_bddvar_map *getxy(int x, int y, xy_bddvar_map *map)
54 {
55 xy_bddvar_map k, *r = NULL;
56 memset(&k, 0, sizeof(xy_bddvar_map));
57 k.key.x = x;
58 k.key.y = y;
59 HASH_FIND(hh, map, &k.key, sizeof(xy), r);
60 return r;
61 }
62
63 bddvar_xy_map *getbdd(int key, bddvar_xy_map *map)
64 {
65 bddvar_xy_map k, *r = NULL;
66 memset(&k, 0, sizeof(bddvar_xy_map));
67 k.key = key;
68 HASH_FIND(hh, map, &k.key, sizeof(int), r);
69 return r;
70 }
71
72 xy_bddvar_map *create_xy_bddvar_map(sokoban_screen *screen)
73 {
74 int varcount = 0;
75 sokoban_screen *r;
76 xy_bddvar_map *xybdd = NULL;
77 for(r=screen; r != NULL; r = (sokoban_screen *)(r->hh.next)){
78 xy_bddvar_map *f = NULL;
79 //bddvar_xy_map *t = NULL;
80
81 f = (xy_bddvar_map *)malloc(sizeof(xy_bddvar_map));
82 memset(f, 0, sizeof(xy_bddvar_map));
83 f->key.x = r->coord.x;
84 f->key.y = r->coord.y;
85 printf("test!: %d %d\n", r->coord.x, r->coord.y);
86 f->value.var[0] = varcount;
87 f->value.var[1] = varcount + 1;
88 f->value.var[2] = varcount + 2;
89 HASH_ADD(hh, xybdd, key, sizeof(xy), f);
90 varcount = varcount + 3;
91 }
92 return xybdd;
93 }
94
95 bddvar_xy_map *create_bddvar_xy_map(sokoban_screen *screen)
96 {
97 int varcount = 0;
98 sokoban_screen *r;
99 bddvar_xy_map *bddxy = NULL;
100 for(r=screen; r != NULL; r = (sokoban_screen *)(r->hh.next)){
101 for (int i = 0; i <3; i++){
102 bddvar_xy_map *f = NULL;
103 //bddvar_xy_map *t = NULL;
104
105 f = (bddvar_xy_map *)malloc(sizeof(bddvar_xy_map));
106 memset(f, 0, sizeof(bddvar_xy_map));
107 f->key = varcount + i;
108 f->value.x = r->coord.x;
109 f->value.y = r->coord.y;
110 HASH_ADD(hh, bddxy, key, sizeof(int), f);
111 }
112 varcount = varcount + 3;
113 }
114 return bddxy;
115 }
116
117 /*
118 * Each coordinate has three related boolean variables. The combination of those boolean variables
119 * defines tiles:
120 * 000: Wall
121 * 001: Free
122 * 010: Box
123 * 100: Box on target
124 * 011: Target
125 * 101: Agent
126 * 110: Agent on target
127 * In the BDD representation, the state is represented by n * 3 variables, where n is the number of
128 * tiles in the shrinked screen.
129 * It seems that the move variable is not necessary since non-deterministic moves can be emvedded
130 * directly in transition relations.
131 */
132
133 BDD encode_screen(sokoban_screen *screen)
134 {
135 BDD state = sylvan_false;
136 int tile_index = 0;
137 sokoban_screen *r;
138 LACE_ME;
139 for(r=screen; r != NULL; r = (sokoban_screen *)(r->hh.next)){
140 switch(r->tile){
141 case FREE:
142 if (state == sylvan_false){
143 state = sylvan_not(sylvan_ithvar(tile_index));
144 tile_index++;
145 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
146 tile_index++;
147 state = sylvan_and(state, sylvan_ithvar(tile_index));
148 tile_index++;
149 }
150 else {
151 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
152 tile_index++;
153 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
154 tile_index++;
155 state = sylvan_and(state, sylvan_ithvar(tile_index));
156 tile_index++;
157 }
158 break;
159 case WALL:
160 if (state == sylvan_false){
161 state = sylvan_not(sylvan_ithvar(tile_index));
162 tile_index++;
163 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
164 tile_index++;
165 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
166 tile_index++;
167 }
168 else {
169 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
170 tile_index++;
171 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
172 tile_index++;
173 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
174 tile_index++;
175 }
176 break;
177 case BOX:
178 if (state == sylvan_false){
179 state = sylvan_not(sylvan_ithvar(tile_index));
180 tile_index++;
181 state = sylvan_and(state, sylvan_ithvar(tile_index));
182 tile_index++;
183 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
184 tile_index++;
185 }
186 else {
187 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
188 tile_index++;
189 state = sylvan_and(state, sylvan_ithvar(tile_index));
190 tile_index++;
191 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
192 tile_index++;
193 }
194 break;
195 case TARGET:
196 if (state == sylvan_false){
197 state = sylvan_not(sylvan_ithvar(tile_index));
198 tile_index++;
199 state = sylvan_and(state, sylvan_ithvar(tile_index));
200 tile_index++;
201 state = sylvan_and(state, sylvan_ithvar(tile_index));
202 tile_index++;
203 }
204 else {
205 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
206 tile_index++;
207 state = sylvan_and(state, sylvan_ithvar(tile_index));
208 tile_index++;
209 state = sylvan_and(state, sylvan_ithvar(tile_index));
210 tile_index++;
211 }
212 break;
213 case AGENT:
214 if (state == sylvan_false){
215 state = sylvan_ithvar(tile_index);
216 tile_index++;
217 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
218 tile_index++;
219 state = sylvan_and(state, sylvan_ithvar(tile_index));
220 tile_index++;
221 }
222 else {
223 state = sylvan_and(state, sylvan_ithvar(tile_index));
224 tile_index++;
225 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
226 tile_index++;
227 state = sylvan_and(state, sylvan_ithvar(tile_index));
228 tile_index++;
229 }
230 break;
231 case TARGAGENT:
232 if (state == sylvan_false){
233 state = sylvan_ithvar(tile_index);
234 tile_index++;
235 state = sylvan_and(state, sylvan_ithvar(tile_index));
236 tile_index++;
237 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
238 tile_index++;
239 }
240 else {
241 state = sylvan_and(state, sylvan_ithvar(tile_index));
242 tile_index++;
243 state = sylvan_and(state, sylvan_ithvar(tile_index));
244 tile_index++;
245 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
246 tile_index++;
247 }
248 break;
249 case TARGBOX:
250 if (state == sylvan_false){
251 state = sylvan_ithvar(tile_index);
252 tile_index++;
253 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
254 tile_index++;
255 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
256 tile_index++;
257 }
258 else {
259 state = sylvan_and(state, sylvan_ithvar(tile_index));
260 tile_index++;
261 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
262 tile_index++;
263 state = sylvan_and(state, sylvan_not(sylvan_ithvar(tile_index)));
264 tile_index++;
265 }
266 break;
267 }
268 }
269 /*
270 xy_bddvar_map *map = NULL;
271 map = create_xy_bddvar_map(screen);
272 xy_bddvar_map *m = getxy(1, 1, map);
273 bddvar_xy_map *map2 = NULL;
274 map2 = create_bddvar_xy_map(screen);
275 bddvar_xy_map *m2 = getbdd(2, map2);
276 printf("Test1: %d %d\n", m->value.var[0], m->value.var[1]);
277 printf("Test2: %d %d\n", m2->value.x, m2->value.y);
278 */
279 printf("%d tiles were encoded\n", tile_index);
280 return state;
281 }
282
283 BDD encode_rel(sokoban_screen *screen)
284 {
285 int num_tiles;
286 num_tiles = HASH_COUNT(screen);
287 printf("Number of tiles: %d\n", num_tiles);
288 return sylvan_true;
289 }
290
291 void test()
292 {
293
294 printf("Test!\n");
295 BDD a = sylvan_true;
296 BDD b = sylvan_not(a);
297 if (b == sylvan_false){
298 printf("BDD works!\n");
299 } else {
300 printf("BDD does not work!\n");
301 }
302 LACE_ME;
303 BDD c = sylvan_ithvar(1);
304 if (sylvan_high(c) == sylvan_true && sylvan_low(c) == sylvan_false) printf("VAR works 1\n");
305 if (sylvan_var(c) == 1) printf("Var works 2\n");
306 }