From b9448d600bb0f3249ae08db3a9ecd5f1f7794fda Mon Sep 17 00:00:00 2001 From: Mart Lubbers <mart@martlubbers.net> Date: Tue, 12 Apr 2016 20:33:05 +0200 Subject: [PATCH] started with transitions, I think agent transitions work... --- modelchecker/object.c | 121 +++++++++++++++++++++++++++++++++++++--- modelchecker/toy.screen | 1 + 2 files changed, 113 insertions(+), 9 deletions(-) create mode 100644 modelchecker/toy.screen diff --git a/modelchecker/object.c b/modelchecker/object.c index 769163f..362802d 100644 --- a/modelchecker/object.c +++ b/modelchecker/object.c @@ -7,6 +7,8 @@ #define MAX_BOX 50 #define EPRINTF(fmt, as...) fprintf(stderr, fmt, ##as) +typedef enum {UP, DOWN, LEFT, RIGHT} direction; + int ilog2(int x) { int l = 1; @@ -27,9 +29,9 @@ void get_screen_metrics(sokoban_screen *screen, *agentx = 0; *agenty = 0; sokoban_screen *r; - for(r=screen; r != NULL; r = (sokoban_screen *)(r->hh.next)){ + for(r=screen; r != NULL; r = r->hh.next){ *mx = r->coord.x > *mx ? r->coord.x : *mx; - *my = r->coord.x > *mx ? r->coord.x : *mx; + *my = r->coord.y > *my ? r->coord.x : *my; switch(r->tile){ case TARGAGENT: case AGENT: @@ -47,15 +49,16 @@ void get_screen_metrics(sokoban_screen *screen, } } +//LSB first BDD encode_int(BDD state, int x, int bx, int *variablenum) { LACE_ME; char *encoding = malloc(bx); for(int i = 0; i<bx; i++){ if((x & (1<<i)) > 0){ - state = sylvan_and(state, sylvan_ithvar(*variablenum)); + state = sylvan_and(state, sylvan_ithvar(*variablenum*2)); } else { - state = sylvan_and(state, sylvan_nithvar(*variablenum)); + state = sylvan_and(state, sylvan_nithvar(*variablenum*2)); } *variablenum += 1; } @@ -69,6 +72,83 @@ BDD encode_position(BDD state, int x, int y, int bx, int by, int *variablenum) return encode_int(state, y, by, variablenum); } +BDD encode_transition(sokoban_screen *scr, BDD state, int bx, int by, int *varnum, direction dir) +{ + LACE_ME; + //Increase the position + int oldvarnum = *varnum; + + //RIGHT + if(dir == RIGHT){ + state = sylvan_and(state, + sylvan_xor(sylvan_ithvar(*varnum*2), sylvan_ithvar(*varnum*2+1))); + *varnum += 1; + for(int i = 1; i<bx; i++){ + state = sylvan_and(state, + sylvan_xor(sylvan_ithvar(*varnum*2-1), + sylvan_xor(sylvan_ithvar(*varnum*2), + sylvan_ithvar(*varnum*2+1)))); + *varnum += 1; + } + } else if(dir == LEFT){ + //TODO + *varnum += bx; + }else { + *varnum += bx; + } + + //DOWN + if(dir == DOWN){ + state = sylvan_and(state, + sylvan_xor(sylvan_ithvar(*varnum*2), sylvan_ithvar(*varnum*2+1))); + *varnum += 1; + for(int i = 1; i<by; i++){ + state = sylvan_and(state, + sylvan_xor(sylvan_ithvar(*varnum*2-1), + sylvan_xor(sylvan_ithvar(*varnum*2), + sylvan_ithvar(*varnum*2+1)))); + *varnum += 1; + } + } else if(dir == UP){ + //TODO + *varnum += by; + } else { + *varnum += by; + } + + //Check wether it is a valid position + BDD legalpos = sylvan_false; + for(sokoban_screen *r=scr; r != NULL; r = r->hh.next){ + int x = r->coord.x; + int y = r->coord.y; + *varnum = oldvarnum; + + BDD currentx = sylvan_true; + for(int i = 0; i<bx; i++){ + if((x & (1<<i)) > 0){ + currentx = sylvan_and(currentx, sylvan_ithvar(*varnum*2+1)); + } else { + currentx = sylvan_and(currentx, sylvan_nithvar(*varnum*2+1)); + } + *varnum += 1; + } + + BDD currenty = sylvan_true; + for(int i = 0; i<by; i++){ + if((y & (1<<i)) > 0){ + currenty = sylvan_and(currenty, sylvan_ithvar(*varnum*2+1)); + } else { + currenty = sylvan_and(currenty, sylvan_nithvar(*varnum*2+1)); + } + *varnum += 1; + } + legalpos = sylvan_or(legalpos, + sylvan_and(currentx, currenty)); + } + + return sylvan_and(state, legalpos); +} + /* * We have variables numbered 1... * Per coordinate we need k=bitsx+bitsy variables @@ -79,21 +159,44 @@ BDD encode_position(BDD state, int x, int y, int bx, int by, int *variablenum) */ BDD solve_object(sokoban_screen *scr) { + LACE_ME; int nboxes, mx, my, wx, wy, agentx, agenty; int varnum = 0; int boxx[MAX_BOX]; int boxy[MAX_BOX]; + get_screen_metrics(scr, &nboxes, &mx, &my, &agentx, &agenty, boxx, boxy); EPRINTF("Max x: %d, thus %d bits\n", mx, (wx = ilog2(mx))); EPRINTF("Max y: %d, thus %d bits\n", my, (wy = ilog2(my))); EPRINTF("%d boxes\n", nboxes); - BDD state = sylvan_true; - state = encode_position(state, agentx, agenty, wx, wy, &varnum); + BDD init = encode_position(sylvan_true, agentx, agenty, wx, wy, &varnum); for(int i = 0; i<nboxes; i++){ - state = encode_position(state, boxx[i], boxy[i], wx, wy, &varnum); + init = encode_position(init, boxx[i], boxy[i], wx, wy, &varnum); } - - return state; + + varnum = 0; + BDD trans_r = encode_transition(scr, sylvan_true, mx, my, &varnum, RIGHT); + varnum = 0; + BDD trans_l = encode_transition(scr, sylvan_true, mx, my, &varnum, LEFT); + varnum = 0; + BDD trans_d = encode_transition(scr, sylvan_true, mx, my, &varnum, DOWN); + varnum = 0; + BDD trans_u = encode_transition(scr, sylvan_true, mx, my, &varnum, UP); + + BDD old = sylvan_false; + BDD new = init; + int iteration = 0; + while(new != old){ + EPRINTF("Iteration %d\n", iteration++); + old = new; + new = sylvan_or(new, sylvan_relnext(new, trans_d, false)); + new = sylvan_or(new, sylvan_relnext(new, trans_r, false)); + new = sylvan_or(new, sylvan_relnext(new, trans_u, false)); + new = sylvan_or(new, sylvan_relnext(new, trans_l, false)); + sylvan_printdot_nc(old); + } + + return init; } diff --git a/modelchecker/toy.screen b/modelchecker/toy.screen new file mode 100644 index 0000000..8d4f16e --- /dev/null +++ b/modelchecker/toy.screen @@ -0,0 +1 @@ +@$. -- 2.20.1