/* 2012 (C) Jussi Rintanen jrintanen.jr@gmail.com */ #include #include #include "asyntax.h" #include "intsets.h" #include "ordintsets.h" #include "operators.h" #include "tables.h" #include "invariants.h" #include "main.h" #define noDEBUG /* Local copies (for inlining) of intsets.c functions */ int *iITptr; int iITcounter; inline void iITstart(intset s) { iITcounter = s->nOfEls; iITptr = s->elements; } inline int iITnext(int *i) { if(iITcounter <= 0) return 0; iITcounter -= 1; *i = *(iITptr++); return 1; } /* */ void printlitlist(intset s) { int i; iITstart(s); while(iITnext(&i)) { if(i&1) printf(" -"); else printf(" "); printatomi(feVAR(i)); } } void showInvariants() { int i,cntpersistent; cntpersistent = 0; printf("PERSISTENT LITERALS:"); fflush(stdout); for(i=0;icondition->t == TRUE && all != current) { ptr = all->effectlits; while(*ptr != -1) { ISinsert(*ptr,s); ptr = ptr+1; } } all = all->tl; } } void guaranteedtrue(fma *f,intset ac) { fmalist *fs; switch(f->t) { case FALSE: case TRUE: break; case conj: fs = f->juncts; while(fs != NULL) { guaranteedtrue(fs->hd,ac); fs = fs->tl; } break; case disj: break; case patom: ISinsert(fePLIT(f->a),ac); break; case natom: ISinsert(feNLIT(f->a),ac); break; } } int nofcondeffs(eff *e) { int cnt; cnt = 0; while(e != NULL) { cnt = cnt + 1; e = e->tl; } return cnt; } llist **prepros; /* */ void preprocess() { int i,j,effcnt; intset preconlits; eff *e; prepros = (llist **)statmalloc(401,nOfActions * sizeof(llist *)); preconlits = IScreate(1000); for(i=0;icondition,prepros[i][j].before); ISaddelements(preconlits,prepros[i][j].before); #ifdef DEBUG printf("BEFORE"); fflush(stdout); printlitlist(prepros[i][j].before); fflush(stdout); printf("\n"); fflush(stdout); #endif prepros[i][j].after = IScreateSize(20); addeffectlitsL(e->effectlits,e,&(actions[i].effects),prepros[i][j].after); #ifdef DEBUG printf("AFTER"); fflush(stdout); printlitlist(prepros[i][j].after); fflush(stdout); printf("\n\n"); fflush(stdout); #endif e = e->tl; j = j + 1; } } } int **alleffectlits; int nofeffectlits(eff *e) { int cnt = 0; int *ptr; while(e != NULL) { ptr = e->effectlits; while(*ptr != -1) { cnt = cnt + 1; ptr = ptr + 1; } e = e-> tl; } return cnt; } void preprocess2() { int i,sz; eff *e; int *ptr,*fill; alleffectlits = (int **)statmalloc(499,nOfActions * sizeof(int *)); for(i=0;ieffectlits; while(*ptr != -1) { *fill = *ptr; fill = fill + 1; ptr = ptr + 1; } e = e->tl; } *fill = -1; } } #ifdef CFMA inline int ctruep(cfma f) { switch(((int)f)&7) { case cNATOMtag: return (onelits[((int)f) >> 3] != 1); case cPATOMtag: return (onelits[((int)f) >> 3] != 0); case cTRUEtag: return 1; case cFALSEtag: return 0; default: if(((int)(*f))&1) { /* Conjunction */ int i,cnt; cnt = ((int)(f[0])) >> 1; for(i=0;i> 1; for(i=0;it) { case natom: return (onelits[f->a] != 1); case patom: return (onelits[f->a] != 0); case disj: fs = f->juncts; while(fs != NULL) { if(truep(fs->hd)) return 1; fs = fs->tl; } return 0; case conj: fs = f->juncts; while(fs != NULL) { if(!truep(fs->hd)) return 0; fs = fs->tl; } return 1; case TRUE: return 1; case FALSE: return 0; } return 0; } //int notmadefalse(int l,eff *e) { // int *ls; // while(e != NULL) { // ls = e->effectlits; // while(*ls != -1) { // if(l == feNEG(*ls)) return 0; // ls = ls + 1; // } // e = e->tl; // } // return 1; //} int madefalse(int l,int i) { int *ptr; ptr = alleffectlits[i]; while(*ptr != -1) { if(*ptr == feNEG(l)) return 1; ptr = ptr + 1; } return 0; } void removefalsified(eff *e,intset s) { int *ptr; while(e != NULL) { ptr = e->effectlits; while(*ptr != -1) { ISremove(feNEG(*ptr),s); ptr = ptr + 1; } e = e->tl; } } int localISmember0(int i,intset s) { int j; for(j=0;jnOfEls;j++) { if(s->elements[j] == i) return 1; } return 0; } int localISmember1(int i,intset s) { int j; for(j=0;jnOfEls;j++) { if(s->elements[j] == i) return 1; } return 0; } int localISmember2(int i,intset s) { int j; for(j=0;jnOfEls;j++) { if(s->elements[j] == i) return 1; } return 0; } int localISmember3(int i,intset s) { int j; for(j=0;jnOfEls;j++) { if(s->elements[j] == i) return 1; } return 0; } int wastruebefore(int l,intset before) { int i; // if(localISmember(l,before)) return 1; /* Go through the relevant invariants. */ for(i=0;inOfEls;i++) { if(before->elements[i] == l) return 1; if(localISmember0(l,twolits[feNEG(before->elements[i])])) return 1; } return 0; } void computeinvariants() { int i,iteration,change,j,k; eff *e; int *il; llist *prep; intset trueones,ext; int trueonesinitialized; preprocess(); preprocess2(); ext = IScreateSize(10000); trueones = IScreateSize(10000); onelits = (int *)statmalloc(403,sizeof(int) * nOfAtoms); twolits = (intset *)statmalloc(404,sizeof(intset) * nOfAtoms * 2); for(i=0;iccondition)) { #else if(truep(e->condition)) { #endif /* In the following: We have newly true literals in prep->after and all true literals in trueones. For every l in prep->after and m in trueones, -l V m is an invariant. These are all invariants involving -l. We want to store all of these such that both -l and m can have both value true and false. */ /* Go through effect literals */ il = e->effectlits; while(*il != -1) { int l; l = *il; il = il + 1; /* See whether making literal l true falsifies something. */ if(onelits[feVAR(l)] == (l&1)) { /* Falsified a 1-literal */ if(trueonesinitialized == 0) { trueonesinitialized = 1; ISmakeempty(trueones); /* literals true because they are in the precondition */ ISaddelements(prep->before,trueones); /* literals true because a 2-literal clause is satisfied */ iITstart(prep->before); while(iITnext(&j)) ISaddelements(twolits[feNEG(j)],trueones); /* Remove literals that are falsified by this conditional effect or possibly by other conditional effects. */ removefalsified(&(actions[i].effects),trueones); /* Add literals that are made true. */ ISaddelements(prep->after,trueones); } change = 1; onelits[feVAR(l)] = -1; /* Add 2-literals -a | l */ iITstart(trueones); while(iITnext(&k)) { if(l != k && (onelits[feVAR(k)] == -1 || (localISmember1(k,prep->after) && onelits[feVAR(k)] == (k&1)))) { ISinsertNODUP(k,twolits[feNEG(l)]); ISinsertNODUP(feNEG(l),twolits[k]); } } } else if(onelits[feVAR(l)] == -1) { /* Check preservation of 2-literal clauses */ /* Remove candidate 2-literal invariants which were falsified. */ IScopyto(twolits[feNEG(l)],ext); iITstart(ext); while(iITnext(&k)) { if(!(localISmember2(k,prep->after) || ( wastruebefore(k,prep->before) && !madefalse(k,i) ))) { change = 1; ISremove(k,twolits[feNEG(l)]); ISremove(feNEG(l),twolits[k]); } } /* If enabled a new state variable value (= invalidated a candidate one-literal invariant), add new candidate two-literal invariants that still remain true. */ iITstart(prep->after); while(iITnext(&k)) { if(l != k && onelits[feVAR(k)] == -1 && localISmember3(k,twolits[feNEG(l)])) { ISinsert(feNEG(l),twolits[k]); } } } } } e = e->tl; prep++; } // showInvariantsBrief(); } iteration += 1; } for(i=0;i