From: bdemsky Date: Thu, 6 May 2004 21:16:22 +0000 (+0000) Subject: Moved the interpreter X-Git-Url: http://plrg.eecs.uci.edu/git/?p=repair.git;a=commitdiff_plain;h=be34c81d43fc69f77c813151c794198ed914a492 Moved the interpreter --- diff --git a/Repair/RepairInterpreter/Action.cc b/Repair/RepairInterpreter/Action.cc new file mode 100755 index 0000000..8d96bda --- /dev/null +++ b/Repair/RepairInterpreter/Action.cc @@ -0,0 +1,370 @@ +#include +#include "Action.h" +#include "omodel.h" +#include "model.h" +#include "dmodel.h" +#include "set.h" +#include "normalizer.h" + +char * Action::calculatebound(Constraint *c, Label *clabel) { + return getset(c,clabel->label()); +} + +char * Action::getset(Constraint *c, char *v) { + char *set=NULL; + if (c==NULL||v==NULL) + return NULL; + for(int i=0;inumquants();i++) { + if(equivalentstrings(c->getquant(i)->getlabel()->label(),v)) { + if (c->getquant(i)->getset()->gettype()==SET_label) + set=c->getquant(i)->getset()->getname(); + break; + } + } + return set; +} + +bool Action::possiblysameset(char *v1, Constraint *c1, char *v2, Constraint *c2) { + return possiblysameset(getset(c1,v1),getset(c2,v2)); +} + +bool Action::comparepredicates(Constraint *c1, CoercePredicate *cp1, Constraint *c2, CoercePredicate *cp2) { + if (cp1->getcoercebool()!=cp2->getcoercebool()) + return false; + Predicate *p1=cp1->getpredicate(); + Predicate *p2=cp2->getpredicate(); + if (p1->gettype()!=p2->gettype()) + return false; + int type=p1->gettype(); + if (type==PREDICATE_LT || + type==PREDICATE_LTE || + type==PREDICATE_EQUALS || + type==PREDICATE_GTE || + type==PREDICATE_GT) { + char *v1=p1->getvalueexpr()->getlabel()->label(); + char *v2=p2->getvalueexpr()->getlabel()->label(); + if (!equivalentstrings(p1->getvalueexpr()->getrelation()->getname(), + p2->getvalueexpr()->getrelation()->getname())) + return false; + if (!(compareee(p1->geteleexpr(),v1,p2->geteleexpr(),v2))) + return false; + else + return true; + } + if (type==PREDICATE_SET) { + char *v1=p1->getlabel()->label(); + char *v2=p2->getlabel()->label(); + return comparesetexpr(p1->getsetexpr(),v1,p2->getsetexpr(),v2); + } + if (type==PREDICATE_EQ1||type==PREDICATE_GTE1) { + if(p1->getsetexpr()->gettype()!=p2->getsetexpr()->gettype()) + return false; + switch(p1->getsetexpr()->gettype()) { + case SETEXPR_LABEL: { + return equivalentstrings(p1->getsetexpr()->getsetlabel()->getname(), p2->getsetexpr()->getsetlabel()->getname()); + } + case SETEXPR_REL: + case SETEXPR_INVREL: { + /* these can't interfere....*/ + return equivalentstrings(p1->getsetexpr()->getrelation()->getname(), p2->getsetexpr()->getrelation()->getname()); + } + } + } + return false; /* by default */ +} + +bool Action::comparesetexpr(Setexpr *s1,char *v1,Setexpr *s2,char *v2) { + if (s1->gettype()!=s2->gettype()) + return false; + switch(s1->gettype()) { + case SETEXPR_LABEL: + if (!equivalentstrings(s1->getsetlabel()->getname(), + s2->getsetlabel()->getname())) + return false; + else return true; + case SETEXPR_REL: + case SETEXPR_INVREL: + if (!equivalentstrings(v1, s1->getlabel()->label())) + return false; + if (!equivalentstrings(v2, s2->getlabel()->label())) + return false; + if (!equivalentstrings(s1->getrelation()->getname(), + s2->getrelation()->getname())) + return false; + else return true; + default: + return false; + } +} + +bool Action::compareee(Elementexpr *ee1,char *v1,Elementexpr *ee2,char *v2) { + if (ee1->gettype()!=ee2->gettype()) + return false; + switch(ee1->gettype()) { + case ELEMENTEXPR_LABEL: + if (!equivalentstrings(ee1->getlabel()->label(),v1)) + return false; + if (!equivalentstrings(ee2->getlabel()->label(),v2)) + return false; + return true; + case ELEMENTEXPR_SUB: + if (compareee(ee1->getleft(),v1,ee2->getleft(),v2) && + compareee(ee1->getright(),v1,ee2->getright(),v2)) + return true; + else return false; + case ELEMENTEXPR_RELATION: + if (compareee(ee1->getleft(),v1,ee2->getleft(),v2) && + equivalentstrings(ee1->getrelation()->getname(),ee2->getrelation()->getname())) + return true; + else return false; + case ELEMENTEXPR_ADD: + case ELEMENTEXPR_MULT: + if ((compareee(ee1->getleft(),v1,ee2->getleft(),v2) && + compareee(ee1->getright(),v1,ee2->getright(),v2))|| + (compareee(ee1->getleft(),v1,ee2->getright(),v2) && + compareee(ee1->getright(),v1,ee2->getleft(),v2))) + return true; + else return false; + case ELEMENTEXPR_LIT: + if (ee1->getliteral()->gettype()!= + ee2->getliteral()->gettype()) + return false; + switch(ee1->getliteral()->gettype()) { + case LITERAL_NUMBER: + return (ee1->getliteral()->number()==ee2->getliteral()->number()); + case LITERAL_TOKEN: + return (equivalentstrings(ee1->getliteral()->token(),ee2->getliteral()->token())); + default: + return false; + } + case ELEMENTEXPR_SETSIZE: + return comparesetexpr(ee1->getsetexpr(),v1,ee2->getsetexpr(),v2); + default: + return false; + } +} + +bool Action::possiblysameset(char *set1, char *v2, Constraint *c2) { + return possiblysameset(set1,getset(c2,v2)); +} + +bool Action::possiblysameset(char *set1,char *set2) { + if (set1==NULL||set2==NULL) + return true; /* At least one variable isn't spanning over a set...could be from any set*/ + DomainSet *dset1=domrelation->getset(set1); + DomainSet *dset2=domrelation->getset(set2); + WorkSet *ws=new WorkSet(true); + while(dset1!=NULL) { + ws->addobject(dset1); + dset1=domrelation->getsuperset(dset1); + } + bool sameset=false; + if (!ws->contains(dset2)) { + while(dset2!=NULL) { + if (ws->contains(dset2)) { + if (dset2->gettype()==DOMAINSET_PARTITION&& + dset2!=dset1) + sameset=false; + else + sameset=true; + break; + } + dset2=domrelation->getsuperset(dset2); + } + } + delete(ws); + return sameset; +} + +bool Action::conflictwithaddtoset(char *set, Constraint *c, CoercePredicate *p) { + /* Test for conflict with abstraction function */ + if (!p->isrule()&& + equivalentstrings(p->gettriggerset(),set)) + return true; + + /* Test for add new constraint */ + if (c!=NULL) { + for(int i=0;inumquants();i++) { + if (c->getquant(i)->getset()->gettype()==SET_label) + if (equivalentstrings(c->getquant(i)->getset()->getname(),set)) { + return true; /*we're adding this constraint because of inclusion*/ + } + } + } + /* Test for conflict with a \notin set */ + if (p->isrule()&& + (p->getcoercebool()==false)&& + (p->getpredicate()->gettype()==PREDICATE_SET)&& + (p->getpredicate()->getsetexpr()->gettype()==SETEXPR_LABEL)) { + char *psetname=p->getpredicate()->getsetexpr()->getsetlabel()->getname(); + if (equivalentstrings(psetname,set)) { + return true; + } + } + /* Test for conflict with setsize=1 */ + if (p->isrule()&& + (p->getcoercebool()==true)&& + (p->getpredicate()->gettype()==PREDICATE_EQ1)&& + (p->getpredicate()->getsetexpr()->gettype()==SETEXPR_LABEL)) { + char *psetname=p->getpredicate()->getsetexpr()->getsetlabel()->getname(); + if (equivalentstrings(psetname,set)) + return true; + } + return false; +} + +bool Action::conflictwithremovefromset(WorkSet * checkother,char *set, Constraint *c, CoercePredicate *p) { + /* Check for conflict with set size predicate */ + if (p->isrule() && + (p->getcoercebool()==true)&& + ((p->getpredicate()->gettype()==PREDICATE_EQ1)|| + (p->getpredicate()->gettype()==PREDICATE_GTE1)) && + (p->getpredicate()->getsetexpr()->gettype()==SETEXPR_LABEL)) { + char *psetname=p->getpredicate()->getsetexpr()->getsetlabel()->getname(); + if (equivalentstrings(psetname,set)) + return true; + } + + /* Check for conflict with a in SET */ + if (p->isrule() && + (p->getcoercebool()==true)&& + (p->getpredicate()->gettype()==PREDICATE_SET)&& + (p->getpredicate()->getsetexpr()->gettype()==SETEXPR_LABEL)) { + char *psetname=p->getpredicate()->getsetexpr()->getsetlabel()->getname(); + if (equivalentstrings(psetname,set)) + return true; + } + + /* Check for domain's of relation */ + DomainRelation *domrelation=globalmodel->getdomainrelation(); + for(int i=0;igetnumrelation();i++) { + DRelation *drelation=domrelation->getrelation(i); + char *domain=drelation->getdomain(); + if(equivalentstrings(domain,set)) { + testforconflictremove(set,NULL,drelation->getname(),c,p); + if(drelation->isstatic()) { + bool flag=false; + if(checkother==NULL) { + flag=true; + checkother=new WorkSet((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings); + } + if(!checkother->contains(drelation->getrange())) { + checkother->addobject(drelation->getrange()); + if (conflictwithremovefromset(checkother, drelation->getrange(),c,p)) + return true; + checkother->removeobject(drelation->getrange()); + } + if(flag) + delete(checkother); + } + } + } + /* Check for range's of relation */ + for(int i=0;igetnumrelation();i++) { + DRelation *drelation=domrelation->getrelation(i); + char *range=drelation->getrange(); + if (equivalentstrings(range,set)) { + testforconflictremove(NULL,set,drelation->getname(),c,p); + } + } + return false; +} + +/* remove from r */ +bool Action::testforconflictremove(char *setv, char *seta, char *rel, Constraint *c, CoercePredicate *p) { + /* check for conflict with v.r=? */ + if (p->isrule()) { + int type=p->getpredicate()->gettype(); + if ((type==PREDICATE_LT||type==PREDICATE_LTE||type==PREDICATE_EQUALS||type==PREDICATE_GT||type==PREDICATE_GTE) && + possiblysameset(setv,p->getpredicate()->getvalueexpr()->getlabel()->label(),c) && + equivalentstrings(rel,p->getpredicate()->getvalueexpr()->getrelation()->getname())) + return true; + + /* check for conflict with |v'.r|?=1 */ + if ((p->getpredicate()->gettype()==PREDICATE_EQ1||p->getpredicate()->gettype()==PREDICATE_GTE1)&& + p->getpredicate()->getsetexpr()->gettype()==SETEXPR_REL&& + possiblysameset(setv,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&& + equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname())) + return true; + + /* check for conflict with |a'.~r|?=1 */ + if ((p->getpredicate()->gettype()==PREDICATE_EQ1||p->getpredicate()->gettype()==PREDICATE_GTE1) && + p->getpredicate()->getsetexpr()->gettype()==SETEXPR_INVREL && + possiblysameset(seta,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&& + equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname())) + return true; + + /* check for conflit with (a' in v'.r)*/ + if (p->getcoercebool()&& + p->getpredicate()->gettype()==PREDICATE_SET&& + p->getpredicate()->getsetexpr()->gettype()==SETEXPR_REL&& + possiblysameset(seta,p->getpredicate()->getlabel()->label(),c)&& + possiblysameset(setv,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&& + equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname())) + return true; + + /* check for conflict with (a' in v'.~r)*/ + if (p->getcoercebool()&& + p->getpredicate()->gettype()==PREDICATE_SET&& + p->getpredicate()->getsetexpr()->gettype()==SETEXPR_INVREL && + possiblysameset(seta,p->getpredicate()->getsetexpr()->getlabel()->label(),c) && + possiblysameset(setv,p->getpredicate()->getlabel()->label(),c) && + equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname())) + return true; + } + return false; +} + + +/* add to r */ +bool Action::testforconflict(char *setv, char *seta, char *rel, Constraint *c, CoercePredicate *p) { + /* check for conflict with valueexpr*/ + if (p->isrule()&& + (p->getpredicate()->gettype()==PREDICATE_LT || + p->getpredicate()->gettype()==PREDICATE_LTE || + p->getpredicate()->gettype()==PREDICATE_EQUALS || + p->getpredicate()->gettype()==PREDICATE_GTE || + p->getpredicate()->gettype()==PREDICATE_GT) && + possiblysameset(setv,p->getpredicate()->getvalueexpr()->getlabel()->label(),c) && + equivalentstrings(rel,p->getpredicate()->getvalueexpr()->getrelation()->getname())) + return true; + + /* check for conflict with |v'.r'|=1 */ + if (p->isrule() && + p->getpredicate()->gettype()==PREDICATE_EQ1&& + p->getpredicate()->getsetexpr()->gettype()==SETEXPR_REL&& + possiblysameset(setv,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&& + equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname())) + return true; + + /* try to catch case of |a'.~r|=1 */ + if (p->isrule() && + p->getpredicate()->gettype()==PREDICATE_EQ1 && + p->getpredicate()->getsetexpr()->gettype()==SETEXPR_INVREL && + possiblysameset(seta,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&& + equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname())) + return true; + + /* try to catch case of !(a' in v'.r)*/ + if (p->isrule() && + !p->getcoercebool()&& + p->getpredicate()->gettype()==PREDICATE_SET&& + p->getpredicate()->getsetexpr()->gettype()==SETEXPR_REL&& + possiblysameset(seta,p->getpredicate()->getlabel()->label(),c)&& + possiblysameset(setv,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&& + equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname())) + return true; + + + /* try to catch case of !(a' in v'.~r)*/ + if (p->isrule() && + !p->getcoercebool()&& + p->getpredicate()->gettype()==PREDICATE_SET&& + p->getpredicate()->getsetexpr()->gettype()==SETEXPR_INVREL&& + possiblysameset(seta,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&& + possiblysameset(setv,p->getpredicate()->getlabel()->label(),c)&& + equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname())) + return true; + + return false; +} diff --git a/Repair/RepairInterpreter/Action.h b/Repair/RepairInterpreter/Action.h new file mode 100755 index 0000000..54197c9 --- /dev/null +++ b/Repair/RepairInterpreter/Action.h @@ -0,0 +1,28 @@ +#ifndef Action_H +#define Action_H + +#include "classlist.h" +class Action { + public: + virtual void repairpredicate(Hashtable *env, CoercePredicate *p)=0; + virtual void breakpredicate(Hashtable *env, CoercePredicate *p)=0; + virtual bool conflict(Constraint *c1, CoercePredicate *p1, Constraint *c2, CoercePredicate *p2)=0; + virtual bool canrepairpredicate(CoercePredicate *p)=0; + + protected: + char * getset(Constraint *c, char *v); + char * calculatebound(Constraint *c, Label *clabel); + bool comparepredicates(Constraint *c1, CoercePredicate *cp1, Constraint *c2, CoercePredicate *cp2); + bool comparesetexpr(Setexpr *s1,char *v1,Setexpr *s2,char *v2); + bool compareee(Elementexpr *ee1,char *v1,Elementexpr *ee2,char *v2); + bool testforconflict(char *setv, char *seta, char *rel, Constraint *c, CoercePredicate *p); + bool testforconflictremove(char *setv, char *seta, char *rel, Constraint *c, CoercePredicate *p); + DomainRelation *domrelation; + model * globalmodel; + bool possiblysameset(char *v1, Constraint *c1, char *v2, Constraint *c2); + bool possiblysameset(char *set1, char *v2, Constraint *c2); + bool possiblysameset(char *set1, char *set2); + bool conflictwithaddtoset(char *set, Constraint *c, CoercePredicate *p); + bool conflictwithremovefromset(WorkSet *,char *set, Constraint *c, CoercePredicate *p); +}; +#endif diff --git a/Repair/RepairInterpreter/ActionAssign.cc b/Repair/RepairInterpreter/ActionAssign.cc new file mode 100755 index 0000000..929d04e --- /dev/null +++ b/Repair/RepairInterpreter/ActionAssign.cc @@ -0,0 +1,319 @@ +// handles prediate of the following forms: VE=E, VE>E + +#include +#include +#include "ActionAssign.h" +#include "dmodel.h" +#include "normalizer.h" +#include "omodel.h" +#include "Relation.h" +#include "set.h" +#include "Hashtable.h" +#include "model.h" +#include "processobject.h" +#include "element.h" +#include "common.h" + + +ActionAssign::ActionAssign(DomainRelation *drel, model *m) { + domrelation=drel; + globalmodel=m; +} + +char * ActionAssign::gettype(Constraint *c,Elementexpr *ee) { + switch(ee->gettype()) { + case ELEMENTEXPR_LABEL: + return getset(c,ee->getlabel()->label()); + case ELEMENTEXPR_SUB: + case ELEMENTEXPR_ADD: + case ELEMENTEXPR_MULT: + return "int"; + case ELEMENTEXPR_LIT: { + Literal *lit=ee->getliteral(); + switch(lit->gettype()) { + case LITERAL_NUMBER: + return "int"; + case LITERAL_TOKEN: + return "token"; + case LITERAL_BOOL: + printf("ERROR in gettype\n"); + exit(-1); + } + } + case ELEMENTEXPR_SETSIZE: + return "int"; + case ELEMENTEXPR_RELATION: { + Relation *r=ee->getrelation(); + DomainRelation *drel=globalmodel->getdomainrelation(); + return drel->getrelation(r->getname())->getrange(); + } + } +} + + +// repairs the given predicate +void ActionAssign::repairpredicate(Hashtable *env, CoercePredicate *cp) { + Predicate *p=cp->getpredicate(); + Element *ele=evaluateexpr(p->geteleexpr(),env,globalmodel); //ele=E + Element *index=(Element *) env->get(p->getvalueexpr()->getlabel()->label()); // index=V + char *rel=p->getvalueexpr()->getrelation()->getname(); // rel=R + WorkRelation *relation=domrelation->getrelation(rel)->getrelation(); + Element *old=(Element *)relation->getobj(index); // old=V.R + if (old!=NULL) + relation->remove(index,old); + DRelation *drel=domrelation->getrelation(rel); + + if(!equivalentstrings(drel->getdomain(),"int")) { + DomainSet *domain=domrelation->getset(drel->getdomain()); + if (!domain->getset()->contains(index)) + domrelation->addtoset(index,domain,globalmodel); + } + + + switch (p->gettype()) { + case PREDICATE_LT: { + Element *ele2=new Element(ele->intvalue()-1); + delete(ele); + relation->put(index,ele2); + break; + } + case PREDICATE_LTE: { + relation->put(index,ele); + break; + } + case PREDICATE_EQUALS: { + relation->put(index,ele); + if(!equivalentstrings(drel->getrange(),"int")&& + !equivalentstrings(drel->getrange(),"token")) { + DomainSet *range=domrelation->getset(drel->getrange()); + if (!range->getset()->contains(ele)) + domrelation->addtoset(ele,range,globalmodel); + } + break; + } + case PREDICATE_GTE: { + relation->put(index,ele); + break; + } + case PREDICATE_GT: { + Element *ele2=new Element(ele->intvalue()+1); + delete(ele); + relation->put(index,ele2); + break; + } + } +} + + + +void ActionAssign::breakpredicate(Hashtable *env, CoercePredicate *cp) +{ +#ifdef DEBUGMESSAGES + printf("ActionAssign::breakpredicate CALLED\n"); + cp->getpredicate()->print(); printf("\n"); +#endif + + Predicate *p = cp->getpredicate(); + Element *ele = evaluateexpr(p->geteleexpr(),env,globalmodel); //ele=E + Element *index = (Element *) env->get(p->getvalueexpr()->getlabel()->label()); // index=V + + +#ifdef DEBUGMESSAGES + printf("index=%s\n", p->getvalueexpr()->getlabel()->label()); + if (index == NULL) + printf("index - bad\n"); + else printf("index - ok\n"); +#endif + + char *rel = p->getvalueexpr()->getrelation()->getname(); // rel=R + WorkRelation *relation = domrelation->getrelation(rel)->getrelation(); + +#ifdef DEBUGMESSAGES + if (relation == NULL) + printf("relation - bad\n"); + else printf("relation - ok\n"); + fflush(NULL); +#endif + + Element *old_ve = (Element *)relation->getobj(index); // old_ve=V.R + + if (old_ve!=NULL) + relation->remove(index,old_ve); + DRelation *drel = domrelation->getrelation(rel); + + if(!equivalentstrings(drel->getdomain(),"int")) + { + DomainSet *domain = domrelation->getset(drel->getdomain()); + if (!domain->getset()->contains(index)) + domrelation->addtoset(index,domain,globalmodel); + } + +#ifdef DEBUGMESSAGES + printf("p->gettype() = %d\n", p->gettype()); + fflush(NULL); +#endif + + + switch (p->gettype()) { + // VEintvalue()); + delete(ele); + relation->put(index,newele); + break; + } + + // VE<=E + case PREDICATE_LTE: + { + // set VE=E+1, which breaks VE<=E + Element *newele=new Element(ele->intvalue()+1); + delete(ele); + relation->put(index,newele); + break; + } + + // VE=E + case PREDICATE_EQUALS: + { + DRelation *drel=domrelation->getrelation(rel); + + // if the V.R is an integer, set VE=E+1, which breaks VE=E + if (equivalentstrings(drel->getrange(),"int")) + { + Element *newele=new Element(ele->intvalue()+1); + delete(ele); + relation->put(index,newele); + } + else + { + Element *newele = NULL; + printf("PREDICATE_EQUALS for tokens\n"); + //printf("range name = %s\n", drel->getrange()); fflush(NULL); + //printf("Current value: "); old_ve->print(); printf("\n"); + + /* find a value in the actual range that is different from the + current value of V.R */ + char* old_token = old_ve->gettoken(); + WorkSet *ws = drel->gettokenrange(); + bool found = false; + char *token = (char*) ws->firstelement(); + while (token) + { + printf("Token: %s\n", token); + if (!equivalentstrings(token, old_token)) + { + found = true; + newele = new Element(token); + break; + } + token = (char*) ws->getnextelement(token); + } + + if (!found) + { + printf("The following predicate cannot be broken:"); + cp->getpredicate()->print(); printf("\n"); + } + else relation->put(index, newele); + + fflush(NULL); + printf("\n\n"); + } + break; + } + + // VE>=E + case PREDICATE_GTE: + { + // set VE=E-1, which breaks VE>=E + Element *newele=new Element(ele->intvalue()-1); + delete(ele); + relation->put(index,newele); + break; + } + + // VE>E + case PREDICATE_GT: + { + // set VE=E, which breaks VE>E + Element *newele=new Element(ele->intvalue()); + delete(ele); + relation->put(index,newele); + break; + } + } +} + + + +bool ActionAssign::conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2) { + assert(canrepairpredicate(p1)); + if(comparepredicates(c1,p1,c2,p2)) + return false; /*same predicates don't conflict*/ + /* we have v.r?a */ + /* add to r */ + + /* Compute bounding set if there is one */ + + + DomainRelation *drel=globalmodel->getdomainrelation(); + char *insertset=drel->getrelation(p1->getpredicate()->getvalueexpr()->getrelation()->getname())->getrange(); + + char *boundset=gettype(c1,p1->getpredicate()->geteleexpr()); + + /* Check conflicts arrising from addition to set */ + { + WorkSet *ws=domrelation->conflictaddsets(insertset,NULL,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(insertset, NULL); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + return testforconflict(getset(c1,p1->getpredicate()->getvalueexpr()->getlabel()->label()), NULL, + p1->getpredicate()->getvalueexpr()->getrelation()->getname(),c2,p2)|| + testforconflictremove(getset(c1,p1->getpredicate()->getvalueexpr()->getlabel()->label()), NULL, + p1->getpredicate()->getvalueexpr()->getrelation()->getname(),c2,p2); +} + +bool ActionAssign::canrepairpredicate(CoercePredicate *cp) { + if (cp->getcoercebool()==false) + return false; + Predicate *p=cp->getpredicate(); + if (p==NULL) + return false; + if (p->gettype()==PREDICATE_LT|| + p->gettype()==PREDICATE_LTE|| + p->gettype()==PREDICATE_EQUALS|| + p->gettype()==PREDICATE_GTE|| + p->gettype()==PREDICATE_GT) { + Valueexpr *ve=p->getvalueexpr(); + DRelation *dr=domrelation->getrelation(ve->getrelation()->getname()); + if (dr->isstatic()) /* can't change static relations */ + return false; + else + return true; + } + /* Coercing set membership */ + return false; +} diff --git a/Repair/RepairInterpreter/ActionAssign.h b/Repair/RepairInterpreter/ActionAssign.h new file mode 100755 index 0000000..e14b6b0 --- /dev/null +++ b/Repair/RepairInterpreter/ActionAssign.h @@ -0,0 +1,18 @@ +// handles prediate of the following forms: VE=E, VE>E + + +#ifndef ActionAssign_H +#define ActionAssign_H +#include "classlist.h" +#include "Action.h" +class ActionAssign:public Action { + public: + ActionAssign(DomainRelation *drel, model *); + void repairpredicate(Hashtable *env, CoercePredicate *p); + void breakpredicate(Hashtable *env, CoercePredicate *p); + bool conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2); + bool canrepairpredicate(CoercePredicate *p); + private: + char * gettype(Constraint *c,Elementexpr *ee); +}; +#endif diff --git a/Repair/RepairInterpreter/ActionEQ1.cc b/Repair/RepairInterpreter/ActionEQ1.cc new file mode 100755 index 0000000..215f2bf --- /dev/null +++ b/Repair/RepairInterpreter/ActionEQ1.cc @@ -0,0 +1,302 @@ +// Repairs and destroys size propositions of the form "size(SE)=1" + +#include +#include "ActionEQ1.h" +#include "dmodel.h" +#include "normalizer.h" +#include "omodel.h" +#include "model.h" +#include "Relation.h" +#include "set.h" +#include "Hashtable.h" +#include "Guidance.h" + +ActionEQ1::ActionEQ1(DomainRelation *drel, model *m) { + domrelation=drel; + globalmodel=m; +} + +void ActionEQ1::repairpredicate(Hashtable *env,CoercePredicate *p) { + switch(p->getpredicate()->getsetexpr()->gettype()) { + // size(S)=1 + case SETEXPR_LABEL: { + char *setname=p->getpredicate()->getsetexpr()->getsetlabel()->getname(); + DomainSet *ds=domrelation->getset(setname); + if (ds->getset()->size()>1) { + Guidance *g=globalmodel->getguidance(); + WorkSet *ws=ds->getset(); + while(ws->size()>1) { + Element *e=(Element *)ws->firstelement(); + domrelation->delfromsetmovetoset(e,domrelation->getset(setname), globalmodel); + } + } else + this->ActionGEQ1::repairpredicate(env,p); + } + break; + + // size(V.R)=1 + case SETEXPR_REL: { + DRelation *dr=domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname()); + WorkRelation *wr=dr->getrelation(); + Element *key=(Element *)env->get(p->getpredicate()->getsetexpr()->getlabel()->label()); + WorkSet *ws=wr->getset(key); + + if (ws!=NULL&&ws->size()>1) { + //Remove elements + int size=ws->size(); + for(int i=0;i<(size-1);i++) { + void *objtoremove=ws->firstelement(); + wr->remove(key,objtoremove); + } + } else + this->ActionGEQ1::repairpredicate(env,p); + } + break; + + // size(R.V)=1 + case SETEXPR_INVREL: { + DRelation *dr=domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname()); + WorkRelation *wr=dr->getrelation(); + Element *key=(Element *)env->get(p->getpredicate()->getsetexpr()->getlabel()->label()); + WorkSet *ws=wr->invgetset(key); + + if (ws!=NULL&&ws->size()>1) { + //Remove elements + int size=ws->size(); + for(int i=0;i<(size-1);i++) { + void *objtoremove=ws->firstelement(); + wr->remove(objtoremove,key); + } + } else + this->ActionGEQ1::repairpredicate(env,p); + } + break; + } +} + + + + +void ActionEQ1::breakpredicate(Hashtable *env, CoercePredicate *p) +{ +#ifdef DEBUGMESSAGES + printf("ActionEQ1::breakpredicate CALLED\n"); + p->getpredicate()->print(); printf("\n"); +#endif + + this->ActionGEQ1::breakpredicate(env, p); +} + + + + +bool ActionEQ1::conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2) { + assert(canrepairpredicate(p1)); + Setexpr *pse=p1->getpredicate()->getsetexpr(); + if(comparepredicates(c1,p1,c2,p2)) + return false; /*same predicates don't conflict*/ + + switch(pse->gettype()) { + case SETEXPR_LABEL: { + char *boundname=NULL; + Guidance *g=globalmodel->getguidance(); + //DomainSet *fromset=domrelation->getsource(domrelation->getset(pse->getsetlabel()->getname())); + char *setname=pse->getsetlabel()->getname(); + + DomainSet *fromset=domrelation->getset(setname); + + { + Source s=g->sourceforsetsize(fromset->getname()); + if (s.setname!=NULL) + boundname=s.setname; + } + + { + /* See what additional addsets we get*/ + + WorkSet *ws=domrelation->conflictaddsets(pse->getsetlabel()->getname(),boundname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + { + /* What additions do we get from removal */ + WorkSet *ws=domrelation->removeconflictaddsets(pse->getsetlabel()->getname(),globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + + /* Check what removals addition into set can cause */ + if (boundname!=NULL) { + WorkSet *ws=domrelation->conflictdelsets(pse->getsetlabel()->getname(), boundname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* What sets will removal cause removal from */ + { + WorkSet *ws=domrelation->removeconflictdelsets(pse->getsetlabel()->getname()); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + return false; + } + case SETEXPR_REL: { + char *fromname=NULL; + /* we have a in v.r */ + /* add to r */ + if (p2->isrule()&& + (p2->getpredicate()->gettype()==PREDICATE_GTE1|| + p2->getpredicate()->gettype()==PREDICATE_EQ1)&& + p2->getpredicate()->getsetexpr()->gettype()==SETEXPR_REL) { + return false; + } + + /* Compute bounding set if there is one */ + + + DomainRelation *drel=globalmodel->getdomainrelation(); + char *insertset=drel->getrelation(pse->getrelation()->getname())->getrange(); + Guidance *g=globalmodel->getguidance(); + Source s=g->sourceforsetsize(insertset); + + + /* Check conflicts arrising from addition to set */ + { + WorkSet *ws=domrelation->conflictaddsets(insertset,s.setname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(insertset, s.setname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + + + return testforconflict(getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), fromname, + p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2)||testforconflictremove(getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), fromname, + p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2); + } + case SETEXPR_INVREL: { + char *fromname=NULL; + /* we have a in v.r */ + /* add to r */ + if (p2->isrule()&& + (p2->getpredicate()->gettype()==PREDICATE_GTE1|| + p2->getpredicate()->gettype()==PREDICATE_EQ1)&& + p2->getpredicate()->getsetexpr()->gettype()==SETEXPR_INVREL) { + return false; + } + + /* Compute bounding set if there is one */ + + + DomainRelation *drel=globalmodel->getdomainrelation(); + char *insertset=drel->getrelation(pse->getrelation()->getname())->getdomain(); + Guidance *g=globalmodel->getguidance(); + Source s=g->sourceforsetsize(insertset); + + + /* Check conflicts arrising from addition to set */ + { + WorkSet *ws=domrelation->conflictaddsets(insertset,s.setname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(insertset, s.setname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + + return testforconflict(fromname, + getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), + p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2)|| + testforconflictremove(fromname, + getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), + p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2); + } + } +} + + + + +bool ActionEQ1::canrepairpredicate(CoercePredicate *cp) { + if (cp->getcoercebool()==false) + return false; + Predicate *p=cp->getpredicate(); + + + if (p->gettype()!=PREDICATE_EQ1) + return false; + + /* Coercing set membership */ + Setexpr *se=p->getsetexpr(); + int setexprtype=se->gettype(); + if (setexprtype==SETEXPR_REL|| + setexprtype==SETEXPR_INVREL) { + DRelation *dr=domrelation->getrelation(se->getrelation()->getname()); + if (dr->isstatic()) + return false; /* Can't change static domain relations */ + } + + return true; +} diff --git a/Repair/RepairInterpreter/ActionEQ1.h b/Repair/RepairInterpreter/ActionEQ1.h new file mode 100755 index 0000000..af61961 --- /dev/null +++ b/Repair/RepairInterpreter/ActionEQ1.h @@ -0,0 +1,14 @@ +#ifndef ActionEQ1_H +#define ActionEQ1_H +#include "classlist.h" +#include "ActionGEQ1.h" +class ActionEQ1:public ActionGEQ1 { + public: + ActionEQ1(DomainRelation *drel,model *); + void repairpredicate(Hashtable *env, CoercePredicate *p); + void breakpredicate(Hashtable *env, CoercePredicate *p); + bool conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2); + bool canrepairpredicate(CoercePredicate *p); + protected: +}; +#endif diff --git a/Repair/RepairInterpreter/ActionGEQ1.cc b/Repair/RepairInterpreter/ActionGEQ1.cc new file mode 100755 index 0000000..c072d25 --- /dev/null +++ b/Repair/RepairInterpreter/ActionGEQ1.cc @@ -0,0 +1,465 @@ +#include +#include +#include "ActionGEQ1.h" +#include "dmodel.h" +#include "normalizer.h" +#include "omodel.h" +#include "model.h" +#include "Relation.h" +#include "set.h" +#include "element.h" +#include "Hashtable.h" +#include "Guidance.h" + + +ActionGEQ1::ActionGEQ1(DomainRelation *drel, model *m) { + domrelation=drel; + globalmodel=m; +} + +void ActionGEQ1::repairpredicate(Hashtable *env,CoercePredicate *p) { +#ifdef DEBUGMESSAGES + printf("ActionGEQ1::repairpredicate CALLED\n"); + fflush(NULL); +#endif + switch(p->getpredicate()->getsetexpr()->gettype()) { + case SETEXPR_LABEL: { + /* Set should be too small if we are doing a repair + We need to add 1 element */ + Guidance *g=globalmodel->getguidance(); + char * newsetname=p->getpredicate()->getsetexpr()->getsetlabel()->getname(); + Source s=g->sourceforsetsize(newsetname); + if (s.setname!=NULL) { + /* just pick an element from s.setname */ + char *setname=s.setname; + if (equivalentstrings(s.setname,"int")) { + /* special case for ints*/ + WorkSet *wsnew=domrelation->getset(newsetname)->getset(); + for(int i=0;;i++) { + Element *e=new Element(i); + if (!wsnew->contains(e)) { + /* Got our element */ + domrelation->addtoset(e,domrelation->getset(newsetname),globalmodel); + return; + } + delete(e); + } + } else { + WorkSet *ws=domrelation->getset(setname)->getset(); + WorkSet *wsnew=domrelation->getset(newsetname)->getset(); + Element *e=(Element *)ws->firstelement(); + while(e!=NULL) { + if (!wsnew->contains(e)) { + /* Got our element */ + domrelation->addtoset(e,domrelation->getset(newsetname),globalmodel); + //printf("HERE?!\n"); fflush(NULL); + return; + } + e=(Element *)ws->getnextelement(e); + } + printf("Error...set %s doesn't have enough elements for %s\n",setname,newsetname); + exit(-1); + } + } else { + /* call functionpointer */ + DomainSet *newset=domrelation->getset(newsetname); + char *type=newset->getelementtype(); + structure *st=globalmodel->getstructure(type); + Element *ele=s.functionptr(st,globalmodel); + if (ele==NULL) { + printf("Error...allocation function doesn't return structure for %s\n",newsetname); + exit(-1); + } + domrelation->addtoset(ele,newset,globalmodel); + return; + } + } + break; + + + + case SETEXPR_REL: { + /* Set should be too small if we are doing a repair + We need to add 1 element */ + Guidance *g=globalmodel->getguidance(); + char * relationname=p->getpredicate()->getsetexpr()->getrelation()->getname(); + Element *key=(Element *)env->get(p->getpredicate()->getsetexpr()->getlabel()->label()); + DRelation *relation=domrelation->getrelation(relationname); + char *rangeset=relation->getrange(); + Source s=g->sourceforrelation(rangeset); + if (s.setname!=NULL) { + /* just pick an element from s.setname */ + char *setname=s.setname; + if (equivalentstrings(s.setname,"int")) { + /* special case for ints*/ + for(int i=0;;i++) { + WorkSet *wsnew=domrelation->getrelation(relationname)->getrelation()->getset(key); + Element *e=new Element(i); + if (wsnew==NULL||!wsnew->contains(e)) { + /* Got our element */ + domrelation->addtoset(e,domrelation->getset(rangeset),globalmodel); + relation->getrelation()->put(key,e); + return; + } + delete(e); + } + } else { + WorkSet *ws=domrelation->getset(s.setname)->getset(); + Element *e=(Element *)ws->firstelement(); + while(e!=NULL) { + WorkSet *wsnew=domrelation->getrelation(relationname)->getrelation()->getset(key); + if (wsnew==NULL||!wsnew->contains(e)) { + /* Got our element */ + domrelation->addtoset(e,domrelation->getset(rangeset),globalmodel); + relation->getrelation()->put(key,e); + return; + } + e=(Element *)ws->getnextelement(e); + } + printf("Error...set %s doesn't have enough elements for relation\n",setname); + exit(-1); + } + } else { + /* call functionpointer */ + DomainSet *newset=domrelation->getset(rangeset); + char *type=newset->getelementtype(); + structure *st=globalmodel->getstructure(type); + Element *ele=s.functionptr(st,globalmodel); + if (ele==NULL) { + printf("Error...allocation function doesn't return structure for %s\n",rangeset); + exit(-1); + } + domrelation->addtoset(ele,domrelation->getset(rangeset),globalmodel); + relation->getrelation()->put(key,ele); + return; + } + } + + + break; + case SETEXPR_INVREL: { + /* Set should be too small if we are doing a repair + We need to add 1 element */ + Guidance *g=globalmodel->getguidance(); + char * relationname=p->getpredicate()->getsetexpr()->getrelation()->getname(); + Element *key=(Element *)env->get(p->getpredicate()->getsetexpr()->getlabel()->label()); + DRelation *relation=domrelation->getrelation(relationname); + char *domainset=relation->getdomain(); + Source s=g->sourceforrelation(domainset); + if (s.setname!=NULL) { + /* just pick an element from s.setname */ + char *setname=s.setname; + if (equivalentstrings(s.setname,"int")) { + /* special case for ints*/ + for(int i=0;;i++) { + Element *e=new Element(i); + WorkSet *wsnew=domrelation->getrelation(relationname)->getrelation()->invgetset(key); + if (wsnew==NULL||!wsnew->contains(e)) { + /* Got our element */ + domrelation->addtoset(e,domrelation->getset(domainset),globalmodel); + relation->getrelation()->put(e,key); + return; + } + delete(e); + } + } else { + WorkSet *ws=domrelation->getset(s.setname)->getset(); + Element *e=(Element *)ws->firstelement(); + while(e!=NULL) { + WorkSet *wsnew=domrelation->getrelation(relationname)->getrelation()->invgetset(key); + if (wsnew==NULL||!wsnew->contains(e)) { + /* Got our element */ + domrelation->addtoset(e,domrelation->getset(domainset),globalmodel); + relation->getrelation()->put(e,key); + return; + } + e=(Element *)ws->getnextelement(e); + } + printf("Error...set %s doesn't have enough elements for relation\n",setname); + exit(-1); + } + } else { + /* call functionpointer */ + DomainSet *newset=domrelation->getset(domainset); + char *type=newset->getelementtype(); + structure *st=globalmodel->getstructure(type); + Element *ele=s.functionptr(st,globalmodel); + if (ele==NULL) { + printf("Error...allocation function doesn't return structure for %s\n",domainset); + exit(-1); + } + domrelation->addtoset(ele,domrelation->getset(domainset),globalmodel); + relation->getrelation()->put(ele,key); + return; + } + } + break; + } +} + + + + +void ActionGEQ1::breakpredicate(Hashtable *env, CoercePredicate *p) +{ +#ifdef DEBUGMESSAGES + printf("ActionGEQ1::breakpredicate CALLED\n"); + p->getpredicate()->print(); printf("\n"); +#endif + + switch(p->getpredicate()->getsetexpr()->gettype()) { + // size(S)>=1 + case SETEXPR_LABEL: + { +#ifdef DEBUGMESSAGES + printf("LABEL\n"); +#endif + + char *setname=p->getpredicate()->getsetexpr()->getsetlabel()->getname(); + DomainSet *ds=domrelation->getset(setname); //S + + // simply delete all elements that S currently contains + Guidance *g=globalmodel->getguidance(); + WorkSet *ws=ds->getset(); + while(ws->size()>0) + { + Element *e=(Element *)ws->firstelement(); + domrelation->delfromsetmovetoset(e,domrelation->getset(setname), globalmodel); + } + } + break; + + + // size(V.R)>=1 + case SETEXPR_REL: + { +#ifdef DEBUGMESSAGES + printf("REL\n"); +#endif + + DRelation *dr=domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname()); + WorkRelation *wr=dr->getrelation(); //R + Element *key=(Element *)env->get(p->getpredicate()->getsetexpr()->getlabel()->label()); //V + WorkSet *ws=wr->getset(key); //V.R + + // simply delete all elements that V.R currently contains + int size=ws->size(); + for(int i=0; ifirstelement(); + wr->remove(key, objtoremove); + } + } + break; + + // size(R.V)=1 + case SETEXPR_INVREL: + { +#ifdef DEBUGMESSAGES + printf("INVREL\n"); +#endif + + DRelation *dr=domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname()); + //dr->print(); printf("\n"); + WorkRelation *wr=dr->getrelation(); //R + Element *key=(Element *)env->get(p->getpredicate()->getsetexpr()->getlabel()->label()); //V + WorkSet *ws=wr->invgetset(key); //R.V + +#ifdef DEBUGMESSAGES + printf("ws size = %d\n", ws->size()); +#endif + + // simply delete all elements that R.V currently contains + int size=ws->size(); + for(int i=0; ifirstelement(); + wr->remove(objtoremove, key); + } + +#ifdef DEBUGMESSAGES + printf("INVREL finished\n"); +#endif + } + break; + } +} + + + +bool ActionGEQ1::conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2) { + assert(canrepairpredicate(p1)); + Setexpr *pse=p1->getpredicate()->getsetexpr(); + if(comparepredicates(c1,p1,c2,p2)) + return false; /*same predicates don't conflict*/ + char *fromname=NULL; + DomainSet *fromset=domrelation->getsource(domrelation->getset(pse->getsetlabel()->getname())); + if (fromset!=NULL) + fromname=fromset->getname(); + /* FIXME: fromname should cycle through set of possibilities ... + if it is null, it should be replaced with the type name the object will have for the REL tests...this is okay already for the label tests... + */ + + switch(pse->gettype()) { + case SETEXPR_LABEL: { + char *boundname=NULL; + Guidance *g=globalmodel->getguidance(); + DomainSet *fromset=domrelation->getsource(domrelation->getset(pse->getsetlabel()->getname())); + + if (fromset!=NULL) { + Source s=g->sourceforsetsize(fromset->getname()); + if (s.setname!=NULL) + boundname=s.setname; + } + char *setname=pse->getsetlabel()->getname(); + + { + WorkSet *ws=domrelation->conflictaddsets(pse->getsetlabel()->getname(),boundname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(pse->getsetlabel()->getname(), boundname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + return false; + } + + case SETEXPR_REL: { + /* we have a in v.r */ + /* add to r */ + if (p2->isrule()&& + (p2->getpredicate()->gettype()==PREDICATE_GTE1|| + p2->getpredicate()->gettype()==PREDICATE_EQ1)&& + p2->getpredicate()->getsetexpr()->gettype()==SETEXPR_REL) { + return false; + } + /* Compute bounding set if there is one */ + + + DomainRelation *drel=globalmodel->getdomainrelation(); + char *insertset=drel->getrelation(pse->getrelation()->getname())->getrange(); + Guidance *g=globalmodel->getguidance(); + Source s=g->sourceforsetsize(insertset); + + + /* Check conflicts arrising from addition to set */ + { + WorkSet *ws=domrelation->conflictaddsets(insertset,s.setname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(insertset, s.setname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + + + return testforconflict(getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), + fromname, + p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2); + } + case SETEXPR_INVREL: { + /* we have a in v.r */ + /* add to r */ + if (p2->isrule()&& + (p2->getpredicate()->gettype()==PREDICATE_GTE1|| + p2->getpredicate()->gettype()==PREDICATE_EQ1)&& + p2->getpredicate()->getsetexpr()->gettype()==SETEXPR_INVREL) { + return false; + } + /* Compute bounding set if there is one */ + + + DomainRelation *drel=globalmodel->getdomainrelation(); + char *insertset=drel->getrelation(pse->getrelation()->getname())->getdomain(); + Guidance *g=globalmodel->getguidance(); + Source s=g->sourceforsetsize(insertset); + + + /* Check conflicts arrising from addition to set */ + { + WorkSet *ws=domrelation->conflictaddsets(insertset,s.setname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(insertset, s.setname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + + return testforconflict(fromname, + getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), + p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2); + } + } +} + +bool ActionGEQ1::canrepairpredicate(CoercePredicate *cp) { + if (cp->getcoercebool()==false) + return false; + Predicate *p=cp->getpredicate(); + + if (p->gettype()!=PREDICATE_GTE1) + return false; + + Setexpr *se=p->getsetexpr(); + int setexprtype=se->gettype(); + if (setexprtype==SETEXPR_REL|| + setexprtype==SETEXPR_INVREL) { + DRelation *dr=domrelation->getrelation(se->getrelation()->getname()); + if (dr->isstatic()) + return false; /* Can't change static domain relations */ + } + + /* Coercing set membership */ + return true; +} diff --git a/Repair/RepairInterpreter/ActionGEQ1.h b/Repair/RepairInterpreter/ActionGEQ1.h new file mode 100755 index 0000000..3d52724 --- /dev/null +++ b/Repair/RepairInterpreter/ActionGEQ1.h @@ -0,0 +1,16 @@ +#ifndef ActionGEQ1_H +#define ActionGEQ1_H +#include "classlist.h" +#include "Action.h" +class ActionGEQ1:public Action { + public: + ActionGEQ1() { + } + ActionGEQ1(DomainRelation *drel, model *); + void repairpredicate(Hashtable *env, CoercePredicate *p); + void breakpredicate(Hashtable *env, CoercePredicate *p); + bool conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2); + bool canrepairpredicate(CoercePredicate *p); + protected: +}; +#endif diff --git a/Repair/RepairInterpreter/ActionInSet.cc b/Repair/RepairInterpreter/ActionInSet.cc new file mode 100755 index 0000000..756816d --- /dev/null +++ b/Repair/RepairInterpreter/ActionInSet.cc @@ -0,0 +1,200 @@ +#include +#include "ActionInSet.h" +#include "dmodel.h" +#include "model.h" +#include "normalizer.h" +#include "omodel.h" +#include "Relation.h" +#include "set.h" +#include "Hashtable.h" +#include "ActionNotInSet.h" + +ActionInSet::ActionInSet(DomainRelation *drel,model *m) { + domrelation=drel; + globalmodel=m; +} + +void ActionInSet::repairpredicate(Hashtable *env,CoercePredicate *p) { + Element *ele=(Element*) env->get(p->getpredicate()->getlabel()->label()); + switch(p->getpredicate()->getsetexpr()->gettype()) { + case SETEXPR_LABEL: + domrelation->addtoset(ele, domrelation->getset(p->getpredicate()->getsetexpr()->getsetlabel()->getname()), + globalmodel); + break; + case SETEXPR_REL: { + Element *key=(Element*) env->get(p->getpredicate()->getsetexpr()->getlabel()->label()); + domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname())->getrelation()->put(key,ele); + char *rangename=domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname())->getrange(); + if (!equivalentstrings(rangename,"int")) { + DomainSet *range=domrelation->getset(rangename); + if (!range->getset()->contains(ele)) + domrelation->addtoset(ele,range,globalmodel); + } + } + break; + case SETEXPR_INVREL: { + Element *key=(Element*) env->get(p->getpredicate()->getsetexpr()->getlabel()->label()); + domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname())->getrelation()->put(ele,key); + char *domainname=domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname())->getdomain(); + if (!equivalentstrings(domainname,"int")) { + DomainSet *domain=domrelation->getset(domainname); + if (!domain->getset()->contains(ele)) + domrelation->addtoset(ele,domain,globalmodel); + } + } + break; + } +} + + + +void ActionInSet::breakpredicate(Hashtable *env,CoercePredicate *p) +{ +#ifdef DEBUGMESSAGES + printf("ActionInSet::breakpredicate CALLED\n"); + p->getpredicate()->print(); printf("\n"); +#endif + + ActionNotInSet *a = new ActionNotInSet(domrelation, globalmodel); + a->repairpredicate(env, p); +} + + + +bool ActionInSet::conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2) { + assert(canrepairpredicate(p1)); + if(comparepredicates(c1,p1,c2,p2)) + return false; /*same predicates don't conflict*/ + Setexpr *pse=p1->getpredicate()->getsetexpr(); + switch(pse->gettype()) { + case SETEXPR_LABEL: { + /* Compute bounding set if there is one */ + char *boundname=calculatebound(c1,p1->getpredicate()->getlabel()); + /* Check conflicts arrising from addition to set */ + { + WorkSet *ws=domrelation->conflictaddsets(pse->getsetlabel()->getname(),boundname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(pse->getsetlabel()->getname(), boundname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + return false; + } + case SETEXPR_REL: { + + /* Compute bounding set if there is one */ + char *boundname=calculatebound(c1,p1->getpredicate()->getlabel()); + DomainRelation *drel=globalmodel->getdomainrelation(); + char *insertset=drel->getrelation(pse->getrelation()->getname())->getrange(); + + /* Check conflicts arrising from addition to set */ + { + WorkSet *ws=domrelation->conflictaddsets(insertset,boundname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(insertset, boundname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + + /* we have a in v.r */ + /* add to r */ + return testforconflict(getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), + getset(c1,p1->getpredicate()->getlabel()->label()), + p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2); + } + case SETEXPR_INVREL: { + /* Compute bounding set if there is one */ + char *boundname=calculatebound(c1,p1->getpredicate()->getlabel()); + DomainRelation *drel=globalmodel->getdomainrelation(); + char *insertset=drel->getrelation(pse->getrelation()->getname())->getdomain(); + + /* Check conflicts arrising from addition to set */ + { + WorkSet *ws=domrelation->conflictaddsets(insertset,boundname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(insertset, boundname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* add to r */ + return testforconflict(getset(c1,p1->getpredicate()->getlabel()->label()), + getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), + p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2); + } + } +} + +bool ActionInSet::canrepairpredicate(CoercePredicate *cp) { + if (cp->getcoercebool()==false) + return false; + Predicate *p=cp->getpredicate(); + if (p==NULL) + return false; + if (p->gettype()!=PREDICATE_SET) + return false; + Setexpr *se=p->getsetexpr(); + int setexprtype=se->gettype(); + if (setexprtype==SETEXPR_REL|| + setexprtype==SETEXPR_INVREL) { + DRelation *dr=domrelation->getrelation(se->getrelation()->getname()); + if (dr->isstatic()) + return false; /* Can't change static domain relations */ + } + + /* Coercing set membership */ + return true; +} diff --git a/Repair/RepairInterpreter/ActionInSet.h b/Repair/RepairInterpreter/ActionInSet.h new file mode 100755 index 0000000..416d1cd --- /dev/null +++ b/Repair/RepairInterpreter/ActionInSet.h @@ -0,0 +1,24 @@ +#ifndef ActionInSet_H +#define ActionInSet_H +#include "classlist.h" +#include "Action.h" +class ActionInSet:public Action { + public: + ActionInSet(DomainRelation *drel,model *); + void repairpredicate(Hashtable *env, CoercePredicate *p); + void breakpredicate(Hashtable *env, CoercePredicate *p); + bool conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2); + bool canrepairpredicate(CoercePredicate *p); + private: + bool testforinvconflictwithinvsetsize(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2); + bool testforinvconflictwithsetsize(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2); + bool testforinvconflictwithinvrelset(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2); + bool testforinvconflictwithrelset(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2); + bool testforconflictwithsetsize(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2); + bool testforconflictwithinvsetsize(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2); + bool testforconflictwithrelset(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2); + bool testforconflictwithinvrelset(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2); + bool testforconflictwithvalueexpr(Constraint *c1, CoercePredicate *cp1,Constraint *c2, CoercePredicate *cp2); + bool testforinvconflictwithvalueexpr(Constraint *c1, CoercePredicate *cp1,Constraint *c2, CoercePredicate *cp2); +}; +#endif diff --git a/Repair/RepairInterpreter/ActionNormal.cc b/Repair/RepairInterpreter/ActionNormal.cc new file mode 100755 index 0000000..f34bc5a --- /dev/null +++ b/Repair/RepairInterpreter/ActionNormal.cc @@ -0,0 +1,140 @@ +#include +#include "ActionNormal.h" +#include "dmodel.h" +#include "normalizer.h" +#include "omodel.h" +#include "Relation.h" +#include "set.h" +#include "Hashtable.h" +#include "model.h" + +ActionNormal::ActionNormal(model *m) { + globalmodel=m; + domrelation=m->getdomainrelation(); +} + +void ActionNormal::repairpredicate(Hashtable *env,CoercePredicate *p) { + /* Don't actually repair stuff */ +} + + +void ActionNormal::breakpredicate(Hashtable *env, CoercePredicate *p) +{ + /* Don't actually break stuff */ +} + + +bool ActionNormal::conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2) { + if(!p1->isrule()&& + !p1->istuple()) { + /* Compute bounding set if there is one */ + char *boundname=p1->getltype(); + /* Check conflicts arrising from addition to set */ + { + WorkSet *ws=domrelation->conflictaddsets(p1->getrelset(),boundname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(p1->getrelset(), boundname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + return false; + } + + if(!p1->isrule()&& + p1->istuple()) { + + { + /* Compute bounding set if there is one */ + char *boundname=getset(c1,p1->getrtype()); + DomainRelation *drel=globalmodel->getdomainrelation(); + char *insertset=drel->getrelation(p1->getrelset())->getrange(); + + /* Check conflicts arrising from addition to set */ + { + WorkSet *ws=domrelation->conflictaddsets(insertset,boundname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(insertset, boundname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + } + /* Compute bounding set if there is one */ + char *boundname=getset(c1,p1->getltype()); + DomainRelation *drel=globalmodel->getdomainrelation(); + char *insertset=drel->getrelation(p1->getrelset())->getdomain(); + + /* Check conflicts arrising from addition to set */ + { + WorkSet *ws=domrelation->conflictaddsets(insertset,boundname,globalmodel); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + /* Check conflicts arrising from deletions from set */ + { + WorkSet *ws=domrelation->conflictdelsets(insertset, boundname); + DomainSet *ds=(DomainSet *) ws->firstelement(); + while (ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *) ws->getnextelement(ds); + } + delete(ws); + } + + /* we have a in v.r */ + /* add to r */ + return testforconflict(getset(c1,p1->getltype()), + getset(c1,p1->getrtype()), + p1->getrelset(),c2,p2); + } +} + + +bool ActionNormal::canrepairpredicate(CoercePredicate *cp) { + return false; /* Doesn't repair stuff */ +} diff --git a/Repair/RepairInterpreter/ActionNormal.h b/Repair/RepairInterpreter/ActionNormal.h new file mode 100755 index 0000000..e34dc45 --- /dev/null +++ b/Repair/RepairInterpreter/ActionNormal.h @@ -0,0 +1,14 @@ +#ifndef ActionNormal_H +#define ActionNormal_H +#include "classlist.h" +#include "Action.h" +class ActionNormal:public Action { + public: + ActionNormal(model *); + void repairpredicate(Hashtable *env, CoercePredicate *p); + void breakpredicate(Hashtable *env, CoercePredicate *p); + bool conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2); + bool canrepairpredicate(CoercePredicate *p); + private: +}; +#endif diff --git a/Repair/RepairInterpreter/ActionNotInSet.cc b/Repair/RepairInterpreter/ActionNotInSet.cc new file mode 100755 index 0000000..2d5aad9 --- /dev/null +++ b/Repair/RepairInterpreter/ActionNotInSet.cc @@ -0,0 +1,121 @@ +#include +#include "ActionNotInSet.h" +#include "dmodel.h" +#include "normalizer.h" +#include "omodel.h" +#include "Relation.h" +#include "set.h" +#include "Hashtable.h" +#include "ActionInSet.h" + +ActionNotInSet::ActionNotInSet(DomainRelation *drel, model *m) { + domrelation=drel; + globalmodel=m; +} + +void ActionNotInSet::repairpredicate(Hashtable *env,CoercePredicate *p) { + Element *ele=(Element*) env->get(p->getpredicate()->getlabel()->label()); + switch(p->getpredicate()->getsetexpr()->gettype()) { + case SETEXPR_LABEL: + domrelation->delfromsetmovetoset(ele, domrelation->getset(p->getpredicate()->getsetexpr()->getsetlabel()->getname()),globalmodel); + break; + case SETEXPR_REL: { + Element *key=(Element*) env->get(p->getpredicate()->getsetexpr()->getlabel()->label()); + domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname())->getrelation()->remove(key,ele); + } + break; + case SETEXPR_INVREL: { + Element *key=(Element*) env->get(p->getpredicate()->getsetexpr()->getlabel()->label()); + domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname())->getrelation()->remove(ele,key); + } + break; + } +} + + + + +void ActionNotInSet::breakpredicate(Hashtable *env, CoercePredicate *p) +{ +#ifdef DEBUGMESSAGES + printf("ActionNotInSet::breakpredicate CALLED\n"); + p->getpredicate()->print(); printf("\n"); +#endif + + ActionInSet *a = new ActionInSet(domrelation, globalmodel); + a->repairpredicate(env, p); +} + + + + +bool ActionNotInSet::conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2) { + assert(canrepairpredicate(p1)); + if(comparepredicates(c1,p1,c2,p2)) + return false; /*same predicates don't conflict*/ + Setexpr *pse=p1->getpredicate()->getsetexpr(); + switch(pse->gettype()) { + case SETEXPR_LABEL: { + /* Go through the sets we add something to */ + { + WorkSet *ws=domrelation->removeconflictaddsets(pse->getsetlabel()->getname(),globalmodel); + DomainSet *ds=(DomainSet *)ws->firstelement(); + while(ds!=NULL) { + if (conflictwithaddtoset(ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *)ws->getnextelement(ds); + } + delete(ws); + } + { + WorkSet *ws=domrelation->removeconflictdelsets(pse->getsetlabel()->getname()); + DomainSet *ds=(DomainSet *)ws->firstelement(); + while(ds!=NULL) { + if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) { + delete(ws); + return true; + } + ds=(DomainSet *)ws->getnextelement(ds); + } + delete(ws); + } + return false; + + } + case SETEXPR_REL: + /* we have !a in v.r */ + /* remove to r */ + return testforconflictremove(getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), + getset(c1,p1->getpredicate()->getlabel()->label()), + p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2); + case SETEXPR_INVREL: + /* we have !a in v.r */ + /* remove to r */ + return testforconflictremove(getset(c1,p1->getpredicate()->getlabel()->label()), + getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), + p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2); + } +} + +bool ActionNotInSet::canrepairpredicate(CoercePredicate *cp) { + if (cp->getcoercebool()==true) + return false; + Predicate *p=cp->getpredicate(); + if (p==NULL) + return false; + if (p->gettype()!=PREDICATE_SET) + return false; + Setexpr *se=p->getsetexpr(); + int setexprtype=se->gettype(); + if (setexprtype==SETEXPR_REL|| + setexprtype==SETEXPR_INVREL) { + DRelation *dr=domrelation->getrelation(se->getrelation()->getname()); + if (dr->isstatic()) + return false; /* Can't change static domain relations */ + } + + /* Coercing set membership */ + return true; +} diff --git a/Repair/RepairInterpreter/ActionNotInSet.h b/Repair/RepairInterpreter/ActionNotInSet.h new file mode 100755 index 0000000..58e8117 --- /dev/null +++ b/Repair/RepairInterpreter/ActionNotInSet.h @@ -0,0 +1,14 @@ +#ifndef ActionNotInSet_H +#define ActionNotInSet_H +#include "classlist.h" +#include "Action.h" +class ActionNotInSet:public Action { + public: + ActionNotInSet(DomainRelation *drel, model *); + void repairpredicate(Hashtable *env, CoercePredicate *p); + void breakpredicate(Hashtable *env, CoercePredicate *p); + bool conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2); + bool canrepairpredicate(CoercePredicate *p); + private: +}; +#endif diff --git a/Repair/RepairInterpreter/DefaultGuidance.cc b/Repair/RepairInterpreter/DefaultGuidance.cc new file mode 100755 index 0000000..6a322a8 --- /dev/null +++ b/Repair/RepairInterpreter/DefaultGuidance.cc @@ -0,0 +1,82 @@ +// for CIV + +#include +#include "DefaultGuidance.h" +#include "model.h" +#include "dmodel.h" +#include "tmodel.h" +#include "element.h" +#include "common.h" + /* This class tells the analysis stuff */ + /* For each set: + 1. Source for atoms if the set is too small - can be another set or function call (assumed to be no set) + 2. Source for atoms if relation requires atom of this set - can be another set or function call (assumed to be no set) + 3. Removal from set - where to insert objects from this set + 4. Insertion into set - which subset to put objects in */ + +DefGuidance::DefGuidance(model *m) { + globalmodel=m; +} + +Source DefGuidance::sourceforsetsize(char *set) { + if (equivalentstrings(set,"TERRAINTYPES")) + return Source(copystr("water")); + if (equivalentstrings(set,"STILE")) + return Source(copystr("STILE")); + return Source(&allocatebytes); +} + +Source DefGuidance::sourceforrelation(char *set) { + if (equivalentstrings(set,"TERRAINTYPES")) + return Source(copystr("water")); + if (equivalentstrings(set,"STILE")) + return Source(copystr("STILE")); + DomainRelation *dr=globalmodel->getdomainrelation(); + DomainSet *ds=dr->getset(set); + if (equivalentstrings(ds->getelementtype(),"int")) + return Source(copystr("int")); + return Source(&allocatebytes); +} + +char * DefGuidance::removefromset(char * set) { + DomainRelation *dr=globalmodel->getdomainrelation(); + DomainSet *ds=dr->getset(set); + DomainSet *ss=dr->getsuperset(ds); + while(ss!=NULL&&ss->gettype()==DOMAINSET_PARTITION) { + for(int i=0;igetnumsubsets();i++) { + char *name=ss->getsubset(i); + if (!equivalentstrings(ds->getname(),name)&& + !equivalentstrings(ds->getname(),name)) { + /* Do search */ + ss=dr->getset(name); + while(ss->gettype()==DOMAINSET_PARTITION) { + char *name=ss->getsubset(0); + ss=dr->getset(name); + } + return ss->getname(); + } + } + ds=ss; + ss=dr->getsuperset(ss); + } + if (ss!=NULL) + return ss->getname(); + else + return NULL; +} + +char * DefGuidance::insertiontoset(char *set) { + DomainRelation *dr=globalmodel->getdomainrelation(); + DomainSet *ds=dr->getset(set); + while (ds->gettype()==DOMAINSET_PARTITION) { + ds=dr->getset(ds->getsubset(0)); + /* have to look for subset; */ + } + return ds->getname(); +} + +Element * allocatebytes(structure * st, model *m) { + int size=st->getsize(m->getbitreader(),m,m->gethashtable()); + Element * e=new Element(new char[size],st); + return e; +} diff --git a/Repair/RepairInterpreter/DefaultGuidance.h b/Repair/RepairInterpreter/DefaultGuidance.h new file mode 100755 index 0000000..867bf59 --- /dev/null +++ b/Repair/RepairInterpreter/DefaultGuidance.h @@ -0,0 +1,27 @@ +// for CIV + +#ifndef DefGuidance_h +#define DefGuidance_h +#include "classlist.h" +#include "Guidance.h" + +class DefGuidance:public Guidance { + /* This class tells the analysis stuff */ + /* For each set: + 1. Source for atoms if the set is too small - can be another set or function call (assumed to be no set) + 2. Source for atoms if relation requires atom of this set - can be another set or function call (assumed to be no set) + 3. Removal from set - where to insert objects from this set + 4. Insertion into set - which subset to put objects in + */ + public: + DefGuidance(model *m); + Source sourceforsetsize(char *set); + Source sourceforrelation(char *set); + char * removefromset(char * set); + char * insertiontoset(char *set); + private: + model * globalmodel; +}; + +Element * allocatebytes(structure * st, model *m); +#endif diff --git a/Repair/RepairInterpreter/DefaultGuidance2.cc b/Repair/RepairInterpreter/DefaultGuidance2.cc new file mode 100755 index 0000000..b054d63 --- /dev/null +++ b/Repair/RepairInterpreter/DefaultGuidance2.cc @@ -0,0 +1,92 @@ +// for the File System benchmark + +#include +#include "DefaultGuidance2.h" +#include "model.h" +#include "dmodel.h" +#include "tmodel.h" +#include "element.h" +#include "common.h" + /* This class tells the analysis stuff */ + /* For each set: + 1. Source for atoms if the set is too small - can be another set or function call (assumed to be no set) + 2. Source for atoms if relation requires atom of this set - can be another set or function call (assumed to be no set) + 3. Removal from set - where to insert objects from this set + 4. Insertion into set - which subset to put objects in */ + +DefGuidance2::DefGuidance2(model *m) { + globalmodel=m; +} + +Source DefGuidance2::sourceforsetsize(char *set) { + DomainRelation *dr=globalmodel->getdomainrelation(); + DomainSet *ds=dr->getset(set); + while(dr->getsuperset(ds)!=NULL) + ds=dr->getsuperset(ds); + if(equivalentstrings(ds->getname(),"Block")) + return Source(copystr("FreeBlock")); + if(equivalentstrings(ds->getname(),"Inode")) + return Source(copystr("FreeInode")); +} + +Source DefGuidance2::sourceforrelation(char *set) { + return Source(set); +} + +char * DefGuidance2::removefromset(char * set) { + DomainRelation *dr=globalmodel->getdomainrelation(); + DomainSet *ds=dr->getset(set); + if (equivalentstrings(set,"token")) + return NULL; + + if (equivalentstrings(dr->getsuperset(ds)->getname(),"UsedBlock")) + return "FreeBlock"; + if (equivalentstrings(dr->getsuperset(ds)->getname(),"UsedInode")) + return "FreeInode"; + + DomainSet *ss=dr->getsuperset(ds); + while(ss!=NULL&&ss->gettype()==DOMAINSET_PARTITION) { + for(int i=0;igetnumsubsets();i++) { + char *name=ss->getsubset(i); + if (!equivalentstrings(ds->getname(),name)&& + !equivalentstrings(ds->getname(),name)) { + /* Do search */ + ss=dr->getset(name); + while(ss->gettype()==DOMAINSET_PARTITION) { + char *name=ss->getsubset(0); + ss=dr->getset(name); + } + return ss->getname(); + } + } + ds=ss; + ss=dr->getsuperset(ss); + } + if (ss!=NULL) + return ss->getname(); + else + return NULL; +} + +char * DefGuidance2::insertiontoset(char *set) { + if (equivalentstrings(set,"token")) + return NULL; + if (equivalentstrings(set,"UsedBlock")) + return "FileBlock"; + if (equivalentstrings(set,"UsedInode")) + return "FileInode"; + + DomainRelation *dr=globalmodel->getdomainrelation(); + DomainSet *ds=dr->getset(set); + while (ds->gettype()==DOMAINSET_PARTITION) { + ds=dr->getset(ds->getsubset(0)); + /* have to look for subset; */ + } + return ds->getname(); +} + +Element * allocatebytes2(structure * st, model *m) { + int size=st->getsize(m->getbitreader(),m,m->gethashtable()); + Element * e=new Element(new char[size],st); + return e; +} diff --git a/Repair/RepairInterpreter/DefaultGuidance2.h b/Repair/RepairInterpreter/DefaultGuidance2.h new file mode 100755 index 0000000..ef61ee6 --- /dev/null +++ b/Repair/RepairInterpreter/DefaultGuidance2.h @@ -0,0 +1,27 @@ +// for the File System benchmark + +#ifndef DefGuidance2_h +#define DefGuidance2_h +#include "classlist.h" +#include "Guidance.h" + +class DefGuidance2:public Guidance { + /* This class tells the analysis stuff */ + /* For each set: + 1. Source for atoms if the set is too small - can be another set or function call (assumed to be no set) + 2. Source for atoms if relation requires atom of this set - can be another set or function call (assumed to be no set) + 3. Removal from set - where to insert objects from this set + 4. Insertion into set - which subset to put objects in + */ + public: + DefGuidance2(model *m); + Source sourceforsetsize(char *set); + Source sourceforrelation(char *set); + char * removefromset(char * set); + char * insertiontoset(char *set); + private: + model * globalmodel; +}; + +Element * allocatebytes2(structure * st, model *m); +#endif diff --git a/Repair/RepairInterpreter/DefaultGuidance3.cc b/Repair/RepairInterpreter/DefaultGuidance3.cc new file mode 100755 index 0000000..bf0b57b --- /dev/null +++ b/Repair/RepairInterpreter/DefaultGuidance3.cc @@ -0,0 +1,84 @@ +#include +#include "DefaultGuidance3.h" +#include "model.h" +#include "dmodel.h" +#include "tmodel.h" +#include "element.h" +#include "common.h" + /* This class tells the analysis stuff */ + /* For each set: + 1. Source for atoms if the set is too small - can be another set or function call (assumed to be no set) + 2. Source for atoms if relation requires atom of this set - can be another set or function call (assumed to be no set) + 3. Removal from set - where to insert objects from this set + 4. Insertion into set - which subset to put objects in */ + +DefGuidance3::DefGuidance3(model *m) { + globalmodel=m; +} + +Source DefGuidance3::sourceforsetsize(char *set) { + DomainRelation *dr=globalmodel->getdomainrelation(); + DomainSet *ds=dr->getset(set); + while(dr->getsuperset(ds)!=NULL) + ds=dr->getsuperset(ds); + if(equivalentstrings(ds->getname(),"blocks")) + return Source(copystr("freeblocks")); +} + +Source DefGuidance3::sourceforrelation(char *set) { + DomainRelation *dr=globalmodel->getdomainrelation(); + DomainSet *ds=dr->getset(set); + while(dr->getsuperset(ds)!=NULL) + ds=dr->getsuperset(ds); + if(equivalentstrings(ds->getname(),"blocks")) + return Source(copystr("freeblocks")); + return Source(set); +} + +char * DefGuidance3::removefromset(char * set) { + DomainRelation *dr=globalmodel->getdomainrelation(); + DomainSet *ds=dr->getset(set); + if (equivalentstrings(set,"token")) + return NULL; + + if (equivalentstrings(dr->getsuperset(ds)->getname(),"fatblocks")) + return "freeblocks"; + if (equivalentstrings(dr->getsuperset(ds)->getname(),"usedblocks")) + return "freeblocks"; + + DomainSet *ss=dr->getsuperset(ds); + while(ss!=NULL&&ss->gettype()==DOMAINSET_PARTITION) { + for(int i=0;igetnumsubsets();i++) { + char *name=ss->getsubset(i); + if (!equivalentstrings(ds->getname(),name)&& + !equivalentstrings(ds->getname(),name)) { + /* Do search */ + ss=dr->getset(name); + while(ss->gettype()==DOMAINSET_PARTITION) { + char *name=ss->getsubset(0); + ss=dr->getset(name); + } + return ss->getname(); + } + } + ds=ss; + ss=dr->getsuperset(ss); + } + if (ss!=NULL) + return ss->getname(); + else + return NULL; +} + +char * DefGuidance3::insertiontoset(char *set) { + if (equivalentstrings(set,"token")) + return NULL; + + DomainRelation *dr=globalmodel->getdomainrelation(); + DomainSet *ds=dr->getset(set); + while (ds->gettype()==DOMAINSET_PARTITION) { + ds=dr->getset(ds->getsubset(0)); + /* have to look for subset; */ + } + return ds->getname(); +} diff --git a/Repair/RepairInterpreter/DefaultGuidance3.h b/Repair/RepairInterpreter/DefaultGuidance3.h new file mode 100755 index 0000000..a6f9e29 --- /dev/null +++ b/Repair/RepairInterpreter/DefaultGuidance3.h @@ -0,0 +1,24 @@ +#ifndef DefGuidance3_h +#define DefGuidance3_h +#include "classlist.h" +#include "Guidance.h" + +class DefGuidance3:public Guidance { + /* This class tells the analysis stuff */ + /* For each set: + 1. Source for atoms if the set is too small - can be another set or function call (assumed to be no set) + 2. Source for atoms if relation requires atom of this set - can be another set or function call (assumed to be no set) + 3. Removal from set - where to insert objects from this set + 4. Insertion into set - which subset to put objects in + */ + public: + DefGuidance3(model *m); + Source sourceforsetsize(char *set); + Source sourceforrelation(char *set); + char * removefromset(char * set); + char * insertiontoset(char *set); + private: + model * globalmodel; +}; + +#endif diff --git a/Repair/RepairInterpreter/GenericHashtable.cc b/Repair/RepairInterpreter/GenericHashtable.cc new file mode 100755 index 0000000..f42c543 --- /dev/null +++ b/Repair/RepairInterpreter/GenericHashtable.cc @@ -0,0 +1,200 @@ +#include +#include +#include +#include +#include +#include +#include "GenericHashtable.h" +//#include "dmalloc.h" + +int genputtable(struct genhashtable *ht, void * key, void * object) { + unsigned int bin=genhashfunction(ht,key); + struct genpointerlist * newptrlist=(struct genpointerlist *) new genpointerlist; + newptrlist->src=key; + newptrlist->object=object; + newptrlist->next=ht->bins[bin]; + newptrlist->inext=NULL; + /* maintain linked list of ht entries for iteration*/ + if (ht->last==NULL) { + ht->last=newptrlist; + ht->list=newptrlist; + newptrlist->iprev=NULL; + } else { + ht->last->inext=newptrlist; + newptrlist->iprev=ht->last; + ht->last=newptrlist; + } + ht->bins[bin]=newptrlist; + ht->counter++; + if(ht->counter>ht->currentsize&&ht->currentsize!=MAXINT) { + /* Expand hashtable */ + long newcurrentsize=(ht->currentsize<(MAXINT/2))?ht->currentsize*2:MAXINT; + long oldcurrentsize=ht->currentsize; + struct genpointerlist **newbins=(struct genpointerlist **) new genpointerlist*[newcurrentsize]; + struct genpointerlist **oldbins=ht->bins; + for(long j=0;jcurrentsize=newcurrentsize; + for(i=0;isrc); + struct genpointerlist *nextptr=tmpptr->next; + tmpptr->next=newbins[hashcode]; + newbins[hashcode]=tmpptr; + tmpptr=nextptr; + } + } + ht->bins=newbins; + delete[](oldbins); + } + return 1; +} + +int hashsize(struct genhashtable *ht) { + return ht->counter; +} + +void * gengettable(struct genhashtable *ht, void * key) { + struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)]; + while(ptr!=NULL) { + if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key))) + return ptr->object; + ptr=ptr->next; + } + printf("XXXXXXXXX: COULDN'T FIND ENTRY FOR KEY %p\n",key); + return NULL; +} + +void * getnext(struct genhashtable *ht, void * key) { + struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)]; + while(ptr!=NULL) { + if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key))) + if (ptr->inext!=NULL) { + return ptr->inext->src; + } else + return NULL; + ptr=ptr->next; + } + printf("XXXXXXXXX: COULDN'T FIND ENTRY FOR KEY %p...\n Likely concurrent removal--bad user!!!\n",key); + return NULL; +} + +int gencontains(struct genhashtable *ht, void * key) { + struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)]; + //printf("In gencontains2\n");fflush(NULL); + while(ptr!=NULL) { + if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key))) + return 1; + ptr=ptr->next; + } + return 0; +} + + +void genfreekey(struct genhashtable *ht, void * key) { + struct genpointerlist * ptr=ht->bins[genhashfunction(ht,key)]; + + if (((ht->comp_function==NULL)&&(ptr->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->src,key))) { + ht->bins[genhashfunction(ht,key)]=ptr->next; + + if (ptr==ht->last) + ht->last=ptr->iprev; + + if (ptr==ht->list) + ht->list=ptr->inext; + + if (ptr->iprev!=NULL) + ptr->iprev->inext=ptr->inext; + if (ptr->inext!=NULL) + ptr->inext->iprev=ptr->iprev; + + delete(ptr); + ht->counter--; + return; + } + while(ptr->next!=NULL) { + if (((ht->comp_function==NULL)&&(ptr->next->src==key))||((ht->comp_function!=NULL)&&(*ht->comp_function)(ptr->next->src,key))) { + struct genpointerlist *tmpptr=ptr->next; + ptr->next=tmpptr->next; + if (tmpptr==ht->list) + ht->list=tmpptr->inext; + if (tmpptr==ht->last) + ht->last=tmpptr->iprev; + if (tmpptr->iprev!=NULL) + tmpptr->iprev->inext=tmpptr->inext; + if (tmpptr->inext!=NULL) + tmpptr->inext->iprev=tmpptr->iprev; + delete(tmpptr); + ht->counter--; + return; + } + ptr=ptr->next; + } + printf("XXXXXXXXX: COULDN'T FIND ENTRY FOR KEY %p\n",key); +} + +unsigned int genhashfunction(struct genhashtable *ht, void * key) { + if (ht->hash_function==NULL) + return ((long unsigned int)key) % ht->currentsize; + else + return ((*ht->hash_function)(key)) % ht->currentsize; +} + +struct genhashtable * genallocatehashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *, void *)) { + struct genhashtable *ght=(struct genhashtable *) new genhashtable; + struct genpointerlist **gpl=(struct genpointerlist **) new genpointerlist *[geninitialnumbins]; + for(int i=0;ihash_function=hash_function; + ght->comp_function=comp_function; + ght->currentsize=geninitialnumbins; + ght->bins=gpl; + ght->counter=0; + ght->list=NULL; + ght->last=NULL; + return ght; +} + +void genfreehashtable(struct genhashtable * ht) { + int i; + for (i=0;icurrentsize;i++) { + if (ht->bins[i]!=NULL) { + struct genpointerlist *genptr=ht->bins[i]; + while(genptr!=NULL) { + struct genpointerlist *tmpptr=genptr->next; + delete(genptr); + genptr=tmpptr; + } + } + } + delete[](ht->bins); + delete(ht); +} + +struct geniterator * gengetiterator(struct genhashtable *ht) { + struct geniterator *gi=new geniterator(); + gi->ptr=ht->list; + return gi; +} + +void * gennext(struct geniterator *it) { + struct genpointerlist *curr=it->ptr; + if (curr==NULL) + return NULL; + if (it->finished&&(curr->inext==NULL)) + return NULL; + if (it->finished) { + it->ptr=curr->inext; + return it->ptr->src; + } + if(curr->inext!=NULL) + it->ptr=curr->inext; + else + it->finished=true; /* change offsetting scheme */ + return curr->src; +} + +void genfreeiterator(struct geniterator *it) { + delete(it); +} diff --git a/Repair/RepairInterpreter/GenericHashtable.h b/Repair/RepairInterpreter/GenericHashtable.h new file mode 100755 index 0000000..1dabec3 --- /dev/null +++ b/Repair/RepairInterpreter/GenericHashtable.h @@ -0,0 +1,50 @@ +// implements a generic hash table + +#ifndef GENHASHTABLE +#define GENHASHTABLE +#define geninitialnumbins 10 + +struct genhashtable { + unsigned int (*hash_function)(void *); + int (*comp_function)(void *,void *); + struct genpointerlist ** bins; + long counter; + int currentsize; + struct genpointerlist *list; + struct genpointerlist *last; +}; + + +struct genpointerlist { + void * src; + void * object; + struct genpointerlist * next; + + struct genpointerlist * inext; + struct genpointerlist * iprev; +}; + + +struct geniterator { + struct genpointerlist * ptr; + bool finished; +}; + +struct genhashtable * genallocatehashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *,void *)); +void genfreehashtable(struct genhashtable * ht); + +void * getnext(struct genhashtable *,void *); +int genputtable(struct genhashtable *, void *, void *); +void * gengettable(struct genhashtable *, void *); +int gencontains(struct genhashtable *, void *); +unsigned int genhashfunction(struct genhashtable *,void *); + +int hashsize(struct genhashtable * ht); +void genfreekey(struct genhashtable *ht, void *); +struct geniterator * gengetiterator(struct genhashtable *ht); +void * gennext(struct geniterator *it); +void genfreeiterator(struct geniterator *it); +#endif + + + diff --git a/Repair/RepairInterpreter/Guidance.cc b/Repair/RepairInterpreter/Guidance.cc new file mode 100755 index 0000000..11e6f14 --- /dev/null +++ b/Repair/RepairInterpreter/Guidance.cc @@ -0,0 +1,12 @@ +#include +#include "Guidance.h" + +Source::Source(Element * (*fptr)(structure *,model *)) { + functionptr=fptr; + setname=NULL; +} + +Source::Source(char *sname) { + functionptr=NULL; + setname=sname; +} diff --git a/Repair/RepairInterpreter/Guidance.h b/Repair/RepairInterpreter/Guidance.h new file mode 100755 index 0000000..cb0b969 --- /dev/null +++ b/Repair/RepairInterpreter/Guidance.h @@ -0,0 +1,30 @@ +#ifndef Guidance_h +#define Guidance_h +#include "classlist.h" + +class Guidance { + /* This class tells the analysis stuff */ + /* For each set: + 1. Source for atoms if the set is too small - can be another set or function call (assumed to be no set) + 2. Source for atoms if relation requires atom of this set - can be another set or function call (assumed to be no set) + 3. Removal from set - where to insert objects from this set + 4. Insertion into set - which subset to put objects in + */ + public: + virtual Source sourceforsetsize(char *set)=0; + virtual Source sourceforrelation(char *set)=0; + virtual char * removefromset(char * set)=0; + virtual char * insertiontoset(char *set)=0; +}; + + +class Source { + public: + Source(Element * (*fptr)(structure *, model *)); + Source(char *sname); + + Element * (*functionptr)(structure *,model *); + char * setname; +}; + +#endif diff --git a/Repair/RepairInterpreter/Hashtable.cc b/Repair/RepairInterpreter/Hashtable.cc new file mode 100755 index 0000000..fb3b66c --- /dev/null +++ b/Repair/RepairInterpreter/Hashtable.cc @@ -0,0 +1,51 @@ +#include +#include "Hashtable.h" +#include "element.h" + +Hashtable::Hashtable() { + forward=genallocatehashtable((unsigned int (*)(void *)) & hashelement,(int (*)(void *,void *)) & elementequals); + parent=NULL; +} + +void Hashtable::setparent(Hashtable *parent) { + this->parent=parent; +} + +Hashtable::Hashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *, void *)) { + forward=genallocatehashtable(hash_function,comp_function); + parent=NULL; +} + +void Hashtable::put(void *key, void*object) { + if (contains(key)) + remove(key); + genputtable(forward,key,object); +} + +void Hashtable::remove(void *key) { + genfreekey(forward,key); +} + +void* Hashtable::get(void *key) { + if (!gencontains(forward,key)) { + if (parent!=NULL) + return parent->get(key); + else + return NULL; + } else + return gengettable(forward,key); +} + +bool Hashtable::contains(void *key) { + if (!gencontains(forward,key)) { + if (parent==NULL) + return false; + else + return parent->contains(key); + } else + return true; +} + +Hashtable::~Hashtable() { + genfreehashtable(forward); +} diff --git a/Repair/RepairInterpreter/Hashtable.h b/Repair/RepairInterpreter/Hashtable.h new file mode 100755 index 0000000..a10ce14 --- /dev/null +++ b/Repair/RepairInterpreter/Hashtable.h @@ -0,0 +1,22 @@ +#ifndef Hashtable_H +#define Hashtable_H + +#include "GenericHashtable.h" +#include "classlist.h" + +class Hashtable { + public: + Hashtable(); + Hashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *, void *)); + ~Hashtable(); + void put(void *key, void*object); + void remove(void *key); + void* get(void *key); + bool contains(void *key); + void setparent(Hashtable *parent); + private: + Hashtable *parent; + struct genhashtable *forward; +}; + +#endif diff --git a/Repair/RepairInterpreter/Makefile b/Repair/RepairInterpreter/Makefile new file mode 100755 index 0000000..289767d --- /dev/null +++ b/Repair/RepairInterpreter/Makefile @@ -0,0 +1,544 @@ +# Makefile.in generated by automake 1.6.3 from Makefile.am. +# checker/Makefile. Generated from Makefile.in by configure. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = /bin/sh + +srcdir = . +top_srcdir = .. + +prefix = /usr/local +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +sbindir = ${exec_prefix}/sbin +libexecdir = ${exec_prefix}/libexec +datadir = ${prefix}/share +sysconfdir = ${prefix}/etc +sharedstatedir = ${prefix}/com +localstatedir = ${prefix}/var +libdir = ${exec_prefix}/lib +infodir = ${prefix}/info +mandir = ${prefix}/man +includedir = ${prefix}/include +oldincludedir = /usr/include +pkgdatadir = $(datadir)/freeciv +pkglibdir = $(libdir)/freeciv +pkgincludedir = $(includedir)/freeciv +top_builddir = .. + +ACLOCAL = aclocal-1.6 +AUTOCONF = autoconf +AUTOMAKE = automake-1.6 +AUTOHEADER = autoheader + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_SCRIPT = ${INSTALL} +INSTALL_HEADER = $(INSTALL_DATA) +transform = s,x,x, +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = +host_triplet = i686-pc-linux-gnu + +EXEEXT = +OBJEXT = o +PATH_SEPARATOR = : +AMTAR = tar +ARFLAGS = +AWK = gawk +BUILD_INCLUDED_LIBINTL = no +CATALOGS = da.gmo de.gmo en_GB.gmo es.gmo fi.gmo fr.gmo hu.gmo it.gmo ja.gmo nl.gmo no.gmo pl.gmo pt.gmo pt_BR.gmo ro.gmo ru.gmo sv.gmo +CATOBJEXT = .gmo +CC = gcc +CLIENT_CFLAGS = -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/X11R6/include -I/usr/X11R6/include +CLIENT_LIBS = -L/usr/lib -lgdk_imlib -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm +CPP = gcc -E +CVS_DEPS = yes +CXX = g++ +DATADIRNAME = share +DEPDIR = .deps +ESD_CFLAGS = +ESD_CONFIG = /usr/bin/esd-config +ESD_LIBS = -L/usr/lib -lesd -laudiofile -lm +GDK_IMLIB_CFLAGS = -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/X11R6/include -I/usr/X11R6/include +GDK_IMLIB_LIBS = -L/usr/lib -lgdk_imlib -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm +GENCAT = gencat +GLIBC21 = yes +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_CONFIG = @GLIB_CONFIG@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMOFILES = da.gmo de.gmo en_GB.gmo es.gmo fi.gmo fr.gmo hu.gmo it.gmo ja.gmo nl.gmo no.gmo pl.gmo pt.gmo pt_BR.gmo ro.gmo ru.gmo sv.gmo +GMSGFMT = /usr/bin/msgfmt +GOBJECT_QUERY = @GOBJECT_QUERY@ +GTK_CFLAGS = -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/X11R6/include +GTK_CONFIG = /usr/bin/gtk-config +GTK_LIBS = -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm +IMLIB_CFLAGS = @IMLIB_CFLAGS@ +IMLIB_CONFIG = /usr/bin/imlib-config +IMLIB_LIBS = @IMLIB_LIBS@ +INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s +INSTOBJEXT = .mo +INTLBISON = bison +INTLDEPS = @INTLDEPS@ +INTLLIBS = +INTLOBJS = +INTL_LIBTOOL_SUFFIX_PREFIX = +LIBICONV = +LN_S = ln -s +MAINT = # +MKINSTALLDIRS = ./mkinstalldirs +MSGFMT = /usr/bin/msgfmt +PACKAGE = freeciv +PKG_CONFIG = +POFILES = da.po de.po en_GB.po es.po fi.po fr.po hu.po it.po ja.po nl.po no.po pl.po pt.po pt_BR.po ro.po ru.po sv.po +POSUB = po +RANLIB = ranlib +SDL_CFLAGS = +SDL_CONFIG = no +SDL_LIBS = +SERVER_LIBS = -lreadline -lncurses -lm +SOUND_CFLAGS = +SOUND_LIBS = -L/usr/lib -lesd -laudiofile -lm +STRIP = +UNAME = uname +UP = @UP@ +USE_INCLUDED_LIBINTL = no +USE_NLS = yes +VERSION = 1.13.0 +X_CFLAGS = +X_EXTRA_LIBS = +X_LIBS = +X_PRE_LIBS = +am__include = include +am__quote = +gui_sources = gui-gtk +install_sh = /root/freeciv-1.13.0/install-sh +noinst_LIBRARIES = libchecker.a + +libchecker_a_SOURCES = \ +ActionAssign.cc \ +ActionAssign.h \ +Action.cc \ +ActionEQ1.cc \ +ActionEQ1.h \ +ActionGEQ1.cc \ +ActionGEQ1.h \ +Action.h \ +ActionInSet.cc \ +ActionInSet.h \ +ActionNormal.cc \ +ActionNormal.h \ +ActionNotInSet.cc \ +ActionNotInSet.h \ +amodel.cc \ +amodel.h \ +aparser.cc \ +aparser.h \ +bitreader.cc \ +bitreader.h \ +bitwriter.cc \ +bitwriter.h \ +classlist.h \ +cmodel.cc \ +cmodel.h \ +common.c \ +common.h \ +cparser.cc \ +cparser.h \ +DefaultGuidance3.cc \ +DefaultGuidance3.h \ +DefaultGuidance2.cc \ +DefaultGuidance2.h \ +DefaultGuidance.cc \ +DefaultGuidance.h \ +dmodel.cc \ +dmodel.h \ +dparser.cc \ +dparser.h \ +element.cc \ +element.h \ +fieldcheck.cc \ +fieldcheck.h \ +file.cc \ +file.h \ +GenericHashtable.c \ +GenericHashtable.h \ +Guidance.cc \ +Guidance.h \ +Hashtable.cc \ +Hashtable.h \ +list.c \ +list.h \ +model.cc \ +model.h \ +normalizer.cc \ +normalizer.h \ +omodel.cc \ +omodel.h \ +oparser.cc \ +oparser.h \ +processabstract.cc \ +processabstract.h \ +processconcrete.cc \ +processconcrete.h \ +processobject.cc \ +processobject.h \ +Relation.cc \ +Relation.h \ +repair.cc \ +repair.h \ +set.cc \ +set.h \ +test.cc \ +test.h \ +tmodel.cc \ +tmodel.h \ +token.cc \ +token.h \ +typeparser.cc \ +typeparser.h \ +tmap.cc \ +tmap.h \ +redblack.c \ +redblack.h \ +cmemory.h + +subdir = checker +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + +libchecker_a_AR = $(AR) cru +libchecker_a_LIBADD = +am_libchecker_a_OBJECTS = ActionAssign.$(OBJEXT) Action.$(OBJEXT) \ + ActionEQ1.$(OBJEXT) ActionGEQ1.$(OBJEXT) ActionInSet.$(OBJEXT) \ + ActionNormal.$(OBJEXT) ActionNotInSet.$(OBJEXT) \ + amodel.$(OBJEXT) aparser.$(OBJEXT) bitreader.$(OBJEXT) \ + bitwriter.$(OBJEXT) cmodel.$(OBJEXT) common.$(OBJEXT) \ + cparser.$(OBJEXT) DefaultGuidance3.$(OBJEXT) \ + DefaultGuidance2.$(OBJEXT) DefaultGuidance.$(OBJEXT) \ + dmodel.$(OBJEXT) dparser.$(OBJEXT) element.$(OBJEXT) \ + fieldcheck.$(OBJEXT) file.$(OBJEXT) GenericHashtable.$(OBJEXT) \ + Guidance.$(OBJEXT) Hashtable.$(OBJEXT) list.$(OBJEXT) \ + model.$(OBJEXT) normalizer.$(OBJEXT) omodel.$(OBJEXT) \ + oparser.$(OBJEXT) processabstract.$(OBJEXT) \ + processconcrete.$(OBJEXT) processobject.$(OBJEXT) \ + Relation.$(OBJEXT) repair.$(OBJEXT) set.$(OBJEXT) \ + test.$(OBJEXT) tmodel.$(OBJEXT) token.$(OBJEXT) \ + typeparser.$(OBJEXT) tmap.$(OBJEXT) redblack.$(OBJEXT) +libchecker_a_OBJECTS = $(am_libchecker_a_OBJECTS) + +DEFS = -DHAVE_CONFIG_H +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +CPPFLAGS = +LDFLAGS = +LIBS = -lz +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +DEP_FILES = ./$(DEPDIR)/Action.Po \ + ./$(DEPDIR)/ActionAssign.Po \ + ./$(DEPDIR)/ActionEQ1.Po ./$(DEPDIR)/ActionGEQ1.Po \ + ./$(DEPDIR)/ActionInSet.Po \ + ./$(DEPDIR)/ActionNormal.Po \ + ./$(DEPDIR)/ActionNotInSet.Po \ + ./$(DEPDIR)/DefaultGuidance.Po \ + ./$(DEPDIR)/DefaultGuidance2.Po \ + ./$(DEPDIR)/DefaultGuidance3.Po \ + ./$(DEPDIR)/GenericHashtable.Po \ + ./$(DEPDIR)/Guidance.Po ./$(DEPDIR)/Hashtable.Po \ + ./$(DEPDIR)/Relation.Po ./$(DEPDIR)/amodel.Po \ + ./$(DEPDIR)/aparser.Po ./$(DEPDIR)/bitreader.Po \ + ./$(DEPDIR)/bitwriter.Po ./$(DEPDIR)/cmodel.Po \ + ./$(DEPDIR)/common.Po ./$(DEPDIR)/cparser.Po \ + ./$(DEPDIR)/dmodel.Po ./$(DEPDIR)/dparser.Po \ + ./$(DEPDIR)/element.Po ./$(DEPDIR)/fieldcheck.Po \ + ./$(DEPDIR)/file.Po ./$(DEPDIR)/list.Po \ + ./$(DEPDIR)/model.Po ./$(DEPDIR)/normalizer.Po \ + ./$(DEPDIR)/omodel.Po ./$(DEPDIR)/oparser.Po \ + ./$(DEPDIR)/processabstract.Po \ + ./$(DEPDIR)/processconcrete.Po \ + ./$(DEPDIR)/processobject.Po \ + ./$(DEPDIR)/redblack.Po ./$(DEPDIR)/repair.Po \ + ./$(DEPDIR)/set.Po ./$(DEPDIR)/test.Po \ + ./$(DEPDIR)/tmap.Po ./$(DEPDIR)/tmodel.Po \ + ./$(DEPDIR)/token.Po ./$(DEPDIR)/typeparser.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CFLAGS = -g -O2 -Wall +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +CXXFLAGS = -g -O2 +DIST_SOURCES = $(libchecker_a_SOURCES) +DIST_COMMON = README Makefile.am Makefile.in +SOURCES = $(libchecker_a_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cc .o .obj +$(srcdir)/Makefile.in: # Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu checker/Makefile +Makefile: # $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +AR = ar + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libchecker.a: $(libchecker_a_OBJECTS) $(libchecker_a_DEPENDENCIES) + -rm -f libchecker.a + $(libchecker_a_AR) libchecker.a $(libchecker_a_OBJECTS) $(libchecker_a_LIBADD) + $(RANLIB) libchecker.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/Action.Po +include ./$(DEPDIR)/ActionAssign.Po +include ./$(DEPDIR)/ActionEQ1.Po +include ./$(DEPDIR)/ActionGEQ1.Po +include ./$(DEPDIR)/ActionInSet.Po +include ./$(DEPDIR)/ActionNormal.Po +include ./$(DEPDIR)/ActionNotInSet.Po +include ./$(DEPDIR)/DefaultGuidance.Po +include ./$(DEPDIR)/DefaultGuidance2.Po +include ./$(DEPDIR)/DefaultGuidance3.Po +include ./$(DEPDIR)/GenericHashtable.Po +include ./$(DEPDIR)/Guidance.Po +include ./$(DEPDIR)/Hashtable.Po +include ./$(DEPDIR)/Relation.Po +include ./$(DEPDIR)/amodel.Po +include ./$(DEPDIR)/aparser.Po +include ./$(DEPDIR)/bitreader.Po +include ./$(DEPDIR)/bitwriter.Po +include ./$(DEPDIR)/cmodel.Po +include ./$(DEPDIR)/common.Po +include ./$(DEPDIR)/cparser.Po +include ./$(DEPDIR)/dmodel.Po +include ./$(DEPDIR)/dparser.Po +include ./$(DEPDIR)/element.Po +include ./$(DEPDIR)/fieldcheck.Po +include ./$(DEPDIR)/file.Po +include ./$(DEPDIR)/list.Po +include ./$(DEPDIR)/model.Po +include ./$(DEPDIR)/normalizer.Po +include ./$(DEPDIR)/omodel.Po +include ./$(DEPDIR)/oparser.Po +include ./$(DEPDIR)/processabstract.Po +include ./$(DEPDIR)/processconcrete.Po +include ./$(DEPDIR)/processobject.Po +include ./$(DEPDIR)/redblack.Po +include ./$(DEPDIR)/repair.Po +include ./$(DEPDIR)/set.Po +include ./$(DEPDIR)/test.Po +include ./$(DEPDIR)/tmap.Po +include ./$(DEPDIR)/tmodel.Po +include ./$(DEPDIR)/token.Po +include ./$(DEPDIR)/typeparser.Po + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.c.o: + source='$<' object='$@' libtool=no \ + depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \ + $(CCDEPMODE) $(depcomp) \ + $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: + source='$<' object='$@' libtool=no \ + depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \ + $(CCDEPMODE) $(depcomp) \ + $(COMPILE) -c `cygpath -w $<` +CCDEPMODE = depmode=gcc3 + +.cc.o: + source='$<' object='$@' libtool=no \ + depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \ + $(CXXDEPMODE) $(depcomp) \ + $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +.cc.obj: + source='$<' object='$@' libtool=no \ + depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \ + $(CXXDEPMODE) $(depcomp) \ + $(CXXCOMPILE) -c -o $@ `cygpath -w $<` +CXXDEPMODE = depmode=gcc3 +uninstall-info-am: + +ETAGS = etags +ETAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @list='$(DISTFILES)'; for file in $$list; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +uninstall-am: uninstall-info-am + +.PHONY: GTAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES distclean distclean-compile \ + distclean-depend distclean-generic distclean-tags distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic tags uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Repair/RepairInterpreter/Makefile.am b/Repair/RepairInterpreter/Makefile.am new file mode 100755 index 0000000..08a717d --- /dev/null +++ b/Repair/RepairInterpreter/Makefile.am @@ -0,0 +1,21 @@ +noinst_LIBRARIES = libchecker.a + +libchecker_a_SOURCES =ActionAssign.cc bitreader.h DefaultGuidance.h model.cc repair.h\ +ActionAssign.h bitwriter.cc dmodel.cc model.h rparser.cc\ +Action.cc bitwriter.h dmodel.h normalizer.cc rparser.h\ +ActionEQ1.cc catcherror.c dparser.cc normalizer.h set.cc\ +ActionEQ1.h catcherror.h dparser.h omodel.cc set.h\ +ActionGEQ1.cc classlist.h element.cc omodel.h SimpleHash.cc\ +ActionGEQ1.h cmemory.h element.h oparser.cc SimpleHash.h\ +Action.h cmodel.cc fieldcheck.cc oparser.h stack.c\ +ActionInSet.cc cmodel.h fieldcheck.h processabstract.cc stack.h\ +ActionInSet.h common.cc processabstract.h test.cc\ +ActionNormal.cc common.h file.h processconcrete.cc test.h\ +ActionNormal.h cparser.cc GenericHashtable.cc processconcrete.h tmap.cc\ +ActionNotInSet.cc cparser.h GenericHashtable.h processobject.cc tmap.h\ +ActionNotInSet.h Guidance.cc processobject.h tmodel.cc\ +amodel.cc DefaultGuidance2.cc Guidance.h redblack.c tmodel.h\ +amodel.h DefaultGuidance2.h Hashtable.cc redblack.h token.cc\ +aparser.cc DefaultGuidance3.cc Hashtable.h Relation.cc token.h\ +aparser.h DefaultGuidance3.h list.cc Relation.h typeparser.cc\ +bitreader.cc DefaultGuidance.cc list.h repair.cc typeparser.h diff --git a/Repair/RepairInterpreter/Makefile.in b/Repair/RepairInterpreter/Makefile.in new file mode 100755 index 0000000..cb64333 --- /dev/null +++ b/Repair/RepairInterpreter/Makefile.in @@ -0,0 +1,544 @@ +# Makefile.in generated by automake 1.6.3 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_HEADER = $(INSTALL_DATA) +transform = @program_transform_name@ +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ + +EXEEXT = @EXEEXT@ +OBJEXT = @OBJEXT@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +AMTAR = @AMTAR@ +ARFLAGS = @ARFLAGS@ +AWK = @AWK@ +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CLIENT_CFLAGS = @CLIENT_CFLAGS@ +CLIENT_LIBS = @CLIENT_LIBS@ +CPP = @CPP@ +CVS_DEPS = @CVS_DEPS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DEPDIR = @DEPDIR@ +ESD_CFLAGS = @ESD_CFLAGS@ +ESD_CONFIG = @ESD_CONFIG@ +ESD_LIBS = @ESD_LIBS@ +GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@ +GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@ +GENCAT = @GENCAT@ +GLIBC21 = @GLIBC21@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_CONFIG = @GLIB_CONFIG@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_CONFIG = @GTK_CONFIG@ +GTK_LIBS = @GTK_LIBS@ +IMLIB_CFLAGS = @IMLIB_CFLAGS@ +IMLIB_CONFIG = @IMLIB_CONFIG@ +IMLIB_LIBS = @IMLIB_LIBS@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLBISON = @INTLBISON@ +INTLDEPS = @INTLDEPS@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ +INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@ +LIBICONV = @LIBICONV@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +SERVER_LIBS = @SERVER_LIBS@ +SOUND_CFLAGS = @SOUND_CFLAGS@ +SOUND_LIBS = @SOUND_LIBS@ +STRIP = @STRIP@ +UNAME = @UNAME@ +UP = @UP@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +am__include = @am__include@ +am__quote = @am__quote@ +gui_sources = @gui_sources@ +install_sh = @install_sh@ +noinst_LIBRARIES = libchecker.a + +libchecker_a_SOURCES = \ +ActionAssign.cc \ +ActionAssign.h \ +Action.cc \ +ActionEQ1.cc \ +ActionEQ1.h \ +ActionGEQ1.cc \ +ActionGEQ1.h \ +Action.h \ +ActionInSet.cc \ +ActionInSet.h \ +ActionNormal.cc \ +ActionNormal.h \ +ActionNotInSet.cc \ +ActionNotInSet.h \ +amodel.cc \ +amodel.h \ +aparser.cc \ +aparser.h \ +bitreader.cc \ +bitreader.h \ +bitwriter.cc \ +bitwriter.h \ +classlist.h \ +cmodel.cc \ +cmodel.h \ +common.c \ +common.h \ +cparser.cc \ +cparser.h \ +DefaultGuidance3.cc \ +DefaultGuidance3.h \ +DefaultGuidance2.cc \ +DefaultGuidance2.h \ +DefaultGuidance.cc \ +DefaultGuidance.h \ +dmodel.cc \ +dmodel.h \ +dparser.cc \ +dparser.h \ +element.cc \ +element.h \ +fieldcheck.cc \ +fieldcheck.h \ +file.cc \ +file.h \ +GenericHashtable.c \ +GenericHashtable.h \ +Guidance.cc \ +Guidance.h \ +Hashtable.cc \ +Hashtable.h \ +list.c \ +list.h \ +model.cc \ +model.h \ +normalizer.cc \ +normalizer.h \ +omodel.cc \ +omodel.h \ +oparser.cc \ +oparser.h \ +processabstract.cc \ +processabstract.h \ +processconcrete.cc \ +processconcrete.h \ +processobject.cc \ +processobject.h \ +Relation.cc \ +Relation.h \ +repair.cc \ +repair.h \ +set.cc \ +set.h \ +test.cc \ +test.h \ +tmodel.cc \ +tmodel.h \ +token.cc \ +token.h \ +typeparser.cc \ +typeparser.h \ +tmap.cc \ +tmap.h \ +redblack.c \ +redblack.h \ +cmemory.h + +subdir = checker +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + +libchecker_a_AR = $(AR) cru +libchecker_a_LIBADD = +am_libchecker_a_OBJECTS = ActionAssign.$(OBJEXT) Action.$(OBJEXT) \ + ActionEQ1.$(OBJEXT) ActionGEQ1.$(OBJEXT) ActionInSet.$(OBJEXT) \ + ActionNormal.$(OBJEXT) ActionNotInSet.$(OBJEXT) \ + amodel.$(OBJEXT) aparser.$(OBJEXT) bitreader.$(OBJEXT) \ + bitwriter.$(OBJEXT) cmodel.$(OBJEXT) common.$(OBJEXT) \ + cparser.$(OBJEXT) DefaultGuidance3.$(OBJEXT) \ + DefaultGuidance2.$(OBJEXT) DefaultGuidance.$(OBJEXT) \ + dmodel.$(OBJEXT) dparser.$(OBJEXT) element.$(OBJEXT) \ + fieldcheck.$(OBJEXT) file.$(OBJEXT) GenericHashtable.$(OBJEXT) \ + Guidance.$(OBJEXT) Hashtable.$(OBJEXT) list.$(OBJEXT) \ + model.$(OBJEXT) normalizer.$(OBJEXT) omodel.$(OBJEXT) \ + oparser.$(OBJEXT) processabstract.$(OBJEXT) \ + processconcrete.$(OBJEXT) processobject.$(OBJEXT) \ + Relation.$(OBJEXT) repair.$(OBJEXT) set.$(OBJEXT) \ + test.$(OBJEXT) tmodel.$(OBJEXT) token.$(OBJEXT) \ + typeparser.$(OBJEXT) tmap.$(OBJEXT) redblack.$(OBJEXT) +libchecker_a_OBJECTS = $(am_libchecker_a_OBJECTS) + +DEFS = @DEFS@ +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/Action.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ActionAssign.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ActionEQ1.Po ./$(DEPDIR)/ActionGEQ1.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ActionInSet.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ActionNormal.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ActionNotInSet.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/DefaultGuidance.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/DefaultGuidance2.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/DefaultGuidance3.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/GenericHashtable.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/Guidance.Po ./$(DEPDIR)/Hashtable.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/Relation.Po ./$(DEPDIR)/amodel.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/aparser.Po ./$(DEPDIR)/bitreader.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/bitwriter.Po ./$(DEPDIR)/cmodel.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/common.Po ./$(DEPDIR)/cparser.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/dmodel.Po ./$(DEPDIR)/dparser.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/element.Po ./$(DEPDIR)/fieldcheck.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/file.Po ./$(DEPDIR)/list.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/model.Po ./$(DEPDIR)/normalizer.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/omodel.Po ./$(DEPDIR)/oparser.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/processabstract.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/processconcrete.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/processobject.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/redblack.Po ./$(DEPDIR)/repair.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/set.Po ./$(DEPDIR)/test.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/tmap.Po ./$(DEPDIR)/tmodel.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/token.Po ./$(DEPDIR)/typeparser.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CFLAGS = @CFLAGS@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +CXXFLAGS = @CXXFLAGS@ +DIST_SOURCES = $(libchecker_a_SOURCES) +DIST_COMMON = README Makefile.am Makefile.in +SOURCES = $(libchecker_a_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cc .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu checker/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +AR = ar + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libchecker.a: $(libchecker_a_OBJECTS) $(libchecker_a_DEPENDENCIES) + -rm -f libchecker.a + $(libchecker_a_AR) libchecker.a $(libchecker_a_OBJECTS) $(libchecker_a_LIBADD) + $(RANLIB) libchecker.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Action.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionAssign.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionEQ1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionGEQ1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionInSet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionNormal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionNotInSet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultGuidance.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultGuidance2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultGuidance3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GenericHashtable.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Guidance.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Hashtable.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Relation.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amodel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aparser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitreader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitwriter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmodel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cparser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmodel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dparser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/element.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fieldcheck.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/model.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/normalizer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omodel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oparser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processabstract.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processconcrete.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processobject.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/redblack.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repair.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmodel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/token.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/typeparser.Po@am__quote@ + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.c.o: +@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(COMPILE) -c `cygpath -w $<` +CCDEPMODE = @CCDEPMODE@ + +.cc.o: +@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +.cc.obj: +@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(CXXCOMPILE) -c -o $@ `cygpath -w $<` +CXXDEPMODE = @CXXDEPMODE@ +uninstall-info-am: + +ETAGS = etags +ETAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @list='$(DISTFILES)'; for file in $$list; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +uninstall-am: uninstall-info-am + +.PHONY: GTAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES distclean distclean-compile \ + distclean-depend distclean-generic distclean-tags distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic tags uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Repair/RepairInterpreter/Relation.cc b/Repair/RepairInterpreter/Relation.cc new file mode 100755 index 0000000..7d5d094 --- /dev/null +++ b/Repair/RepairInterpreter/Relation.cc @@ -0,0 +1,162 @@ +#include "Relation.h" +#include "element.h" +#include "GenericHashtable.h" +#include "set.h" +#include "stdio.h" + + +// class Tuple + +Tuple::Tuple(void *l,void *r) { + left=l; + right=r; +} + +Tuple::Tuple() { + left=NULL;right=NULL; +} + +bool Tuple::isnull() { + if (left==NULL&&right==NULL) + return true; + else + return false; +} + + +// class WorkRelation + +WorkRelation::WorkRelation() { + forward=genallocatehashtable((unsigned int (*)(void *)) & hashelement,(int (*)(void *,void *)) & elementequals); + inverse=genallocatehashtable((unsigned int (*)(void *)) & hashelement,(int (*)(void *,void *)) & elementequals); + flag=false; +} + +WorkRelation::WorkRelation(bool flag) { + forward=genallocatehashtable(NULL,NULL); + inverse=genallocatehashtable(NULL,NULL); + this->flag=true; +} + +Tuple WorkRelation::firstelement() { + if (forward->list==NULL) + return Tuple(); + void * forwardfirst=forward->list->src; + WorkSet *ws=getset(forwardfirst); + return Tuple(forwardfirst,ws->firstelement()); +} + +Tuple WorkRelation::getnextelement(void *left,void *right) { + WorkSet *ws=getset(left); + if (ws->getnextelement(right)!=NULL) { + return Tuple(left, ws->getnextelement(right)); + } + void *leftnext=getnext(forward,left); + if (leftnext!=NULL) { + return Tuple(leftnext,getset(leftnext)->firstelement()); + } else return Tuple(); +} + +bool WorkRelation::contains(void *key, void*object) { + /*Set up forward reference*/ + if(!gencontains(forward,key)) + return false; + WorkSet *w=(WorkSet *)gengettable(forward,key); + return w->contains(object); +} + +void WorkRelation::put(void *key, void*object) { + { /*Set up forward reference*/ + if(!gencontains(forward,key)) { + WorkSet *w=flag?new WorkSet(true):new WorkSet(); + genputtable(forward,key,w); + } + WorkSet *w=(WorkSet *)gengettable(forward,key); + w->addobject(object); + } + {/*Set up backwars reference*/ + if(!gencontains(inverse,object)) { + WorkSet *w=flag?new WorkSet(true):new WorkSet(); + genputtable(inverse,object,w); + } + WorkSet *w=(WorkSet *) gengettable(inverse,object); + w->addobject(key); + } +} + +void WorkRelation::remove(void *key, void *object) { + { /*Set up forward reference*/ + WorkSet *w=(WorkSet *)gengettable(forward,key); + w->removeobject(object); + if (w->isEmpty()) { + genfreekey(forward,key); + delete(w); + } + } + { /*Set up backwards reference*/ + WorkSet *w=(WorkSet *)gengettable(inverse,object); + w->removeobject(key); + if (w->isEmpty()) { + genfreekey(inverse,object); + delete(w); + } + } +} + +WorkSet* WorkRelation::getset(void *key) { + if (gencontains(forward,key)) + return (WorkSet *) gengettable(forward,key); + else return NULL; +} + +void* WorkRelation::getobj(void *key) { + WorkSet *ws=getset(key); + if (ws==NULL) + return NULL; + return ws->firstelement(); +} + +WorkSet* WorkRelation::invgetset(void *key) { + if (gencontains(inverse,key)) + return (WorkSet *) gengettable(inverse,key); + else + return NULL; +} + +void* WorkRelation::invgetobj(void *key) { + WorkSet *ws=invgetset(key); + if (ws==NULL) + return NULL; + return ws->firstelement(); +} + +WorkRelation::~WorkRelation() { + destroyer(forward); + destroyer(inverse); +} + +void WorkRelation::destroyer(struct genhashtable *d) { + struct geniterator *it=gengetiterator(d); + while (true) { + void *key=gennext(it); + if (key==NULL) + break; + WorkSet *ws=(WorkSet *)gengettable(d,key); + delete(ws); + } + genfreeiterator(it); + genfreehashtable(d); +} + +void WorkRelation::print() +{ + printf("\n"); + Tuple tuple = firstelement(); + while (!tuple.isnull()) + { + Element *l = (Element *) tuple.left; + Element *r = (Element *) tuple.right; + printf("("); l->print(); printf(", "); r->print(); printf(")\n"); + tuple = getnextelement(tuple.left, tuple.right); + } +} diff --git a/Repair/RepairInterpreter/Relation.h b/Repair/RepairInterpreter/Relation.h new file mode 100755 index 0000000..7b9083f --- /dev/null +++ b/Repair/RepairInterpreter/Relation.h @@ -0,0 +1,44 @@ +#ifndef Relation_H +#define Relation_h +#include "classlist.h" + +class Tuple { + public: + Tuple(void *l,void *r); + Tuple(); + bool isnull(); + void *left,*right; +}; + + + +#define WRELATION_SINGDOMAIN 0x1 +#define WRELATION_MANYDOMAIN 0x2 +#define WRELATION_SINGRANGE 0x10 +#define WRELATION_MANYRANGE 0x20 + +class WorkRelation { + public: + WorkRelation(); + WorkRelation(bool); + ~WorkRelation(); + bool contains(void *key, void *object); + Tuple firstelement(); + Tuple getnextelement(void *left, void *right); + void put(void *key, void *object); + void remove(void *key, void *object); + WorkSet* getset(void *key); + void* getobj(void *key); + WorkSet* invgetset(void *key); + void* invgetobj(void *key); + void print(); + + private: + void destroyer(struct genhashtable *d); + bool flag; + struct genhashtable *forward, *inverse; +}; +#endif + + + diff --git a/Repair/RepairInterpreter/SimpleHash.cc b/Repair/RepairInterpreter/SimpleHash.cc new file mode 100755 index 0000000..a98b205 --- /dev/null +++ b/Repair/RepairInterpreter/SimpleHash.cc @@ -0,0 +1,189 @@ +#include "SimpleHash.h" + +/* LINKED HASH NODE ****************************************************/ + +LinkedHashNode::LinkedHashNode(int key, int data, LinkedHashNode *next) { + this->key = key; + this->data = data; + this->next = next; +} + +LinkedHashNode::LinkedHashNode() { + this->key = -1; + this->data = -1; + this->next = 0; +} + +/* SIMPLE LIST ****************************************************/ + +SimpleList::SimpleList() { + ptr = 0; + head.next = 0; +} + +void SimpleList::reset() { + ptr = &head; +} + +int SimpleList::hasMoreElements() { + return (ptr->next == 0); +} + +int SimpleList::nextElement() { + ptr = ptr->next; + return ptr->data; +} + +void SimpleList::add(int data) { + LinkedHashNode *cur = &head; + while (cur->next) { + cur = cur->next; + if (cur->data == data) { + return; // no duplicates + } + } + cur->next = new LinkedHashNode(0, data, 0); + return; +} + +int SimpleList::contains(int data) { + LinkedHashNode *cur = &head; + while (cur->next) { + cur = cur->next; + if (cur->data == data) { + return 1; // found! + } + } + return 0; +} + +/* SIMPLE HASH ********************************************************/ + +SimpleHash::SimpleHash(int size) { + if (size <= 0) { + throw SimpleHashException(); + } + this->size = size; + this->bucket = new LinkedHashNode[size]; + this->last = &all; + all.next = 0; + this->numparents = 0; + this->numelements = 0; +} + +SimpleHash::SimpleHash() { + this->size = 100; + this->bucket = new LinkedHashNode[size]; + this->last = &all; + all.next = 0; + this->numparents = 0; + this->numelements = 0; +} + + +SimpleHash::~SimpleHash() { +} + +void SimpleHash::addParent(SimpleHash* parent) { + parents[numparents++] = parent; +} + +int SimpleHash::add(int key, int data) { + unsigned int hashkey = (unsigned int)key % size; + + LinkedHashNode *ptr = &bucket[hashkey]; + + /* check that this key/object pair isn't already here */ + // TBD can be optimized for set v. relation */ + while (ptr->next) { + ptr = ptr->next; + if (ptr->key == key && ptr->data == data) { + return 0; + } + } + + ptr->next = new LinkedHashNode(key, data, 0); + last = last->next = new LinkedHashNode(key, data, 0); + numelements++; + + for (int i = 0; i < numparents; i++) { + parents[i]->add(key, data); + } + + return key; +} + +bool SimpleHash::contains(int key) { + unsigned int hashkey = (unsigned int)key % size; + + LinkedHashNode *ptr = &bucket[hashkey]; + while (ptr->next) { + ptr = ptr->next; + if (ptr->key == key) { + // we already have this object + // stored in the hash so just return + return true; + } + } + return false; +} + +bool SimpleHash::contains(int key, int data) { + unsigned int hashkey = (unsigned int)key % size; + + LinkedHashNode *ptr = &bucket[hashkey]; + while (ptr->next) { + ptr = ptr->next; + if (ptr->key == key && ptr->data == data) { + // we already have this object + // stored in the hash so just return + return true; + } + } + return false; +} + +int SimpleHash::count(int key) { + unsigned int hashkey = (unsigned int)key % size; + int count = 0; + + LinkedHashNode *ptr = &bucket[hashkey]; + while (ptr->next) { + ptr = ptr->next; + if (ptr->key == key) { + count++; + } + } + return count; +} + +int SimpleHash::get(int key, int&data) { + unsigned int hashkey = (unsigned int)key % size; + + LinkedHashNode *ptr = &bucket[hashkey]; + while (ptr->next) { + ptr = ptr->next; + if (ptr->key == key) { + data = ptr->data; + return 1; // success + } + } + + return 0; // failure +} + +int SimpleHash::countdata(int data) { + int count = 0; + for (int i = 0; i < size ; i++) { + LinkedHashNode *ptr = &bucket[i]; + while(ptr->next) { + ptr = ptr->next; + if (ptr->data == data) { + count++; + } + } + } + return count; +} + +SimpleHashException::SimpleHashException() {} diff --git a/Repair/RepairInterpreter/SimpleHash.h b/Repair/RepairInterpreter/SimpleHash.h new file mode 100755 index 0000000..04b128b --- /dev/null +++ b/Repair/RepairInterpreter/SimpleHash.h @@ -0,0 +1,126 @@ +#ifndef SIMPLEHASH_H +#define SIMPLEHASH_H + +/* LinkedHashNode *****************************************************/ + +class LinkedHashNode { + +public: + LinkedHashNode *next; + int data; + int key; + LinkedHashNode(int key, int data, LinkedHashNode *next); + LinkedHashNode(); + +}; + +/* SimpleList *********************************************************/ + +class SimpleList { +private: + LinkedHashNode head; + LinkedHashNode *ptr; +public: + SimpleList(); + void add(int data); + int contains(int data); + void reset(); + int hasMoreElements(); + int nextElement(); +}; + + +/* SimpleIterator *****************************************************/ + +class SimpleIterator { + +private: + + LinkedHashNode *cur; + +public: + + inline SimpleIterator(LinkedHashNode *start) { + cur = start; + } + + inline int hasNext() { + return (int)cur->next == 0 ? 0 : 1; + } + + inline int next() { + cur = cur->next; + return cur->data; + } + + inline int key() { + return cur->key; + } + + inline int size() { + int temp = 0; + while (cur->next) { + temp++; + cur = cur->next; + } + return temp; + } + +}; + +/* SimpleHash *********************************************************/ + +class SimpleHash { + +private: + int numelements; + + int size; + LinkedHashNode *bucket; + LinkedHashNode all; + LinkedHashNode *last; + + int numparents; + SimpleHash* parents[10]; + +public: + + SimpleHash(); + + SimpleHash(int size); + + ~SimpleHash(); + + int add(int key, int data); + + bool contains(int key); + + bool contains(int key, int data); + + int get(int key, int& data); + + int countdata(int data); + + void addParent(SimpleHash* parent); + + inline SimpleIterator* iterator() { + return new SimpleIterator(&all); + } + + inline int count() { + return numelements; + } + + int count(int key); + +}; + +/* SimpleHashExcepion *************************************************/ + +class SimpleHashException { +public: + SimpleHashException(); +}; + +#endif + diff --git a/Repair/RepairInterpreter/amodel.cc b/Repair/RepairInterpreter/amodel.cc new file mode 100755 index 0000000..03c1cd2 --- /dev/null +++ b/Repair/RepairInterpreter/amodel.cc @@ -0,0 +1,510 @@ +// Defines the Model Definition Language (MDL) + +#include +#include "amodel.h" +#include "omodel.h" + + +// class Field + +Field::Field(char *s) { + str=s; +} + +void Field::print() { + printf("%s",str); +} + +char * Field::field() { + return str; +} + +// class AElementexpr + +AElementexpr::AElementexpr(AElementexpr *l, AElementexpr *r, int op) { + left=l;right=r;type=op; +} + +AElementexpr::AElementexpr(char *ctype, AElementexpr *l) { + type=AELEMENTEXPR_CAST; + left=l; + casttype=ctype; +} + +AElementexpr::AElementexpr(Literal *lit) { + literal=lit; + type=AELEMENTEXPR_LIT; +} + +AElementexpr::AElementexpr(Label *lab) { + label=lab; + type=AELEMENTEXPR_LABEL; +} + +AElementexpr::AElementexpr(AElementexpr *l,Field *f) { + field=f; + left=l; + type=AELEMENTEXPR_FIELD; +} + +AElementexpr::AElementexpr() { + type=AELEMENTEXPR_NULL; +} + +AElementexpr::AElementexpr(AElementexpr *l,Field *f, AElementexpr * i) { + field=f; + left=l; + right=i; + type=AELEMENTEXPR_FIELDARRAY; +} + +AElementexpr * AElementexpr::getleft() { + return left; +} + +char * AElementexpr::getcasttype() { + return casttype; +} + +AElementexpr * AElementexpr::getright() { + return right; +} + +int AElementexpr::gettype() { + return type; +} + +Label * AElementexpr::getlabel() { + return label; +} + +Literal * AElementexpr::getliteral() { + return literal; +} + +Field * AElementexpr::getfield() { + return field; +} + +void AElementexpr::print() { + switch(type) { + case AELEMENTEXPR_LABEL: + label->print(); + break; + case AELEMENTEXPR_SUB: + printf("("); + left->print(); + printf("-"); + right->print(); + printf(")"); + break; + case AELEMENTEXPR_ADD: + printf("("); + left->print(); + printf("+"); + right->print(); + printf(")"); + break; + case AELEMENTEXPR_MULT: + printf("("); + left->print(); + printf("*"); + right->print(); + printf(")"); + break; + case AELEMENTEXPR_DIV: + printf("("); + left->print(); + printf("/"); + right->print(); + printf(")"); + break; + case AELEMENTEXPR_LIT: + literal->print(); + break; + case AELEMENTEXPR_FIELD: + left->print(); + printf("."); + field->print(); + break; + case AELEMENTEXPR_FIELDARRAY: + left->print(); + printf("."); + field->print(); + printf("["); + right->print(); + printf("]"); + break; + case AELEMENTEXPR_CAST: + printf("cast(%s,",casttype); + left->print(); + printf(")"); + break; + case AELEMENTEXPR_NULL: + printf("NULL"); + break; + } +} + +// class Type + +Type::Type(char *s, int n, Label** l) { + str=s;numlabels=n;labels=l; +} + +void Type::print() { + printf("(%s(",str); + for(int i=0;i>numlabels;i++) { + labels[i]->print(); + } + printf("))"); +} + +int Type::getnumlabels() { + return numlabels; +} + +Label * Type::getlabel(int i) { + return labels[i]; +} + +// class TypeEle + +TypeEle::TypeEle(char *s, int n, AElementexpr** e) { + str=s;numexpr=n;exprs=e; +} + +void TypeEle::print() { + printf("(%s(",str); + for(int i=0;iprint(); + } + printf("))"); +} + +int TypeEle::getnumexpr() { + return numexpr; +} + +AElementexpr * TypeEle::getexpr(int i) { + return exprs[i]; +} + +// class AQuantifier + +AQuantifier::AQuantifier(Label *l,Type *t, Set *s) { + left=l; + tleft=t; + set=s; + type=AQUANTIFIER_SING; +} + +AQuantifier::AQuantifier(Label *l,Type *tl, Label *r, Type *tr, Set *s) { + left=l; + tleft=tl; + right=r; + tright=tr; + set=s; + type=AQUANTIFIER_TUPLE; +} + +AQuantifier::AQuantifier(Label *l,AElementexpr *e1, AElementexpr *e2) { + left=l; + lower=e1;upper=e2; + type=AQUANTIFIER_RANGE; +} + +Label * AQuantifier::getleft() { + return left; +} + +Type * AQuantifier::gettleft() { + return tleft; +} + +Type * AQuantifier::gettright() { + return tright; +} + +Label * AQuantifier::getright() { + return right; +} + +Set * AQuantifier::getset() { + return set; +} + +AElementexpr * AQuantifier::getlower() { + return lower; +} + +AElementexpr * AQuantifier::getupper() { + return upper; +} + +int AQuantifier::gettype() { + return type; +} + +void AQuantifier::print() { + switch(type) { + case AQUANTIFIER_SING: + printf("forall "); + if (tleft!=NULL) + tleft->print(); + left->print(); + printf(" in "); + set->print(); + break; + case AQUANTIFIER_TUPLE: + printf("forall <"); + if (tleft!=NULL) + tleft->print(); + left->print(); + if (tright!=NULL) + tright->print(); + right->print(); + printf("> in "); + set->print(); + break; + case AQUANTIFIER_RANGE: + printf("for "); + left->print(); + printf("="); + lower->print(); + printf(" to "); + upper->print(); + break; + } +} + +// class Statementa + +Statementa::Statementa(AElementexpr *l, char *vt) { + leftee=l; + validtype=vt; + type=STATEMENTA_VALID; +} + +char * Statementa::getvalidtype() { + return validtype; +} + +Statementa::Statementa(AElementexpr *l, Set *s) { + leftee=l; + set=s; + type=STATEMENTA_SET; +} + +Statementa::Statementa(Statementa *l, Statementa *r, int t) { + left=l; + right=r; + type=t; +} + +int Statementa::gettype() { + return type; +} + +Statementa * Statementa::getleft() { + return left; +} + +Statementa * Statementa::getright() { + return right; +} + +AElementexpr * Statementa::getleftee() { + return leftee; +} + +AElementexpr * Statementa::getrightee() { + return rightee; +} + +Statementa::Statementa(Statementa *l) { + type=STATEMENTA_NOT; + left=l; +} + +Statementa::Statementa() { + type=STATEMENTA_TRUE; +} + +Statementa::Statementa(AElementexpr *l, AElementexpr *r, int t) { + leftee=l; + rightee=r; + type=t; +} + +Set * Statementa::getset() { + return set; +} + +void Statementa::print() { + printf("("); + switch(type) { + case STATEMENTA_SET: + leftee->print(); + printf(" in "); + set->print(); + break; + case STATEMENTA_OR: + left->print(); + printf(" OR "); + right->print(); + break; + case STATEMENTA_AND: + left->print(); + printf(" AND "); + right->print(); + break; + case STATEMENTA_NOT: + printf("!"); + left->print(); + break; + case STATEMENTA_EQUALS: + leftee->print(); + printf("="); + rightee->print(); + break; + case STATEMENTA_LT: + leftee->print(); + printf("<"); + rightee->print(); + break; + case STATEMENTA_TRUE: + printf("true"); + break; + } + printf(")"); +} + +// class Statementb + +TypeEle * Statementb::gettleft() { + return tleft; +} + +TypeEle * Statementb::gettright() { + return tright; +} + +AElementexpr * Statementb::getleft() { + return left; +} + +AElementexpr * Statementb::getright() { + return right; +} + +Setlabel * Statementb::getsetlabel() { + return setlabel; +} + +Statementb::Statementb(TypeEle *tl,AElementexpr *l, Setlabel *sl) { + left=l;setlabel=sl;tleft=tl; + type=STATEMENTB_SING; +} + +int Statementb::gettype() { + return type; +} + +Statementb::Statementb(TypeEle *tl,AElementexpr *l, TypeEle *tr,AElementexpr *r, Setlabel *sl) { + left=l;right=r; + tleft=tl;tright=tr; + setlabel=sl; + type=STATEMENTB_TUPLE; +} + +void Statementb::print() { + switch(type) { + case STATEMENTB_SING: + left->print(); + printf(" in "); + setlabel->print(); + break; + case STATEMENTB_TUPLE: + printf("<"); + left->print(); + printf(","); + right->print(); + printf("> in "); + setlabel->print(); + break; + } +} + +// class Rule + +Rule::Rule() { + quantifiers=NULL; + numquantifiers=0; + statementa=NULL; + statementb=NULL; + delay=false; + staticrule=false; +} + +Rule::Rule(AQuantifier **q, int nq) { + quantifiers=q; + numquantifiers=nq; + statementa=NULL; + statementb=NULL; + delay=false; + staticrule=false; +} + +void Rule::setdelay() { + delay=true; +} + +bool Rule::isdelayed() { + return delay; +} + +bool Rule::isstatic() { + return staticrule; +} +void Rule::setstatic() { + staticrule=true; +} + +void Rule::setstatementa(Statementa *sa) { + statementa=sa; +} + +void Rule::setstatementb(Statementb *sb) { + statementb=sb; +} + +Statementa * Rule::getstatementa() { + return statementa; +} + +Statementb * Rule::getstatementb() { + return statementb; +} + +int Rule::numquants() { + return numquantifiers; +} + +AQuantifier* Rule::getquant(int i) { + return quantifiers[i]; +} + +void Rule::print() { + printf("["); + for(int i=0;iprint(); + } + printf("],"); + statementa->print(); + printf(" => "); + statementb->print(); + printf("\n"); +} diff --git a/Repair/RepairInterpreter/amodel.h b/Repair/RepairInterpreter/amodel.h new file mode 100755 index 0000000..29e74f9 --- /dev/null +++ b/Repair/RepairInterpreter/amodel.h @@ -0,0 +1,222 @@ +// Defines the Model Definition Language (MDL) + +#ifndef Abstract_H +#define Abstract_H +#include +#include "classlist.h" + + +class Field { + public: + Field(char *s); + void print(); + char * field(); + private: + char *str; +}; + + + + + +#define AELEMENTEXPR_LABEL 1 +#define AELEMENTEXPR_SUB 2 +#define AELEMENTEXPR_ADD 3 +#define AELEMENTEXPR_MULT 4 +#define AELEMENTEXPR_LIT 5 +#define AELEMENTEXPR_FIELD 6 +#define AELEMENTEXPR_FIELDARRAY 7 +#define AELEMENTEXPR_NULL 8 +#define AELEMENTEXPR_DIV 12 +#define AELEMENTEXPR_CAST 13 + +class AElementexpr { + public: + AElementexpr(AElementexpr *l, AElementexpr *r, int op); + AElementexpr(Literal *lit); + AElementexpr(Label *lab); + AElementexpr(char *ctype, AElementexpr *l); + AElementexpr(AElementexpr *l,Field *f); + AElementexpr(); + AElementexpr(AElementexpr *l,Field *f, AElementexpr * i); + AElementexpr * getleft(); + AElementexpr * getright(); + int gettype(); + Label * getlabel(); + Literal * getliteral(); + Field * getfield(); + virtual void print(); + char * getcasttype(); + + protected: + int type; + char *casttype; + AElementexpr *left, *right; + Label *label; + Literal *literal; + Field *field; +}; + + + + + +class Type { + public: + Type(char *s, int n, Label** l); + void print(); + int getnumlabels(); + Label * getlabel(int i); + + private: + char *str; + int numlabels; + Label **labels; +}; + + + + + +class TypeEle { + public: + TypeEle(char *s, int n, AElementexpr ** e); + void print(); + int getnumexpr(); + AElementexpr * getexpr(int i); + private: + char *str; + int numexpr; + AElementexpr **exprs; +}; + + + + + +#define AQUANTIFIER_SING 1 +#define AQUANTIFIER_TUPLE 2 +#define AQUANTIFIER_RANGE 3 + +class AQuantifier { + public: + AQuantifier(Label *l,Type *t, Set *s); + AQuantifier(Label *l,Type *tl, Label *r, Type *tr, Set *s); + AQuantifier(Label *l,AElementexpr *e1, AElementexpr *e2); + void print(); + int gettype(); + Label *getleft(); + Type *gettleft(); + Type *gettright(); + Label *getright(); + Set *getset(); + AElementexpr * getlower(); + AElementexpr * getupper(); + + private: + int type; + AElementexpr *lower, *upper; + Label *left, *right; + Type *tleft,*tright; + Set *set; +}; + + + + + + +#define STATEMENTA_OR 1 +#define STATEMENTA_AND 2 +#define STATEMENTA_NOT 3 +#define STATEMENTA_EQUALS 4 +#define STATEMENTA_LT 5 +#define STATEMENTA_TRUE 6 +#define STATEMENTA_SET 7 +#define STATEMENTA_VALID 8 + +class Statementa { + public: + Statementa(Statementa *l, Statementa *r, int t); + Statementa(Statementa *l); + Statementa(); + Statementa(AElementexpr *l, AElementexpr *r, int t); + Statementa(AElementexpr *l, Set *s); + Statementa(AElementexpr *, char *); + void print(); + int gettype(); + Statementa * getleft(); + Statementa * getright(); + AElementexpr * getleftee(); + AElementexpr * getrightee(); + Set * getset(); + char *getvalidtype(); + + private: + int type; + Set *set; + Statementa *left,*right; + AElementexpr *leftee, *rightee; + char *validtype; +}; + + + + + + +#define STATEMENTB_SING 1 +#define STATEMENTB_TUPLE 2 + +class Statementb { + public: + Statementb(TypeEle *tl,AElementexpr *l, Setlabel *sl); + Statementb(TypeEle *tl,AElementexpr *l, TypeEle *tr,AElementexpr *r, Setlabel *sl); + Statementb() {} + virtual void print(); + int gettype(); + AElementexpr *getleft(); + AElementexpr *getright(); + Setlabel *getsetlabel(); + TypeEle * gettleft(); + TypeEle * gettright(); + + protected: + TypeEle *tleft, *tright; + AElementexpr *left, *right; + Setlabel *setlabel; + int type; +}; + + + + + + +class Rule { + public: + Rule(); + Rule(AQuantifier **q, int nq); + void setstatementa(Statementa *sa); + void setstatementb(Statementb *sb); + void setdelay(); + void print(); + int numquants(); + AQuantifier* getquant(int i); + Statementa *getstatementa(); + Statementb *getstatementb(); + bool isdelayed(); + bool isstatic(); + void setstatic(); + + private: + bool staticrule; + bool delay; + int numquantifiers; + AQuantifier **quantifiers; + Statementa *statementa; + Statementb *statementb; +}; + + +#endif diff --git a/Repair/RepairInterpreter/aparser.cc b/Repair/RepairInterpreter/aparser.cc new file mode 100755 index 0000000..57b8df9 --- /dev/null +++ b/Repair/RepairInterpreter/aparser.cc @@ -0,0 +1,591 @@ +#include +#include +#include +#include "aparser.h" +#include "list.h" +#include "common.h" +#include "token.h" +#include "amodel.h" +#include "omodel.h" +#include "model.h" + +AParser::AParser(Reader *r) { + reader=r; +} + +Rule * AParser::parserule() { + Token token=reader->peakahead(); + while(token.token_type==TOKEN_EOL) { + skiptoken(); + token=reader->peakahead(); + } + if (token.token_type==TOKEN_EOF) + return NULL; + bool delay=false;bool staticrule=false; + if (token.token_type==TOKEN_DELAY||token.token_type==TOKEN_STATIC) { + /* both shouldn't be allowed..doesn't make sense...*/ + if(token.token_type==TOKEN_DELAY) + delay=true; + else + staticrule=true; + skiptoken(); + token=reader->peakahead(); + } + Rule *c; + /*Get Quantifiers*/ + if (token.token_type==TOKEN_OPENBRACK) { + skiptoken(); + c=parsequantifiers(); + needtoken(TOKEN_COMMA); + } else c=new Rule(); + if (delay) + c->setdelay(); + if (staticrule) { + int count=0; + for(int i=0;inumquants();i++) { + AQuantifier *aq=c->getquant(i); + switch(aq->gettype()) { + case AQUANTIFIER_SING: + if (count>=1) + error(); + count++; + break; + case AQUANTIFIER_RANGE: + break; + default: + error(); + } + } + c->setstatic(); + } + + /*Peek ahead to see if sizeof*/ + c->setstatementa(parsestatementa(false)); + needtoken(TOKEN_IMPLIES); + c->setstatementb(parsestatementb()); + return c; +} + +TypeEle * AParser::parsetypeele() { + Token type=reader->readnext(); + needtoken(TOKEN_OPENPAREN); + List *list=new List(); + while(true) { + Token token=reader->peakahead(); + switch(token.token_type) { + case TOKEN_CLOSEPAREN: { + skiptoken(); + AElementexpr** larray=new AElementexpr* [list->size()]; + list->toArray((void **)larray); + TypeEle *t=new TypeEle(copystr(type.str),list->size(),larray); + delete(list); + return t; + } + default: + list->addobject(parseaelementexpr(false)); + if (reader->peakahead().token_type!=TOKEN_CLOSEPAREN) + needtoken(TOKEN_COMMA); + break; + } + } +} + +Type * AParser::parsetype() { + Token type=reader->readnext(); + needtoken(TOKEN_OPENPAREN); + List *list=new List(); + while(true) { + Token token=reader->readnext(); + switch(token.token_type) { + case TOKEN_CLOSEPAREN: + { + Label** larray=new Label* [list->size()]; + list->toArray((void **)larray); + Type *t=new Type(copystr(type.str),list->size(),larray); + delete(list); + return t; + } + default: + list->addobject(new Label(copystr(token.str))); + if (reader->peakahead().token_type!=TOKEN_CLOSEPAREN) + needtoken(TOKEN_COMMA); + break; + } + } +} + +Statementa * AParser::parsestatementa(bool flag) { + Statementa * oldst=NULL; + AElementexpr *oldee=NULL; + int eeflag=-1; + int joinflag=-1; + while(true) { + Token token=reader->peakahead(); + switch(token.token_type) { + case TOKEN_EOL: + error(); + case TOKEN_OPENPAREN: + { + skiptoken(); + Statementa *st=parsestatementa(false); + if (flag) + return st; + if (oldst==NULL) { + oldst=st; + } else { + if (joinflag==TOKEN_AND) { + oldst=new Statementa(oldst, st, STATEMENTA_AND); + } else if (joinflag==TOKEN_OR) { + oldst=new Statementa(oldst, st, STATEMENTA_OR); + } else { + error(); + } + joinflag=-1; + } + } + break; + case TOKEN_IMPLIES: + return oldst; + case TOKEN_CLOSEPAREN: + skiptoken(); + return oldst; + case TOKEN_AND: + skiptoken(); + if (oldst==NULL) error(); + joinflag=TOKEN_AND; + break; + case TOKEN_OR: + skiptoken(); + if (oldst==NULL) error(); + joinflag=TOKEN_OR; + break; + case TOKEN_TRUE: + { + skiptoken(); + Statementa *st=new Statementa(); + if (flag) + return st; + if (oldst==NULL) { + oldst=st; + } else { + if (joinflag==TOKEN_AND) { + oldst=new Statementa(oldst, st, STATEMENTA_AND); + } else if (joinflag==TOKEN_OR) { + oldst=new Statementa(oldst, st, STATEMENTA_OR); + } else { + error(); + } + joinflag=-1; + } + } + break; + case TOKEN_NOT: + { + skiptoken(); + Statementa * st=new Statementa(parsestatementa(true)); + if (flag) + return st; + if (oldst==NULL) { + oldst=st; + } else { + if (joinflag==TOKEN_AND) { + oldst=new Statementa(oldst, st, STATEMENTA_AND); + } else if (joinflag==TOKEN_OR) { + oldst=new Statementa(oldst, st, STATEMENTA_OR); + } else { + error(); + } + joinflag=-1; + } + } + break; + case TOKEN_IN: { + skiptoken(); + Set *s=parseset(); + if (oldee==NULL||eeflag!=-1) + error(); + Statementa * st=new Statementa(oldee,s); + if (flag) + return st; + oldee=NULL; + if (oldst==NULL) { + oldst=st; + } else { + if (joinflag==TOKEN_AND) { + oldst=new Statementa(oldst, st, STATEMENTA_AND); + } else if (joinflag==TOKEN_OR) { + oldst=new Statementa(oldst, st, STATEMENTA_OR); + } else { + error(); + } + joinflag=-1; + } + } + break; + case TOKEN_ISVALID: { + if (oldee!=NULL) error(); + skiptoken(); + needtoken(TOKEN_OPENPAREN); + AElementexpr *ae=parseaelementexpr(false); + Token t=reader->peakahead(); + char *type=NULL; + if (t.token_type==TOKEN_COMMA) { + skiptoken(); + Token t2=reader->readnext(); + type=copystr(t2.str); + } + Statementa *st=new Statementa(ae, type); + needtoken(TOKEN_CLOSEPAREN); + if (flag) + return st; + if (oldst==NULL) { + oldst=st; + } else { + if (joinflag==TOKEN_AND) { + oldst=new Statementa(oldst, st, STATEMENTA_AND); + } else if (joinflag==TOKEN_OR) { + oldst=new Statementa(oldst, st, STATEMENTA_OR); + } else { + error(); + } + joinflag=-1; + } + } + break; + case TOKEN_EQUALS: + skiptoken(); + if (oldee==NULL) error(); + eeflag=STATEMENTA_EQUALS; + break; + case TOKEN_LT: + skiptoken(); + if (oldee==NULL) error(); + eeflag=STATEMENTA_LT; + break; + default: + if ((oldee!=NULL) && (eeflag==-1)) + error(); + else if ((oldee==NULL)&&(eeflag==-1)) + oldee=parseaelementexpr(false); + else { + /*oldee!=NULL, and joinee!=-1*/ + Statementa * sa=new Statementa(oldee, parseaelementexpr(false), eeflag); + eeflag=-1; + oldee=NULL; + if (flag) return sa; + if (oldst==NULL) { + oldst=sa; + } else { + if (joinflag==TOKEN_AND) { + oldst=new Statementa(oldst, sa, STATEMENTA_AND); + } else if (joinflag==TOKEN_OR) { + oldst=new Statementa(oldst, sa, STATEMENTA_OR); + } else { + error(); + } + joinflag=-1; + } + } + break; + } + } +} + +AElementexpr * AParser::checkdot(AElementexpr * incoming) { + Token tdot=reader->peakahead(); + if (tdot.token_type!=TOKEN_DOT) return incoming; + skiptoken(); + Token tfield=reader->readnext(); + Token tpeak=reader->peakahead(); + if (tpeak.token_type==TOKEN_OPENBRACK) { + skiptoken(); + AElementexpr *index=parseaelementexpr(false); + return checkdot(new AElementexpr(incoming, new Field(copystr(tfield.str)),index)); + } else { + return checkdot(new AElementexpr(incoming, new Field(copystr(tfield.str)))); + } +} + +AElementexpr * AParser::parseaelementexpr(bool isquant) { + AElementexpr *oldee=NULL; + int joinop=-1; + while(true) { + Token t=reader->peakahead(); + switch(t.token_type) { + case TOKEN_LITERAL: + { + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + needtoken(TOKEN_OPENPAREN); + Token literal=reader->readnext(); + needtoken(TOKEN_CLOSEPAREN); + if (oldee==NULL) + oldee=new AElementexpr(new Literal(copystr(literal.str))); + else { + if (joinop!=-1) { + oldee=new AElementexpr(oldee,new AElementexpr(new Literal(copystr(literal.str))),joinop); + joinop=-1; + } else error(); + } + break; + } + case TOKEN_CAST: + { + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + needtoken(TOKEN_OPENPAREN); + Token casttype=reader->readnext(); + needtoken(TOKEN_COMMA); + AElementexpr *ee=parseaelementexpr(false); + AElementexpr *tee=checkdot(new AElementexpr(copystr(casttype.str),ee)); + if (oldee==NULL) + oldee=tee; + else { + if (joinop!=-1) { + oldee=new AElementexpr(oldee,tee,joinop); + joinop=-1; + } else error(); + } + break; + } + + case TOKEN_OPENPAREN: + { + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + AElementexpr *ee=checkdot(parseaelementexpr(false)); + if (oldee==NULL) + oldee=ee; + else { + if (joinop!=-1) { + oldee=new AElementexpr(oldee,ee,joinop); + joinop=-1; + } else error(); + } + break; + } + case TOKEN_CLOSEBRACK: + if (isquant) + return oldee; + skiptoken(); + return oldee; + case TOKEN_CLOSEPAREN: + skiptoken(); + return oldee; + case TOKEN_SUB: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=AELEMENTEXPR_SUB; + else + error(); + break; + case TOKEN_ADD: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=AELEMENTEXPR_ADD; + else + error(); + break; + case TOKEN_MULT: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=AELEMENTEXPR_MULT; + else + error(); + break; + case TOKEN_DIV: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=AELEMENTEXPR_DIV; + else + error(); + break; + case TOKEN_NULL: + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + if (oldee==NULL) + oldee=checkdot(new AElementexpr()); + else { + if (joinop!=-1) { + oldee=new AElementexpr(oldee,checkdot(new AElementexpr()),joinop); + joinop=-1; + } else error(); + } + break; + default: + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + if (oldee==NULL) + oldee=checkdot(new AElementexpr(new Label(copystr(t.str)))); + else { + if (joinop!=-1) { + oldee=new AElementexpr(oldee,checkdot(new AElementexpr(new Label(copystr(t.str)))),joinop); + joinop=-1; + } else error(); + } + } + } +} + +Statementb * AParser::parsestatementb() { + Token t=reader->peakahead(); + if (t.token_type==TOKEN_LT) { + skiptoken(); + Token tpeak=reader->peakahead(); + TypeEle *typel=NULL,*typer=NULL; + if (tpeak.token_type==TOKEN_OPENPAREN) { + skiptoken(); + typel=parsetypeele(); + needtoken(TOKEN_CLOSEPAREN); + } + AElementexpr *ael=parseaelementexpr(false); + needtoken(TOKEN_COMMA); + if (tpeak.token_type==TOKEN_OPENPAREN) { + skiptoken(); + typer=parsetypeele(); + needtoken(TOKEN_CLOSEPAREN); + } + AElementexpr *aer=parseaelementexpr(false); + needtoken(TOKEN_GT); + needtoken(TOKEN_IN); + Token setlabel=reader->readnext(); + return new Statementb(typel,ael,typer,aer,new Setlabel(copystr(setlabel.str))); + } + + TypeEle *type=NULL; + if (t.token_type==TOKEN_OPENPAREN) { + skiptoken(); + type=parsetypeele(); + needtoken(TOKEN_CLOSEPAREN); + } + AElementexpr *ae=parseaelementexpr(false); + needtoken(TOKEN_IN); + Token setlabel=reader->readnext(); + return new Statementb(type,ae,new Setlabel(copystr(setlabel.str))); +} + +void AParser::error() { + printf("ERROR\n"); + reader->error(); + exit(-1); +} + +void AParser::skiptoken() { + reader->readnext(); +} + +void AParser::needtoken(int token) { + Token t=reader->readnext(); + if (!(t.token_type==token)) { + printf("Needed token: "); + tokenname(token); + printf("\n Got token: %s ",t.str); + tokenname(t.token_type); + error(); + } +} + +Rule * AParser::parsequantifiers() { + bool bool_continue=true; + List * list=new List(); + do { + Token token2=reader->readnext(); + switch(token2.token_type) { + case TOKEN_CLOSEBRACK: + bool_continue=false; + break; + case TOKEN_FORALL: + list->addobject(parsequantifier()); + break; + case TOKEN_FOR: + list->addobject(parsequantifierfor()); + case TOKEN_COMMA: + break; + default: + error(); + } + } while(bool_continue); + AQuantifier** qarray=new AQuantifier* [list->size()]; + list->toArray((void **)qarray); + Rule *c=new Rule(qarray,list->size()); + delete(list); + return c; +} + +AQuantifier * AParser::parsequantifier() { + Token token=reader->peakahead(); + if (token.token_type==TOKEN_LT) { + skiptoken(); + Type *tl=NULL, *tr=NULL; + if (token.token_type==TOKEN_OPENPAREN) { + skiptoken(); + tl=parsetype(); + needtoken(TOKEN_CLOSEPAREN); + } + Token labell=reader->readnext(); + needtoken(TOKEN_COMMA); + + if (token.token_type==TOKEN_OPENPAREN) { + skiptoken(); + tr=parsetype(); + needtoken(TOKEN_CLOSEPAREN); + } + Token labelr=reader->readnext(); + + needtoken(TOKEN_GT); + needtoken(TOKEN_IN); + return new AQuantifier(new Label(copystr(labell.str)),tl,new Label(copystr(labelr.str)),tr,parseset()); + } else { + Type *t=NULL; + if (token.token_type==TOKEN_OPENPAREN) { + skiptoken(); + t=parsetype(); + needtoken(TOKEN_CLOSEPAREN); + } + Token label=reader->readnext(); + needtoken(TOKEN_IN); + return new AQuantifier(new Label(copystr(label.str)),t,parseset()); + } +} + +AQuantifier * AParser::parsequantifierfor() { + Token label=reader->readnext(); + needtoken(TOKEN_EQUALS); + AElementexpr *lower=parseaelementexpr(false); + needtoken(TOKEN_TO); + AElementexpr *upper=parseaelementexpr(true); + return new AQuantifier(new Label(copystr(label.str)),lower,upper); +} + +Set * AParser::parseset() { + Token label=reader->readnext(); + if (label.token_type==TOKEN_OPENBRACE) { + bool bool_continue=true; + List * list=new List(); + do { + Token token2=reader->readnext(); + switch(token2.token_type) { + case TOKEN_CLOSEBRACE: + bool_continue=false; + break; + case TOKEN_COMMA: + break; + default: + list->addobject(new Literal(copystr(token2.str))); + break; + } + } while(bool_continue); + int size=list->size(); + Literal** qarray=new Literal* [size]; + list->toArray((void **)qarray); + delete(list); + return new Set(qarray,size); + } else + return new Set(new Setlabel(copystr(label.str))); +} + diff --git a/Repair/RepairInterpreter/aparser.h b/Repair/RepairInterpreter/aparser.h new file mode 100755 index 0000000..a155b6d --- /dev/null +++ b/Repair/RepairInterpreter/aparser.h @@ -0,0 +1,32 @@ +#ifndef AbstractParser_H +#define AbstractParser_H + +#include "common.h" +#include +#include +#include "classlist.h" + +class AParser { + public: + AParser(Reader *r); + Rule * parserule(); + AParser() {} + + protected: + Type * parsetype(); + TypeEle * parsetypeele(); + AElementexpr * checkdot(AElementexpr * incoming); + Rule * parsequantifiers(); + AQuantifier * parsequantifierfor(); + AQuantifier * parsequantifier(); + Set * parseset(); + Setexpr * parsesetexpr(); + Statementa * parsestatementa(bool); + virtual Statementb * parsestatementb(); + virtual AElementexpr * parseaelementexpr(bool); + void skiptoken(); + void needtoken(int); + void error(); + Reader *reader; +}; +#endif diff --git a/Repair/RepairInterpreter/bitreader.cc b/Repair/RepairInterpreter/bitreader.cc new file mode 100755 index 0000000..6561bb8 --- /dev/null +++ b/Repair/RepairInterpreter/bitreader.cc @@ -0,0 +1,110 @@ +// Interface for reading structures + +#include +#include "bitreader.h" +#include "element.h" +#include "Hashtable.h" +#include "tmodel.h" +#include "amodel.h" +#include "model.h" +#include "processabstract.h" + +bitreader::bitreader(model *m, Hashtable *e) { + globalmodel=m; + env=e; +} + +Element * bitreader::readfieldorarray(Element *element, Field * field, Element * index) { + assert(element->type()==ELEMENT_OBJECT); + // Hashtable *env=new Hashtable((int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);; + if (element->getobject()==NULL) + return NULL; + structure *type=element->getstructure(); + // assert(type->getnumparams()==element->getnumparams()); + /* build parameter mapping */ + /* for(int i=0;igetnumparams();i++) { + env->put(type->getparam(i)->getname(),element->paramvalue(i)); + }*/ + char *fieldname=field->field(); + ttype *typeoffield=NULL; + AElementexpr *lindex=NULL; + for(int i=0;igetnumlabels();i++) { + if (equivalentstrings(type->getlabel(i)->getname(),fieldname)) { + /* got label not field... */ + typeoffield=type->getlabel(i)->gettype(); + fieldname=type->getlabel(i)->getfield(); + lindex=type->getlabel(i)->getindex(); + break; + } + } + int offset=0; + int bitoffset=0; + for(int i=0;igetnumfields();i++) { + if(equivalentstrings(type->getfield(i)->getname(), fieldname)) { + /* got fieldname */ + if (typeoffield==NULL) + typeoffield=type->getfield(i)->gettype(); + break; + } else { + offset+=type->getfield(i)->gettype()->getbytes(this,globalmodel,env); + } + } + if (index!=NULL||lindex!=NULL) { + if (lindex!=NULL) + index=evaluateexpr(globalmodel,lindex,env,true,true); + if(typeoffield->gettype()==TTYPE_BIT) { + offset+=(index->intvalue())/8; + bitoffset=(index->intvalue())%8; + } else { + if (index->intvalue()!=0) { + /* Don't want to force computation of basesize unless we really need to... + we'd like to handle the filesystem example...:) */ + int size=typeoffield->basesize(this,globalmodel,env); + offset+=size*index->intvalue(); + } + } + if (lindex!=NULL) + delete(index); + } + Element *ele=NULL; + void *addr=(void *)(((char *) element->getobject())+offset); + if (typeoffield->isptr()) + addr=*((void **)addr); + switch(typeoffield->gettype()) { + case TTYPE_INT: + { + int i=*((int *) addr); + ele=new Element(i); + break; + } + case TTYPE_SHORT: + { + short i=*((short *) addr); + ele=new Element(i); + break; + } + case TTYPE_BIT: + { + char c=*((char *) addr); + ele=new Element((bool)((c&(1<getnumparamvalues()]; + for(int i=0;igetnumparamvalues();i++) { + earray[i]=evaluateexpr(this,typeoffield->getparamvalues(i),env); + }*/ + ele=new Element(addr,globalmodel->getstructure(typeoffield->getname())); + break; + } + } + return ele; +} + diff --git a/Repair/RepairInterpreter/bitreader.h b/Repair/RepairInterpreter/bitreader.h new file mode 100755 index 0000000..5a9c9c4 --- /dev/null +++ b/Repair/RepairInterpreter/bitreader.h @@ -0,0 +1,16 @@ +// Interface for reading structures + +#ifndef BITREADER_H +#define BITREADER_H +#include "classlist.h" + +class bitreader { + public: + bitreader(model *m, Hashtable *env); + Element * readfieldorarray(Element *element, Field *field, Element *index); + private: + model *globalmodel; + Hashtable *env; +}; + +#endif diff --git a/Repair/RepairInterpreter/bitwriter.cc b/Repair/RepairInterpreter/bitwriter.cc new file mode 100755 index 0000000..a99a3c5 --- /dev/null +++ b/Repair/RepairInterpreter/bitwriter.cc @@ -0,0 +1,127 @@ +// Interface for writing structures + +#include +#include +#include "bitwriter.h" +#include "bitreader.h" +#include "element.h" +#include "Hashtable.h" +#include "tmodel.h" +#include "amodel.h" +#include "model.h" +#include "processabstract.h" + + +bitwriter::bitwriter(model *m, Hashtable *e) { + globalmodel=m; + bitread=new bitreader(m,e); + env=e; +} + +void bitwriter::writefieldorarray(Element *element, Field * field, Element * index, Element *target) { + assert(element->type()==ELEMENT_OBJECT); + // DEBUG STATEMENT + /* + element->print(); + printf("."); + field->print(); + if (index!=NULL) { + printf("["); + index->print(); + printf("]"); + } + printf("="); + target->print(); + printf("\n"); + */ + // Hashtable *env=new Hashtable((int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);; + structure *type=element->getstructure(); + //assert(type->getnumparams()==element->getnumparams()); + + /* build parameter mapping */ + /* for(int i=0;igetnumparams();i++) { + env->put(type->getparam(i)->getname(),element->paramvalue(i)); + }*/ + char *fieldname=field->field(); + ttype *typeoffield=NULL; + AElementexpr *lindex=NULL; + for(int i=0;igetnumlabels();i++) { + if (equivalentstrings(type->getlabel(i)->getname(),fieldname)) { + /* got label not field... */ + typeoffield=type->getlabel(i)->gettype(); + fieldname=type->getlabel(i)->getfield(); + lindex=type->getlabel(i)->getindex(); + break; + } + } + int offset=0; + int bitoffset=0; + for(int i=0;igetnumfields();i++) { + if(equivalentstrings(type->getfield(i)->getname(), fieldname)) { + /* got fieldname */ + if (typeoffield==NULL) + typeoffield=type->getfield(i)->gettype(); + break; + } else { + offset+=type->getfield(i)->gettype()->getbytes(bitread,globalmodel,env); + } + } + if (index!=NULL||lindex!=NULL) { + if (lindex!=NULL) + index=evaluateexpr(globalmodel,lindex,env,true,true); + if(typeoffield->gettype()==TTYPE_BIT) { + offset+=(index->intvalue())/8; + bitoffset=(index->intvalue())%8; + } else { + int size=typeoffield->basesize(bitread,globalmodel,env); + offset+=size*index->intvalue(); + } + if (lindex!=NULL) + delete(index); + } + void *addr=(void *)(((char *) element->getobject())+offset); + + if (typeoffield->isptr()) + addr=*((void **)addr); + switch(typeoffield->gettype()) { + case TTYPE_INT: + { + *((int *) addr)=target->intvalue(); + break; + } + case TTYPE_SHORT: + { + *((short *) addr)=target->getshortvalue(); + break; + } + case TTYPE_BIT: + { + char c=*((char *) addr); + char co=c; + bool b=target->getboolvalue(); + char mask=0xFF^(1<getbytevalue(); + break; + } + case TTYPE_STRUCT: + { + assert(typeoffield->isptr()); + *((void **)(((char *) element->getobject())+offset))=target->getobject(); + break; + } + } +} + diff --git a/Repair/RepairInterpreter/bitwriter.h b/Repair/RepairInterpreter/bitwriter.h new file mode 100755 index 0000000..35a04b7 --- /dev/null +++ b/Repair/RepairInterpreter/bitwriter.h @@ -0,0 +1,17 @@ +// Interface for writing structures + +#ifndef BITWRITER_H +#define BITWRITER_H +#include "classlist.h" + +class bitwriter { + public: + bitwriter(model *m, Hashtable *env); + void writefieldorarray(Element *element, Field *field, Element *index, Element *); + private: + model *globalmodel; + bitreader * bitread; + Hashtable *env; +}; + +#endif diff --git a/Repair/RepairInterpreter/catcherror.c b/Repair/RepairInterpreter/catcherror.c new file mode 100755 index 0000000..9fd8a31 --- /dev/null +++ b/Repair/RepairInterpreter/catcherror.c @@ -0,0 +1,18 @@ +#include +#include "catcherror.h" + +struct StackElement * stackptr=NULL; + +void handler(int signal) { + jmp_buf *jb=(jmp_buf *)popstack(&stackptr); + if (jb==NULL) { + printf("Signal %d\n",signal); + exit(-1); + } + longjmp(*jb,1); +} + +void installhandlers() { + signal(SIGSEGV,&handler); + signal(SIGFPE,&handler); +} diff --git a/Repair/RepairInterpreter/catcherror.h b/Repair/RepairInterpreter/catcherror.h new file mode 100755 index 0000000..f7e05e9 --- /dev/null +++ b/Repair/RepairInterpreter/catcherror.h @@ -0,0 +1,30 @@ +#ifndef CATCHERROR_H +#define CATCHERROR_H + +#include "stack.h" +#include +#include +#include + +void handler(int signal); +void installhandlers(); +extern struct StackElement * stackptr; + +#define STARTREPAIR(repair, label) \ + jmp_buf label_save_buf; \ + if (setjmp(label_save_buf)) { \ + repair \ + resetanalysis(); \ + goto label_error; \ + } \ +label_error:\ + pushstack(&stackptr, &label_save_buf); + + + + +#define ENDREPAIR(label) popstack(&stackptr); + + + +#endif diff --git a/Repair/RepairInterpreter/classlist.h b/Repair/RepairInterpreter/classlist.h new file mode 100755 index 0000000..71b8385 --- /dev/null +++ b/Repair/RepairInterpreter/classlist.h @@ -0,0 +1,84 @@ +#ifndef classlist_h +#define classlist_h +//#include "dmalloc.h" +//#define REPAIR +#define DEBUGMESSAGES +//#define DEBUGMANYMESSAGES +#define TOOL + +class TypeEle; +class Rule; +class AQuantifier; +class Statementa; +class Statementb; +class AElementexpr; +class Type; +class Field; +class AParser; +class bitreader; +class DomainSet; +class DRelation; +class DomainRelation; +class Dparser; +class ElementWrapper; +class Element; +class Hashtable; +class List; +class model; +class Literal; +class Setlabel; +class Constraint; +class Quantifier; +class Statement; +class Predicate; +class Valueexpr; +class Elementexpr; +class Set; +class Setexpr; +class Relation; +class Label; +class Parser; +class processabstract; +class processconcrete; +class processobject; +class RelationSet; +class State; +class Tuple; +class WorkRelation; +class WorkSet; +class Iterator; +class structure; +class ttype; +//class tparam; +class tlabel; +class tfield; +class Token; +class Reader; +class Typeparser; +class NormalForm; +class SentenceArray; +class CoerceSentence; +class CoercePredicate; +class Action; +class ActionInSet; +class ActionNotInSet; +class ActionGEQ1; +class ActionEQ1; +class ActionAssign; +class ActionNotAssign; +class CParser; +class CStatementb; +class CAElementexpr; +class Expr; +class Repair; +class bitwriter; +class Guidance; +class Source; +class FieldCheck; +class FieldTuple; +class ActionNormal; +class typemap; +//class RParser; + +extern model *exportmodel; +#endif diff --git a/Repair/RepairInterpreter/cmemory.h b/Repair/RepairInterpreter/cmemory.h new file mode 100755 index 0000000..1b108cb --- /dev/null +++ b/Repair/RepairInterpreter/cmemory.h @@ -0,0 +1,8 @@ +#ifndef CMEMORY_H +#define CMEMORY_H +#include "test.h" +#define malloc(size) ourmalloc(size) +#define calloc(memb,size) ourcalloc(memb,size) +#define realloc(ptr,size) ourrealloc(ptr,size) +#define free(size) ourfree(size) +#endif diff --git a/Repair/RepairInterpreter/cmodel.cc b/Repair/RepairInterpreter/cmodel.cc new file mode 100755 index 0000000..116a3f6 --- /dev/null +++ b/Repair/RepairInterpreter/cmodel.cc @@ -0,0 +1,236 @@ +#include +#include "cmodel.h" +#include "amodel.h" +#include "omodel.h" + + + +// class CAElementexpr + +CAElementexpr::CAElementexpr(CAElementexpr *index, Setexpr *se) { + left=index;right=NULL;type=CAELEMENTEXPR_ELEMENT; + setexpr=se; +} + + +CAElementexpr::CAElementexpr(CAElementexpr *l, CAElementexpr *r, int op) { + left=l;right=r;type=op; +} + +CAElementexpr::CAElementexpr(Literal *lit) { + literal=lit; + type=CAELEMENTEXPR_LIT; +} + +CAElementexpr::CAElementexpr(Label *lab) { + label=lab; + type=CAELEMENTEXPR_LABEL; +} +CAElementexpr::CAElementexpr() { + type=CAELEMENTEXPR_NULL; +} + +CAElementexpr * CAElementexpr::getleft() { + return (CAElementexpr *) left; +} + +CAElementexpr * CAElementexpr::getright() { + return (CAElementexpr *) right; +} + +Relation * CAElementexpr::getrelation() { + return rrelation; +} + +CAElementexpr::CAElementexpr(CAElementexpr *index, Relation *r) { + left=index;right=NULL;type=CAELEMENTEXPR_RELATION; + rrelation=r; +} + +CAElementexpr::CAElementexpr(Setexpr *se) { + setexpr=se; + type=CAELEMENTEXPR_SIZEOF; +} + + +void CAElementexpr::print() { + switch(type) { + case CAELEMENTEXPR_LABEL: + label->print(); + break; + case CAELEMENTEXPR_NULL: + printf("NULL"); + break; + case CAELEMENTEXPR_RELATION: + left->print(); + printf("."); + rrelation->print(); + break; + case CAELEMENTEXPR_SUB: + left->print(); + printf("-"); + right->print(); + break; + case CAELEMENTEXPR_ADD: + left->print(); + printf("+"); + right->print(); + break; + case CAELEMENTEXPR_MULT: + left->print(); + printf("*"); + right->print(); + break; + case CAELEMENTEXPR_DIV: + left->print(); + printf("/"); + right->print(); + break; + case CAELEMENTEXPR_LIT: + literal->print(); + break; + case CAELEMENTEXPR_SIZEOF: + printf("sizeof("); + setexpr->print(); + printf(")"); + break; + case CAELEMENTEXPR_ELEMENT: + printf("element "); + left->print(); + printf(" of "); + setexpr->print(); + break; + } +} + +Setexpr * CAElementexpr::getsetexpr() { + return setexpr; +} + + + + + +// class Expr + + +Expr::Expr(Label *l) { + label=l; + type=EXPR_LABEL; +} + +Expr::Expr(Expr *e, Field *f) { + field=f;expr=e; type=EXPR_FIELD; +} + +Expr::Expr(char *ctype, Expr *e) { + expr=e; + casttype=ctype; + type=EXPR_CAST; +} + +char * Expr::getcasttype() { + return casttype; +} + +Expr::Expr(Expr *e, Field *f, CAElementexpr *cae) { + field=f;expr=e;index=cae; + type=EXPR_ARRAY; +} + +Expr * Expr::getexpr() { + return expr; +} + +int Expr::gettype() { + return type; +} + +Field * Expr::getfield() { + return field; +} + +Label * Expr::getlabel() { + return label; +} + +CAElementexpr * Expr::getindex() { + return index; +} + +void Expr::print() { + switch(type) { + case EXPR_LABEL: + label->print(); + break; + case EXPR_FIELD: + expr->print(); + printf("."); + field->print(); + break; + case EXPR_CAST: + printf("cast(%s,",casttype); + expr->print(); + printf(")"); + break; + case EXPR_ARRAY: + expr->print(); + printf("."); + field->print(); + printf("["); + index->print(); + printf("]"); + break; + } +} + + + + + + +// class CStatementb + +void CStatementb::print() { + switch(type) { + case CSTATEMENTB_ARRAYASSIGN: + expr->print(); + printf("."); + field->print(); + printf("["); + left->print(); + printf("]="); + right->print(); + break; + case CSTATEMENTB_FIELDASSIGN: + expr->print(); + printf("."); + field->print(); + printf("="); + right->print(); + break; + } +} + +CStatementb::CStatementb(Expr *l, Field *f, CAElementexpr *rvalue) { + expr=l; + field=f; + right=rvalue; + type=CSTATEMENTB_FIELDASSIGN; +} + +CStatementb::CStatementb(Expr *l, Field *f, CAElementexpr *index, CAElementexpr *rvalue) { + expr=l; + field=f; + left=index; + right=rvalue; + type=CSTATEMENTB_ARRAYASSIGN; +} + +Expr * CStatementb::getexpr() { + return expr; +} + +Field * CStatementb::getfield() { + return field; +} diff --git a/Repair/RepairInterpreter/cmodel.h b/Repair/RepairInterpreter/cmodel.h new file mode 100755 index 0000000..a4eba9a --- /dev/null +++ b/Repair/RepairInterpreter/cmodel.h @@ -0,0 +1,78 @@ +#ifndef Cmodel_H +#define Cmodel_H +#include +#include "classlist.h" +#include "amodel.h" + +#define CAELEMENTEXPR_LABEL 1 +#define CAELEMENTEXPR_SUB 2 +#define CAELEMENTEXPR_ADD 3 +#define CAELEMENTEXPR_MULT 4 +#define CAELEMENTEXPR_LIT 5 +#define CAELEMENTEXPR_NULL 8 +#define CAELEMENTEXPR_SIZEOF 9 +#define CAELEMENTEXPR_ELEMENT 10 +#define CAELEMENTEXPR_RELATION 11 +#define CAELEMENTEXPR_DIV 12 +class CAElementexpr:public AElementexpr { + public: + CAElementexpr(CAElementexpr *index, Setexpr *se); + CAElementexpr(Setexpr *se); + CAElementexpr(CAElementexpr *,Relation *r); + CAElementexpr(CAElementexpr *l, CAElementexpr *r, int op); + CAElementexpr(Literal *lit); + CAElementexpr(Label *lab); + CAElementexpr(); + CAElementexpr * getleft(); + CAElementexpr * getright(); + Setexpr * getsetexpr(); + void print(); + Relation * getrelation(); + private: + Relation *rrelation; + Setexpr *setexpr; +}; + +#define EXPR_LABEL 1 +#define EXPR_FIELD 2 +#define EXPR_ARRAY 3 +#define EXPR_CAST 4 + +class Expr { + public: + Expr(Label *l); + Expr(Expr *, Field *); + Expr(Expr *, Field *, CAElementexpr *); + Expr(char *, Expr *); + int gettype(); + Expr * getexpr(); + Field * getfield(); + Label * getlabel(); + CAElementexpr * getindex(); + void print(); + char * getcasttype(); + + private: + int type; + CAElementexpr *index; + Expr *expr; + Field *field; + Label *label; + char *casttype; +}; + +#define CSTATEMENTB_FIELDASSIGN 3 +#define CSTATEMENTB_ARRAYASSIGN 4 + +class CStatementb:public Statementb { + public: + void print(); + CStatementb(Expr *l, Field *f, CAElementexpr *rvalue); + CStatementb(Expr *l, Field *f, CAElementexpr *index, CAElementexpr *rvalue); + Expr * getexpr(); + Field * getfield(); + protected: + Expr *expr; + Field *field; +}; +#endif diff --git a/Repair/RepairInterpreter/common.cc b/Repair/RepairInterpreter/common.cc new file mode 100755 index 0000000..77b5a24 --- /dev/null +++ b/Repair/RepairInterpreter/common.cc @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include "common.h" +#include "classlist.h" + +char * copystr(const char *buf) { + int i; + if (buf==NULL) + return NULL; + for(i=0;;i++) + if (buf[i]==0) { + char *ptr=new char[i+1]; + memcpy(ptr,buf,i+1); + return ptr; + } +} + + +unsigned int hashstring(char *strptr) { + unsigned int hashcode=0; + int *intptr=(int *) strptr; + if(intptr==NULL) + return 0; + while(1) { + int copy1=*intptr; + if((copy1&0xFF000000)&& + (copy1&0xFF0000)&& + (copy1&0xFF00)&& + (copy1&0xFF)) { + hashcode^=*intptr; + intptr++; + } else { + if (!copy1&0xFF000000) + hashcode^=copy1&0xFF000000; + else if (!copy1&0xFF0000) + hashcode^=copy1&0xFF0000; + else if (!copy1&0xFF00) + hashcode^=copy1&0xFF00; + else if (!copy1&0xFF) + hashcode^=copy1&0xFF; + return hashcode; + } + } +} + +int equivalentstrings(char *str1, char *str2) { + if ((str1!=NULL)&&(str2!=NULL)) { + if (strcmp(str1,str2)!=0) + return 0; + else + return 1; + } else if ((str1==NULL)&&(str2==NULL)) + return 1; + else return 0; +} + diff --git a/Repair/RepairInterpreter/common.h b/Repair/RepairInterpreter/common.h new file mode 100755 index 0000000..e9b2034 --- /dev/null +++ b/Repair/RepairInterpreter/common.h @@ -0,0 +1,7 @@ +#ifndef COMMON_H +#define COMMON_H + +char * copystr(const char *buf); +unsigned int hashstring(char *strptr); +int equivalentstrings(char *str1, char *str2); +#endif diff --git a/Repair/RepairInterpreter/cparser.cc b/Repair/RepairInterpreter/cparser.cc new file mode 100755 index 0000000..911181a --- /dev/null +++ b/Repair/RepairInterpreter/cparser.cc @@ -0,0 +1,268 @@ +#include "cparser.h" +#include "token.h" +#include "amodel.h" +#include "omodel.h" +#include "cmodel.h" +#include "element.h" + +CParser::CParser(Reader *r) { + reader=r; +} + +AElementexpr * CParser::parseaelementexpr(bool isquant) { + CAElementexpr *oldee=NULL; + int joinop=-1; + while(true) { + Token t=reader->peakahead(); + switch(t.token_type) { + case TOKEN_LITERAL: + { + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + needtoken(TOKEN_OPENPAREN); + Token literal=reader->readnext(); + needtoken(TOKEN_CLOSEPAREN); + if (oldee==NULL) + oldee=new CAElementexpr(new Literal(copystr(literal.str))); + else { + if (joinop!=-1) { + oldee=new CAElementexpr(oldee,new CAElementexpr(new Literal(copystr(literal.str))),joinop); + joinop=-1; + } else error(); + } + break; + } + + case TOKEN_OPENPAREN: + { + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + CAElementexpr *ee=(CAElementexpr *)parseaelementexpr(false); + if (oldee==NULL) + oldee=ee; + else { + if (joinop!=-1) { + oldee=new CAElementexpr(oldee,ee,joinop); + joinop=-1; + } else error(); + } + break; + } + + case TOKEN_CLOSEBRACK: + if (isquant) + return oldee; + // Otherwise fall through + case TOKEN_CLOSEPAREN: + skiptoken(); + return checkdot(oldee); + break; + case TOKEN_SUB: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=CAELEMENTEXPR_SUB; + else + error(); + break; + case TOKEN_ADD: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=CAELEMENTEXPR_ADD; + else + error(); + break; + case TOKEN_SIZEOF: { + skiptoken(); + needtoken(TOKEN_OPENPAREN); + Setexpr *sae=parsesetexpr(); + needtoken(TOKEN_CLOSEPAREN); + return new CAElementexpr(sae); + } + case TOKEN_ELEMENT: { + skiptoken(); + CAElementexpr *cae=(CAElementexpr *)parseaelementexpr(false); + needtoken(TOKEN_OF); + Setexpr *sae=parsesetexpr(); + return new CAElementexpr(cae,sae); + } + case TOKEN_OF: + return oldee; + case TOKEN_MULT: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=CAELEMENTEXPR_MULT; + else + error(); + break; + case TOKEN_DIV: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=CAELEMENTEXPR_DIV; + else + error(); + break; + case TOKEN_NULL: + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + if (oldee==NULL) + oldee=checkdot(new CAElementexpr()); + else { + if (joinop!=-1) { + oldee=new CAElementexpr(oldee,checkdot(new CAElementexpr()),joinop); + joinop=-1; + } else error(); + } + break; + default: + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + if (oldee==NULL) + oldee=checkdot(new CAElementexpr(new Label(copystr(t.str)))); + else { + if (joinop!=-1) { + oldee=new CAElementexpr(oldee,checkdot(new CAElementexpr(new Label(copystr(t.str)))),joinop); + joinop=-1; + } else error(); + } + } + } +} + +CAElementexpr * CParser::checkdot(CAElementexpr * incoming) { + Token tdot=reader->peakahead(); + if (tdot.token_type!=TOKEN_DOT) return incoming; + skiptoken(); + Token tfield=reader->readnext(); + Token tpeak=reader->peakahead(); + return new CAElementexpr(incoming, new Relation(copystr(tfield.str))); +} + +Setexpr * CParser::parsesetexpr() { + Token label=reader->readnext(); + Token peak=reader->peakahead(); + if (peak.token_type==TOKEN_DOT) { + skiptoken(); + return new Setexpr(new Label(copystr(label.str)),false,new Relation(copystr(reader->readnext().str))); + } else if (peak.token_type==TOKEN_DOTINV) { + skiptoken(); + return new Setexpr(new Label(copystr(label.str)),true,new Relation(copystr(reader->readnext().str))); + } else + return new Setexpr(new Setlabel(copystr(label.str))); +} + +Expr * CParser::parseexpr() { + Expr * oldee=NULL; + Field *oldf=NULL; + CAElementexpr *oldindex=NULL; + bool parselside=true; + while(parselside) { + Token t=reader->readnext(); + switch(t.token_type) { + case TOKEN_DOT: + if (oldf!=NULL) { + /* do shift-pack stuff */ + if(oldindex==NULL) + oldee=new Expr(oldee,oldf); + else + oldee=new Expr(oldee,oldf,oldindex); + oldf=NULL; + oldindex=NULL; + } + { + Token name=reader->readnext(); + oldf=new Field(copystr(name.str)); + } + break; + case TOKEN_OPENBRACK: + oldindex=(CAElementexpr *)parseaelementexpr(true); + needtoken(TOKEN_CLOSEBRACK); + break; + case TOKEN_CAST: { + if(oldee!=NULL) + error(); + needtoken(TOKEN_OPENPAREN); + Token fld=reader->readnext(); + needtoken(TOKEN_COMMA); + Expr *ex=parseexpr(); + needtoken(TOKEN_CLOSEPAREN); + oldee=new Expr(copystr(fld.str),ex); + break; + } + case TOKEN_CLOSEPAREN: + if (oldf!=NULL) { + /* do shift-pack stuff */ + if(oldindex==NULL) + oldee=new Expr(oldee,oldf); + else + oldee=new Expr(oldee,oldf,oldindex); + oldf=NULL; + oldindex=NULL; + } + return oldee; + default: + if(oldee!=NULL) + error(); + oldee=new Expr(new Label(copystr(t.str))); + } + } + return oldee; +} + +Statementb * CParser::parsestatementb() { + Expr * oldee=NULL; + Field *oldf=NULL; + CAElementexpr *oldindex=NULL; + bool parselside=true; + while(parselside) { + Token t=reader->readnext(); + switch(t.token_type) { + case TOKEN_DOT: + if (oldf!=NULL) { + /* do shift-pack stuff */ + if(oldindex==NULL) + oldee=new Expr(oldee,oldf); + else + oldee=new Expr(oldee,oldf,oldindex); + oldf=NULL; + oldindex=NULL; + } + { + Token name=reader->readnext(); + oldf=new Field(copystr(name.str)); + } + break; + case TOKEN_OPENBRACK: + oldindex=(CAElementexpr *)parseaelementexpr(true); + needtoken(TOKEN_CLOSEBRACK); + break; + case TOKEN_CAST: { + if(oldee!=NULL) + error(); + needtoken(TOKEN_OPENPAREN); + Token fld=reader->readnext(); + needtoken(TOKEN_COMMA); + Expr *ex=parseexpr(); + oldee=new Expr(copystr(fld.str),ex); + break; + } + case TOKEN_EQUALS: + parselside=false; + if (oldf==NULL) + error(); + break; + default: + if(oldee!=NULL) + error(); + oldee=new Expr(new Label(copystr(t.str))); + } + } + CAElementexpr *rside=(CAElementexpr *)parseaelementexpr(false); + if (oldindex==NULL) + return new CStatementb(oldee,oldf,rside); + else + return new CStatementb(oldee,oldf,oldindex,rside); +} diff --git a/Repair/RepairInterpreter/cparser.h b/Repair/RepairInterpreter/cparser.h new file mode 100755 index 0000000..fe4306d --- /dev/null +++ b/Repair/RepairInterpreter/cparser.h @@ -0,0 +1,20 @@ +#ifndef CParser_H +#define CParser_H + +#include "common.h" +#include +#include +#include "classlist.h" +#include "aparser.h" + +class CParser:public AParser { + public: + CParser(Reader *r); + protected: + Expr * parseexpr(); + AElementexpr * parseaelementexpr(bool); + CAElementexpr * checkdot(CAElementexpr * incoming); + Setexpr * parsesetexpr(); + Statementb * parsestatementb(); +}; +#endif diff --git a/Repair/RepairInterpreter/danfile.cc b/Repair/RepairInterpreter/danfile.cc new file mode 100755 index 0000000..2d71d04 --- /dev/null +++ b/Repair/RepairInterpreter/danfile.cc @@ -0,0 +1,1117 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +extern int errno; + +#include "file.h" +extern "C" { +#include "test.h" +} +#include "Hashtable.h" +#include "model.h" +#include "element.h" +#include "tmap.h" + +char *dstring="d\0"; +struct filedesc files[MAXFILES]; +struct InodeBitmap ib; +struct BlockBitmap bb; + +int bbbptr; // pointer to the BlockBitmap block +int ibbptr; // pointer to the InodeBlock block +int itbptr; // pointer to the InodeTable block +int rdiptr; // pointer to the RootDirectoryInode block + +struct InodeBitmap* sc_ib; +struct BlockBitmap* sc_bb; +struct InodeBlock* sc_it; +int sc_bbbptr; +int sc_ibbptr; +int sc_itbptr; +int sc_rdiptr; + +#include "SimpleHash.h" + +int testinode(int i) { + char temp; + assert(sc_ib); + temp = sc_ib->inode[i/8]&(1<<(i%8)); + return temp == 0 ? 0 : 1; +} + +int testblock(int i) { + char temp; + assert(sc_bb); + temp = sc_bb->blocks[i/8]&(1<<(i%8)); + return temp == 0 ? 0 : 1; +} + +void assertvalidmemory(int low, int high) { + typemap *tm=exportmodel->gettypemap(); + assert(tm->assertvalidmemory((void*) low, (void*) high)); +} + +unsigned long selfcheck2(struct block* d) { + + struct timeval begin,end; + unsigned long t; + gettimeofday(&begin,NULL); + +#include "RepairCompiler/MCC/test2.cc" + + gettimeofday(&end,NULL); + t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec; + return t; +} + +void selfcheck(struct block* diskptr) { + + /* get time information for statistics */ + struct timeval begin,end; + unsigned long t; + gettimeofday(&begin,NULL); + + + /* hand written data structure consistency */ + + struct SuperBlock* sb = (struct SuperBlock*)&diskptr[0]; + struct GroupBlock* gb = (struct GroupBlock*)&diskptr[1]; + + int numblocks = sb->NumberofBlocks; + int numinodes = sb->NumberofInodes; + + SimpleHash* hash_inodeof = new SimpleHash(1000); // estimation of the number of files! + SimpleHash* hash_contents = new SimpleHash(1000); // contents + SimpleList* list_inodes = new SimpleList(); + SimpleList* list_blocks = new SimpleList(); + + // simple test + + // check bitmap consistency with superblock, groupblock, inotetableblock + // inodebitmapblock, blockbitmapblock, rootidrectoryinode + + sc_bbbptr = gb->BlockBitmapBlock; + sc_ibbptr = gb->InodeBitmapBlock; + sc_itbptr = gb->InodeTableBlock; + sc_rdiptr = sb->RootDirectoryInode; + + // constraint 8: automatic... + // constraint 9: automatic... + + // constraint 10: + if (sc_itbptr < numblocks) { + sc_it = (InodeBlock*)&diskptr[sc_itbptr]; + } else { + sc_it = NULL; + } + + // constraint 11: + if (sc_ibbptr < numblocks) { + sc_ib = (InodeBitmap*)&diskptr[sc_ibbptr]; + } else { + sc_ib = NULL; + } + + // constraint 12: + if (sc_bbbptr < numblocks) { + sc_bb = (BlockBitmap*)&diskptr[sc_bbbptr]; + } else { + sc_bb = NULL; + } + + // rule 1 + if (sc_bb) { + // constraint 3 + assert(testblock(0)); // superblock + + // building blocks + list_blocks->add(0); + } + + // rule 2 + if (sc_bb) { + // constraint 3 + assert(testblock(1)); // groupblock + + // building list_blocks + list_blocks->add(1); + } + + // rule 3 + if (sc_bb) { + // constraint 3 + assert(testblock(sc_itbptr)); + + // building list_blocks + list_blocks->add(sc_itbptr); + } + + // rule 4 + if (sc_bb) { + // constraint 3 + assert(testblock(sc_ibbptr)); + + // building list_blocks + list_blocks->add(sc_ibbptr); + } + + // rule 5 + if (sc_bb) { + // constraint 3 + assert(testblock(sc_bbbptr)); + + // building list_blocks + list_blocks->add(sc_bbbptr); + } + + // build inodeof and contents + if (sb->RootDirectoryInode < numinodes) { + int dinode = sb->RootDirectoryInode; + + // building list_inodes + list_inodes->add(dinode); + + for (int k = 0 ; k <= 11 ; k++) { + + int block = sc_it->entries[dinode].Blockptr[k]; + + if (block != 0) { + hash_contents->add(dinode, block); + list_blocks->add(block); + } + + if (block < numblocks) { + + DirectoryBlock* db = (DirectoryBlock*)&diskptr[block]; + + for (int j = 0; j < sb->blocksize/128 ; j++) { + + DirectoryEntry* de = (DirectoryEntry*)&db->entries[j]; + + if (de->inodenumber < numinodes) { + // add to inodeof + hash_inodeof->add((int)de, de->inodenumber); + } + + if (de->inodenumber < numinodes && de->inodenumber != 0) { + + // build list_inodes + list_inodes->add(de->inodenumber); + + for (int j2 = 0 ; j2 <= 11 ; j2++) { + int block2 = sc_it->entries[de->inodenumber].Blockptr[j2]; + if (block2 != 0) { + hash_contents->add(de->inodenumber, block2); + if (block2 < numblocks) { + list_blocks->add(block2); + } + } + } + } + } + } + } + } + + //printf("\n"); + + // rule 6 and rule 11: rootdirectoryinode + if (sb->RootDirectoryInode < numinodes) { + int inode = sb->RootDirectoryInode; + + // constraint 1 + assert(testinode(inode)); + + int filesize = sc_it->entries[inode].filesize; + int contents = 0; + for (int j = 0; j <= 11; j++) { + int block2 = sc_it->entries[inode].Blockptr[j]; + if (block2 != 0) { + // TBD: needs to actual store state because + // there could be duplicate numbers and they + // shouldn't be double counted + contents++; + + // rule 11 + if (block2 < numblocks) { + // constraint 3 + assert(testblock(block2)); + + // constraint 7 + //printf("%d - %d %d %d\n", inode, j, block2, hash_contents->countdata(block2)); + assert(hash_contents->countdata(block2)==1); + } + } + } + + // constraint 6 + assert(filesize <= (contents*8192)); + + // constraint 5: + assert(sc_it->entries[inode].referencecount == hash_inodeof->countdata(inode)); + } + + // rule 14 + if (sb->RootDirectoryInode < numinodes) { + int dinode = sb->RootDirectoryInode; + + for (int j = 0; j < sb->blocksize/128 ; j++) { + for (int k = 0 ; k <= 11 ; k++) { + int block = sc_it->entries[dinode].Blockptr[k]; + if (block < numblocks) { + DirectoryBlock* db = (DirectoryBlock*)&diskptr[block]; + DirectoryEntry* de = (DirectoryEntry*)&db->entries[j]; + + int inode = de->inodenumber; + if (inode < numinodes && inode != 0) { + + // constraint 1 + assert(testinode(inode)); + + // constraint 6 + int filesize = sc_it->entries[inode].filesize; + int contents = 0; + for (int j2 = 0; j2 <= 11; j2++) { + int block2 = sc_it->entries[inode].Blockptr[j2]; + if (block2 != 0) { + // TBD + contents++; + + // rule 11 + if (block2 < numblocks) { + // constraint 3 + assert(testblock(block2)); + + // constraint 7 + assert(hash_contents->countdata(block2)==1); + } + } + } + assert(filesize <= (contents*8192)); + + // constraint 5: + assert(sc_it->entries[inode].referencecount == hash_inodeof->countdata(inode)); + } + } + } + } + } + + // to go, [7, 8 ] + // interesting question is going to be how to deal with 7 and 8 + // actually it turns out that the constraints bound to rules 7 and 8 are + // easy... its just that creating the lists for 7 and 8 is a little tricky... + // 7 can easily piggyback on the creation of inodeof/contents... it fits quite + // nicely into that traversal... same goes for 8 + + // rule 7 + for (int i = 0 ; i < numinodes ; i++) { + if (!list_inodes->contains(i)) { + // constraint 2 + if (testinode(i)) { + printf("", i); + assert(testinode(i)==0); + } + } + } + + // rule 8 + for (int i = 0 ; i < numblocks ; i++) { + if (!list_blocks->contains(i)) { + // constraint 4 + if (testblock(i)) { + printf("", i); + assert(testblock(i)==0); + } + + } + } + + + gettimeofday(&end,NULL); + t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec; + + printf("\npassed tests in %ld u-seconds!\n", t); + + +} + + +int main(int argc, char **argv) +{ + + for(int i=0;igethashtable(); + alloc(ptr,LENGTH); + addmapping(dstring,ptr,"Disk"); + + // insert errors that break the specs + doanalysis2(); + dealloc(ptr); + unmountdisk(ptr); + break; + } + + + // insert errors that do not break the specs + case '4': { + struct block * ptr=mountdisk("disk"); + initializeanalysis(); + Hashtable *env=exportmodel->gethashtable(); + alloc(ptr,LENGTH); + addmapping(dstring,ptr,"Disk"); + + // insert errors that do not break the specs + doanalysis3(); + dealloc(ptr); + unmountdisk(ptr); + break; + } + + + case '5': { + // prints the directory structure, and prints the contents of each file + struct block * ptr=mountdisk("disk"); + printdirectory(ptr); + for(int i=1; i1; i--) { + char filename[10]; + sprintf(filename,"file_%d",i); + openfile(ptr,filename); + } + for(int j=0; j<90; j++) { + for(int i=NUMFILES; i>1; i--) { + char *buf="01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123"; + writefile(ptr,i,buf,122); + } + } + for(int i=NUMFILES; i>1; i--) { + closefile(ptr,i); + } + unmountdisk(ptr); + break; + } + + case '7': { + struct block * ptr=mountdisk("disk"); + for(int i=NUMFILES; i>=0; i--) { + char filename[10]; + sprintf(filename,"file_%d",i); + openfile(ptr,filename); + } + + for(int j=0;j<6000;j++) { + for(int i=NUMFILES; i>=0; i--) { + char name[10]; + int len=sprintf(name, "%d ",i); + writefile(ptr,i,name,len); + } + } + for(int i=NUMFILES; i>=0; i--) { + closefile(ptr,i); + } + for(int i=NUMFILES; i>=0; i--) { + char filename[10]; + sprintf(filename,"file_%d",i); + openfile(ptr,filename); + } + + for(int j=0;j<400;j++) { + for(int i=NUMFILES; i>=0; i--) { + int l=0; + char name[10]; + int len=sprintf(name, "%d ",i); + readfile(ptr,i,name,len); + sscanf(name, "%d ", &l); + if (l!=i) { + printf("ERROR in benchmark\n"); + } + } + } + for(int i=NUMFILES; i>=0; i--) { + closefile(ptr,i); + } + unmountdisk(ptr); + } + break; + + + case '8': { + { + struct block * ptr=chmountdisk("disk"); + initializeanalysis(); + Hashtable *env=exportmodel->gethashtable(); + alloc(ptr,LENGTH); + addmapping(dstring,ptr,"Disk"); + doanalysis(); + dealloc(ptr); + chunmountdisk(ptr); + } + struct block * ptr=mountdisk("disk"); + for(int i=NUMFILES; i>=0; i--) { + char filename[10]; + sprintf(filename,"file_%d",i); + openfile(ptr,filename); + } + for(int j=0; j<6000; j++) { + for(int i=NUMFILES; i>=0; i--) { + char name[10]; + int len=sprintf(name, "%d ",i); + writefile(ptr,i,name,len); + } + } + for(int i=NUMFILES; i>=0; i--) { + closefile(ptr,i); + } + for(int i=NUMFILES; i>=0; i--) { + char filename[10]; + sprintf(filename,"file_%d",i); + openfile(ptr,filename); + } + for(int j=0;j<400;j++) { + for(int i=NUMFILES; i>=0; i--) { + int l=0; + char name[10]; + int len=sprintf(name, "%d ",i); + readfile(ptr,i,name,len); + sscanf(name, "%d ", &l); + if (l!=i) { + printf("ERROR in benchmark\n"); + } + } + } + for(int i=NUMFILES; i>=0; i--) { + closefile(ptr,i); + } + unmountdisk(ptr); + } + + case '9': { + for(int i=0;iBlockBitmapBlock; + ibbptr=gb->InodeBitmapBlock; + itbptr=gb->InodeTableBlock; + rdiptr=sb->RootDirectoryInode; + + struct InodeBitmap *ibb=(struct InodeBitmap *) &ptr[ibbptr]; + for(int i=0;i<(NUMINODES/8+1);i++) + ib.inode[i]=ibb->inode[i]; + + struct BlockBitmap *bbb=(struct BlockBitmap *) &ptr[bbbptr]; + for(int i=0;i<(NUMBLOCK/8+1);i++) + bb.blocks[i]=bbb->blocks[i]; + + printf("Disk mounted successfully from the file %s\n", filename); + fflush(NULL); + + return ptr; +} + + + +void unmountdisk(struct block *vptr) { + struct InodeBitmap *ibb=(struct InodeBitmap *) &vptr[ibbptr]; + for(int i=0;i<(NUMINODES/8+1);i++) + ibb->inode[i]=ib.inode[i]; + + struct BlockBitmap *bbb=(struct BlockBitmap *) &vptr[bbbptr]; + for(int i=0;i<(NUMBLOCK/8+1);i++) + bbb->blocks[i]=bb.blocks[i]; + int val=munmap(vptr,LENGTH); + if (val!=0) + printf("Error!\n"); +} + + +void removefile(char *filename, struct block *ptr) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename,db->entries[j].name)==0) { + /* Found file */ + db->entries[j].name[0]=0; //Delete entry + int inode=db->entries[j].inodenumber; + db->entries[j].inodenumber=0; + + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + itb->entries[inode].referencecount--; + + if (itb->entries[inode].referencecount==0) { + for(int i=0;i<((itb->entries[inode].filesize+BLOCKSIZE-1)/BLOCKSIZE);i++) { + int blocknum=itb->entries[inode].Blockptr[i]; + bb.blocks[blocknum/8]^=(1<<(blocknum%8)); + } + ib.inode[inode/8]^=(1<<(inode%8)); + } + } + } + } + } +} + + +void createlink(struct block *ptr,char *filename, char *linkname) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename,db->entries[j].name)==0) { + /* Found file */ + int inode=db->entries[j].inodenumber; + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + itb->entries[inode].referencecount++; + addtode(ptr, inode, linkname); + } + } + } + } +} + + +void closefile(struct block *ptr, int fd) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + + + msync(&itb->entries[fd],sizeof(DirectoryEntry),MS_SYNC); + files[fd].used=false; +} + + +bool writefile(struct block *ptr, int fd, char *s) { + return (writefile(ptr,fd,s,1)==1); +} + + +int writefile(struct block *ptr, int fd, char *s, int len) { + struct filedesc *tfd=&files[fd]; + if (tfd->used==false) + return -1; + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + int filelen=itb->entries[tfd->inode].filesize; + if ((12*BLOCKSIZE-tfd->offset)offset; + for(int i=0;ioffset/BLOCKSIZE; + int noffset=tfd->offset%BLOCKSIZE; + if (tfd->offset>=filelen) { + if (noffset==0) { + int bptr=getblock(ptr); + if (bptr==-1) { + if (itb->entries[files[fd].inode].filesizeentries[files[fd].inode].filesize=files[fd].offset; + return i; + } + itb->entries[tfd->inode].Blockptr[nbuffer]=bptr; + } + } + int block=itb->entries[tfd->inode].Blockptr[nbuffer]; + char *fchar=(char *)&ptr[block]; + int tocopy=len-i; + if (tocopy>(BLOCKSIZE-noffset)) + tocopy=BLOCKSIZE-noffset; + memcpy(&fchar[noffset],&s[i],tocopy); + msync(&fchar[noffset],tocopy,MS_SYNC); + i+=tocopy; + tfd->offset+=tocopy; + } + if (itb->entries[files[fd].inode].filesizeentries[files[fd].inode].filesize=files[fd].offset; + return len; +} + + +// reads one char from the file fd and returns it +char readfile(struct block *ptr, int fd) { + char array[1]; + if (readfile(ptr,fd,array,1)==1) + return array[0]; + else + return EOF; +} + +// reads len chars from file fd (file system *ptr) and returns them in buf +int readfile(struct block *ptr, int fd, char *buf, int len) { + struct filedesc *tfd=&files[fd]; + if (tfd->used==false) + return -1; + + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + int filelen=itb->entries[tfd->inode].filesize; + + // if there are fewer than len chars left, read until the end + if ((filelen-tfd->offset)offset; + + for(int i=0;ioffset/BLOCKSIZE; + int noffset=tfd->offset%BLOCKSIZE; + int block=itb->entries[tfd->inode].Blockptr[nbuffer]; + char *fchar=(char *)&ptr[block]; + int tocopy=len-i; + if (tocopy>(BLOCKSIZE-noffset)) + tocopy=BLOCKSIZE-noffset; + memcpy(&buf[i],&fchar[noffset],tocopy); + i+=tocopy; + tfd->offset+=tocopy; + } + return len; +} + + + +int openfile(struct block *ptr, char *filename) { + /* Locate fd */ + int fd=-1; + for(int k=0;kentries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename, db->entries[j].name)==0) + { + files[fd].inode=db->entries[j].inodenumber; + files[fd].offset=0; + return fd; + } + } + } + } + + /* If file doesn't exist, create it */ + int inode=getinode(ptr); + if (inode==-1) { + files[fd].used=false; + return -1; + } + itb->entries[inode].filesize=0; + itb->entries[inode].referencecount=1; + for (int i=0;i<12;i++) + itb->entries[inode].Blockptr[i]=0; + + addtode(ptr, inode, filename); + files[fd].inode=inode; + files[fd].offset=0; + return fd; +} + + +void createfile(struct block *ptr,char *filename, char *buf,int buflen) { + int fd=openfile(ptr,filename); + writefile(ptr,fd,buf,buflen); + closefile(ptr,fd); +} + + + +// adds a file to the directory entry +void addtode(struct block *ptr, int inode, char *filename) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]==0) { + /* lets finish */ + strncpy(db->entries[j].name,filename,124); + db->entries[j].inodenumber=inode; + msync(&db->entries[j],sizeof(DirectoryEntry),MS_SYNC); + return; + } + } + } +} + + +// return the first free node in the InodeTable. Marks that inode as used. +int getinode(struct block *ptr) { + for(int i=0;iFreeBlockCount=NUMBLOCK-5; + sb->FreeInodeCount=NUMINODES-1; + sb->NumberofInodes=NUMINODES; + sb->NumberofBlocks=NUMBLOCK; + sb->RootDirectoryInode=0; + sb->blocksize=BLOCKSIZE; + } + { + struct GroupBlock * gb=(struct GroupBlock *) &ptr[1]; + gb->BlockBitmapBlock=2; + gb->InodeBitmapBlock=3; + gb->InodeTableBlock=4; + gb->GroupFreeBlockCount=NUMBLOCK-5; + gb->GroupFreeInodeCount=NUMINODES-1; + } + { + struct BlockBitmap * bb=(struct BlockBitmap *) &ptr[2]; + //memset(bb, 0, sizeof(BlockBitmap)); + for(int i=0;i<(5+12);i++) { + bb->blocks[i/8]=bb->blocks[i/8]|(1<<(i%8)); + } + } + { + struct InodeBitmap * ib=(struct InodeBitmap *) &ptr[3]; + //memset(ib, 0, sizeof(InodeBitmap)); + ib->inode[0]=1; + } + { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + + itb->entries[0].filesize=12*BLOCKSIZE; + for(int i=0;i<12;i++) + itb->entries[0].Blockptr[i]=i+5; // blocks 5 to 16 are RootDirectory entries + itb->entries[0].referencecount=0; + } + + int val=munmap(vptr,LENGTH); + if (val!=0) + printf("Error!\n"); + + printf("Disk created successfully!\n"); +} + + +void printdirectory(struct block *ptr) +{ + struct InodeBlock *itb=(struct InodeBlock *) &ptr[itbptr]; + + for(int i=0;i<12;i++) + { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + + for(int j=0;jentries[j].name[0]!=0) + { + /* lets finish */ + //printf("%s %d\n",db->entries[j].name, db->entries[j].inodenumber); + printf("%s (inode %d) (%d bytes)\n",db->entries[j].name, db->entries[j].inodenumber, itb->entries[db->entries[j].inodenumber].filesize); + } + } + } + + //printf("end of printdirectory\n"); +} + +// prints the contents of the file with filename "filename" +void printfile(char *filename, struct block *ptr) +{ + printf("=== BEGIN of %s ===\n", filename); + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename,db->entries[j].name)==0) { + /* Found file */ + int inode=db->entries[j].inodenumber; + + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<((itb->entries[inode].filesize+BLOCKSIZE-1)/BLOCKSIZE);i++) { + struct block *b=&ptr[itb->entries[inode].Blockptr[i]]; + write(0,b,BLOCKSIZE); + } + } + } + } + } + printf("\n=== END of %s ===\n", filename); +} + + +void printinodeblock(struct block *ptr) +{ + struct InodeBlock *itb=(struct InodeBlock *) &ptr[itbptr]; + + for (int i=0; ientries[i]; + printf("inode %d: (filesize %d), (referencecount %d)\n", i, inode.filesize, inode.referencecount); + } +} + + diff --git a/Repair/RepairInterpreter/dmodel.cc b/Repair/RepairInterpreter/dmodel.cc new file mode 100755 index 0000000..f26fc78 --- /dev/null +++ b/Repair/RepairInterpreter/dmodel.cc @@ -0,0 +1,609 @@ +// defines the sets and the relations used + +#include +#include +#include "dmodel.h" +#include "set.h" +#include "Relation.h" +#include "Hashtable.h" +#include "model.h" +#include "Guidance.h" + + +// class DomainSet + +DomainSet::DomainSet(char *name) { + setname=name; + flag=0; + this->type=NULL; + numsubsets=0; + subsets=NULL; + set=new WorkSet(); +} + +void DomainSet::reset() { + delete(set); + set=new WorkSet(); +} + +char * DomainSet::getelementtype() { + return type; +} + +int DomainSet::gettype() { + return flag%DOMAINSET_TYPED; +} + +void DomainSet::settype(char *type) { + this->type=type; + flag|=DOMAINSET_TYPED; +} + +void DomainSet::setsubsets(char **subsets, int numsubsets) { + this->subsets=subsets; + this->numsubsets=numsubsets; + flag=DOMAINSET_SUBSET; +} + +void DomainSet::setpartition(char **subsets, int numsubsets) { + this->subsets=subsets; + this->numsubsets=numsubsets; + flag=DOMAINSET_PARTITION; +} + +void DomainSet::print() { + printf("%s",setname); + if (DOMAINSET_TYPED&flag) + printf("(%s)",type); + printf(":"); + if (DOMAINSET_PARTITION&flag) + printf("partition "); + for(int i=0;isize()); +} + +char * DomainSet::getname() { + return setname; +} + +WorkSet * DomainSet::getset() { + return set; +} + +int DomainSet::getnumsubsets() { + return numsubsets; +} + +char * DomainSet::getsubset(int i) { + return subsets[i]; +} + + + + +// class DRelation + +DRelation::DRelation(char *n, char *d, char *r, int t, bool b) { + domain=d;range=r;type=t;name=n; + relation=new WorkRelation(); + staticrel=b; + tokenrange = NULL; +} + +void DRelation::reset() { + delete(relation); + relation=new WorkRelation(); +} + +bool DRelation::isstatic() { + return staticrel; +} + +char * DRelation::getdomain() { + return domain; +} + +char * DRelation::getrange() { + return range; +} + +WorkSet* DRelation::gettokenrange() { + return tokenrange; +} + +void DRelation::settokenrange(WorkSet *ws) { + tokenrange = ws; +} + + + +void DRelation::print() { + printf("%s: %s -> %s (",name,domain,range); + if (type&DRELATION_MANYDOMAIN) + printf("M"); + else + printf("1"); + printf("->"); + if (type&DRELATION_MANYRANGE) + printf("M"); + else + printf("1"); + printf(")"); + +} + +char * DRelation::getname() { + return name; +} + +WorkRelation * DRelation::getrelation() { + return relation; +} + + + + + +// class DomainRelation + +DomainRelation::DomainRelation(DomainSet **s, int ns, DRelation **r,int nr) { + sets=s; numsets=ns; + relations=r;numrelations=nr; + settable=new Hashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings); + relationtable=new Hashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings); + for(int i=0;iput(sets[i]->getname(),sets[i]); + for(int i=0;iput(relations[i]->getname(),relations[i]); +} + +void DomainRelation::reset() { + for(int i=0;ireset(); + } + for(int i=0;ireset(); + } +} + +bool DomainRelation::issupersetof(DomainSet *sub,DomainSet *super) { + while(sub!=NULL) { + if (sub==super) + return true; + sub=getsuperset(sub); + } + return false; +} + +void DomainRelation::print() { + for(int i=0;iprint(); + printf("\n"); + } + printf("\n"); + for(int i=0;iprint(); + printf("\n"); + } +} + +DomainSet * DomainRelation::getset(char * setname) { + if (setname!=NULL) + return (DomainSet *)settable->get(setname); + else return NULL; +} + +DRelation * DomainRelation::getrelation(char * relationname) { + if (relationname!=NULL) + return (DRelation *)relationtable->get(relationname); + else + return NULL; +} + +DomainRelation::~DomainRelation() { + delete(settable); + delete(relationtable); + for(int i=0;iaddobject(ds); + while(!tmp->isEmpty()) { + DomainSet *s=(DomainSet *)tmp->firstelement(); + tmp->removeobject(s); + ws->addobject(s); + for(int j=0;jgetnumsubsets();j++) { + tmp->addobject(getset(s->getsubset(j))); + } + } + delete(tmp); +} + +WorkSet * DomainRelation::conflictdelsets(char * setname, char * boundset) { + /* Want to know what set removals insertion into "setname" could cause */ + if (equivalentstrings(setname,"int")) + return new WorkSet(true); + if (equivalentstrings(setname,"token")) + return new WorkSet(true); + DomainSet *bs=getset(boundset); + WorkSet *wsret=new WorkSet(true); + WorkSet *ws=new WorkSet(true); + while(bs!=NULL) { + ws->addobject(bs); + bs=getsuperset(bs); + } + + DomainSet *oldcs=getset(setname); + DomainSet *cs=getsuperset(oldcs); + + + while(cs!=NULL) { + if (ws->contains(cs)) { + if (cs->gettype()==DOMAINSET_PARTITION && + !equivalentstrings(cs->getname(),boundset)) { + delete(ws); + delete(wsret); + ws=new WorkSet(true); + + DomainSet *bs=getset(boundset); + addallsubsets(bs,ws); + DomainSet *oldbs=bs; + bs=getsuperset(oldbs); + while(bs!=cs) { + ws->addobject(bs); + if (bs->gettype()!=DOMAINSET_PARTITION) { + for(int i=0;igetnumsubsets();i++) { + DomainSet *tss=getset(bs->getsubset(i)); + if (oldbs!=tss) { + addallsubsets(tss,ws); + } + } + } + oldbs=bs; + bs=getsuperset(oldbs); + } + return ws; + } + break; + } + if (cs->gettype()==DOMAINSET_PARTITION) { + /* We have a partition...got to look at all other subsets */ + for(int i=0;igetnumsubsets();i++) { + if (!equivalentstrings(cs->getsubset(i),oldcs->getname())) { + addallsubsets(getset(cs->getsubset(i)),wsret); + } + } + } + oldcs=cs; + cs=getsuperset(cs); + } + delete(ws); + return wsret; +} + +DomainSet * DomainRelation::getsuperset(DomainSet *s) { + char *name=s->getname(); + for(int i=0;igetnumsubsets();j++) { + if(equivalentstrings(name,sets[i]->getsubset(j))) + return sets[i]; + } + return NULL; +} + +WorkSet * DomainRelation::conflictaddsets(char * setname, char *boundset, model *m) { + /* Want to know what set additions insertion into "setname" could cause */ + if (equivalentstrings(setname,"int")) + return new WorkSet(true); + if (equivalentstrings(setname,"token")) + return new WorkSet(true); + DomainSet *bs=getset(boundset); + WorkSet *wsret=new WorkSet(true); + WorkSet *ws=new WorkSet(true); + while(bs!=NULL) { + ws->addobject(bs); + bs=getsuperset(bs); + } + + Guidance *g=m->getguidance(); + DomainSet *ds=getset(g->insertiontoset(setname)); + while(ds!=NULL) { + if (ws->contains(ds)) + break; + wsret->addobject(ds); + ds=getsuperset(ds); + } + + delete(ws); + return wsret; +} + +WorkSet * DomainRelation::removeconflictdelsets(char *setname) { + /* Obviously remove from all subsets*/ + WorkSet *tmp=new WorkSet(true); + WorkSet *wsret=new WorkSet(true); + tmp->addobject(getset(setname)); + while(!tmp->isEmpty()) { + DomainSet *s=(DomainSet *)tmp->firstelement(); + tmp->removeobject(s); + wsret->addobject(s); + for(int j=0;jgetnumsubsets();j++) + tmp->addobject(getset(s->getsubset(j))); + } + delete(tmp); + return wsret; +} + +WorkSet * DomainRelation::removeconflictaddsets(char *setname, model *m) { + /* Remove could cause addition to a new set...*/ + DomainSet *ds=getset(setname); + Guidance *g=m->getguidance(); + char *settoputin=g->removefromset(setname); + if (settoputin==NULL) + return new WorkSet(true); + return conflictaddsets(settoputin, setname, m); +} + +DomainSet * DomainRelation::getsource(DomainSet *s) { + return getsuperset(s); +} + +void DomainRelation::addtoset(Element *ele, DomainSet *settoadd, model *m) { + /* Assumption is that object is not in set*/ + if(settoadd->getset()->contains(ele)) /* Already in set-no worries */ + return; + if(settoadd->gettype()==DOMAINSET_PARTITION) { + /* Have to find subset to add to */ + char *subsettoadd=m->getguidance()->insertiontoset(settoadd->getname()); + DomainSet *setptr=getset(subsettoadd); + while(setptr!=settoadd) { + setptr->getset()->addobject(ele); + m->triggerrule(ele,setptr->getname()); + setptr=getsuperset(setptr); + } + } + settoadd->getset()->addobject(ele); + m->triggerrule(ele,settoadd->getname()); + DomainSet *oldptr=settoadd; + DomainSet *ptr=getsuperset(oldptr); + while((ptr!=NULL)&&(!ptr->getset()->contains(ele))) { + ptr->getset()->addobject(ele); + m->triggerrule(ele,ptr->getname()); + oldptr=ptr; + ptr=getsuperset(ptr); + } + if(ptr!=NULL&& + ptr->gettype()==DOMAINSET_PARTITION) { + /* may have to do removes....*/ + for(int i=0;igetnumsubsets();i++) { + char *subset=ptr->getsubset(i); + DomainSet *ptrsubset=getset(subset); + if (oldptr!=ptrsubset&& + ptrsubset->getset()->contains(ele)) { + /* GOT THE ONE*/ + WorkSet *ws=new WorkSet(true); + ws->addobject(ptrsubset); + while(!ws->isEmpty()) { + DomainSet *ds=(DomainSet *)ws->firstelement(); + ws->removeobject(ds); + if (ds->getset()->contains(ele)) { + for(int j=0;jgetnumsubsets();j++) { + ws->addobject(getset(ds->getsubset(j))); + } + removefromthisset(ele, ds,m); + } + } + delete(ws); + break; + } + } + } +} + +void DomainRelation::abstaddtoset(Element *ele, DomainSet *settoadd, model *m) { + /* Assumption is that object is not in set*/ + if(settoadd->getset()->contains(ele)) /* Already in set-no worries */ + return; + if(settoadd->gettype()==DOMAINSET_PARTITION) { + /* Have to find subset to add to */ + char *subsettoadd=m->getguidance()->insertiontoset(settoadd->getname()); + DomainSet *setptr=getset(subsettoadd); + while(setptr!=settoadd) { + setptr->getset()->addobject(ele); + m->triggerrule(ele,setptr->getname()); + setptr=getsuperset(setptr); + } + } + settoadd->getset()->addobject(ele); + m->triggerrule(ele,settoadd->getname()); + DomainSet *oldptr=settoadd; + DomainSet *ptr=getsuperset(oldptr); + while((ptr!=NULL)&&(!ptr->getset()->contains(ele))) { + ptr->getset()->addobject(ele); + m->triggerrule(ele,ptr->getname()); + oldptr=ptr; + ptr=getsuperset(ptr); + } +} + +void DomainRelation::removefromthisset(Element *ele, DomainSet *ds, model *m) { + ds->getset()->removeobject(ele); /*removed from set*/ + /* Next need to search relations */ + for(int i=0;igetdomain(),ds->getname())) + for(Element *target=(Element *) relation->getrelation()->getobj(ele);target!=NULL;target=(Element *) relation->getrelation()->getobj(ele)) { + relation->getrelation()->remove(ele,target); + if (relation->isstatic()) { + /* Have to actually remove target*/ + DomainSet *targetset=getset(relation->getrange()); + delfromsetmovetoset(target,targetset,m); + } + } + if (equivalentstrings(relation->getrange(),ds->getname())) + for(Element *target=(Element *) relation->getrelation()->invgetobj(ele);target!=NULL;target=(Element *) relation->getrelation()->invgetobj(ele)) { + relation->getrelation()->remove(target,ele); + if (relation->isstatic()) { + DomainSet *targetset=getset(relation->getdomain()); + delfromsetmovetoset(target,targetset,m); + } + } + } +} + +void DomainRelation::delfromsetmovetoset(Element *ele,DomainSet *deletefromset,model *m) { + WorkSet *ws=new WorkSet(true); + ws->addobject(deletefromset); + while(!ws->isEmpty()) { + DomainSet *ds=(DomainSet *)ws->firstelement(); + ws->removeobject(ds); + if (ds->getset()->contains(ele)) { + for(int j=0;jgetnumsubsets();j++) { + ws->addobject(getset(ds->getsubset(j))); + } + removefromthisset(ele, ds,m); + } + } + delete(ws); + char *mts=m->getguidance()->removefromset(deletefromset->getname()); + DomainSet *movetoset=getset(mts); + addtoset(ele, movetoset, m); //Add to the movetoset now... +} + +int DomainRelation::getnumrelation() { + return numrelations; +} + +DRelation * DomainRelation::getrelation(int i) { + return relations[i]; +} + + +bool DomainRelation::fixstuff() { + bool anychange=false; + /* Guaranteed fixpoint because we keep removing items...finite # of items */ + while(true) { + bool changed=false; + for(int i=0;igetset(); + WorkSet *wssuper=ds->getset(); + + void *ele=ws->firstelement(); + while(ele!=NULL) { + if (!wssuper->contains(ele)) { + void *old=ele; + ele=ws->getnextelement(ele); + changed=true; +#ifdef REPAIR + ws->removeobject(old); +#endif + } else + ele=ws->getnextelement(ele); + } + /* Superset inclusion property guaranteed */ + + + /* If an element is contained by more than one subset, remove it from + all subsets but the first one. If an element is not contained by + any subset, remove it from the superset */ + if (ds->gettype()==DOMAINSET_PARTITION) { + ele=ws->firstelement(); + while(ele!=NULL) { + int inccount=0; + for(int i=0;igetnumsubsets();i++) { + char *subsetname=ds->getsubset(i); + DomainSet *subset=getset(subsetname); + if (subset->getset()->contains(ele)) { + if (inccount==0) + inccount++; + else { + /* Partition exclusion property */ + changed=true; +#ifdef REPAIR + subset->getset()->removeobject(ele); +#endif + } + } + } + if (inccount==0) { + /* Partition inclusion property */ + changed=true; +#ifdef REPAIR + ws->removeobject(ele); +#endif + } + ele=ws->getnextelement(ele); + } + } + return changed; +} + + + +bool DomainRelation::checkrelations(DRelation *dr) { + DomainSet *range=getset(dr->getrange()); + DomainSet *domain=getset(dr->getdomain()); + WorkSet *rangeset=NULL,*domainset=NULL; + bool changed=false; + if (range!=NULL) + rangeset=range->getset(); + if (domain!=NULL) + domainset=domain->getset(); + WorkRelation *rel=dr->getrelation(); + Tuple ele=rel->firstelement(); + while(!ele.isnull()) { + if((domainset!=NULL&&!domainset->contains(ele.left))|| + (rangeset!=NULL&&!rangeset->contains(ele.right))) { + void *l=ele.left; + void *r=ele.right; + ele=rel->getnextelement(l,r); + changed=true; +#ifdef REPAIR + rel->remove(l,r); +#endif + } else { + ele=rel->getnextelement(ele.left,ele.right); + } + } + /* Relation is clean now also */ + return changed; +} diff --git a/Repair/RepairInterpreter/dmodel.h b/Repair/RepairInterpreter/dmodel.h new file mode 100755 index 0000000..41965b9 --- /dev/null +++ b/Repair/RepairInterpreter/dmodel.h @@ -0,0 +1,105 @@ +// defines the sets and the relations used + +#ifndef DMODEL_H +#define DMODEL_H + +#include "common.h" +#include "classlist.h" + +#define DOMAINSET_SUBSET 1 +#define DOMAINSET_PARTITION 2 +#define DOMAINSET_TYPED 0x100 + +// represents a set +class DomainSet { + public: + DomainSet(char *name); + void settype(char *type); + void setsubsets(char **subsets, int numsubsets); + void setpartition(char **subsets, int numsubsets); + void print(); + char *getname(); + WorkSet *getset(); + int getnumsubsets(); + char *getsubset(int i); + int gettype(); + char * getelementtype(); + void reset(); + private: + WorkSet *set; // the set itself + char *type; // the type of the elements in the set + char *setname; // the name of the set + int flag; + char ** subsets;// the subsets + int numsubsets; +}; + + + + +#define DRELATION_SINGDOMAIN 0x1 +#define DRELATION_MANYDOMAIN 0x2 +#define DRELATION_SINGRANGE 0x10 +#define DRELATION_MANYRANGE 0x20 + +// represents a relation +class DRelation { + public: + DRelation(char *name, char *d, char *r, int t, bool); + void print(); + char *getname(); + WorkRelation *getrelation(); + char *getdomain(); + char *getrange(); + WorkSet *gettokenrange(); + void settokenrange(WorkSet *ws); + bool isstatic(); + void reset(); + private: + bool staticrel; + char *name; + char *domain; + char *range; + WorkSet *tokenrange; // the actual range, if the range is of type token + int type; + WorkRelation *relation; +}; + + + +// manages the entire collection of sets and relations +class DomainRelation { + public: + DomainRelation(DomainSet **s, int ns, DRelation **r,int nr); + void print(); + DomainSet * getset(char * setname); + DRelation * getrelation(char * relationname); + ~DomainRelation(); + WorkSet * conflictdelsets(char *setname, char *boundset); + WorkSet * conflictaddsets(char *setname, char *boundset, model *m); + WorkSet * removeconflictdelsets(char *setname); + WorkSet * removeconflictaddsets(char *setname, model *m); + DomainSet * getsuperset(DomainSet *); + DomainSet * getsource(DomainSet *); + /* Tells what set we might get objects from for a given set */ + void delfromsetmovetoset(Element *e,DomainSet *deletefromset,model *m); + void abstaddtoset(Element *e,DomainSet *addtoset,model *m); + void addtoset(Element *e,DomainSet *addtoset,model *m); + bool issupersetof(DomainSet *sub,DomainSet *super); + int getnumrelation(); + DRelation * getrelation(int i); + bool fixstuff(); + void reset(); + + private: + bool checkrelations(DRelation *dr); + bool checksubset(DomainSet *ds); + void addallsubsets(DomainSet *ds, WorkSet *ws); + void removefromthisset(Element *ele, DomainSet *ds,model *m); + Hashtable *settable, *relationtable; + DomainSet ** sets; + int numsets; + DRelation **relations; + int numrelations; +}; +#endif diff --git a/Repair/RepairInterpreter/dparser.cc b/Repair/RepairInterpreter/dparser.cc new file mode 100755 index 0000000..c84f3b2 --- /dev/null +++ b/Repair/RepairInterpreter/dparser.cc @@ -0,0 +1,143 @@ +#include +#include "dparser.h" +#include "list.h" +#include "common.h" +#include "token.h" +#include "dmodel.h" + +Dparser::Dparser(Reader *r) { + reader=r; +} + +DomainRelation *Dparser::parsesetrelation() { + List *sets=new List(); + List *relations=new List(); + for(Token t=reader->peakahead();t.token_type!=TOKEN_EOF;t=reader->peakahead()) { + switch(t.token_type) { + case TOKEN_EOL: + skiptoken(); + break; + case TOKEN_SET: + sets->addobject(parseset()); + break; + default: + relations->addobject(parserelation()); + } + } + DomainSet **dsarray=new DomainSet*[sets->size()]; + DRelation **drarray=new DRelation*[relations->size()]; + sets->toArray((void **)dsarray); + relations->toArray((void **)drarray); + DomainRelation *dr=new DomainRelation(dsarray,sets->size(), + drarray,relations->size()); + delete(sets); + delete(relations); + return dr; +} + +DomainSet * Dparser::parseset() { + needtoken(TOKEN_SET); + Token name=reader->readnext(); + DomainSet *ds=new DomainSet(copystr(name.str)); + // Token istype=reader->peakahead(); + // if (istype.token_type==TOKEN_OPENPAREN) { + //skiptoken(); + needtoken(TOKEN_OPENPAREN); + ds->settype(copystr(reader->readnext().str)); + needtoken(TOKEN_CLOSEPAREN); + //} + needtoken(TOKEN_COLON); + bool ispart=(reader->peakahead().token_type==TOKEN_PARTITION); + if (ispart) + skiptoken(); + bool needset=false; + bool cont=true; + List *subsets=new List(); + while(cont) { + Token t=reader->peakahead(); + switch(t.token_type) { + case TOKEN_EOF: + if (!needset) { + printf("ERROR: Need set name"); + exit(-1); + } + cont=false; + break; + case TOKEN_EOL: + if (!needset) + cont=false; + skiptoken(); + break; + case TOKEN_BAR: + needset=true; + skiptoken(); + break; + default: + subsets->addobject(copystr(t.str)); + skiptoken(); + needset=false; + } + } + char **carray=new char*[subsets->size()]; + subsets->toArray((void **)carray); + if (ispart) + ds->setpartition(carray,subsets->size()); + else + ds->setsubsets(carray,subsets->size()); + delete(subsets); + return ds; +} + +DRelation * Dparser::parserelation() { + Token name=reader->readnext(); + bool isstat=false; + if (name.token_type==TOKEN_STATIC) { + isstat=true; + name=reader->readnext(); + } + needtoken(TOKEN_COLON); + Token domain=reader->readnext(); + needtoken(TOKEN_ARROW); + Token range=reader->readnext(); + needtoken(TOKEN_OPENPAREN); + Token domainmult=reader->readnext(); + needtoken(TOKEN_ARROW); + Token rangemult=reader->readnext(); + needtoken(TOKEN_CLOSEPAREN); + int type=0; + if (domainmult.token_type==TOKEN_ONE) + type+=0x1; + else if (domainmult.token_type==TOKEN_MANY) + type+=0x2; + else error(); + + if (rangemult.token_type==TOKEN_ONE) + type+=0x10; + else if (rangemult.token_type==TOKEN_MANY) + type+=0x20; + else error(); + + return new DRelation(copystr(name.str),copystr(domain.str), + copystr(range.str),type,isstat); +} + +void Dparser::error() { + printf("ERROR\n"); + reader->error(); + exit(-1); +} + +void Dparser::skiptoken() { + reader->readnext(); +} + +void Dparser::needtoken(int token) { + Token t=reader->readnext(); + if (!(t.token_type==token)) { + printf("Needed token: "); + tokenname(token); + printf("\n Got token: %s ",t.str); + tokenname(t.token_type); + error(); + } +} diff --git a/Repair/RepairInterpreter/dparser.h b/Repair/RepairInterpreter/dparser.h new file mode 100755 index 0000000..2ba7734 --- /dev/null +++ b/Repair/RepairInterpreter/dparser.h @@ -0,0 +1,20 @@ +#ifndef DPARSER_H +#define DPARSER_H +#include "common.h" +#include +#include +#include "classlist.h" + +class Dparser { + public: + Dparser(Reader *r); + DomainRelation * parsesetrelation(); + private: + DomainSet * parseset(); + DRelation * parserelation(); + Reader *reader; + void skiptoken(); + void needtoken(int); + void error(); +}; +#endif diff --git a/Repair/RepairInterpreter/element.cc b/Repair/RepairInterpreter/element.cc new file mode 100755 index 0000000..87fad2a --- /dev/null +++ b/Repair/RepairInterpreter/element.cc @@ -0,0 +1,258 @@ +// provides an object wrapper around elementary types + +#include +#include +#include +#include "element.h" + + +Element::Element() { + typevalue=ELEMENT_OBJECT; + token=NULL; + object=NULL; + integervalue=0; + bytevalue=0; + bitvalue=false; + shortvalue=0; + itemtype=NULL; +} + +char * Element::gettoken() { + assert(typevalue==ELEMENT_TOKEN); + return token; +} + +bool Element::isnumber() { + if ((type()==ELEMENT_INT)|| + (type()==ELEMENT_BYTE)|| + (type()==ELEMENT_SHORT)) + return true; + else + return false; +} + +Element::Element(void * objptr, structure * str) { + object=objptr; + typevalue=ELEMENT_OBJECT; + itemtype=str; + token=NULL; + integervalue=0; + bytevalue=0; + bitvalue=false; + shortvalue=0; +} + +Element::Element(int value) { + typevalue=ELEMENT_INT; + integervalue=value; + object=NULL; + itemtype=NULL; + bytevalue=0; + bitvalue=false; + token=NULL; + shortvalue=0; +} + +Element::Element(short value) { + typevalue=ELEMENT_SHORT; + shortvalue=value; + integervalue=0; + object=NULL; + itemtype=NULL; + bytevalue=0; + bitvalue=false; + token=NULL; +} + +Element::Element(bool b) { + typevalue=ELEMENT_BIT; + bitvalue=b; + integervalue=0; + object=NULL; + itemtype=NULL; + bytevalue=0; + token=NULL; + shortvalue=0; +} + +Element::Element(char byte) { + typevalue=ELEMENT_BYTE; + bytevalue=byte; + integervalue=0; + object=NULL; + itemtype=NULL; + token=NULL; + bitvalue=false; + shortvalue=0; +} + +Element::Element(char * token) {/*Value destroyed by this destructor*/ + this->token=token; + typevalue=ELEMENT_TOKEN; + integervalue=0; + bytevalue=0; + bitvalue=false; + object=NULL; + itemtype=NULL; + shortvalue=0; +} + +Element::Element(Element * o) { + this->integervalue=o->integervalue; + this->bytevalue=o->bytevalue; + this->itemtype=o->itemtype; + this->token=copystr(o->token); + this->object=o->object; + this->typevalue=o->typevalue; + this->bitvalue=o->bitvalue; + this->shortvalue=o->shortvalue; +} + +void Element::print() { + switch(typevalue) { + case ELEMENT_INT: +#ifndef TOOL + printf("Int(%d)",integervalue); +#else + printf("%d", integervalue); +#endif + break; + + case ELEMENT_SHORT: +#ifndef TOOL + printf("Short(%d)",shortvalue); +#else + printf("%d", shortvalue); +#endif + break; + + case ELEMENT_BIT: + if (bitvalue) +#ifndef TOOL + printf("Bit(true)"); +#else + printf("true"); +#endif + else +#ifndef TOOL + printf("Bit(false)"); +#else + printf("false"); +#endif + break; + + case ELEMENT_BYTE: +#ifndef TOOL + printf("Int(%c)",bytevalue); +#else + printf("%c",bytevalue); +#endif + break; + + case ELEMENT_TOKEN: +#ifndef TOOL + printf("Token(%s)",token); +#else + printf("%s",token); +#endif + break; + + case ELEMENT_OBJECT: + printf("Object(%p)",object); + break; + } +} + +unsigned int Element::hashCode() { + switch(typevalue) { + case ELEMENT_INT: + return integervalue; + case ELEMENT_SHORT: + return shortvalue; + case ELEMENT_BIT: + if (bitvalue) + return 1; + else + return 0; + case ELEMENT_BYTE: + return bytevalue; + case ELEMENT_TOKEN: + return hashstring(token); + case ELEMENT_OBJECT: + return (int)object; + } +} + +bool Element::equals(ElementWrapper *other) { + if (other->type()!=typevalue) + return false; + switch(typevalue) { + case ELEMENT_INT: + return (this->integervalue==((Element *)other)->integervalue); + case ELEMENT_SHORT: + return (this->shortvalue==((Element *)other)->shortvalue); + case ELEMENT_BIT: + return (this->bitvalue==((Element *)other)->bitvalue); + case ELEMENT_BYTE: + return (this->bytevalue==((Element *)other)->bytevalue); + case ELEMENT_TOKEN: + return (equivalentstrings(token,((Element *)other)->token)==1); + case ELEMENT_OBJECT: + return object==((Element *)other)->object; + } +} + +int Element::intvalue() { + switch(typevalue) { + case ELEMENT_INT: + return integervalue; + case ELEMENT_SHORT: + return shortvalue; + case ELEMENT_BYTE: + return bytevalue; + default: + printf("Illegal int conversion on Element\n"); + exit(-1); + } +} + +short Element::getshortvalue() { + assert(typevalue==ELEMENT_SHORT); + return shortvalue; +} + +char Element::getbytevalue() { + assert(typevalue==ELEMENT_BYTE); + return bytevalue; +} + +bool Element::getboolvalue() { + assert(typevalue==ELEMENT_BIT); + return bitvalue; +} + +void * Element::getobject() { + assert(typevalue==ELEMENT_OBJECT); + return object; +} + +int Element::type() { + return typevalue; +} + +structure * Element::getstructure() { + return itemtype; +} + +Element::~Element() { + if(typevalue==ELEMENT_TOKEN) + delete[] token; +} + +unsigned int hashelement(ElementWrapper *e) { + return e->hashCode(); +} + +int elementequals(ElementWrapper *e1, ElementWrapper *e2) { + return e1->equals(e2); +} diff --git a/Repair/RepairInterpreter/element.h b/Repair/RepairInterpreter/element.h new file mode 100755 index 0000000..f8987e1 --- /dev/null +++ b/Repair/RepairInterpreter/element.h @@ -0,0 +1,67 @@ +// provides an object wrapper around elementary types + + +#ifndef ELEMENT_H +#define ELEMENT_H +#include "common.h" +#include "classlist.h" + +class ElementWrapper; + +#define ELEMENT_INT 1 +#define ELEMENT_BIT 2 +#define ELEMENT_BYTE 3 +#define ELEMENT_TOKEN 4 +#define ELEMENT_OBJECT 5 +#define ELEMENT_FTUPLE 6 +#define ELEMENT_SHORT 7 + +class ElementWrapper { + public: + virtual unsigned int hashCode()=0; + virtual bool equals(ElementWrapper *other)=0; + virtual int type()=0; + private: +}; + + +class Element:public ElementWrapper { + public: + Element(); + Element(int value); + Element(short value); + Element(bool b); + Element(char byte); + Element(char * token); + Element(Element * o); + unsigned int hashCode(); + bool equals(ElementWrapper *other); + int intvalue(); + short getshortvalue(); + char getbytevalue(); + bool getboolvalue(); + bool isnumber(); + void * getobject(); + int type(); + structure * getstructure(); + Element(void * objptr, structure * str); + char * gettoken(); + ~Element(); + void print(); + + private: + char *token; + void *object; + int typevalue; + short shortvalue; + int integervalue; + char bytevalue; + bool bitvalue; + structure *itemtype; +}; + +unsigned int hashelement(ElementWrapper *e); + +int elementequals(ElementWrapper *e1, ElementWrapper *e2); + +#endif diff --git a/Repair/RepairInterpreter/fieldcheck.cc b/Repair/RepairInterpreter/fieldcheck.cc new file mode 100755 index 0000000..2911fa2 --- /dev/null +++ b/Repair/RepairInterpreter/fieldcheck.cc @@ -0,0 +1,287 @@ +#include +#include "classlist.h" +#include "fieldcheck.h" +#include "common.h" +#include "set.h" +#include "dmodel.h" +#include "omodel.h" +#include "model.h" +#include "Hashtable.h" +#include "normalizer.h" + +FieldCheck::FieldCheck(model *m) { + cptoreqs=NULL; + nftoprovides=NULL; + globalmodel=m; + propertytonf=NULL; +} + +bool FieldCheck::testsatisfy(WorkSet *satisfies, FieldTuple *ft) { + FieldTuple *copy=new FieldTuple(ft); + bool sat=false; + while(!sat&©!=NULL) { + if(satisfies->contains(copy)) { + sat=true; + break; + } + copy->set=globalmodel->getdomainrelation()->getsuperset(globalmodel->getdomainrelation()->getset(copy->set))->getname(); + } + delete(copy); + return sat; +} + +int FieldCheck::getindexthatprovides(char *set, char *relation) { + FieldTuple *copy=new FieldTuple(set,relation); + while(copy!=NULL) { + if(propertytonf->contains(copy)) { + /* Found!!! Do stuff */ + NormalForm *nf=(NormalForm *)propertytonf->get(copy); + for(int i=0;igetnumconstraints();i++) { + if (nf==globalmodel->getnormalform(i)) { + delete(copy); + return i; + } + } + printf("Error in getindexthatprovides\n"); + exit(-1); + } + copy->set=globalmodel->getdomainrelation()->getsuperset(globalmodel->getdomainrelation()->getset(copy->set))->getname(); + } + delete(copy); + return -1; /* Couldn't find...too bad */ +} + +void FieldCheck::analyze() { + WorkSet *satisfied=new WorkSet(); + propertytonf=new Hashtable(NULL,NULL); + bool change=true; + bool allsatisfied=true; + FieldTuple *badft=NULL; + while(change) { + allsatisfied=true; + change=false; + for(int i=0;igetnumconstraints();i++) { + NormalForm *nf=globalmodel->getnormalform(i); + bool gotallreqs=true; + for(int j=0;jgetnumsentences();j++) { + CoerceSentence *cs=nf->getsentence(j); + for (int k=0;kgetnumpredicates();k++) { + CoercePredicate *cp=cs->getpredicate(k); + WorkSet *reqs=(WorkSet *)cptoreqs->get(cp); + if (reqs!=NULL) { + for(FieldTuple *ft=(FieldTuple *)reqs->firstelement();ft!=NULL; + ft=(FieldTuple*)reqs->getnextelement(ft)) { + if (!testsatisfy(satisfied,ft)) { + gotallreqs=false; + allsatisfied=false; + badft=ft; + break; + } + } + } + if(!gotallreqs) + break; + } + if (gotallreqs) { + WorkSet *provides=(WorkSet *)nftoprovides->get(nf); + if(provides!=NULL) { + for(FieldTuple *ft=(FieldTuple *)provides->firstelement();ft!=NULL; + ft=(FieldTuple*)provides->getnextelement(ft)) { + if(!testsatisfy(satisfied,ft)) { + /* something to add */ + satisfied->addobject(ft); + propertytonf->put(ft,nf); + change=true; + } + } + } + } + } + } + } + if (!allsatisfied) { + printf("Some relations can't be established:<%s,%s>",badft->relation,badft->set); + exit(-1); + } + delete(satisfied); +} + +void FieldCheck::buildmaps() { + cptoreqs=new Hashtable(NULL,NULL); + nftoprovides=new Hashtable(NULL,NULL); + + for(int i=0;igetnumconstraints();i++) { + NormalForm *nf=globalmodel->getnormalform(i); + Constraint *c=globalmodel->getconstraint(i); + WorkSet *old=NULL; + for(int j=0;jgetnumsentences();j++) { + WorkSet *curr=new WorkSet(); + CoerceSentence *cs=nf->getsentence(j); + for (int k=0;kgetnumpredicates();k++) { + CoercePredicate *cp=cs->getpredicate(k); + WorkSet *wr=requireswhat(c,cp); + if (wr!=NULL) + cptoreqs->put(cp,wr); + FieldTuple *ft=provideswhat(c,cp); + if(ft!=NULL) + curr->addobject(ft); + else + delete(ft); + } + if (old==NULL) + old=curr; + else { + for(FieldTuple *ft=(FieldTuple *)old->firstelement();ft!=NULL; + ft=(FieldTuple *)old->getnextelement(ft)) { + if (!curr->contains(ft)) + old->removeobject(ft); + } + delete(curr); + } + } + if(old!=NULL) { + if(old->isEmpty()) + delete old; + else + nftoprovides->put(nf, old); + } + } +} + +WorkSet * FieldCheck::requireswhat(Constraint *c,CoercePredicate *cp) { + Predicate *p=cp->getpredicate(); + int type=p->gettype(); + if (type==PREDICATE_LT || + type==PREDICATE_LTE || + type==PREDICATE_EQUALS || + type==PREDICATE_GT || + type==PREDICATE_GTE) { + WorkSet *ws=new WorkSet(); + Elementexpr *ee=p->geteleexpr(); + processee(ws,c,ee); + if (ws->isEmpty()) { + delete(ws); + return NULL; + } else return ws; + } else return NULL; +} + +void FieldCheck::processee(WorkSet *ws, Constraint *c, Elementexpr *ee) { + switch(ee->gettype()) { + case ELEMENTEXPR_SUB: + case ELEMENTEXPR_ADD: + case ELEMENTEXPR_MULT: + processee(ws,c,ee->getleft()); + processee(ws,c,ee->getright()); + return; + case ELEMENTEXPR_RELATION: { + /* Interesting case */ + char *rel=ee->getrelation()->getname(); + Elementexpr *left=ee->getleft(); + int tleft=left->gettype(); + if (tleft==ELEMENTEXPR_LABEL) { + ws->addobject(new FieldTuple(rel,getset(c, left->getlabel()->label()))); + } else if (tleft==ELEMENTEXPR_RELATION) { + DRelation *drl=globalmodel->getdomainrelation()->getrelation(left->getrelation()->getname()); + char *rangeofl=drl->getrange(); + ws->addobject(new FieldTuple(rel,rangeofl)); + } else { + ee->print(); + printf("Can't determine domain\n"); + exit(-1); + } + } + return; + default: + return; + } +} + +bool FieldCheck::setok(Constraint *c, char *set) { + for(int i=0;inumquants();i++) { + Quantifier *q=c->getquant(i); + char *qs=q->getset()->getname(); + DomainRelation *dr=globalmodel->getdomainrelation(); + DomainSet *iset=dr->getset(set); + DomainSet *qset=dr->getset(qs); + if (dr->issupersetof(iset,qset)) + return false; + } + return true; +} + +FieldTuple * FieldCheck::provideswhat(Constraint *c,CoercePredicate *cp) { + if (cp->getcoercebool()) + return NULL; + Predicate *p=cp->getpredicate(); + switch(p->gettype()) { + case PREDICATE_LT: + case PREDICATE_LTE: + case PREDICATE_EQUALS: + case PREDICATE_GTE: + case PREDICATE_GT: { + char *relation=p->getvalueexpr()->getrelation()->getname(); + char *var=p->getvalueexpr()->getlabel()->label(); + char *set=getset(c,var); + if (setok(c,set)) { + return new FieldTuple(relation,set); + } else + return NULL; + } + case PREDICATE_SET: + case PREDICATE_EQ1: + case PREDICATE_GTE1: { + Setexpr *se=p->getsetexpr(); + if (se->gettype()==SETEXPR_REL) { + char *relation=se->getrelation()->getname(); + char *var=se->getlabel()->label(); + char *set=getset(c,var); + if (setok(c,set)) { + return new FieldTuple(relation,set); + } else return NULL; + } + return NULL; + } + default: + return NULL; + } +} + +char *getset(Constraint *c, char *var) { + for (int i=0;inumquants();i++) { + Quantifier *q=c->getquant(i); + if (equivalentstrings(var,q->getlabel()->label())) { + return q->getset()->getname(); + } + } + return NULL; +} + +unsigned int FieldTuple::hashCode() { + return hashstring(relation)^hashstring(set); +} + +bool FieldTuple::equals(ElementWrapper *other) { + if (other->type()!=ELEMENT_FTUPLE) + return false; + FieldTuple *oft=(FieldTuple *)other; + if (equivalentstrings(relation, oft->relation)&& + equivalentstrings(set,oft->set)) + return true; + else + return false; +} + +int FieldTuple::type() { + return ELEMENT_FTUPLE; +} + +FieldTuple::FieldTuple(char * r, char *s) { + relation=r; + set=s; +} + +FieldTuple::FieldTuple(FieldTuple *o) { + this->relation=o->relation; + this->set=o->set; +} diff --git a/Repair/RepairInterpreter/fieldcheck.h b/Repair/RepairInterpreter/fieldcheck.h new file mode 100755 index 0000000..f783946 --- /dev/null +++ b/Repair/RepairInterpreter/fieldcheck.h @@ -0,0 +1,38 @@ +#ifndef Fieldcheck_H +#define Fieldcheck_H +#include "classlist.h" +#include "element.h" + +class FieldCheck { + public: + FieldCheck(model *m); + void analyze(); + void buildmaps(); + int getindexthatprovides(char *set, char *relation); + private: + bool setok(Constraint *c, char *set); + bool testsatisfy(WorkSet *satisfies, FieldTuple *ft); + WorkSet * requireswhat(Constraint *c,CoercePredicate *cp); + void processee(WorkSet *ws, Constraint *c, Elementexpr *ee); + FieldTuple * provideswhat(Constraint *c,CoercePredicate *cp); + model *globalmodel; + Hashtable *cptoreqs; + Hashtable *propertytonf; + Hashtable *nftoprovides; +}; + +char *getset(Constraint *c, char *var); + +class FieldTuple:public ElementWrapper { + public: + FieldTuple(FieldTuple *o); + unsigned int hashCode(); + bool equals(ElementWrapper *other); + int type(); + + FieldTuple(char * r, char *s); + char * relation; + char * set; +}; +#endif + diff --git a/Repair/RepairInterpreter/file.cc b/Repair/RepairInterpreter/file.cc new file mode 100755 index 0000000..0ecd6af --- /dev/null +++ b/Repair/RepairInterpreter/file.cc @@ -0,0 +1,518 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "file.h" +extern "C" { +#include "test.h" +} +#include "Hashtable.h" +#include "model.h" +#include "element.h" + +char *dstring="d\0"; +struct filedesc files[MAXFILES]; +struct InodeBitmap ib; +struct BlockBitmap bb; +int bbbptr,ibbptr,itbptr,rdiptr; +int main(int argc, char **argv) { + for(int i=0;igethashtable(); + alloc(ptr,LENGTH); + addmapping(dstring,ptr,"Disk"); + // env->put(dstring,new Element(ptr,exportmodel->getstructure("Disk")));//should be of badstruct + doanalysis(); + dealloc(ptr); + chunmountdisk(ptr); + break; + } + case '3': { + struct block * ptr=mountdisk("disk"); + printdirectory(ptr); + for(int i=1;i<145;i++) { + char filename[10]; + sprintf(filename,"fil%d",i); + printfile(filename,ptr); + } + unmountdisk(ptr); + break; + } + case '4': { + struct block * ptr=mountdisk("disk"); + for(int i=145;i>1;i--) { + char filename[10]; + sprintf(filename,"fil%d",i); + openfile(ptr,filename); + } + for(int j=0;j<90;j++) { + for(int i=145;i>1;i--) { + char *buf="01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123"; + writefile(ptr,i,buf,122); + } + } + for(int i=145;i>1;i--) { + closefile(ptr,i); + } + unmountdisk(ptr); + break; + } + case '5': { + struct block * ptr=mountdisk("disk"); + for(int i=145;i>=0;i--) { + char filename[10]; + sprintf(filename,"fil%d",i); + openfile(ptr,filename); + } + for(int j=0;j<6000;j++) { + for(int i=145;i>=0;i--) { + char name[10]; + int len=sprintf(name, "%d ",i); + writefile(ptr,i,name,len); + } + } + for(int i=145;i>=0;i--) { + closefile(ptr,i); + } + for(int i=145;i>=0;i--) { + char filename[10]; + sprintf(filename,"fil%d",i); + openfile(ptr,filename); + } + for(int j=0;j<400;j++) { + for(int i=145;i>=0;i--) { + int l=0; + char name[10]; + int len=sprintf(name, "%d ",i); + readfile(ptr,i,name,len); + sscanf(name, "%d ", &l); + if (l!=i) { + printf("ERROR in benchmark\n"); + } + } + } + for(int i=145;i>=0;i--) { + closefile(ptr,i); + } + unmountdisk(ptr); + } + break; + case '6': { + { + struct block * ptr=chmountdisk("disk"); + initializeanalysis(); + Hashtable *env=exportmodel->gethashtable(); + alloc(ptr,LENGTH); + addmapping(dstring,ptr,"Disk"); + doanalysis(); + dealloc(ptr); + chunmountdisk(ptr); + } + struct block * ptr=mountdisk("disk"); + for(int i=145;i>=0;i--) { + char filename[10]; + sprintf(filename,"fil%d",i); + openfile(ptr,filename); + } + for(int j=0;j<6000;j++) { + for(int i=145;i>=0;i--) { + char name[10]; + int len=sprintf(name, "%d ",i); + writefile(ptr,i,name,len); + } + } + for(int i=145;i>=0;i--) { + closefile(ptr,i); + } + for(int i=145;i>=0;i--) { + char filename[10]; + sprintf(filename,"fil%d",i); + openfile(ptr,filename); + } + for(int j=0;j<400;j++) { + for(int i=145;i>=0;i--) { + int l=0; + char name[10]; + int len=sprintf(name, "%d ",i); + readfile(ptr,i,name,len); + sscanf(name, "%d ", &l); + if (l!=i) { + printf("ERROR in benchmark\n"); + } + } + } + for(int i=145;i>=0;i--) { + closefile(ptr,i); + } + unmountdisk(ptr); + } + } +} + +struct block * chmountdisk(char *filename) { + int fd=open(filename,O_CREAT|O_RDWR); + struct block *ptr=(struct block *) mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0); + return ptr; +} + +void chunmountdisk(struct block *vptr) { + int val=munmap(vptr,LENGTH); +} + +struct block * mountdisk(char *filename) { + int fd=open(filename,O_CREAT|O_RDWR); + struct block *ptr=(struct block *) mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0); + struct SuperBlock *sb=(struct SuperBlock *) &ptr[0]; + struct GroupBlock *gb=(struct GroupBlock *) &ptr[1]; + bbbptr=gb->BlockBitmapBlock; + ibbptr=gb->InodeBitmapBlock; + itbptr=gb->InodeTableBlock; + rdiptr=sb->RootDirectoryInode; + + struct InodeBitmap *ibb=(struct InodeBitmap *) &ptr[ibbptr]; + for(int i=0;i<(NUMINODES/8+1);i++) + ib.inode[i]=ibb->inode[i]; + struct BlockBitmap *bbb=(struct BlockBitmap *) &ptr[bbbptr]; + for(int i=0;i<(NUMBLOCK/8+1);i++) + bb.blocks[i]=bbb->blocks[i]; + return ptr; +} + +void unmountdisk(struct block *vptr) { + struct InodeBitmap *ibb=(struct InodeBitmap *) &vptr[ibbptr]; + for(int i=0;i<(NUMINODES/8+1);i++) + ibb->inode[i]=ib.inode[i]; + + struct BlockBitmap *bbb=(struct BlockBitmap *) &vptr[bbbptr]; + for(int i=0;i<(NUMBLOCK/8+1);i++) + bbb->blocks[i]=bb.blocks[i]; + int val=munmap(vptr,LENGTH); +} + +void printdirectory(struct block *ptr) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + /* lets finish */ + printf("%s %d inode %d bytes\n",db->entries[j].name, db->entries[j].inodenumber,itb->entries[db->entries[j].inodenumber].filesize); + } + } + } +} + +void printfile(char *filename, struct block *ptr) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename,db->entries[j].name)==0) { + /* Found file */ + int inode=db->entries[j].inodenumber; + + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<((itb->entries[inode].filesize+BLOCKSIZE-1)/BLOCKSIZE);i++) { + struct block *b=&ptr[itb->entries[inode].Blockptr[i]]; + write(0,b,BLOCKSIZE); + } + } + } + } + } +} + +void removefile(char *filename, struct block *ptr) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename,db->entries[j].name)==0) { + /* Found file */ + db->entries[j].name[0]=0; //Delete entry + int inode=db->entries[j].inodenumber; + + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + itb->entries[inode].referencecount--; + + if (itb->entries[inode].referencecount==0) { + for(int i=0;i<((itb->entries[inode].filesize+BLOCKSIZE-1)/BLOCKSIZE);i++) { + int blocknum=itb->entries[inode].Blockptr[i]; + bb.blocks[blocknum/8]^=(1<<(blocknum%8)); + } + ib.inode[inode/8]^=(1<<(inode%8)); + } + } + } + } + } +} + +void createlink(struct block *ptr,char *filename, char *linkname) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename,db->entries[j].name)==0) { + /* Found file */ + int inode=db->entries[j].inodenumber; + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + itb->entries[inode].referencecount++; + addtode(ptr, inode, linkname); + } + } + } + } +} + +void closefile(struct block *ptr, int fd) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + + + msync(&itb->entries[fd],sizeof(DirectoryEntry),MS_SYNC); + files[fd].used=false; +} + +bool writefile(struct block *ptr, int fd, char *s) { + return (writefile(ptr,fd,s,1)==1); +} + +int writefile(struct block *ptr, int fd, char *s, int len) { + struct filedesc *tfd=&files[fd]; + if (tfd->used==false) + return -1; + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + int filelen=itb->entries[tfd->inode].filesize; + if ((12*BLOCKSIZE-tfd->offset)offset; + for(int i=0;ioffset/BLOCKSIZE; + int noffset=tfd->offset%BLOCKSIZE; + if (tfd->offset>=filelen) { + if (noffset==0) { + int bptr=getblock(ptr); + if (bptr==-1) { + if (itb->entries[files[fd].inode].filesizeentries[files[fd].inode].filesize=files[fd].offset; + return i; + } + itb->entries[tfd->inode].Blockptr[nbuffer]=bptr; + } + } + int block=itb->entries[tfd->inode].Blockptr[nbuffer]; + char *fchar=(char *)&ptr[block]; + int tocopy=len-i; + if (tocopy>(BLOCKSIZE-noffset)) + tocopy=BLOCKSIZE-noffset; + memcpy(&fchar[noffset],&s[i],tocopy); + msync(&fchar[noffset],tocopy,MS_SYNC); + i+=tocopy; + tfd->offset+=tocopy; + } + if (itb->entries[files[fd].inode].filesizeentries[files[fd].inode].filesize=files[fd].offset; + return len; +} + + +char readfile(struct block *ptr, int fd) { + char array[1]; + if (readfile(ptr,fd,array,1)==1) + return array[0]; + else + return EOF; +} + +int readfile(struct block *ptr, int fd, char *buf, int len) { + struct filedesc *tfd=&files[fd]; + if (tfd->used==false) + return -1; + + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + int filelen=itb->entries[tfd->inode].filesize; + if ((filelen-tfd->offset)offset; + for(int i=0;ioffset/BLOCKSIZE; + int noffset=tfd->offset%BLOCKSIZE; + int block=itb->entries[tfd->inode].Blockptr[nbuffer]; + char *fchar=(char *)&ptr[block]; + int tocopy=len-i; + if (tocopy>(BLOCKSIZE-noffset)) + tocopy=BLOCKSIZE-noffset; + memcpy(&buf[i],&fchar[noffset],tocopy); + i+=tocopy; + tfd->offset+=tocopy; + } + return len; +} + +int openfile(struct block *ptr, char *filename) { + /* Locate fd */ + int fd=-1; + for(int k=0;kentries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]!=0) { + if(strcmp(filename,db->entries[j].name)==0) { + files[fd].inode=db->entries[j].inodenumber; + files[fd].offset=0; + return fd; + } + } + } + } + /* Create file */ + + int inode=getinode(ptr); + if (inode==-1) { + files[fd].used=false; + return -1; + } + itb->entries[inode].filesize=0; + itb->entries[inode].referencecount=1; + + addtode(ptr, inode, filename); + files[fd].inode=inode; + files[fd].offset=0; + return fd; +} + +void createfile(struct block *ptr,char *filename, char *buf,int buflen) { + int fd=openfile(ptr,filename); + writefile(ptr,fd,buf,buflen); + closefile(ptr,fd); +} + +void addtode(struct block *ptr, int inode, char * filename) { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[itbptr]; + for(int i=0;i<12;i++) { + struct DirectoryBlock *db=(struct DirectoryBlock *) &ptr[itb->entries[rdiptr].Blockptr[i]]; + for(int j=0;jentries[j].name[0]==0) { + /* lets finish */ + strncpy(db->entries[j].name,filename,124); + db->entries[j].inodenumber=inode; + msync(&db->entries[j],sizeof(DirectoryEntry),MS_SYNC); + return; + } + } + } +} + +int getinode(struct block *ptr) { + for(int i=0;iFreeBlockCount=BLOCKSIZE-5; + sb->FreeInodeCount=NUMINODES-1; + sb->NumberofInodes=NUMINODES; + sb->NumberofBlocks=NUMBLOCK; + sb->RootDirectoryInode=0; + sb->blocksize=BLOCKSIZE; + } + { + struct GroupBlock * gb=(struct GroupBlock *) &ptr[1]; + gb->BlockBitmapBlock=2; + gb->InodeBitmapBlock=3; + gb->InodeTableBlock=4; + gb->GroupFreeBlockCount=BLOCKSIZE-5; + gb->GroupFreeInodeCount=NUMINODES-1; + } + { + struct BlockBitmap * bb=(struct BlockBitmap *) &ptr[2]; + for(int i=0;i<(5+12);i++) + bb->blocks[i/8]=bb->blocks[i/8]|(1<<(i%8)); + } + { + struct InodeBitmap * ib=(struct InodeBitmap *) &ptr[3]; + ib->inode[0]=1; + } + { + struct InodeBlock * itb=(struct InodeBlock *) &ptr[4]; + itb->entries[0].filesize=12*BLOCKSIZE; + for(int i=0;i<12;i++) + itb->entries[0].Blockptr[i]=i+5; + itb->entries[0].referencecount=1; + } + + int val=munmap(vptr,LENGTH); + if (val!=0) + printf("Error!\n"); +} + diff --git a/Repair/RepairInterpreter/file.h b/Repair/RepairInterpreter/file.h new file mode 100755 index 0000000..1dc3436 --- /dev/null +++ b/Repair/RepairInterpreter/file.h @@ -0,0 +1,104 @@ +#ifndef FILE_H +#define FILE_H + +#define BLOCKSIZE 8192 +#define NUMBLOCK 1024 +#define LENGTH BLOCKSIZE*NUMBLOCK +#define NUMINODES BLOCKSIZE/56 +#define NUMFILES 100 + +struct block { + char array[BLOCKSIZE]; +}; + + +struct SuperBlock { + int FreeBlockCount; + int FreeInodeCount; + int NumberofBlocks; + int NumberofInodes; + int RootDirectoryInode; + int blocksize; +}; + + +struct GroupBlock { + int BlockBitmapBlock; + int InodeBitmapBlock; + int InodeTableBlock; + int GroupFreeBlockCount; + int GroupFreeInodeCount; +}; + + +struct BlockBitmap { + char blocks[NUMBLOCK/8+1]; +}; + + +struct InodeBitmap { + char inode[NUMINODES/8+1]; +}; + + +struct Inode { + int filesize; + int Blockptr[12]; + int referencecount; +}; + + +//the inode table +struct InodeBlock { + struct Inode entries[NUMINODES]; +}; + + +#define DIRECTORYENTRYSIZE 128 +struct DirectoryEntry { + char name[124]; + int inodenumber; +}; + + + +struct DirectoryBlock { + struct DirectoryEntry entries[BLOCKSIZE/128]; +}; + + + + + +void createdisk(); +void createfile(struct block *ptr,char *filename, char *buf,int buflen); +void addtode(struct block *ptr, int inode, char * filename); +int getinode(struct block *ptr); +int getblock(struct block * ptr); + +void removefile(char *filename, struct block *ptr); +void createlink(struct block *ptr,char *filename, char *linkname); +struct block * chmountdisk(char *filename); +void chunmountdisk(struct block *vptr); +struct block * mountdisk(char *filename); +void unmountdisk(struct block *vptr); +void closefile(struct block *ptr, int fd); +bool writefile(struct block *ptr, int fd, char *s); +int writefile(struct block *ptr, int fd, char *s, int len); +char readfile(struct block *ptr, int fd); +int readfile(struct block *ptr, int fd, char *buf, int len); +int openfile(struct block *ptr, char *filename); + +void printdirectory(struct block *ptr); +void printfile(char *filename, struct block *ptr); +void printinodeblock(struct block* ptr); + + +#define MAXFILES 300 +struct filedesc { + int inode; + int offset; + bool used; +}; +#endif + diff --git a/Repair/RepairInterpreter/list.cc b/Repair/RepairInterpreter/list.cc new file mode 100755 index 0000000..df1371a --- /dev/null +++ b/Repair/RepairInterpreter/list.cc @@ -0,0 +1,35 @@ +#include "list.h" +//#include "dmalloc.h" + +List::List() { + array=new void*[INITIAL_LIST_SIZE]; + length=0; + arraysize=INITIAL_LIST_SIZE; +} + +List::~List() { + delete[](array); +} + +void List::addobject(void *object) { + if ((length+1)>arraysize) { + void **oldarray=array; + int oldarraysize=arraysize; + arraysize*=2; + array=new void*[arraysize]; + for(int i=0;i +#include +#include +#include +#include +#include "classlist.h" +#include "model.h" +#include "token.h" +#include "typeparser.h" +#include "dparser.h" +#include "aparser.h" +#include "cparser.h" +#include "oparser.h" +#include "rparser.h" +#include "dmodel.h" +#include "omodel.h" +#include "amodel.h" +#include "tmodel.h" +#include "list.h" +#include "processabstract.h" +#include "processobject.h" +#include "processconcrete.h" +#include "normalizer.h" +#include "Hashtable.h" +#include "element.h" +#include "bitreader.h" +#include "DefaultGuidance2.h" +#include "DefaultGuidance.h" +#include "DefaultGuidance3.h" +#include "repair.h" +#include "fieldcheck.h" +#include "tmap.h" +#include "string.h" +#include "set.h" +#include + +Hashtable * model::gethashtable() { + return env; +} + +bitreader * model::getbitreader() { + return br; +} + +Guidance * model::getguidance() { + return guidance; +} + +model::model(char *abstractfile, char *modelfile, char *spacefile, char *structfile, char *concretefile, char *rangefile) +{ + parsestructfile(structfile); + + + //Hashtable first for lookups + env=new Hashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings); + // env->put(&bstring,new Element(&badstruct,getstructure("arrayofstructs")));//should be of badstruct + parseabstractfile(abstractfile); + parsemodelfile(modelfile); + parsespacefile(spacefile); + parseconcretefile(concretefile); + // parserangefile(rangefile); + // committing out because of memory problems + + br=new bitreader(this,env); + guidance=new DefGuidance(this); // for the file system benchmark + +#ifdef REPAIR + repair=new Repair(this); + if (!repair->analyzetermination()) { +#ifdef DEBUGMESSAGES + printf("Constraint set might not terminate and can't be repaired!\n"); +#endif + exit(-1); + } + fc=new FieldCheck(this); + fc->buildmaps(); + fc->analyze(); +#endif + typmap=new typemap(this); +} + +void model::reset() { + // typmap->reset(); Don't rebuild trees + domainrelation->reset(); +} + +typemap * model::gettypemap() { + return typmap; +} + +Repair * model::getrepair() { + return repair; +} + +NormalForm * model::getnormalform(Constraint *c) { + for (int i=0;iisdelayed()) { + pa->setclean(); + pa->processrule(rulearray[i]); + if (pa->dirtyflagstatus()) + clean=true; + } + } + } while(clean); + + /* Then the delayed rules */ + do { + clean=false; + for(int i=0;iisdelayed()) { + pa->setclean(); + pa->processrule(rulearray[i]); + if (pa->dirtyflagstatus()) + clean=true; + } + } + } while(clean); + gettimeofday(&end,NULL); + time=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec; + printf("Time used for abstraction(us): %ld\n",time); + + pa->printstats(); +} + + +void model::triggerrule(Element *ele,char *set) { + for(int i=0;iisstatic()) { + pa->processrule(rulearray[i], ele, set); + } + } +} + + +// processes the external constraints +void model::doconcrete() { + struct timeval begin,end; + unsigned long time; + gettimeofday(&begin,NULL); + + processconcrete *pr=new processconcrete(this); + for(int i=0;iprocessrule(concretearray[i]); + } + gettimeofday(&end,NULL); + time=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec; + printf("Time used for concretization(us): %ld\n",time); + + pr->printstats(); + delete(pr); +} + + + +// inserts faults that break the specifications +void model::breakspec() +{ + srandom((unsigned) time(NULL)); + + processobject *po = new processobject(this); + + // takes each satisfied constraint and breaks it with probability prob_breakconstraint + for (int i=0; iissatisfied(c)) + if (random()breakconstraint(c); + } + + delete(po); +} + + + +// inserts faults that don not break the specifications +void model::inserterrors() +{ + printf("\nmodel::inserterrors CALLED\n\n"); + + srandom((unsigned) time(NULL)); + + processobject *po = new processobject(this); + + // takes each satisfied constraint and modifies it with probability prob_modifyconstraint + long int r; + for (int i=0; iprint(); + if (po->issatisfied(c)) + printf(" is satisfied\n"); + else printf(" is not satisfied\n"); + fflush(NULL); +#endif + if (po->issatisfied(c)) + { + r=random(); +#ifdef DEBUGMESSAGES + printf("r=%ld\n", r); +#endif + if (rmodifyconstraint(c); + } + } + + delete(po); +} + + + +// processes the internal constraints +// returns true only if no violated constraints were found +bool model::docheck() +{ + struct timeval begin,end; + unsigned long time; + bool found=false; + processobject *po=new processobject(this); + bool t=false; + gettimeofday(&begin,NULL); + + do { + t=false; + /* Process rules until we reach a fixpoint*/ + for(int i=0;iprocessconstraint(constraintarray[i])) + { + found=true; +#ifdef TOOL + break; +#endif + t=true; //Got to keep running + } + } + } while(t); + gettimeofday(&end,NULL); + time=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec; + printf("Time used for check(us): %ld\n",time); + po->printstats(); + delete(po); + //printf("return from docheck()"); + return found; +} + + +DomainRelation * model::getdomainrelation() { + return domainrelation; +} + + + +/* reads the testspace file, which keeps the sets and relations involved; + these sets and relations are managed by "domainrelation" */ +void model::parsespacefile(char *spacefile) { + ifstream *ifs=new ifstream(); + ifs->open(spacefile); + Reader *r=new Reader(ifs); + Dparser *p=new Dparser(r); + domainrelation=p->parsesetrelation(); + +#ifdef DEBUGMANYMESSAGES + domainrelation->print(); +#endif + + ifs->close(); + delete(ifs); +} + + + +/* reads the teststruct file, which keeps the structure definitions; + these definitions are kept in "structurearray" */ +void model::parsestructfile(char *structfile) { + ifstream *ifs=new ifstream(); + ifs->open(structfile); + Reader *r=new Reader(ifs); + Typeparser *p=new Typeparser(r); + List *list=new List(); + + do { + structure *st=p->parsestructure(); + if (st!=NULL) { + list->addobject(st); + +#ifdef DEBUGMANYMESSAGES + st->print(); +#endif + + } + else + break; + } while(true); + structurearray=new structure *[list->size()]; + list->toArray((void **)structurearray); + numstarray=list->size(); + + ifs->close(); + delete(list); + delete(ifs); +} + + +/* parses the testabstract file, which contains the model definition rules + these rules are kept in "rulearray" */ +void model::parseabstractfile(char *abstractfile) { + ifstream *ifs=new ifstream(); + ifs->open(abstractfile); + Reader *r=new Reader(ifs); + AParser *p=new AParser(r); + List *list=new List(); + int countstatic=0; + do { + Rule *ru=p->parserule(); + if (ru!=NULL) { + list->addobject(ru); + if(ru->isstatic()) + countstatic++; +#ifdef DEBUGMANYMESSAGES + ru->print(); +#endif + } + else + break; + } while(true); + rulearray=new Rule *[list->size()]; + list->toArray((void **)rulearray); + numrules=list->size(); + numrulenormal=countstatic; + rulenormal=new NormalForm *[countstatic]; + int count=0; + for(int i=0;iisstatic()) { + rulenormal[count++]=new NormalForm(rulearray[i]); + } + } + ifs->close(); + delete(ifs); + delete(list); +} + + + +/* parses the testconcrete file, which contains the external constraints; + these constraints are kept in "concretearray" */ +void model::parseconcretefile(char *abstractfile) { + ifstream *ifs=new ifstream(); + ifs->open(abstractfile); + Reader *r=new Reader(ifs); + CParser *p=new CParser(r); + List *list=new List(); + do { + Rule *ru=p->parserule(); + if (ru!=NULL) { + list->addobject(ru); +#ifdef DEBUGMANYMESSAGES + ru->print(); +#endif + } + else + break; + } while(true); + concretearray=new Rule *[list->size()]; + list->toArray((void **)concretearray); + numconcrete=list->size(); + + ifs->close(); + delete(ifs); + delete(list); +} + + + +/* parses the testmodel file, which contains the internal constraints + these constraints are kept in constraintarray; + the constraints in normal form are kept in constraintnormal */ +void model::parsemodelfile(char *modelfile) { + ifstream* ifs=new ifstream(); + ifs->open(modelfile); + Reader *r=new Reader(ifs); + Parser *p=new Parser(r); + List *list=new List(); + do { + Constraint *c=p->parseconstraint(); + if (c!=NULL) { + list->addobject(c); +#ifdef DEBUGMANYMESSAGES + c->print(); +#endif + } else + break; + } while(true); + + constraintarray=new Constraint *[list->size()]; + list->toArray((void **)constraintarray); + numconstraint=list->size(); + constraintnormal=new NormalForm *[list->size()]; + for(int i=0;isize();i++) + constraintnormal[i]=new NormalForm(constraintarray[i]); + + ifs->close(); + delete(ifs); + delete(list); +} + + + +/* reads the testrange file, which keeps the ranges of the relations + of the form "relation: A -> token". + This information is used only by the fault injection mechanism. + This file should be read only after the testspace file. +*/ +void model::parserangefile(char *rangefile) +{ + ifstream *ifs=new ifstream(); + ifs->open(rangefile); + Reader *r = new Reader(ifs); + RParser *rp = new RParser(r); + + do { + char* relation = rp->parserelation(); + + if (relation != NULL) + { +#ifdef DEBUGMANYMESSAGES + printf("Reading relation: %s\n", relation); + fflush(NULL); +#endif + + // find the given relation, whose range should be of type "token" + DRelation *drel = domainrelation->getrelation(relation); + if (strcmp(drel->getrange(), "token") != 0) + { + printf("Error! Range of %s should be of type token.", relation); + exit(0); + } + + WorkSet *ws = rp->parseworkset(); +#ifdef DEBUGMANYMESSAGES + printf("The range for %s is:\n", relation); + void *obj = ws->firstelement(); + while (obj) + { + printf("%s ", (char *) obj); + obj = ws->getnextelement(obj); + } + fflush(NULL); + printf("\n\n"); +#endif + drel->settokenrange(ws); + delete(relation); + } + else + break; + } while(true); + + ifs->close(); + delete(ifs); + delete(r); + delete(rp); +} + + + +structure * model::getstructure(char *name) { + for(int i=0;igetname())) { + /* got match */ + return structurearray[i]; + } + } + return NULL; +} + +FieldCheck * model::getfieldcheck() { + return fc; +} + +int model::getnumrulenormal() { + return numrulenormal; +} + +NormalForm * model::getrulenormal(int i) { + return rulenormal[i]; +} + +bool model::subtypeof(structure *sub,structure *super) { + while(sub!=NULL) { + if (sub==super) + return true; + if (sub->getsubtype()==NULL) + return false; + sub=getstructure(sub->getsubtype()->getname()); + } + printf("Error in subtypeof\n"); + return false; /* Should get here*/ +} diff --git a/Repair/RepairInterpreter/model.h b/Repair/RepairInterpreter/model.h new file mode 100755 index 0000000..bf2b9b1 --- /dev/null +++ b/Repair/RepairInterpreter/model.h @@ -0,0 +1,74 @@ +#ifndef MODEL_H +#define MODEL_H +#include "classlist.h" + +class model { + public: + model(char *abstractfile, char *modelfile, char *spacefile,char *structfile, char *concretefile, char *rangefile); + DomainRelation * getdomainrelation(); + structure *getstructure(char * name); + void doabstraction(); // processes the model definition rules + bool docheck(); // processes the internal constraints + void doconcrete(); // processes the external constraints + + void breakspec(); // inserts faults that break the specs + void inserterrors(); // inserts faults that do not break the specs + + NormalForm * getnormalform(Constraint *c); + Hashtable * gethashtable(); + bitreader * getbitreader(); + Guidance * getguidance(); + int getnumconstraints(); + Constraint * getconstraint(int i); + NormalForm * getnormalform(int i); + Repair *getrepair(); + FieldCheck * getfieldcheck(); + void triggerrule(Element *,char *); + int getnumrulenormal(); + NormalForm * getrulenormal(int i); + bool subtypeof(structure *sub,structure *super); + typemap * gettypemap(); + void reset(); + + static const double prob_breakconstraint = 1; // the probability with which each constraint is broken when inserting errors + static const double prob_breakpredicate = 1; // the probability with which each predicate from the selected sentences is broken + static const double prob_modifyconstraint = 1; // the probability with which each constraint is modified when inserting errors + static const double prob_breaksatisfiedsentence = 1; // the probability with which each satisfied sentence is modified (broken) when inserting errors + static const double prob_repairbrokensentence = 1; // the probability with which each broken sentence is modified (repaired) when inserting errors + + private: + void parsespacefile(char *spacefile); + void parsestructfile(char *structfile); + void parseabstractfile(char *abstractfile); + void parseconcretefile(char *concretefile); + void parsemodelfile(char *modelfile); + void parserangefile(char *rangefile); + + Hashtable *env; + bitreader *br; + Guidance * guidance; + Repair *repair; + FieldCheck *fc; + processabstract *pa; + + structure **structurearray; // the structure definitions + int numstarray; + + DomainRelation *domainrelation; // the sets and relations + + Rule **rulearray; // the model definition rules + int numrules; + NormalForm **rulenormal; // the model definition rules in normal form + int numrulenormal; + + Constraint **constraintarray; // the internal constraints + int numconstraint; + NormalForm **constraintnormal; // the internal constraints in normal form + + Rule **concretearray; // the external constraints + int numconcrete; + + + typemap * typmap; +}; +#endif diff --git a/Repair/RepairInterpreter/normalizer.cc b/Repair/RepairInterpreter/normalizer.cc new file mode 100755 index 0000000..e3d561c --- /dev/null +++ b/Repair/RepairInterpreter/normalizer.cc @@ -0,0 +1,348 @@ +// converts constraints into disjunctive normal form + +#include +#include "normalizer.h" +#include "omodel.h" +#include "processobject.h" +#include "set.h" +#include "amodel.h" +#include "common.h" + + + +// class CoercePredicate + +CoercePredicate::CoercePredicate(char *ts, char *lt, char *rs) { + triggerset=ts; + ltype=lt; + rtype=NULL; + relset=rs; + rule=false; + tuple=false; + predicate=NULL; +} + +CoercePredicate::CoercePredicate(char *ts, char *lt, char *rt,char *rs) { + triggerset=ts; + ltype=lt; + rtype=rt; + relset=rs; + rule=false; + tuple=true; + predicate=NULL; +} + +CoercePredicate::CoercePredicate(bool b, Predicate *p) { + rule=true; + coercebool=b; + predicate=p; +#ifdef REPAIR + if((p->gettype()==PREDICATE_EQ1|| + p->gettype()==PREDICATE_GTE1)&&coercebool==false) { + printf("Possible forcing size predicate to be false. Error!\n"); + exit(-1); + } +#endif +} + +Predicate * CoercePredicate::getpredicate() { + return predicate; +} + +bool CoercePredicate::isrule() { + return rule; +} + +bool CoercePredicate::istuple() { + return tuple; +} + +bool CoercePredicate::getcoercebool() { + return coercebool; +} + +char * CoercePredicate::gettriggerset() { + return triggerset; +} + +char * CoercePredicate::getrelset() { + return relset; +} + +char * CoercePredicate::getltype() { + return ltype; +} + +char * CoercePredicate::getrtype() { + return rtype; +} + + + + +// class CoerceSentence + +CoerceSentence::CoerceSentence(CoercePredicate **pred, int numpred) { + predicates=pred; + numpreds=numpred; +} + + +int CoerceSentence::getnumpredicates() { + return numpreds; +} + + +CoercePredicate * CoerceSentence::getpredicate(int i) { + return predicates[i]; +} + + + +// returns true iff the sentence is satisfied +bool CoerceSentence::issatisfied(processobject *po, Hashtable *env) +{ + for (int i=0; igetpredicate(); + if (!po->processpredicate(cp->getpredicate(),env)) + return false; + } + return true; +} + + +// returns how much we pay if we satisfy this sentence +int CoerceSentence::cost(processobject *po, Hashtable *env) { + int cost=0; + for(int i=0;igetpredicate()!=NULL) + pvalue=po->processpredicate(cp->getpredicate(),env); + if (pvalue!=cp->getcoercebool()) + cost+=costfunction(cp); + } + return cost; +} + + +CoerceSentence::~CoerceSentence() { + for(int i=0;igetstatement(),true); + this->length=sa->length; + this->sentences=sa->sentences; + this->c=c; + delete(sa); +} + +void NormalForm::fprint(FILE *f) { + if (c!=NULL) + c->fprint(f); +} + +NormalForm::NormalForm(Rule *r) { + int count=-1; + char *label, *triggerset; + c=NULL; + for(int i=0;inumquants();i++) { + AQuantifier *aq=r->getquant(i); + switch(aq->gettype()) { + case AQUANTIFIER_SING: + triggerset=aq->getset()->getname(); + label=aq->getleft()->label(); + break; + default: + break; + } + } + Statementb *sb=r->getstatementb(); + CoercePredicate *cp=NULL; + if(sb->gettype()==STATEMENTB_SING) { + cp=new CoercePredicate(triggerset,gettype(label,triggerset,sb->getleft()),sb->getsetlabel()->getname()); + } else { + cp=new CoercePredicate(triggerset,gettype(label,triggerset,sb->getleft()),gettype(label,triggerset,sb->getright()),sb->getsetlabel()->getname()); + } + CoercePredicate **cpa=new CoercePredicate*[1]; + cpa[0]=cp; + CoerceSentence *cs=new CoerceSentence(cpa,1); + sentences=new CoerceSentence*[1]; + sentences[0]=cs; + length=1; +} + + +char * gettype(char *label, char *set,AElementexpr *ae) { + switch(ae->gettype()) { + case AELEMENTEXPR_SUB: + case AELEMENTEXPR_ADD: + case AELEMENTEXPR_MULT: + case AELEMENTEXPR_DIV: + return "int"; + case AELEMENTEXPR_NULL: + return NULL; + case AELEMENTEXPR_FIELD: + case AELEMENTEXPR_FIELDARRAY: + return NULL; + case AELEMENTEXPR_LIT: + switch(ae->getliteral()->gettype()) { + case LITERAL_NUMBER: + return "int"; + case LITERAL_TOKEN: + return "token"; + default: + printf("error in normalizer.gettype()\n"); + exit(-1); + } + case AELEMENTEXPR_LABEL: + if (equivalentstrings(ae->getlabel()->label(),label)) + return set; + return NULL; + case AELEMENTEXPR_CAST: + return gettype(label,set,ae->getleft()); + } +} + + +int NormalForm::getnumsentences() { + return length; +} + + +CoerceSentence * NormalForm::getsentence(int i) { + return sentences[i]; +} + + +/* returns the sentence in this constraint that can be satisfied + with a minimum cost, and which is different from any sentence + in the "badsentences" structure */ +CoerceSentence * NormalForm::closestmatch(WorkSet *badsentences, processobject *po, Hashtable *env) { + int totalcost=-1; int bestmatch=-1; + for(int i=0;icontains(sentences[i])) + { + int cost=sentences[i]->cost(po,env); + if ((totalcost==-1)||(totalcost>cost)) { + totalcost=cost; + bestmatch=i; + } + } + } + return sentences[bestmatch]; +} + +int costfunction(CoercePredicate *p) { + return 1; +} + + +// computes the normal form of the given statement +SentenceArray * computesentences(Statement *st,bool stat) { + switch(st->gettype()) { + case STATEMENT_OR: { + SentenceArray *left=computesentences(st->getleft(),stat); + SentenceArray *right=computesentences(st->getright(),stat); + if (stat) { + CoerceSentence **combine=new CoerceSentence *[left->length+right->length]; + for(int i=0;ilength;i++) + combine[i]=left->sentences[i]; + for(int i=0;ilength;i++) + combine[i+left->length]=right->sentences[i]; + SentenceArray *sa=new SentenceArray(combine, left->length+right->length); + delete[](left->sentences);delete[](right->sentences); + delete(left);delete(right); + return sa; + } else { + CoerceSentence **combine=new CoerceSentence *[left->length*right->length]; + for(int i=0;ilength;i++) + for(int j=0;jlength;j++) { + CoerceSentence *leftsent=left->sentences[i]; + CoerceSentence *rightsent=right->sentences[j]; + CoercePredicate **preds=new CoercePredicate *[leftsent->getnumpredicates()+rightsent->getnumpredicates()]; + for(int il=0;ilgetnumpredicates();il++) + preds[il]=new CoercePredicate(leftsent->getpredicate(il)->getcoercebool(),leftsent->getpredicate(il)->getpredicate()); + for(int ir=0;irgetnumpredicates();ir++) + preds[ir+leftsent->getnumpredicates()]=new CoercePredicate(rightsent->getpredicate(ir)->getcoercebool(),rightsent->getpredicate(ir)->getpredicate()); + combine[i*right->length+j]=new CoerceSentence(preds,left->length*right->length); + } + SentenceArray *sa=new SentenceArray(combine, left->length*right->length); + for(int i=0;ilength;i++) + delete(left->sentences[i]); + for(int i=0;ilength;i++) + delete(right->sentences[i]); + delete(left->sentences);delete(right->sentences); + delete(left);delete(right); + return sa; + } + } + case STATEMENT_AND: { + SentenceArray *left=computesentences(st->getleft(),stat); + SentenceArray *right=computesentences(st->getright(),stat); + if (stat) { + CoerceSentence **combine=new CoerceSentence *[left->length*right->length]; + for(int i=0;ilength;i++) + for(int j=0;jlength;j++) { + CoerceSentence *leftsent=left->sentences[i]; + CoerceSentence *rightsent=right->sentences[j]; + CoercePredicate **preds=new CoercePredicate *[leftsent->getnumpredicates()+rightsent->getnumpredicates()]; + for(int il=0;ilgetnumpredicates();il++) + preds[il]=new CoercePredicate(leftsent->getpredicate(il)->getcoercebool(),leftsent->getpredicate(il)->getpredicate()); + for(int ir=0;irgetnumpredicates();ir++) + preds[ir+leftsent->getnumpredicates()]=new CoercePredicate(rightsent->getpredicate(ir)->getcoercebool(),rightsent->getpredicate(ir)->getpredicate()); + combine[i*right->length+j]=new CoerceSentence(preds,left->length*right->length); + } + SentenceArray *sa=new SentenceArray(combine, left->length*right->length); + for(int i=0;ilength;i++) + delete(left->sentences[i]); + for(int i=0;ilength;i++) + delete(right->sentences[i]); + delete(left->sentences);delete(right->sentences); + delete(left);delete(right); + return sa; + } else { + CoerceSentence **combine=new CoerceSentence *[left->length+right->length]; + for(int i=0;ilength;i++) + combine[i]=left->sentences[i]; + for(int i=0;ilength;i++) + combine[i+left->length]=right->sentences[i]; + SentenceArray *sa=new SentenceArray(combine, left->length+right->length); + delete(left->sentences);delete(right->sentences); + delete(left);delete(right); + return sa; + } + } + case STATEMENT_NOT: + return computesentences(st->getleft(),!stat); + case STATEMENT_PRED: + CoercePredicate *cp=new CoercePredicate(stat, st->getpredicate()); + CoercePredicate **cparray=new CoercePredicate *[1]; + cparray[0]=cp; + CoerceSentence *cs=new CoerceSentence(cparray,1); + CoerceSentence **csarray=new CoerceSentence *[1]; + csarray[0]=cs; + return new SentenceArray(csarray,1); + } +} + + + + +// class SentenceArray + +SentenceArray::SentenceArray(CoerceSentence **sentences, int l) { + length=l; + this->sentences=sentences; +} + diff --git a/Repair/RepairInterpreter/normalizer.h b/Repair/RepairInterpreter/normalizer.h new file mode 100755 index 0000000..401232f --- /dev/null +++ b/Repair/RepairInterpreter/normalizer.h @@ -0,0 +1,80 @@ +// converts constraints into disjunctive normal form + +#ifndef NORMALIZER_H +#define NORMALIZER_H +#include "classlist.h" +#include + + +class CoercePredicate { + public: + CoercePredicate(bool, Predicate *); + CoercePredicate(char *ts, char *lt, char *rs); + CoercePredicate(char *ts, char *lt, char *rt,char *rs); + Predicate * getpredicate(); + bool getcoercebool(); + bool isrule(); + bool istuple(); + char *gettriggerset(); + char *getrelset(); + char *getltype(); + char *getrtype(); + + private: + char *triggerset; + bool tuple; + char *ltype; + char *rtype; + char *relset; + bool rule; + bool coercebool; + Predicate *predicate; +}; + + + +class CoerceSentence { + public: + CoerceSentence(CoercePredicate **pred, int numpredicates); + int getnumpredicates(); + CoercePredicate *getpredicate(int i); + bool issatisfied(processobject *po, Hashtable *env); + int cost(processobject *po, Hashtable *env); + ~CoerceSentence(); + + private: + CoercePredicate **predicates; + int numpreds; +}; + + + +// represents a statement in normal form +class SentenceArray { + public: + SentenceArray(CoerceSentence **sentences, int l); + int length; + CoerceSentence **sentences; +}; + + +// represents a constraint in normal form +class NormalForm { + public: + NormalForm(Constraint *c); + CoerceSentence * closestmatch(WorkSet *,processobject *po,Hashtable *env); + int getnumsentences(); + CoerceSentence *getsentence(int i); + NormalForm(Rule *r); + void fprint(FILE *f); + private: + Constraint *c; /*keep reference for quantifiers */ + CoerceSentence **sentences; // the number of sentences in this constraint + int length; +}; + + +SentenceArray * computesentences(Statement *st,bool stat); +int costfunction(CoercePredicate *p); +char * gettype(char *label, char *set,AElementexpr *ae); +#endif diff --git a/Repair/RepairInterpreter/omodel.cc b/Repair/RepairInterpreter/omodel.cc new file mode 100755 index 0000000..e090af0 --- /dev/null +++ b/Repair/RepairInterpreter/omodel.cc @@ -0,0 +1,1017 @@ +// Defines the Internal Constraint Language + +#include +#include "omodel.h" +#include "common.h" +#include "model.h" +#include "Hashtable.h" +#include "dmodel.h" +#include "element.h" +#include "set.h" +#include "Relation.h" + + +// class Literal + +Literal::Literal(char *s) { + str=s; +} + + +// there are three types of literals: numbers, bools, and tokens +int Literal::gettype() { + int val; + if (sscanf(str,"%d",&val)==1) + return LITERAL_NUMBER; + else { + if (equivalentstrings(str,"true")|| + equivalentstrings(str,"false")) + return LITERAL_BOOL; + return LITERAL_TOKEN; + } +} + +bool Literal::getbool() { + if (equivalentstrings(str,"true")) + return true; + else + return false; +} + +int Literal::number() { + int val; + sscanf(str,"%d",&val); + return val; +} + +char * Literal::token() { + return str; +} + +void Literal::print() { + printf("%s",str); +} + +void Literal::fprint(FILE *f) { + fprintf(f,"%s",str); +} + + + + + + +// class Setlabel + +Setlabel::Setlabel(char *s) { + str=s; +} + +char * Setlabel::getname() { + return str; +} + +void Setlabel::print() { + printf("%s",str); +} + +void Setlabel::fprint(FILE *f) { + fprintf(f,"%s",str); +} + + + + + +// class Set + +// a set is either a label or a set of literals + +Set::Set(Setlabel *sl) { + type=SET_label; + setlabel=sl; +} + +int Set::getnumliterals() { + return numliterals; +} + +Literal * Set::getliteral(int i) { + return literals[i]; +} + +Set::Set(Literal **l, int nl) { + type=SET_literal; + literals=l; + numliterals=nl; +} + +Set::~Set() { + if (type==SET_label) + delete(setlabel); + if (type==SET_literal) { + for(int i=0;igetname(); +} + +void Set::print() { + switch(type) { + case SET_label: + setlabel->print(); + break; + case SET_literal: + printf("{"); + for(int i=0;iprint(); + } + printf("}"); + break; + } +} + +void Set::fprint(FILE *f) { + switch(type) { + case SET_label: + setlabel->fprint(f); + break; + case SET_literal: + fprintf(f,"{"); + for(int i=0;ifprint(f); + } + fprintf(f,"}"); + break; + } +} + + + + + + +// class Label + +Label::Label(char *s) { + str=s; +} + +void Label::print() { + printf("%s",str); +} + +void Label::fprint(FILE *f) { + fprintf(f,"%s",str); +} + + + + + +// class Relation + +Relation::Relation(char * r) { + str=r; +} + +char * Relation::getname() { + return str; +} + +void Relation::print() { + printf("%s",str); +} + +void Relation::fprint(FILE *f) { + fprintf(f,"%s",str); +} + + + + + +// class Quantifier + +Quantifier::Quantifier(Label *l, Set *s) { + label=l; + set=s; +} + +Label * Quantifier::getlabel() { + return label; +} + +Set * Quantifier::getset() { + return set; +} + +void Quantifier::print() { + printf("forall "); + label->print(); + printf(" in "); + set->print(); +} + +void Quantifier::fprint(FILE *f) { + fprintf(f,"forall "); + label->fprint(f); + fprintf(f," in "); + set->fprint(f); +} + + + + + + +// class Setexpr + +Setexpr::Setexpr(Setlabel *sl) { + setlabel=sl; + type=SETEXPR_LABEL; +} + +Setexpr::Setexpr(Label *l, bool invert, Relation *r) { + label=l; + type=invert?SETEXPR_INVREL:SETEXPR_REL; + relation=r; +} + +void Setexpr::print() { + switch(type) { + case SETEXPR_LABEL: + setlabel->print(); + break; + case SETEXPR_REL: + label->print(); + printf("."); + relation->print(); + break; + case SETEXPR_INVREL: + label->print(); + printf(".~"); + relation->print(); + break; + } +} + +void Setexpr::fprint(FILE *f) { + switch(type) { + case SETEXPR_LABEL: + setlabel->fprint(f); + break; + case SETEXPR_REL: + label->fprint(f); + fprintf(f,"."); + relation->fprint(f); + break; + case SETEXPR_INVREL: + label->fprint(f); + fprintf(f,".~"); + relation->fprint(f); + break; + } +} + + +void Setexpr::print_size(Hashtable *stateenv, model *m) +{ + switch(type) { + case SETEXPR_LABEL:{ + printf("sizeof("); + setlabel->print(); + printf(")="); + + DomainRelation *dr = m->getdomainrelation(); + Hashtable *env = m->gethashtable(); + DomainSet *dset = dr->getset(setlabel->getname()); + WorkSet *ws = dset->getset(); + + if (ws != NULL) + printf("%d", ws->size()); + else printf("0"); + break; + } + + case SETEXPR_REL:{ + printf("sizeof("); + label->print(); + printf("."); + relation->print(); + printf(")="); + + Element *key = (Element *) stateenv->get(label->label()); + + DomainRelation *dr = m->getdomainrelation(); + Hashtable *env = m->gethashtable(); + DRelation *rel = dr->getrelation(relation->getname()); + WorkRelation *wr = rel->getrelation(); + + WorkSet *ws = wr->getset(key); + + if (ws != NULL) + printf("%d", ws->size()); + else printf("0"); + break; + } + + case SETEXPR_INVREL:{ + printf("sizeof("); + label->print(); + printf(".~"); + relation->print(); + printf(")="); + + Element *key = (Element *) stateenv->get(label->label()); + + DomainRelation *dr = m->getdomainrelation(); + + Hashtable *env = m->gethashtable(); + DRelation *rel = dr->getrelation(relation->getname()); + WorkRelation *wr = rel->getrelation(); + + WorkSet *ws = wr->invgetset(key); + + if (ws != NULL) + printf("%d", ws->size()); + else printf("0"); + break; + } + } +} + + +void Setexpr::print_value(Hashtable *stateenv, model *m) +{ + switch(type) { + case SETEXPR_LABEL:{ + //printf(" "); + setlabel->print(); + printf("="); + + DomainRelation *dr = m->getdomainrelation(); + Hashtable *env = m->gethashtable(); + DomainSet *dset = dr->getset(setlabel->getname()); + + WorkSet *ws = dset->getset(); + ws->print(); + break; + } + + case SETEXPR_REL:{ + /* + printf(" sizeof("); + label->print(); + printf("."); + relation->print(); + printf(") = "); + + Element *key = (Element *) stateenv->get(label->label()); + + DomainRelation *dr = m->getdomainrelation(); + Hashtable *env = m->gethashtable(); + DRelation *rel = dr->getrelation(relation->getname()); + WorkRelation *wr = rel->getrelation(); + + WorkSet *ws = wr->getset(key); + + printf("%d\n", ws->size()); + */ + break; + } + + case SETEXPR_INVREL:{ + /* + printf(" sizeof("); + label->print(); + printf(".~"); + relation->print(); + printf(") = "); + + Element *key = (Element *) stateenv->get(label->label()); + + DomainRelation *dr = m->getdomainrelation(); + + Hashtable *env = m->gethashtable(); + DRelation *rel = dr->getrelation(relation->getname()); + WorkRelation *wr = rel->getrelation(); + + WorkSet *ws = wr->invgetset(key); + + printf("%d\n", ws->size()); + */ + break; + } + } +} + + +Setlabel * Setexpr::getsetlabel() { + return setlabel; +} + +Relation * Setexpr::getrelation() { + return relation; +} + +Label * Setexpr::getlabel() { + return label; +} + +int Setexpr::gettype() { + return type; +} + + + + + +// class Valueexpr + +Label * Valueexpr::getlabel() { + return label; +} + +int Valueexpr::gettype() { + return type; +} + +Relation * Valueexpr::getrelation() { + return relation; +} + +Valueexpr::Valueexpr(Label *l,Relation *r, bool inv) { + label=l;relation=r; + type=0;inverted=inv; +} + +Valueexpr::Valueexpr(Valueexpr *ve,Relation *r,bool inv) { + valueexpr=ve;relation=r; + type=1;inverted=inv; +} + +bool Valueexpr::getinverted() { + return inverted; +} + +void Valueexpr::print() { + switch(type) { + case 0: + label->print(); + printf("."); + if (inverted) + printf("~"); + relation->print(); + break; + case 1: + valueexpr->print(); + printf("."); + if (inverted) + printf("~"); + relation->print(); + break; + } +} + +void Valueexpr::fprint(FILE *f) { + switch(type) { + case 0: + label->fprint(f); + fprintf(f,"."); + if (inverted) + fprintf(f,"~"); + relation->fprint(f); + break; + case 1: + valueexpr->fprint(f); + fprintf(f,"."); + if (inverted) + fprintf(f,"~"); + relation->fprint(f); + break; + } +} + +Element * Valueexpr::get_value(Hashtable *stateenv, model *m) { + Element *key=NULL; + if (type==0) { + key = (Element *) stateenv->get(label->label()); + } else + key = valueexpr->get_value(stateenv,m); + + DomainRelation *dr = m->getdomainrelation(); + Hashtable *env = m->gethashtable(); + DRelation *rel = dr->getrelation(relation->getname()); + WorkRelation *wr = rel->getrelation(); + + if (inverted) + return (Element *) wr->invgetobj(key); + else + return (Element *) wr->getobj(key); + +} + +void Valueexpr::print_value(Hashtable *stateenv, model *m) { + this->print(); + printf("="); + Element *elem = this->get_value(stateenv,m); + elem->print(); + //printf("\n"); +} + +Valueexpr * Valueexpr::getvalueexpr() { + return valueexpr; +} + + + + + +// class Elementexpr + +int Elementexpr::gettype() { + return type; +} + +Relation * Elementexpr::getrelation() { + return relation; +} + +Elementexpr::Elementexpr(Elementexpr *l,Relation *r) { + type=ELEMENTEXPR_RELATION; + left=l; + relation=r; +} + +Setexpr * Elementexpr::getsetexpr() { + return setexpr; +} + +Elementexpr::Elementexpr(Setexpr *se) { + setexpr=se; + type=ELEMENTEXPR_SETSIZE; +} + +Label * Elementexpr::getlabel() { + return label; +} + +Elementexpr * Elementexpr::getleft() { + return left; +} + +Elementexpr * Elementexpr::getright() { + return right; +} + +Literal * Elementexpr::getliteral() { + return literal; +} + +Elementexpr::Elementexpr(Elementexpr *l, Elementexpr *r, int op) { + left=l;right=r;type=op; +} + +Elementexpr::Elementexpr(Literal *lit) { + literal=lit; + type=ELEMENTEXPR_LIT; +} + +Elementexpr::Elementexpr(Label *lab) { + label=lab; + type=ELEMENTEXPR_LABEL; +} + +void Elementexpr::print() { + switch(type) { + case ELEMENTEXPR_LABEL: + label->print(); + break; + case ELEMENTEXPR_SUB: + left->print(); + printf("-"); + right->print(); + break; + case ELEMENTEXPR_ADD: + left->print(); + printf("+"); + right->print(); + break; + case ELEMENTEXPR_MULT: + left->print(); + printf("*"); + right->print(); + break; + case ELEMENTEXPR_LIT: + literal->print(); + break; + case ELEMENTEXPR_SETSIZE: + printf("sizeof("); + setexpr->print(); + printf(")"); + break; + case ELEMENTEXPR_RELATION: + left->print(); + printf("."); + relation->print(); + break; + } +} + +void Elementexpr::fprint(FILE *f) { + switch(type) { + case ELEMENTEXPR_LABEL: + label->fprint(f); + break; + case ELEMENTEXPR_SUB: + left->fprint(f); + fprintf(f,"-"); + right->fprint(f); + break; + case ELEMENTEXPR_ADD: + left->fprint(f); + fprintf(f,"+"); + right->fprint(f); + break; + case ELEMENTEXPR_MULT: + left->fprint(f); + fprintf(f,"*"); + right->fprint(f); + break; + case ELEMENTEXPR_LIT: + literal->fprint(f); + break; + case ELEMENTEXPR_SETSIZE: + fprintf(f,"sizeof("); + setexpr->fprint(f); + fprintf(f,")"); + break; + case ELEMENTEXPR_RELATION: + left->fprint(f); + fprintf(f,"."); + relation->fprint(f); + break; + } +} + + +void Elementexpr::print_value(Hashtable *stateenv, model *m) { + switch(type) { + case ELEMENTEXPR_SUB: + case ELEMENTEXPR_ADD: + case ELEMENTEXPR_MULT: + left->print_value(stateenv, m); + right->print_value(stateenv, m); + break; + case ELEMENTEXPR_SETSIZE: + setexpr->print_size(stateenv, m); + break; + case ELEMENTEXPR_RELATION: + /* + left->print(); + printf("."); + relation->print(); + */ + break; + } +} + + + +// class Predicate + +Predicate::Predicate(Valueexpr *ve, int t, Elementexpr *ee) { + valueexpr=ve; + type=t; + elementexpr=ee; +} + +Predicate::Predicate(Label *l,Setexpr *se) { + label=l; + setexpr=se; + type=PREDICATE_SET; +} + +Predicate::Predicate(bool greaterthan, Setexpr *se) { + if (greaterthan) + type=PREDICATE_GTE1; + else + type=PREDICATE_EQ1; + setexpr=se; +} + +Valueexpr * Predicate::getvalueexpr() { + return valueexpr; +} + +Elementexpr * Predicate::geteleexpr() { + return elementexpr; +} + +Label * Predicate::getlabel() { + return label; +} + +Setexpr * Predicate::getsetexpr() { + return setexpr; +} + +int Predicate::gettype() { + return type; +} + +void Predicate::print() { + switch(type) { + case PREDICATE_LT: + valueexpr->print(); + printf("<"); + elementexpr->print(); + break; + case PREDICATE_LTE: + valueexpr->print(); + printf("<="); + elementexpr->print(); + break; + case PREDICATE_EQUALS: + valueexpr->print(); + printf("="); + elementexpr->print(); + break; + case PREDICATE_GTE: + valueexpr->print(); + printf(">="); + elementexpr->print(); + break; + case PREDICATE_GT: + valueexpr->print(); + printf(">"); + elementexpr->print(); + break; + case PREDICATE_SET: + label->print(); + printf(" in "); + setexpr->print(); + break; + case PREDICATE_EQ1: + case PREDICATE_GTE1: + printf("sizeof("); + setexpr->print(); + if (type==PREDICATE_EQ1) + printf(")=1"); + if (type==PREDICATE_GTE1) + printf(")>=1"); + break; + } +} + +void Predicate::fprint(FILE *f) { + switch(type) { + case PREDICATE_LT: + valueexpr->fprint(f); + fprintf(f,"<"); + elementexpr->fprint(f); + break; + case PREDICATE_LTE: + valueexpr->fprint(f); + fprintf(f,"<="); + elementexpr->fprint(f); + break; + case PREDICATE_EQUALS: + valueexpr->fprint(f); + fprintf(f,"="); + elementexpr->fprint(f); + break; + case PREDICATE_GTE: + valueexpr->fprint(f); + fprintf(f,">="); + elementexpr->fprint(f); + break; + case PREDICATE_GT: + valueexpr->fprint(f); + fprintf(f,">"); + elementexpr->fprint(f); + break; + case PREDICATE_SET: + label->fprint(f); + fprintf(f," in "); + setexpr->fprint(f); + break; + case PREDICATE_EQ1: + case PREDICATE_GTE1: + fprintf(f,"sizeof("); + setexpr->fprint(f); + if (type==PREDICATE_EQ1) + fprintf(f,")=1"); + if (type==PREDICATE_GTE1) + fprintf(f,")>=1"); + break; + } +} + + + +void Predicate::print_sets(Hashtable *stateenv, model *m) { + switch(type) { + case PREDICATE_LT: + case PREDICATE_LTE: + case PREDICATE_EQUALS: + case PREDICATE_GTE: + case PREDICATE_GT: + valueexpr->print_value(stateenv, m); + printf("; "); + elementexpr->print_value(stateenv, m); + break; + case PREDICATE_SET: + setexpr->print_value(stateenv, m); + break; + case PREDICATE_EQ1: + case PREDICATE_GTE1: + setexpr->print_size(stateenv, m); + break; + } +} + + + + + +// class Statement + +Statement::Statement(Statement *l, Statement *r, int t) { + left=l; + right=r; + type=t; +} + +Statement::Statement(Statement *l) { + type=STATEMENT_NOT; + left=l; +} + +Statement::Statement(Predicate *p) { + pred=p; + type=STATEMENT_PRED; +} + +void Statement::print() { + switch(type) { + case STATEMENT_OR: + left->print(); + printf(" OR "); + right->print(); + break; + case STATEMENT_AND: + left->print(); + printf(" AND "); + right->print(); + break; + case STATEMENT_NOT: + printf("!"); + left->print(); + break; + case STATEMENT_PRED: + pred->print(); + break; + } +} + +void Statement::fprint(FILE *f) { + switch(type) { + case STATEMENT_OR: + left->fprint(f); + fprintf(f," OR "); + right->fprint(f); + break; + case STATEMENT_AND: + left->fprint(f); + fprintf(f," AND "); + right->fprint(f); + break; + case STATEMENT_NOT: + fprintf(f,"!"); + left->fprint(f); + break; + case STATEMENT_PRED: + pred->fprint(f); + break; + } +} + + +void Statement::print_sets(Hashtable *stateenv, model *m) { + switch(type) { + case STATEMENT_OR: + case STATEMENT_AND: + left->print_sets(stateenv, m); + printf("; "); + right->print_sets(stateenv, m); + break; + case STATEMENT_NOT: + left->print_sets(stateenv, m); + break; + case STATEMENT_PRED: + pred->print_sets(stateenv, m); + break; + } + //printf("\n"); +} + + +int Statement::gettype() { + return type; +} + +Statement* Statement::getleft() { + return left; +} + +Statement* Statement::getright() { + return right; +} + +Predicate * Statement::getpredicate() { + return pred; +} + + + + + + +// class Constraint + +Constraint::Constraint() { + quantifiers=NULL; + numquantifiers=0; + statement=NULL; +} + +void Constraint::setcrash(bool c) { + crash=c; +} + +bool Constraint::getcrash() { + return crash; +} + +Constraint::Constraint(Quantifier **q, int nq) { + quantifiers=q; + numquantifiers=nq; + statement=NULL; +} + +void Constraint::setstatement(Statement *s) { + statement=s; +} + +int Constraint::numquants() { + return numquantifiers; +} + +Quantifier * Constraint::getquant(int i) { + return quantifiers[i]; +} + +Statement * Constraint::getstatement() { + return statement; +} + +void Constraint::print() { + printf("["); + for(int i=0;iprint(); + } + printf("], "); + if (statement!=NULL) { + statement->print(); + } + printf("\n"); +} + +void Constraint::fprint(FILE *f) { + printf("["); + for(int i=0;ifprint(f); + } + printf("],"); + if (statement!=NULL) { + statement->fprint(f); + } +} diff --git a/Repair/RepairInterpreter/omodel.h b/Repair/RepairInterpreter/omodel.h new file mode 100755 index 0000000..8e7b616 --- /dev/null +++ b/Repair/RepairInterpreter/omodel.h @@ -0,0 +1,301 @@ +// Defines the Internal Constraint Language + + +#ifndef ObjectModel_H +#define ObjectModel_H +#include +#include +#include "classlist.h" + + +#define LITERAL_NUMBER 1 +#define LITERAL_TOKEN 2 +#define LITERAL_BOOL 3 + + +class Literal { + public: + Literal(char *s); + bool getbool(); + int gettype(); + int number(); + char * token(); + void print(); + void fprint(FILE *f); + + private: + char *str; +}; + + + + +class Setlabel { + public: + Setlabel(char *s); + char * getname(); + void print(); + void fprint(FILE *f); + private: + char *str; +}; + + + + + +#define SET_label 0 +#define SET_literal 1 + +class Set { + public: + Set(Setlabel *sl); + Set(Literal **l, int nl); + ~Set(); + void fprint(FILE *f); + void print(); + int gettype(); + char * getname(); + int getnumliterals(); + Literal * getliteral(int i); + private: + int type; + Setlabel *setlabel; + int numliterals; + Literal **literals; +}; + + + + + +class Label { + public: + Label(char *s); + void print(); + void fprint(FILE *f); + char* label() { + return str; + } + + private: + char *str; +}; + + + + + +class Relation { + public: + Relation(char * r); + void print(); + void fprint(FILE *f); + char * getname(); + + private: + char *str; +}; + + + + + +class Quantifier { + public: + Quantifier(Label *l, Set *s); + void print(); + void fprint(FILE *f); + Label * getlabel(); + Set * getset(); + + private: + Label *label; + Set *set; +}; + + + + + + +#define SETEXPR_LABEL 1 +#define SETEXPR_REL 2 +#define SETEXPR_INVREL 3 + +class Setexpr { + public: + Setexpr(Setlabel *sl); + Setexpr(Label *l, bool invert, Relation *r); + void print(); + void fprint(FILE *f); + void print_size(Hashtable *stateenv, model *m); + void print_value(Hashtable *stateenv, model *m); + Setlabel * getsetlabel(); + Relation * getrelation(); + Label * getlabel(); + int gettype(); + + private: + int type; + Setlabel *setlabel; + Label *label; + Relation *relation; +}; + + + + + + +class Valueexpr { + public: + Valueexpr(Label *l,Relation *r, bool inv); + Valueexpr(Valueexpr *ve,Relation *r, bool inv); + void print(); + void fprint(FILE *f); + void print_value(Hashtable *stateenv, model *m); + Element * get_value(Hashtable *stateenv, model *m); + int gettype(); + Label * getlabel(); + Valueexpr * getvalueexpr(); + Relation * getrelation(); + bool getinverted(); + + private: + int type; + bool inverted; + Label *label; + Valueexpr *valueexpr; + Relation *relation; +}; + + + + + + +#define ELEMENTEXPR_LABEL 1 +#define ELEMENTEXPR_SUB 2 +#define ELEMENTEXPR_ADD 3 +#define ELEMENTEXPR_MULT 4 +#define ELEMENTEXPR_LIT 5 +#define ELEMENTEXPR_SETSIZE 6 +#define ELEMENTEXPR_RELATION 11 + +class Elementexpr { + public: + Elementexpr(Setexpr *se); + Elementexpr(Elementexpr *l, Elementexpr *r, int op); + Elementexpr(Literal *lit); + Elementexpr(Label *lab); + Elementexpr(Elementexpr *l,Relation *r); + void print(); + void fprint(FILE *f); + void print_value(Hashtable *stateenv, model *m); + + int gettype(); + Label * getlabel(); + Elementexpr *getleft(); + Elementexpr *getright(); + Literal * getliteral(); + Setexpr * getsetexpr(); + Relation * getrelation(); + + private: + int type; + Relation *relation; + Elementexpr *left, *right; + Label *label; + Literal *literal; + Setexpr *setexpr; +}; + + + + + +#define PREDICATE_LT 1 +#define PREDICATE_LTE 2 +#define PREDICATE_EQUALS 3 +#define PREDICATE_GTE 4 +#define PREDICATE_GT 5 +#define PREDICATE_SET 6 +#define PREDICATE_EQ1 7 +#define PREDICATE_GTE1 8 + +class Predicate { + public: + Predicate(Valueexpr *ve, int t, Elementexpr *ee); + Predicate(Label *l,Setexpr *se); + Predicate(bool greaterthan, Setexpr *se); + void print(); + void fprint(FILE *f); + void print_sets(Hashtable *stateenv, model *m); + int gettype(); + Valueexpr * getvalueexpr(); + Elementexpr * geteleexpr(); + Label * getlabel(); + Setexpr * getsetexpr(); + private: + int type; + Valueexpr *valueexpr; + Elementexpr *elementexpr; + Label *label; + Setexpr *setexpr; +}; + + + + + + +#define STATEMENT_OR 1 +#define STATEMENT_AND 2 +#define STATEMENT_NOT 3 +#define STATEMENT_PRED 4 + +class Statement { + public: + Statement(Statement *l, Statement *r, int t); + Statement(Statement *l); + Statement(Predicate *p); + void print(); + void fprint(FILE *f); + void print_sets(Hashtable *env, model *m); // prints the sets and the relations involved in the statement + int gettype(); + Statement *getleft(); + Statement *getright(); + Predicate *getpredicate(); + private: + int type; + Statement *left,*right; + Predicate *pred; +}; + + + + + + +class Constraint { + public: + Constraint(); + Constraint(Quantifier **q, int nq); + void setstatement(Statement *s); + void print(); + void fprint(FILE *f); + int numquants(); + Quantifier * getquant(int i); + Statement * getstatement(); + void setcrash(bool c); + bool getcrash(); + private: + bool crash; + int numquantifiers; + Quantifier **quantifiers; + Statement *statement; +}; + + +#endif diff --git a/Repair/RepairInterpreter/oparser.cc b/Repair/RepairInterpreter/oparser.cc new file mode 100755 index 0000000..ed93e45 --- /dev/null +++ b/Repair/RepairInterpreter/oparser.cc @@ -0,0 +1,411 @@ +#include +#include +#include +#include "oparser.h" +#include "omodel.h" +#include "list.h" +#include "common.h" +#include "token.h" + + +Constraint * Parser::parseconstraint() { + Token token=reader->peakahead(); + while(token.token_type==TOKEN_EOL) { + skiptoken(); + token=reader->peakahead(); + } + if (token.token_type==TOKEN_EOF) + return NULL; + bool crash=false; + if (token.token_type==TOKEN_CRASH) { + crash=true; + skiptoken(); + } + Constraint *c; + /*Get Quantifiers*/ + if (token.token_type==TOKEN_OPENBRACK) { + skiptoken(); + c=parsequantifiers(); + needtoken(TOKEN_COMMA); + } else c=new Constraint(); + /*Peek ahead to see if sizeof*/ + c->setcrash(crash); + c->setstatement(parsestatement(false)); + return c; +} + +Statement * Parser::parsestatement(bool flag) { + Statement * oldst=NULL; + int joinflag=-1; + while(true) { + Token token=reader->peakahead(); + switch(token.token_type) { + case TOKEN_EOL: + skiptoken(); + return oldst; + case TOKEN_OPENPAREN: + { + skiptoken(); + Statement *st=parsestatement(false); + if (flag) + return st; + if (oldst==NULL) { + oldst=st; + } else { + if (joinflag==TOKEN_AND) { + oldst=new Statement(oldst, st, STATEMENT_AND); + } else if (joinflag==TOKEN_OR) { + oldst=new Statement(oldst, st, STATEMENT_OR); + } else { + error(); + } + joinflag=-1; + } + } + break; + case TOKEN_CLOSEPAREN: + skiptoken(); + return oldst; + case TOKEN_AND: + skiptoken(); + if (oldst==NULL) error(); + joinflag=TOKEN_AND; + break; + case TOKEN_OR: + skiptoken(); + if (oldst==NULL) error(); + joinflag=TOKEN_OR; + break; + case TOKEN_NOT: + { + skiptoken(); + Statement * st=new Statement(parsestatement(true)); + if (flag) + return st; + if (oldst==NULL) { + oldst=st; + } else { + if (joinflag==TOKEN_AND) { + oldst=new Statement(oldst, st, STATEMENT_AND); + } else if (joinflag==TOKEN_OR) { + oldst=new Statement(oldst, st, STATEMENT_OR); + } else { + error(); + } + joinflag=-1; + } + } + break; + default: + { + Statement * st=new Statement(parsepredicate()); + if (flag) return st; + if (oldst==NULL) { + oldst=st; + } else { + if (joinflag==TOKEN_AND) { + oldst=new Statement(oldst, st, STATEMENT_AND); + } else if (joinflag==TOKEN_OR) { + oldst=new Statement(oldst, st, STATEMENT_OR); + } + joinflag=-1; + } + } + } + } +} + +Elementexpr * Parser::parseelementexpr() { + Elementexpr *oldee=NULL; + int joinop=-1; + while(true) { + Token t=reader->peakahead(); + switch(t.token_type) { + case TOKEN_SIZEOF: + { + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + needtoken(TOKEN_OPENPAREN); + Setexpr* se=parsesetexpr(); + needtoken(TOKEN_CLOSEPAREN); + if (oldee==NULL) + oldee=new Elementexpr(se); + else { + if (joinop!=-1) { + oldee=new Elementexpr(oldee,new Elementexpr(se),joinop); + joinop=-1; + } else error(); + } + break; + } + case TOKEN_LITERAL: + { + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + needtoken(TOKEN_OPENPAREN); + Token literal=reader->readnext(); + needtoken(TOKEN_CLOSEPAREN); + if (oldee==NULL) + oldee=new Elementexpr(new Literal(copystr(literal.str))); + else { + if (joinop!=-1) { + oldee=new Elementexpr(oldee,new Elementexpr(new Literal(copystr(literal.str))),joinop); + joinop=-1; + } else error(); + } + break; + } + /* case TOKEN_PARAM: + { + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + needtoken(TOKEN_OPENPAREN); + Elementexpr *ee=parseelementexpr(); + needtoken(TOKEN_COMMA); + Token number=reader->readnext(); + needtoken(TOKEN_CLOSEPAREN); + + if (oldee==NULL) + oldee=new Elementexpr(ee,new Literal(copystr(number.str))); + else { + if (joinop!=-1) { + oldee=new Elementexpr(oldee,new Elementexpr(ee,new Literal(copystr(number.str))),joinop); + joinop=-1; + } else error(); + } + + break; + } */ + case TOKEN_OPENPAREN: + { + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + Elementexpr *ee=parseelementexpr(); + if (oldee==NULL) + oldee=ee; + else { + if (joinop!=-1) { + oldee=new Elementexpr(oldee,ee,joinop); + joinop=-1; + } else error(); + } + break; + } + case TOKEN_CLOSEPAREN: + skiptoken(); + return oldee; + break; + case TOKEN_SUB: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=ELEMENTEXPR_SUB; + else + error(); + break; + case TOKEN_ADD: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=ELEMENTEXPR_ADD; + else + error(); + break; + case TOKEN_MULT: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=ELEMENTEXPR_MULT; + else + error(); + break; + default: + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + if (oldee==NULL) + oldee=checkdot(new Elementexpr(new Label(copystr(t.str)))); + else { + if (joinop!=-1) { + oldee=new Elementexpr(oldee,new Elementexpr(new Label(copystr(t.str))),joinop); + joinop=-1; + } else error(); + } + } + } +} + +Elementexpr * Parser::checkdot(Elementexpr * incoming) { + Token tdot=reader->peakahead(); + if (tdot.token_type!=TOKEN_DOT) return incoming; + skiptoken(); + Token tfield=reader->readnext(); + Token tpeak=reader->peakahead(); + return checkdot(new Elementexpr(incoming, new Relation(copystr(tfield.str)))); +} + +Predicate * Parser::parsepredicate() { + Token label=reader->readnext(); + + if (label.token_type==TOKEN_SIZEOF) { + needtoken(TOKEN_OPENPAREN); + Setexpr * setexpr=parsesetexpr(); + needtoken(TOKEN_CLOSEPAREN); + Token tokentest=reader->readnext(); + bool greaterthan=false; + switch(tokentest.token_type) { + case TOKEN_EQUALS: + greaterthan=false; + break; + case TOKEN_GT: + greaterthan=true; + break; + default: + error(); + } + needtoken(TOKEN_ONE); + return new Predicate(greaterthan, setexpr); + } + + Token nexttoken=reader->readnext(); + bool inverted=false; + switch(nexttoken.token_type) { + case TOKEN_DOTINV: + inverted=true; + case TOKEN_DOT: + { + Token relation=reader->readnext(); + Token compareop=reader->readnext(); + Valueexpr *ve=new Valueexpr(new Label(copystr(label.str)), + new Relation(copystr(relation.str)),inverted); + while(compareop.token_type==TOKEN_DOT||compareop.token_type==TOKEN_DOTINV) { + Token nrelation=reader->readnext(); + bool invert=(compareop.token_type==TOKEN_DOTINV); + compareop=reader->readnext(); + ve=new Valueexpr(ve, + new Relation(copystr(nrelation.str)),invert); + } + Elementexpr * ee=parseelementexpr(); + + + switch(compareop.token_type) { + case TOKEN_LT: + return new Predicate(ve,PREDICATE_LT,ee); + case TOKEN_LTE: + return new Predicate(ve,PREDICATE_LTE,ee); + case TOKEN_EQUALS: + return new Predicate(ve,PREDICATE_EQUALS,ee); + case TOKEN_GTE: + return new Predicate(ve,PREDICATE_GTE,ee); + case TOKEN_GT: + return new Predicate(ve,PREDICATE_GT,ee); + default: + error(); + } + } + case TOKEN_IN: + { + Setexpr * se=parsesetexpr(); + return new Predicate(new Label(copystr(label.str)),se); + } + default: + error(); + } +} + +void Parser::error() { + printf("ERROR\n"); + reader->error(); + exit(-1); +} + +void Parser::skiptoken() { + reader->readnext(); +} + +void Parser::needtoken(int token) { + Token t=reader->readnext(); + if (!(t.token_type==token)) { + printf("Needed token: "); + tokenname(token); + printf("\n Got token: %s ",t.str); + tokenname(t.token_type); + error(); + } +} + +Constraint * Parser::parsequantifiers() { + bool bool_continue=true; + List * list=new List(); + do { + Token token2=reader->readnext(); + switch(token2.token_type) { + case TOKEN_CLOSEBRACK: + bool_continue=false; + break; + case TOKEN_FORALL: + list->addobject(parsequantifier()); + break; + case TOKEN_COMMA: + break; + default: + error(); + } + } while(bool_continue); + Quantifier** qarray=new Quantifier* [list->size()]; + list->toArray((void **)qarray); + Constraint *c=new Constraint(qarray,list->size()); + delete(list); + return c; +} + +Quantifier * Parser::parsequantifier() { + Token label=reader->readnext(); + needtoken(TOKEN_IN); + return new Quantifier(new Label(copystr(label.str)),parseset()); +} + +Set * Parser::parseset() { + Token label=reader->readnext(); + if (label.token_type==TOKEN_OPENBRACE) { + bool bool_continue=true; + List * list=new List(); + do { + Token token2=reader->readnext(); + switch(token2.token_type) { + case TOKEN_CLOSEBRACE: + bool_continue=false; + break; + case TOKEN_COMMA: + break; + default: + list->addobject(new Literal(copystr(token2.str))); + break; + } + } while(bool_continue); + int size=list->size(); + Literal** qarray=new Literal* [size]; + list->toArray((void **)qarray); + delete(list); + return new Set(qarray,size); + } else + return new Set(new Setlabel(copystr(label.str))); +} + +Setexpr * Parser::parsesetexpr() { + Token label=reader->readnext(); + Token peak=reader->peakahead(); + if (peak.token_type==TOKEN_DOT) { + skiptoken(); + return new Setexpr(new Label(copystr(label.str)),false,new Relation(copystr(reader->readnext().str))); + } else if (peak.token_type==TOKEN_DOTINV) { + skiptoken(); + return new Setexpr(new Label(copystr(label.str)),true,new Relation(copystr(reader->readnext().str))); + } else + return new Setexpr(new Setlabel(copystr(label.str))); +} + +Parser::Parser(Reader *r) { + reader=r; +} diff --git a/Repair/RepairInterpreter/oparser.h b/Repair/RepairInterpreter/oparser.h new file mode 100755 index 0000000..f3329c4 --- /dev/null +++ b/Repair/RepairInterpreter/oparser.h @@ -0,0 +1,28 @@ +#ifndef ObjectModelParser_H +#define ObjectModelParser_H + +#include "common.h" +#include +#include +#include "classlist.h" + +class Parser { + public: + Parser(Reader *r); + Constraint * parseconstraint(); + + private: + Elementexpr * checkdot(Elementexpr * incoming); + Constraint * parsequantifiers(); + Quantifier * parsequantifier(); + Set * parseset(); + Setexpr * parsesetexpr(); + Statement * parsestatement(bool); + Elementexpr * parseelementexpr(); + Predicate * parsepredicate(); + void skiptoken(); + void needtoken(int); + void error(); + Reader *reader; +}; +#endif diff --git a/Repair/RepairInterpreter/processabstract.cc b/Repair/RepairInterpreter/processabstract.cc new file mode 100755 index 0000000..f2574d1 --- /dev/null +++ b/Repair/RepairInterpreter/processabstract.cc @@ -0,0 +1,982 @@ +// evaluates model definition rules + +#include +#include +#include + +#include "processabstract.h" +#include "processconcrete.h" +#include "amodel.h" +#include "omodel.h" +#include "dmodel.h" +#include "Hashtable.h" +#include "element.h" +#include "common.h" +#include "bitreader.h" +#include "model.h" +#include "set.h" +#include "Relation.h" +#include "tmap.h" + +static int abstractcheck=0; +static int abstracttrigger=0; +static int paircount=0; + +// class processabstract + +processabstract::processabstract(model *m) { + globalmodel=m; + br=new bitreader(globalmodel,m->gethashtable()); + dirtyflag=false; +} + +bool processabstract::dirtyflagstatus() { + return dirtyflag; +} + +void processabstract::setclean() { + dirtyflag=false; +} + + +bool processabstract::evaluatestatementa(Statementa *sa, Hashtable *env) { + switch(sa->gettype()) { + case STATEMENTA_OR: + return evaluatestatementa(sa->getleft(),env)||evaluatestatementa(sa->getright(),env); + case STATEMENTA_AND: + return evaluatestatementa(sa->getleft(),env)&&evaluatestatementa(sa->getright(),env); + case STATEMENTA_NOT: + return !evaluatestatementa(sa->getleft(),env); + case STATEMENTA_EQUALS: { + Element *left=evaluateexpr(globalmodel,sa->getleftee(),env,true,true); + Element *right=evaluateexpr(globalmodel,sa->getrightee(),env,true,true); + bool tvalue=left->equals(right); + delete(left); + delete(right); + return tvalue; + } + case STATEMENTA_SET: { + Element *left=evaluateexpr(globalmodel,sa->getleftee(),env,true,true); + Set *set=sa->getset(); + if (set->gettype()==SET_label) { + DomainSet *ds=globalmodel->getdomainrelation()->getset(set->getname()); + if (ds->getset()->contains(left)) { + delete(left); + return true; + } else { + delete(left); + return false; + } + } else if (set->gettype()==SET_literal) { + for(int j=0;jgetnumliterals();j++) { + Literal *l=set->getliteral(j); + switch(l->gettype()) { + case LITERAL_NUMBER: + if(left->isnumber()&& + left->intvalue()==l->number()) { + delete(left); + return true; + } + case LITERAL_TOKEN: + if((left->type()==ELEMENT_TOKEN)&& + equivalentstrings(left->gettoken(),l->token())) { + delete(left); + return true; + } + } + } + delete(left); + return false; + } + } + case STATEMENTA_VALID: { + Element *left=evaluateexpr(globalmodel,sa->getleftee(),env,true,true); + if (left->type()!=ELEMENT_OBJECT) { + printf("ERROR in processabstract.cc\n"); + } + if (left->getobject()==NULL) { + delete(left); + return new Element(false); + } + char *structuretype=sa->getvalidtype(); + structure *st=(structuretype==NULL)?left->getstructure():globalmodel->getstructure(structuretype); + bool validity=globalmodel->gettypemap()->istype(left->getobject(),st); + delete(left); + return new Element(validity); + } + + case STATEMENTA_LT: { + Element *left=evaluateexpr(globalmodel,sa->getleftee(),env,true,true); + Element *right=evaluateexpr(globalmodel,sa->getrightee(),env,true,true); + if (!left->isnumber()|| + !right->isnumber()) { + printf("Bad lt compare\n"); + exit(-1); + } + bool tvalue=left->intvalue()intvalue(); + delete(left); + delete(right); + return tvalue; + } + case STATEMENTA_TRUE: + return true; + } +} + + +/* a Statementb is of the type "E in S" or " in R" so we just add the + respective element to S or R if the statement is not satisfied */ +void processabstract::satisfystatementb(Statementb *sb, Hashtable *env) { + switch(sb->gettype()) { + case STATEMENTB_SING: { + Element *ele=evaluateexpr(globalmodel,sb->getleft(),env,true,true); + /*if (sb->gettleft()!=NULL) { + Element **earray=new Element *[sb->gettleft()->getnumexpr()]; + for(int i=0;igettleft()->getnumexpr();i++) { + earray[i]=evaluateexpr(br,sb->gettleft()->getexpr(i),env); + } + ele->setnewparams(earray,sb->gettleft()->getnumexpr()); + }*/ + if (ele==NULL) + break; + if (!globalmodel->getdomainrelation()->getset(sb->getsetlabel()->getname())->getset()->contains(ele)) { + dirtyflag=true; +#ifdef DEBUGMANYMESSAGES + printf("element: "); + ele->print(); + printf(" into %s\n",sb->getsetlabel()->getname()); +#endif + globalmodel->getdomainrelation()->abstaddtoset(ele,globalmodel->getdomainrelation()->getset(sb->getsetlabel()->getname()),globalmodel); + } else { + delete(ele); + } + break; + } + case STATEMENTB_TUPLE:{ + Element *left=evaluateexpr(globalmodel,sb->getleft(),env,true,true); + if (left==NULL) + break; + Element *right=evaluateexpr(globalmodel,sb->getright(),env,true,true); + if (right==NULL) { + delete(left); + break; + } + /* if (sb->gettleft()!=NULL) { + Element **earray=new Element *[sb->gettleft()->getnumexpr()]; + for(int i=0;igettleft()->getnumexpr();i++) { + earray[i]=evaluateexpr(br,sb->gettleft()->getexpr(i),env); + } + left->setnewparams(earray,sb->gettleft()->getnumexpr()); + }*/ + /* if (sb->gettright()!=NULL) { + Element **earray=new Element *[sb->gettright()->getnumexpr()]; + for(int i=0;igettright()->getnumexpr();i++) { + earray[i]=evaluateexpr(br,sb->gettright()->getexpr(i),env); + } + right->setnewparams(earray,sb->gettright()->getnumexpr()); + }*/ + if (!globalmodel->getdomainrelation()->getrelation(sb->getsetlabel()->getname())->getrelation()->contains(left,right)) { + dirtyflag=true; + paircount++; +#ifdef DEBUGMANYMESSAGES + printf("element: <"); + left->print(); + printf(","); + right->print(); + printf("> into %s\n",sb->getsetlabel()->getname()); +#endif + globalmodel->getdomainrelation()->getrelation(sb->getsetlabel()->getname())->getrelation()->put(left,right); + } else { + delete(left); + delete(right); + } + break; + } + } +} + +void processabstract::printstats() { + printf("Abstraction Rules Checked: %d Triggered: %d\n",abstractcheck,abstracttrigger); + printf("Pair count: %d\n",paircount); +} + +void processabstract::processrule(Rule *r) { + State *st=new State(r, globalmodel->gethashtable()); + if (st->initializestate(br, globalmodel)) { + while(true) { + abstractcheck++; + if (evaluatestatementa(r->getstatementa(),st->env)) { + abstracttrigger++; + satisfystatementb(r->getstatementb(),st->env); + } + if (!st->increment(br, globalmodel)) + break; /* done */ + } + } + delete(st); +} + +void processabstract::processrule(Rule *r, Element *ele, char *set) { + int count=-1; + + + for(int i=0;inumquants();i++) { + AQuantifier *aq=r->getquant(i); + switch(aq->gettype()) { + case AQUANTIFIER_SING: + count=i; + break; + default: + break; + } + } + + AQuantifier *aq=r->getquant(count); + if (!equivalentstrings(aq->getset()->getname(),set)) + return; + + Hashtable *env=new Hashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings); + env->setparent(globalmodel->gethashtable()); + + RelationSet **relset=new RelationSet*[r->numquants()-1]; + int c=0; + for(int i=0;inumquants();i++) { + if (i!=count) { + AQuantifier *aq=r->getquant(i); + RelationSet *rs=new RelationSet(aq->getleft()->label(),aq->getlower(),aq->getupper()); + rs->incrementassignment(br,env,globalmodel); + relset[c++]=rs; + } + } + + env->put(aq->getleft()->label(),ele); + bool flag=true; + while(flag) { + if (evaluatestatementa(r->getstatementa(),env)) + satisfystatementb(r->getstatementb(),env); + int i=r->numquants()-2; + for(;i>=0;i--) { + if (relset[i]->incrementassignment(br,env,globalmodel)) { + break; + } else { + relset[i]->resetassignment(env); + if (!relset[i]->incrementassignment(br,env,globalmodel)) { + flag=false; + break; + } + } + } + if (i==-1) + flag=false; + } + for(int i=0;inumquants()-1;i++) { + delete(relset[i]); + } + delete(relset); + delete(env); +} + +processabstract::~processabstract() { + delete(br); +} + + + + + +// class State + +State::State(Rule *r, Hashtable *oldenv) { + env=new Hashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);; + env->setparent(oldenv); + numrelset=r->numquants(); + relset=new RelationSet*[numrelset]; + for(int i=0;inumquants();i++) { + AQuantifier *aq=r->getquant(i); + + switch(aq->gettype()) { + case AQUANTIFIER_SING: + relset[i]=new RelationSet(aq->getset(),aq->getleft()->label(),aq->gettleft()); + break; + case AQUANTIFIER_TUPLE: + relset[i]=new RelationSet(aq->getset(),aq->getleft()->label(),aq->gettleft(),aq->getright()->label(),aq->gettright()); + break; + case AQUANTIFIER_RANGE: + relset[i]=new RelationSet(aq->getleft()->label(),aq->getlower(),aq->getupper()); + break; + } + } +} + + + +State::State(Constraint *c,Hashtable *oldenv) { + env=new Hashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);; + env->setparent(oldenv); + numrelset=c->numquants(); + relset=new RelationSet*[numrelset]; + for(int i=0;inumquants();i++) { + Quantifier *q=c->getquant(i); + relset[i]=new RelationSet(q->getset(),q->getlabel()->label(),NULL); + } +} + + + +State::~State() { + delete(env); + for(int i=0;iincrementassignment(br,env,m)) + return false; + } + return true; +} + + +/* initializes all quantifiers of this constraint and returns false + if there exists a quantifier that cannot be initialized */ +bool State::initializestate(model * m) { + for(int i=0;iincrementassignment(env,m)) + return false; + } + return true; +} + +bool State::initializestate(processconcrete *pc,model * m) { + for(int i=0;iincrementassignment(pc,env,m)) + return false; + } + return true; +} + +bool State::increment(bitreader *br, model *m) { + for(int i=numrelset-1;i>=0;i--) { + if (relset[i]->incrementassignment(br,env,m)) + return true; + else { + relset[i]->resetassignment(env); + if (!relset[i]->incrementassignment(br,env,m)) + return false; + } + } + return false; +} + +bool State::increment(model *m) { + for(int i=numrelset-1;i>=0;i--) { + if (relset[i]->incrementassignment(env,m)) + return true; + else { + relset[i]->resetassignment(env); + if (!relset[i]->incrementassignment(env,m)) + return false; + } + } + return false; +} + +bool State::increment(processconcrete *pc,model *m) { + for(int i=numrelset-1;i>=0;i--) { + if (relset[i]->incrementassignment(pc,env,m)) + return true; + else { + relset[i]->resetassignment(env); + if (!relset[i]->incrementassignment(pc,env,m)) + return false; + } + } + return false; +} + + + +Element * evaluateexpr(model *m,AElementexpr *ee, Hashtable *env, bool enforcetyping, bool compute) { + bitreader *br=m->getbitreader(); + switch(ee->gettype()) { + case AELEMENTEXPR_NULL: + return new Element(); + case AELEMENTEXPR_LABEL: { + Element *r=new Element((Element *)env->get(ee->getlabel()->label())); + typemap *tm=m->gettypemap(); + if (compute) + if(r->type()==ELEMENT_OBJECT&& + r->getobject()!=NULL&& + !tm->asserttype(r->getobject(),r->getstructure())) { + delete(r); + return NULL; + } + return r; + } + case AELEMENTEXPR_SUB: { + AElementexpr *left=ee->getleft(); + AElementexpr *right=ee->getright(); + Element *leftval=evaluateexpr(m,left,env,true,compute); + if (leftval==NULL) + return NULL; + Element *rightval=evaluateexpr(m,right,env,true,compute); + if (rightval==NULL) { + delete(leftval); + return NULL; + } + Element *diff=new Element(leftval->intvalue()-rightval->intvalue()); + delete(leftval);delete(rightval); + return diff; + } + case AELEMENTEXPR_ADD: { + AElementexpr *left=ee->getleft(); + AElementexpr *right=ee->getright(); + Element *leftval=evaluateexpr(m,left,env,true,compute); + if (leftval==NULL) + return NULL; + Element *rightval=evaluateexpr(m,right,env,true,compute); + if (rightval==NULL) { + delete(leftval); + return NULL; + } + Element *sum=new Element(leftval->intvalue()+rightval->intvalue()); + delete(leftval);delete(rightval); + return sum; + } + case AELEMENTEXPR_MULT: { + AElementexpr *left=ee->getleft(); + AElementexpr *right=ee->getright(); + Element *leftval=evaluateexpr(m,left,env,true,compute); + if (leftval==NULL) + return NULL; + Element *rightval=evaluateexpr(m,right,env,true,compute); + if (rightval==NULL) { + delete(leftval); + return NULL; + } + Element *diff=new Element(leftval->intvalue()*rightval->intvalue()); + delete(leftval);delete(rightval); + return diff; + } + case AELEMENTEXPR_DIV: { + AElementexpr *left=ee->getleft(); + AElementexpr *right=ee->getright(); + Element *leftval=evaluateexpr(m,left,env,true,compute); + if (leftval==NULL) + return NULL; + Element *rightval=evaluateexpr(m,right,env,true,compute); + if (rightval==NULL) { + delete(leftval); + return NULL; + } + Element *diff=new Element(leftval->intvalue()/rightval->intvalue()); + delete(leftval);delete(rightval); + return diff; + } + case AELEMENTEXPR_LIT: { + Literal *l=ee->getliteral(); + switch(l->gettype()) { + case LITERAL_NUMBER: + return new Element(l->number()); + case LITERAL_TOKEN: + return new Element(copystr(l->token())); + case LITERAL_BOOL: + return new Element(l->getbool()); + default: + printf("ERROR with lit type\n"); + exit(-1); + } + } + case AELEMENTEXPR_FIELD: { + Element *e=evaluateexpr(m,ee->getleft(),env,true,compute); + if (e==NULL) + return NULL; + Element *r=br->readfieldorarray(e,ee->getfield(),NULL); + delete(e); + if (r==NULL) + return NULL; + if (enforcetyping&&compute) { + typemap *tm=m->gettypemap(); + if(r->type()==ELEMENT_OBJECT&& + r->getobject()!=NULL&& + !tm->asserttype(r->getobject(),r->getstructure())) { + delete(r); + return NULL; + } + } else if (compute) { + typemap *tm=m->gettypemap(); + if(r->type()==ELEMENT_OBJECT&& + r->getobject()!=NULL&& + !tm->istype(r->getobject(),r->getstructure())) { + delete(r); + return NULL; + } + } + return r; + } + case AELEMENTEXPR_CAST: { + Element *e=evaluateexpr(m,ee->getleft(),env,true,compute); + if (e==NULL) + return NULL; + typemap *tm=m->gettypemap(); + if (e->getobject()!=NULL&&compute&& + !tm->asserttype(e->getobject(),m->getstructure(ee->getcasttype()))) { + delete(e); + return NULL; + } + Element *r=new Element(e->getobject(),m->getstructure(ee->getcasttype())); + delete(e); + return r; + } + case AELEMENTEXPR_FIELDARRAY: { + Element *e=evaluateexpr(m,ee->getleft(),env,true,compute); + if (e==NULL) + return NULL; + Element *ind=evaluateexpr(m,ee->getright(),env,true,compute); + if (ind==NULL) { + delete(e); + return NULL; + } + Element *r=br->readfieldorarray(e,ee->getfield(),ind); + delete(ind); + delete(e); + if (r==NULL) + return NULL; + if (enforcetyping&&compute) { + typemap *tm=m->gettypemap(); + if(r->type()==ELEMENT_OBJECT&& + r->getobject()!=NULL&& + !tm->asserttype(r->getobject(),r->getstructure())) { + delete(r); + return NULL; + } + } else if (compute) { + typemap *tm=m->gettypemap(); + if(r->type()==ELEMENT_OBJECT&& + r->getobject()!=NULL&& + !tm->istype(r->getobject(),r->getstructure())) { + delete(r); + return NULL; + } + } + return r; + } + } +} + + +// prints the current state +void State::print(model *m) +{ + for(int i=0; iprint(env, m); + printf(" "); + } +} + + + + +// class RelationSet + +RelationSet::RelationSet(Set *s, char *l,Type *tl) { + set=s; + type=TYPE_SET; + left=l; + tleft=tl; + tright=NULL; + right=NULL; +} + +RelationSet::RelationSet(Set *s,char *l, Type *tl,char *r,Type *tr) { + set=s; + type=TYPE_RELATION; + left=l; + tleft=tl; + tright=tr; + right=r; +} + +RelationSet::RelationSet(char *l,AElementexpr *lower,AElementexpr*upper) { + this->lower=lower; + this->upper=upper; + left=l; + type=TYPE_RANGE; +} + +int RelationSet::gettype() { + return type; +} + +void RelationSet::resetassignment(Hashtable *env) { + switch(type) { + case TYPE_SET: + env->remove(left); + break; + case TYPE_RELATION: + env->remove(left); + env->remove(right); + break; + case TYPE_RANGE: + env->remove(left); + break; + } +} + +bool RelationSet::incrementassignment(bitreader *br,Hashtable *env, model *m) { + switch(type) { + case TYPE_SET: { + if (set->gettype()==SET_label) { + DomainSet *ds=m->getdomainrelation()->getset(set->getname()); + + if (!env->contains(left)) { + Element *fele=(Element *)ds->getset()->firstelement(); + if (fele==NULL) + return false; + env->put(left,fele); + /* if (tleft!=NULL) { + assert(tleft->getnumlabels()==ele->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tleft->getlabel(i)->label(),ele->paramvalue(i)); + } + }*/ + return true; + } + Element *ele=(Element *)env->get(left); + Element *nextele=(Element *)ds->getset()->getnextelement(ele); + if (nextele==NULL) + return false; + else { + /* if (tleft!=NULL) { + assert(tleft->getnumlabels()==nextele->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tleft->getlabel(i)->label(),nextele->paramvalue(i)); + } + }*/ + env->put(left,nextele); + return true; + } + } else if(set->gettype()==SET_literal) { + + if (!env->contains(left)) { + Literal *l=set->getliteral(0); + switch(l->gettype()) { + case LITERAL_NUMBER: + env->put(left,new Element(l->number())); + break; + case LITERAL_TOKEN: + env->put(left,new Element(l->token())); + break; + } + return true; + } + Element *ele=(Element *)env->get(left); + for(int j=0;jgetnumliterals();j++) { + Literal *l=set->getliteral(j); + switch(l->gettype()) { + case LITERAL_NUMBER: + if(ele->isnumber()&& + ele->intvalue()==l->number()) { + if ((j+1)getnumliterals()) { + env->put(left,new Element(set->getliteral(j+1)->number())); + delete(ele); + return true; + } + else return false; + } + case LITERAL_TOKEN: + if((ele->type()==ELEMENT_TOKEN)&& + equivalentstrings(ele->gettoken(),l->token())) { + if ((j+1)getnumliterals()) { + env->put(left,new Element(set->getliteral(j+1)->token())); + delete(ele); + return true; + } + else return false; + } + } + } + } + } + case TYPE_RELATION: { + DRelation *dr=m->getdomainrelation()->getrelation(set->getname()); + Element *eleleft=(Element *)env->get(left); + Element *eleright=(Element *)env->get(right); + if ((eleleft==NULL)||(eleright==NULL)) { + if((eleleft!=NULL)||(eleright!=NULL)) { + printf("ERROR in TYPE_RELATION in processabstract.cc\n"); + exit(-1); + } + Tuple t=dr->getrelation()->firstelement(); + if (t.isnull()) + return false; + env->put(left,t.left); + env->put(right,t.right); + /* if (tleft!=NULL) { + assert(tleft->getnumlabels()==((Element *)t.left)->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tleft->getlabel(i)->label(),((Element *)t.left)->paramvalue(i)); + } + }*/ + /* if (tright!=NULL) { + assert(tright->getnumlabels()==((Element *)t.right)->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tright->getlabel(i)->label(),((Element *)t.right)->paramvalue(i)); + } + }*/ + + return true; + } + Tuple nextele=dr->getrelation()->getnextelement(eleleft,eleright); + if (nextele.isnull()) + return false; + else { + env->put(left,nextele.left); + env->put(right,nextele.right); + /* if (tleft!=NULL) { + assert(tleft->getnumlabels()==((Element *)nextele.left)->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tleft->getlabel(i)->label(),((Element *)nextele.left)->paramvalue(i)); + } + }*/ + /* if (tright!=NULL) { + assert(tright->getnumlabels()==((Element *)nextele.right)->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tright->getlabel(i)->label(),((Element *)nextele.right)->paramvalue(i)); + } + }*/ + return true; + } + } + case TYPE_RANGE: { + + if (!env->contains(left)) { + Element *lowerele=(Element *)evaluateexpr(m,lower,env,true,true); + env->put(left,lowerele); + return true; + } + Element *val=(Element *)env->get(left); + Element *upperele=evaluateexpr(m,upper,env,true,true); + if (val->intvalue()>=upperele->intvalue()) { + delete(upperele); + return false; + } else { + Element *nval=new Element(val->intvalue()+1); + env->put(left,nval); + delete(val); + return true; + } + } + } +} + +bool RelationSet::incrementassignment(processconcrete *pc,Hashtable *env, model *m) { + switch(type) { + case TYPE_SET: { + if (set->gettype()==SET_label) { + DomainSet *ds=m->getdomainrelation()->getset(set->getname()); + + if (!env->contains(left)) { + Element *fele=(Element *)ds->getset()->firstelement(); + if (fele==NULL) + return false; + env->put(left,fele); + /* if (tleft!=NULL) { + assert(tleft->getnumlabels()==ele->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tleft->getlabel(i)->label(),ele->paramvalue(i)); + } + }*/ + return true; + } + Element *ele=(Element *)env->get(left); + Element *nextele=(Element *)ds->getset()->getnextelement(ele); + if (nextele==NULL) + return false; + else { + /* if (tleft!=NULL) { + assert(tleft->getnumlabels()==nextele->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tleft->getlabel(i)->label(),nextele->paramvalue(i)); + } + }*/ + env->put(left,nextele); + return true; + } + } else if(set->gettype()==SET_literal) { + + if (!env->contains(left)) { + Literal *l=set->getliteral(0); + switch(l->gettype()) { + case LITERAL_NUMBER: + env->put(left,new Element(l->number())); + break; + case LITERAL_TOKEN: + env->put(left,new Element(l->token())); + break; + } + return true; + } + Element *ele=(Element *)env->get(left); + for(int j=0;jgetnumliterals();j++) { + Literal *l=set->getliteral(j); + switch(l->gettype()) { + case LITERAL_NUMBER: + if(ele->isnumber()&& + ele->intvalue()==l->number()) { + if ((j+1)getnumliterals()) { + env->put(left,new Element(set->getliteral(j+1)->number())); + delete(ele); + return true; + } + else return false; + } + case LITERAL_TOKEN: + if((ele->type()==ELEMENT_TOKEN)&& + equivalentstrings(ele->gettoken(),l->token())) { + if ((j+1)getnumliterals()) { + env->put(left,new Element(set->getliteral(j+1)->token())); + delete(ele); + return true; + } + else return false; + } + } + } + } + } + case TYPE_RELATION: { + DRelation *dr=m->getdomainrelation()->getrelation(set->getname()); + Element *eleleft=(Element *)env->get(left); + Element *eleright=(Element *)env->get(right); + if ((eleleft==NULL)||(eleright==NULL)) { + if((eleleft!=NULL)||(eleright!=NULL)) { + printf("ERROR in TYPE_RELATION in processabstract.cc\n"); + exit(-1); + } + Tuple t=dr->getrelation()->firstelement(); + if (t.isnull()) + return false; + env->put(left,t.left); + env->put(right,t.right); + /* if (tleft!=NULL) { + assert(tleft->getnumlabels()==((Element *)t.left)->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tleft->getlabel(i)->label(),((Element *)t.left)->paramvalue(i)); + } + }*/ + /* if (tright!=NULL) { + assert(tright->getnumlabels()==((Element *)t.right)->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tright->getlabel(i)->label(),((Element *)t.right)->paramvalue(i)); + } + }*/ + + return true; + } + Tuple nextele=dr->getrelation()->getnextelement(eleleft,eleright); + if (nextele.isnull()) + return false; + else { + env->put(left,nextele.left); + env->put(right,nextele.right); + /* if (tleft!=NULL) { + assert(tleft->getnumlabels()==((Element *)nextele.left)->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tleft->getlabel(i)->label(),((Element *)nextele.left)->paramvalue(i)); + } + }*/ + /* if (tright!=NULL) { + assert(tright->getnumlabels()==((Element *)nextele.right)->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tright->getlabel(i)->label(),((Element *)nextele.right)->paramvalue(i)); + } + }*/ + return true; + } + } + case TYPE_RANGE: { + + if (!env->contains(left)) { + env->put(left,pc->evaluateexpr((CAElementexpr *)lower, env)); + return true; + } + Element *val=(Element *)env->get(left); + Element *upperele=pc->evaluateexpr((CAElementexpr *)upper,env); + if (val->intvalue()>=upperele->intvalue()) { + delete(upperele); + return false; + } else { + Element *nval=new Element(val->intvalue()+1); + env->put(left,nval); + delete(val); + return true; + } + } + } +} + + +/* increments the value of "left" and returns "false" if this is not possible. + When this method is called for the first time, it simply initializes + the value of the quantifier ("left") */ +bool RelationSet::incrementassignment(Hashtable *env, model *m) { + switch(type) { + case TYPE_SET: { + if (set->gettype()==SET_label) { + DomainSet *ds=m->getdomainrelation()->getset(set->getname()); + + Element *ele=NULL; + if (!env->contains(left)) { + ele=(Element *)ds->getset()->firstelement(); + if (ele==NULL) + return false; + env->put(left,ele); + /* if (tleft!=NULL) { + assert(tleft->getnumlabels()==ele->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tleft->getlabel(i)->label(),ele->paramvalue(i)); + } + }*/ + return true; + } + + ele=(Element *) env->get(left); + Element *nextele=(Element *)ds->getset()->getnextelement(ele); + if (nextele==NULL) + return false; + else { + /* if (tleft!=NULL) { + assert(tleft->getnumlabels()==nextele->getnumparams()); + for (int i=0;igetnumlabels();i++) { + env->put(tleft->getlabel(i)->label(),nextele->paramvalue(i)); + } + }*/ + env->put(left,nextele); + return true; + } + } + } + } +} + + +// prints the quantifier and its current state +void RelationSet::print(Hashtable *env, model *m) +{ + switch(type) { + case TYPE_SET: { + if (set->gettype()==SET_label) + { + printf("%s=", left); + DomainSet *ds=m->getdomainrelation()->getset(set->getname()); + Element *ele = (Element *) env->get(left); + ele->print(); + printf("\n"); + } + }} +} diff --git a/Repair/RepairInterpreter/processabstract.h b/Repair/RepairInterpreter/processabstract.h new file mode 100755 index 0000000..3979245 --- /dev/null +++ b/Repair/RepairInterpreter/processabstract.h @@ -0,0 +1,86 @@ +// evaluates model definition rules + +#ifndef PROCESSABSTRACT_H +#define PROCESSABSTRACT_H +#include "classlist.h" + + +Element * evaluateexpr(model *m, AElementexpr *ee, Hashtable *env,bool enforcetyping,bool compute); + + + +class processabstract { + public: + processabstract(model *m); + void processrule(Rule *r); + void setclean(); + void printstats(); + bool dirtyflagstatus(); + ~processabstract(); + void processrule(Rule *r, Element *ele, char *set); + private: + bool evaluatestatementa(Statementa *sa, Hashtable *env); + void satisfystatementb(Statementb *sb, Hashtable *env); + model * globalmodel; + bool dirtyflag; + bitreader * br; +}; + + + + +/* A RelationSet keeps the current state of a quantifier. + There are three types of RelationSet's: + TYPE_SET: "for left in set" + TYPE_RELATION: "for in set" + TYPE_RANGE: "for left=lower..upper */ +#define TYPE_SET 1 +#define TYPE_RELATION 2 +#define TYPE_RANGE 3 + +class RelationSet { + public: + RelationSet(Set *s, char *l, Type *tl); + RelationSet(Set *s, char *l, Type *tl, char *r, Type *tr); + RelationSet(char *l,AElementexpr *lower,AElementexpr*upper); + int gettype(); + bool incrementassignment(bitreader *br,Hashtable *env, model *m); + bool incrementassignment(Hashtable *env, model *m); + bool incrementassignment(processconcrete *pc,Hashtable *env, model *m); + void resetassignment(Hashtable *env); + + void print(Hashtable *env, model *m); // prints the quantifier and its current state + + AElementexpr *lower,*upper; + char *left,*right; + Type *tleft,*tright; + /* char's are not the responsibility of this class to dispose of*/ + int type; + Set *set; +}; + + + + +// Keeps the current state of the quantifiers of a given rule or constraint +class State { + public: + State(Rule *r, Hashtable *h); + State(Constraint *c, Hashtable *h); + ~State(); + bool initializestate(bitreader *br, model *m); + bool increment(bitreader *br, model *m); + bool initializestate(model *m); + bool increment(model *m); + + bool initializestate(processconcrete*, model *m); + bool increment(processconcrete*, model *m); + + void print(model *m); + + Hashtable *env; + RelationSet **relset; + int numrelset; + +}; +#endif diff --git a/Repair/RepairInterpreter/processconcrete.cc b/Repair/RepairInterpreter/processconcrete.cc new file mode 100755 index 0000000..72af173 --- /dev/null +++ b/Repair/RepairInterpreter/processconcrete.cc @@ -0,0 +1,244 @@ +#include +#include +#include "processconcrete.h" +#include "processabstract.h" +#include "amodel.h" +#include "omodel.h" +#include "dmodel.h" +#include "cmodel.h" +#include "Hashtable.h" +#include "element.h" +#include "common.h" +#include "bitreader.h" +#include "bitwriter.h" +#include "model.h" +#include "set.h" +#include "Relation.h" +static int concretecheck=0; +static int concretetrigger=0; + +processconcrete::processconcrete(model *m) { + globalmodel=m; + bw=new bitwriter(globalmodel,m->gethashtable()); + br=new bitreader(globalmodel,m->gethashtable()); +} + +void processconcrete::printstats() { + printf("Concretization Rules Checked: %d Triggered: %d\n",concretecheck,concretetrigger); +} + + +void processconcrete::processrule(Rule *r) { + State *st=new State(r,globalmodel->gethashtable()); + if (st->initializestate(this, globalmodel)) { + while(true) { + concretecheck++; + if (evaluatestatementa(r->getstatementa(),st->env)) { + concretetrigger++; + satisfystatementb((CStatementb *)r->getstatementb(),st->env); + } + + if (!st->increment(this, globalmodel)) + break; /* done */ + } + } + delete(st); +} + +processconcrete::~processconcrete() { + delete(br); +} + +bool processconcrete::evaluatestatementa(Statementa *sa, Hashtable *env) { + switch(sa->gettype()) { + case STATEMENTA_OR: + return evaluatestatementa(sa->getleft(),env)||evaluatestatementa(sa->getright(),env); + case STATEMENTA_AND: + return evaluatestatementa(sa->getleft(),env)&&evaluatestatementa(sa->getright(),env); + case STATEMENTA_NOT: + return !evaluatestatementa(sa->getleft(),env); + case STATEMENTA_EQUALS: { + Element *left=evaluateexpr((CAElementexpr *)sa->getleftee(),env); + Element *right=evaluateexpr((CAElementexpr *)sa->getrightee(),env); + bool tvalue=left->equals(right); + delete(left); + delete(right); + return tvalue; + } + case STATEMENTA_LT: { + Element *left=evaluateexpr((CAElementexpr *)sa->getleftee(),env); + Element *right=evaluateexpr((CAElementexpr *)sa->getrightee(),env); + if (!left->isnumber()|| + !right->isnumber()) { + printf("Bad lt compare\n"); + exit(-1); + } + bool tvalue=left->intvalue()intvalue(); + delete(left); + delete(right); + return tvalue; + } + case STATEMENTA_TRUE: + return true; + } +} + +void processconcrete::satisfystatementb(CStatementb *sb, Hashtable *env) { + Element * rvalue=evaluateexpr((CAElementexpr *)sb->getright(),env); + Element *index=NULL; + if (sb->gettype()==CSTATEMENTB_ARRAYASSIGN) + index=evaluateexpr((CAElementexpr *)sb->getleft(),env); + Field *field=sb->getfield(); + Element *src=evaluateexpr(sb->getexpr(),env); + bw->writefieldorarray(src,field,index,rvalue); + delete(rvalue); + if (index!=NULL) + delete(index); + delete(src); +} + +Element * processconcrete::evaluateexpr(Expr *e, Hashtable *env) { + switch(e->gettype()) { + case EXPR_LABEL: + return new Element((Element *)env->get(e->getlabel()->label())); + case EXPR_FIELD: { + Element *old=evaluateexpr(e->getexpr(),env); + Element *newe=br->readfieldorarray(evaluateexpr(e->getexpr(),env),e->getfield(),NULL); + delete(old); + return newe; + } + case EXPR_CAST: { + Element *old=evaluateexpr(e->getexpr(),env); + char *type=e->getcasttype(); + structure *st=globalmodel->getstructure(type); + Element *newe=new Element(old->getobject(),st); + delete(old); + return newe; + } + case EXPR_ARRAY: { + Element *old=evaluateexpr(e->getexpr(),env); + Element *index=evaluateexpr(e->getindex(),env); + Element *newe=br->readfieldorarray(evaluateexpr(e->getexpr(),env),e->getfield(),index); + delete(old); + delete(index); + return newe; + } + } +} + +Element * processconcrete::evaluateexpr(CAElementexpr *ee, Hashtable *env) { + switch(ee->gettype()) { + case CAELEMENTEXPR_LABEL: + { + return new Element((Element *)env->get(ee->getlabel()->label())); + } + case CAELEMENTEXPR_NULL: + { + return new Element(); + } + case CAELEMENTEXPR_SUB: + { + CAElementexpr *left=ee->getleft(); + CAElementexpr *right=ee->getright(); + Element *leftval=evaluateexpr(left,env); + Element *rightval=evaluateexpr(right,env); + Element *diff=new Element(leftval->intvalue()-rightval->intvalue()); + delete(leftval);delete(rightval); + return diff; + } + case CAELEMENTEXPR_ADD: + { + CAElementexpr *left=ee->getleft(); + CAElementexpr *right=ee->getright(); + Element *leftval=evaluateexpr(left,env); + Element *rightval=evaluateexpr(right,env); + Element *sum=new Element(leftval->intvalue()+rightval->intvalue()); + delete(leftval);delete(rightval); + return sum; + } + case CAELEMENTEXPR_MULT: + { + CAElementexpr *left=ee->getleft(); + CAElementexpr *right=ee->getright(); + Element *leftval=evaluateexpr(left,env); + Element *rightval=evaluateexpr(right,env); + Element *diff=new Element(leftval->intvalue()*rightval->intvalue()); + delete(leftval);delete(rightval); + return diff; + } + case CAELEMENTEXPR_DIV: + { + CAElementexpr *left=ee->getleft(); + CAElementexpr *right=ee->getright(); + Element *leftval=evaluateexpr(left,env); + Element *rightval=evaluateexpr(right,env); + Element *diff=new Element(leftval->intvalue()/rightval->intvalue()); + delete(leftval);delete(rightval); + return diff; + } + case CAELEMENTEXPR_LIT: + { + Literal *l=ee->getliteral(); + switch(l->gettype()) { + case LITERAL_NUMBER: + return new Element(l->number()); + case LITERAL_TOKEN: + return new Element(copystr(l->token())); + case LITERAL_BOOL: + return new Element(l->getbool()); + default: + printf("ERROR with lit type\n"); + exit(-1); + } + } + case CAELEMENTEXPR_SIZEOF: + { + Setexpr * setexpr=ee->getsetexpr(); + switch(setexpr->gettype()) { + case SETEXPR_LABEL: + return new Element(globalmodel->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->size()); + case SETEXPR_REL: { + Element *key=(Element *)env->get(setexpr->getlabel()->label()); + WorkSet *ws=globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(key); + if (ws==NULL) + return new Element(0); + else + return new Element(ws->size()); + } + case SETEXPR_INVREL: { + Element *key=(Element *)env->get(setexpr->getlabel()->label()); + WorkSet *ws=globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(key); + if (ws==NULL) + return new Element(0); + else + return new Element(ws->size()); + } + } + } + case CAELEMENTEXPR_ELEMENT: { + Element *index=evaluateexpr(ee->getleft(),env); + int ind=index->intvalue(); + delete(index); + + Setexpr * setexpr=ee->getsetexpr(); + switch(setexpr->gettype()) { + case SETEXPR_LABEL: + return new Element((Element *)globalmodel->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->getelement(ind)); + case SETEXPR_REL: { + Element *key=(Element *)env->get(setexpr->getlabel()->label()); + return new Element((Element *)globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(key)->getelement(ind)); + } + case SETEXPR_INVREL: { + Element *key=(Element *)env->get(setexpr->getlabel()->label()); + return new Element((Element *)globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(key)->getelement(ind)); + } + } + } + case CAELEMENTEXPR_RELATION: + { + Element *e=evaluateexpr(ee->getleft(),env); + Element *r=(Element *)globalmodel->getdomainrelation()->getrelation(ee->getrelation()->getname())->getrelation()->getobj(e); + return new Element(r); + } + } +} diff --git a/Repair/RepairInterpreter/processconcrete.h b/Repair/RepairInterpreter/processconcrete.h new file mode 100755 index 0000000..6a06bcc --- /dev/null +++ b/Repair/RepairInterpreter/processconcrete.h @@ -0,0 +1,22 @@ +#ifndef PROCESSCONCRETE_H +#define PROCESSCONCRETE_H +#include "classlist.h" + +class processconcrete { + public: + processconcrete(model *m); + void processrule(Rule *r); + ~processconcrete(); + Element * evaluateexpr(CAElementexpr *ee, Hashtable *env); + void printstats(); + private: + Element * evaluateexpr(Expr *e, Hashtable *env); + bool evaluatestatementa(Statementa *sa, Hashtable *env); + void satisfystatementb(CStatementb *sb, Hashtable *env); + model * globalmodel; + bitwriter * bw; + bitreader * br; +}; + + +#endif diff --git a/Repair/RepairInterpreter/processobject.cc b/Repair/RepairInterpreter/processobject.cc new file mode 100755 index 0000000..b917f4a --- /dev/null +++ b/Repair/RepairInterpreter/processobject.cc @@ -0,0 +1,557 @@ +// evaluates constraints in the ICL + +#include +#include "processobject.h" +#include "processabstract.h" +#include "omodel.h" +#include "Hashtable.h" +#include "element.h" +#include "model.h" +#include "dmodel.h" +#include "set.h" +#include "Relation.h" +#include "repair.h" +#include "normalizer.h" +#include "Action.h" + +static int modelcheck=0; +static int modeltrigger=0; + +processobject::processobject(model *m) { + globalmodel=m; + repair=m->getrepair(); +} + +void processobject::printstats() { + printf("Models Rules Checked: %d Triggered: %d\n",modelcheck,modeltrigger); +} + +// evaluates the truth value of the given predicate +int processobject::processpredicate(Predicate *p, Hashtable *env) { + switch(p->gettype()) { + case PREDICATE_LT: { + Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel); + Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel); + if (right==NULL) { + return PFAIL; + } + if (left==NULL) { + delete(right); + return false; + } + int t=left->intvalue()intvalue(); + delete(right); + return t; + } + case PREDICATE_LTE: { + Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel); + Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel); + if (right==NULL) {return PFAIL;} + if (left==NULL) { + delete(right); + return false; + } + bool t=left->intvalue()<=right->intvalue(); + delete(right); + return t; + } + case PREDICATE_EQUALS: { + Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel); + Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel); + if (right==NULL) {return PFAIL;} + if (left==NULL) { + delete(right); + return false; + } + /* Can have more than just int's here */ + bool t=left->equals(right); /*Just ask the equals method*/ + delete(right); + return t; + } + case PREDICATE_GTE: { + Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel); + Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel); + if (right==NULL) {return PFAIL;} + if (left==NULL) { + delete(right); + return false; + } + bool t=left->intvalue()>=right->intvalue(); + delete(right); + return t; + } + case PREDICATE_GT: { + Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel); + Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel); + if (right==NULL) {return PFAIL;} + if (left==NULL) { + delete(right); + return false; + } + bool t=left->intvalue()>right->intvalue(); + delete(right); + return t; + } + case PREDICATE_SET: { + Label *label=p->getlabel(); + Setexpr * setexpr=p->getsetexpr(); + Element *labelele=(Element *) env->get(label->label()); + switch(setexpr->gettype()) { + case SETEXPR_LABEL: + return globalmodel->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->contains(labelele); + case SETEXPR_REL: + return globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(setexpr->getlabel()->label())->contains(labelele); + case SETEXPR_INVREL: + return globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(setexpr->getlabel()->label())->contains(labelele); + } + } + case PREDICATE_EQ1: + case PREDICATE_GTE1: { + int setsize; + Setexpr * setexpr=p->getsetexpr(); + switch(setexpr->gettype()) { + case SETEXPR_LABEL: + setsize=globalmodel->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->size(); + break; + case SETEXPR_REL: { + Element *key=(Element *)env->get(setexpr->getlabel()->label()); + WorkSet *ws=globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(key); + if (ws!=NULL) + setsize=ws->size(); + else + setsize=0; + break; + } + case SETEXPR_INVREL: { + Element *key=(Element *)env->get(setexpr->getlabel()->label()); + WorkSet *ws=globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(key); + if (ws!=NULL) + setsize=ws->size(); + else + setsize=0; + break; + } + } + return ((p->gettype()==PREDICATE_EQ1)&&(setsize==1))|| + ((p->gettype()==PREDICATE_GTE1)&&(setsize>=1)); + } + } +} + + +// evaluates the truth value of the given statement +int processobject::processstatement(Statement *s, Hashtable *env) { + switch (s->gettype()) { + case STATEMENT_OR: { + int l=processstatement(s->getleft(),env); + int r=processstatement(s->getright(),env); + if (l==PFAIL&&(r==PFAIL||r==PFALSE)) return PFAIL; + if ((l==PFAIL||l==PFALSE)&&r==PFAIL) return PFAIL; + return l||r; + } + case STATEMENT_AND: { + int l=processstatement(s->getleft(),env); + int r=processstatement(s->getright(),env); + if (l==PFAIL&&(r==PFAIL||r==PTRUE)) return PFAIL; + if (r==PFAIL&&(l==PFAIL||l==PTRUE)) return PFAIL; + return l&&r; + } + case STATEMENT_NOT: { + int l=processstatement(s->getleft(),env); + if (l==PFAIL) return PFAIL; + return !l; + } + case STATEMENT_PRED: + return processpredicate(s->getpredicate(),env); + } +} + + +// returns true if and only if the given constraint is satisfied +bool processobject::issatisfied(Constraint *c) +{ + State *st=new State(c,globalmodel->gethashtable()); + bool satisfied = true; + if (st->initializestate(globalmodel)) + while (true) + { + if (c->getstatement()!=NULL) + if (processstatement(c->getstatement(),st->env)!=PTRUE) + satisfied = false; + if (!st->increment(globalmodel)) + break; + } + + delete(st); + return satisfied; +} + + + +/* processed the given constraint and if it's not satisfied, + displays a message and tries to repair the constraint + The function returns true only if the constraint was initially + satisfied. */ +bool processobject::processconstraint(Constraint *c) { + State *st=new State(c,globalmodel->gethashtable()); + bool clean=true; + if (st->initializestate(globalmodel)) { + while(true) { + if (c->getstatement()!=NULL) { + modelcheck++; + if (processstatement(c->getstatement(),st->env)!=PTRUE) { + modeltrigger++; +#ifdef TOOL + printf("Constraint violation\n"); + printf(" Violated constraint: "); c->print(); + printf(" State for which it was violated: "); st->print(globalmodel); + printf(" Current value(s):"); + c->getstatement()->print_sets(st->env, globalmodel); + printf("\n\n"); + return false; +#endif + +#ifdef REPAIR + printf("Repairing...\n"); + if (c->getcrash()) { + printf("Fatal program error violating special constraint.\n"); + exit(-1); + } + repair->repairconstraint(c,this,st->env); + clean=false; +#endif + } + } + + if (!st->increment(globalmodel)) + break; /* done */ + } + } + delete(st); + return clean; +} + + + +/* breaks the given constraint by invalidating each of its satisfied sentences */ +void processobject::breakconstraint(Constraint *c) +{ +#ifdef DEBUGMESSAGES + printf("Constraint to be broken: "); + c->print(); + printf("\n"); + fflush(NULL); +#endif + + // first, get get the constraint in normal form + NormalForm *nf = globalmodel->getnormalform(c); + + // for each CoerceSentence in nf, find if it's satisfied. If so, break it. + for (int i=0; igetnumsentences(); i++) + { +#ifdef DEBUGMESSAGES + printf("In processobject::breakconstraint, i=%d \n", i); + fflush(NULL); +#endif + + CoerceSentence *s = nf->getsentence(i); + + // find if s is satisfied + bool satisfied = true; + State *st = new State(c, globalmodel->gethashtable()); + if (st->initializestate(globalmodel)) + while(true) + { + if (!s->issatisfied(this, st->env)) + satisfied=false; + + if (!st->increment(globalmodel)) + break; + } + delete(st); + + + // if s is satisfied, then break it + + if (satisfied) + { + // first, select an arbitrary binding, for ex. the first one + st = new State(c, globalmodel->gethashtable()); + + if (st->initializestate(globalmodel)) + { +#ifdef DEBUGMESSAGES + printf("numpredicates = %d\n", s->getnumpredicates()); +#endif + + for (int j=0; jgetnumpredicates(); j++) + { + CoercePredicate *cp = s->getpredicate(j); + // break this predicate with probability prob_breakpredicate + if (random()findbreakaction(cp); + action->breakpredicate(st->env, cp); + +#ifdef DEBUGMESSAGES + printf("After action->breakpredicate was called\n"); + fflush(NULL); +#endif + } + } + } + + delete(st); + } + } +} + + + +/* satisfies the given satisfied contraint in another way */ +void processobject::modifyconstraint(Constraint *c) +{ +#ifdef DEBUGMESSAGES + printf("Constraint to be modified: "); + c->print(); + printf("\n"); + fflush(NULL); +#endif + + // first, get the constraint in normal form + NormalForm *nf = globalmodel->getnormalform(c); + + /* for each CoerceSentence in nf, find if it's satisfied. + If it's satisfied, we break it with probability prob_breaksatisfiedsentence; + If it's not satisfied, we repair it with probability prob_repairbrokensentence + */ + + bool still_valid = false; + + for (int i=0; igetnumsentences(); i++) + { +#ifdef DEBUGMESSAGES + printf("In processobject::modifyconstraint, i=%d \n", i); + fflush(NULL); +#endif + + CoerceSentence *s = nf->getsentence(i); + + // find if s is satisfied + bool satisfied = true; + State *st = new State(c, globalmodel->gethashtable()); + if (st->initializestate(globalmodel)) + while(true) + { + if (!s->issatisfied(this, st->env)) + satisfied=false; + + if (!st->increment(globalmodel)) + break; + } + delete(st); + + // if s is satisfied, then break it + if (satisfied) + if (random()gethashtable()); + + if (st->initializestate(globalmodel)) + { + for (int j=0; jgetnumpredicates(); j++) + { + CoercePredicate *cp = s->getpredicate(j); + // break this predicate with probability prob_breakpredicate + if (random()findbreakaction(cp); + action->breakpredicate(st->env, cp); + +#ifdef DEBUGMESSAGES + printf("After action->modifypredicate was called\n"); + fflush(NULL); +#endif + } + } + } + delete(st); + } + else still_valid = true; + else // if not satisfied, then repair it with prob_repairbrokensentence + if (random()gethashtable()); + + if (st->initializestate(globalmodel)) + { + for (int j=0; jgetnumpredicates(); j++) + { + CoercePredicate *cp = s->getpredicate(j); + Action *action = repair->findrepairaction(cp); + action->repairpredicate(st->env, cp); + +#ifdef DEBUGMESSAGES + printf("After action->repairpredicate was called\n"); + fflush(NULL); +#endif + } + } + + delete(st); + still_valid = true; + } + } + + if (!still_valid) // if all sentences are broken, repair the first one + { + CoerceSentence *saux = nf->getsentence(0); + // first, select an arbitrary binding, for ex. the first one + State *st = new State(c, globalmodel->gethashtable()); + + if (st->initializestate(globalmodel)) + { + for (int j=0; jgetnumpredicates(); j++) + { + CoercePredicate *cp = saux->getpredicate(j); + Action *action = repair->findrepairaction(cp); + action->repairpredicate(st->env, cp); + +#ifdef DEBUGMESSAGES + printf("After action->repairpredicate was called\n"); + fflush(NULL); +#endif + } + } + + delete(st); + } + +} + + +processobject::~processobject() { +} + + +// computes ve = V.R +Element * evaluatevalueexpr(Valueexpr *ve, Hashtable *env, model *m) { + Element *e=NULL; + if (ve->gettype()==0) { + e=(Element *) env->get(ve->getlabel()->label()); + } else + e=evaluatevalueexpr(ve->getvalueexpr(),env,m); + if (e==NULL) + return e; + if (ve->getinverted()) + return (Element *)m->getdomainrelation()->getrelation(ve->getrelation()->getname())->getrelation()->invgetobj(e); + else + return (Element *)m->getdomainrelation()->getrelation(ve->getrelation()->getname())->getrelation()->getobj(e); +} + + + +// evaluates E = V | number | string | E-E | E+E | E*E | E/E | E.R |size(SE) +Element * evaluateexpr(Elementexpr *ee, Hashtable *env, model *m) { + switch(ee->gettype()) { + case ELEMENTEXPR_LABEL: { + return new Element((Element *)env->get(ee->getlabel()->label())); + } + case ELEMENTEXPR_SUB: { + Elementexpr *left=ee->getleft(); + Elementexpr *right=ee->getright(); + Element *leftval=evaluateexpr(left,env,m); + if(leftval==NULL) return NULL; + Element *rightval=evaluateexpr(right,env,m); + if(rightval==NULL) {delete(leftval);return NULL;} + Element *diff=new Element(leftval->intvalue()-rightval->intvalue()); + delete(leftval);delete(rightval); + return diff; + } + case ELEMENTEXPR_ADD: { + Elementexpr *left=ee->getleft(); + Elementexpr *right=ee->getright(); + Element *leftval=evaluateexpr(left,env,m); + if(leftval==NULL) return NULL; + Element *rightval=evaluateexpr(right,env,m); + if(rightval==NULL) {delete(leftval);return NULL;} + Element *sum=new Element(leftval->intvalue()+rightval->intvalue()); + delete(leftval);delete(rightval); + return sum; + } + case ELEMENTEXPR_RELATION: { + Elementexpr *left=ee->getleft(); + Relation *rel=ee->getrelation(); + Element *leftval=evaluateexpr(left,env,m); + if(leftval==NULL) return NULL; + Element *retval=(Element *)m->getdomainrelation()->getrelation(rel->getname())->getrelation()->getobj(leftval); + delete(leftval); + return new Element(retval); + } + case ELEMENTEXPR_MULT: { + Elementexpr *left=ee->getleft(); + Elementexpr *right=ee->getright(); + Element *leftval=evaluateexpr(left,env,m); + if(leftval==NULL) return NULL; + Element *rightval=evaluateexpr(right,env,m); + if(rightval==NULL) {delete(leftval);return NULL;} + Element *diff=new Element(leftval->intvalue()*rightval->intvalue()); + delete(leftval);delete(rightval); + return diff; + } + case ELEMENTEXPR_LIT: { + Literal *l=ee->getliteral(); + switch(l->gettype()) { + case LITERAL_NUMBER: + return new Element(l->number()); + case LITERAL_TOKEN: + return new Element(copystr(l->token())); + default: + printf("ERROR with lit type\n"); + exit(-1); + } + } + /* case ELEMENTEXPR_PARAM: { + Element *ele=evaluateexpr(ee->getleft(),env,m); + Element *eec=ele->paramvalue(ee->getliteral()->number()); + Element *retval=new Element(eec); + delete(ele); + return eec; + }*/ //NO OBJECT PARAMETERS + case ELEMENTEXPR_SETSIZE: + Setexpr * setexpr=ee->getsetexpr(); + switch(setexpr->gettype()) { + case SETEXPR_LABEL: + return new Element(m->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->size()); + case SETEXPR_REL: { + Element *key=(Element *)env->get(setexpr->getlabel()->label()); + WorkSet *ws=m->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(key); + if (ws==NULL) + return new Element(0); + else + return new Element(ws->size()); + } + case SETEXPR_INVREL: { + Element *key=(Element *)env->get(setexpr->getlabel()->label()); + WorkSet *ws=m->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(key); + if (ws==NULL) + return new Element(0); + else + return new Element(ws->size()); + } + } + break; + } +} diff --git a/Repair/RepairInterpreter/processobject.h b/Repair/RepairInterpreter/processobject.h new file mode 100755 index 0000000..595433f --- /dev/null +++ b/Repair/RepairInterpreter/processobject.h @@ -0,0 +1,32 @@ +// evaluates constraints in the ICL + + +#ifndef PROCESSOBJECT_H +#define PROCESSOBJECT_H +#include "classlist.h" + +#define PTRUE 1 +#define PFALSE 0 +#define PFAIL -1 + +class processobject { + public: + processobject(model *m); + int processpredicate(Predicate *p, Hashtable *env); + bool issatisfied(Constraint *c); // returns true iff c is satisfied + bool processconstraint(Constraint *c); // evaluates c and if it's not satisfied, calls the repair alg. + void breakconstraint(Constraint *c); // breaks the given constraint by invalidating each of its satisfied sentences + void modifyconstraint(Constraint *c); // modifies the given constraint + void setclean(); + ~processobject(); + void printstats(); + + private: + Repair * repair; + int processstatement(Statement *s, Hashtable *env); + model * globalmodel; +}; + +Element * evaluateexpr(Elementexpr *ee, Hashtable *env, model *m); +Element * evaluatevalueexpr(Valueexpr *ve, Hashtable *env, model *m); +#endif diff --git a/Repair/RepairInterpreter/redblack.c b/Repair/RepairInterpreter/redblack.c new file mode 100755 index 0000000..1238b2a --- /dev/null +++ b/Repair/RepairInterpreter/redblack.c @@ -0,0 +1,985 @@ +static char rcsid[]="$Id: redblack.c,v 1.1 2004/05/06 21:16:22 bdemsky Exp $"; + +/* + Redblack balanced tree algorithm + Copyright (C) Damian Ivereigh 2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. See the file COPYING for details. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Implement the red/black tree structure. It is designed to emulate +** the standard tsearch() stuff. i.e. the calling conventions are +** exactly the same +*/ + +#include +#include +#include +#include "redblack.h" +//#include "dmalloc.h" + +#define assert(expr) +#define RB_TRUE 1 +#define RB_FALSE 0 + +/* Uncomment this if you would rather use a raw sbrk to get memory +** (however the memory is never released again (only re-used). Can't +** see any point in using this these days. +*/ +/* #define USE_SBRK */ + +enum nodecolour { BLACK, RED }; + +struct rbnode { + struct rbnode *left; /* Left down */ + struct rbnode *right; /* Right down */ + struct rbnode *up; /* Up */ + enum nodecolour colour; /* Node colour */ + const void *key; /* Pointer to user's key (and data) */ + const void *high; + const void *max; + void *object; +}; + +/* Dummy (sentinel) node, so that we can make X->left->up = X +** We then use this instead of NULL to mean the top or bottom +** end of the rb tree. It is a black node. +*/ +struct rbnode rb_null={&rb_null, &rb_null, &rb_null, BLACK, NULL,NULL,NULL,NULL}; +#define RBNULL (&rb_null) + +#if defined(USE_SBRK) + +static struct rbnode *rb_alloc(); +static void rb_free(struct rbnode *); + +#else + +#define rb_alloc() ((struct rbnode *) malloc(sizeof(struct rbnode))) +#define rb_free(x) (free(x)) + +#endif + +static struct rbnode *rb_traverse(const void *, struct rbtree *); +static struct rbnode *rb_lookup(const void *low,const void *high, struct rbtree *); +static void rb_destroy(struct rbnode *,void (*)(void *)); +static void rb_left_rotate(struct rbnode **, struct rbnode *); +static void rb_right_rotate(struct rbnode **, struct rbnode *); +static void rb_delete(struct rbnode **, struct rbnode *); +static void rb_delete_fix(struct rbnode **, struct rbnode *); +static struct rbnode *rb_successor(const struct rbnode *); +static struct rbnode *rb_preccessor(const struct rbnode *); +static void rb_walk(const struct rbnode *, void (*)(const void *, const VISIT, const int, void *), void *, int); +static RBLIST *rb_openlist(const struct rbnode *); +static const void *rb_readlist(RBLIST *); +static void rb_closelist(RBLIST *); + +/* +** OK here we go, the balanced tree stuff. The algorithm is the +** fairly standard red/black taken from "Introduction to Algorithms" +** by Cormen, Leiserson & Rivest. Maybe one of these days I will +** fully understand all this stuff. +** +** Basically a red/black balanced tree has the following properties:- +** 1) Every node is either red or black (colour is RED or BLACK) +** 2) A leaf (RBNULL pointer) is considered black +** 3) If a node is red then its children are black +** 4) Every path from a node to a leaf contains the same no +** of black nodes +** +** 3) & 4) above guarantee that the longest path (alternating +** red and black nodes) is only twice as long as the shortest +** path (all black nodes). Thus the tree remains fairly balanced. +*/ + +/* + * Initialise a tree. Identifies the comparison routine and any config + * data that must be sent to it when called. + * Returns a pointer to the top of the tree. + */ +struct rbtree * rbinit() { + struct rbtree *retval; + char c; + + c=rcsid[0]; /* This does nothing but shutup the -Wall */ + + if ((retval=(struct rbtree *) malloc(sizeof(struct rbtree)))==NULL) + return(NULL); + + retval->rb_root=RBNULL; + + return(retval); +} + +void rbdestroy(struct rbtree *rbinfo, void (*free_function)(void *)) { + if (rbinfo==NULL) + return; + + if (rbinfo->rb_root!=RBNULL) + rb_destroy(rbinfo->rb_root,free_function); + + free(rbinfo); +} + +const void * rbdelete(const void *key, struct rbtree *rbinfo) { + struct rbnode *x; + const void *y; + + if (rbinfo==NULL) + return(NULL); + + x=rb_traverse(key, rbinfo); + + if (x==RBNULL) { + return(NULL); + } else { + y=x->key; + rb_delete(&rbinfo->rb_root, x); + + return(y); + } +} + +void rbwalk(const struct rbtree *rbinfo, void (*action)(const void *, const VISIT, const int, void *), void *arg) { + if (rbinfo==NULL) + return; + + rb_walk(rbinfo->rb_root, action, arg, 0); +} + +RBLIST * rbopenlist(const struct rbtree *rbinfo) { + if (rbinfo==NULL) + return(NULL); + + return(rb_openlist(rbinfo->rb_root)); +} + +const void * rbreadlist(RBLIST *rblistp) { + if (rblistp==NULL) + return(NULL); + + return(rb_readlist(rblistp)); +} + +void rbcloselist(RBLIST *rblistp) { + if (rblistp==NULL) + return; + + rb_closelist(rblistp); +} + +/** + * finds an overlapping region with low->high and returns the object associated with + * that region + */ +void * rblookup(const void *low,const void *high, struct rbtree *rbinfo) { + struct rbnode *x; + + /* If we have a NULL root (empty tree) then just return NULL */ + if (rbinfo==NULL || rbinfo->rb_root==NULL) + return(NULL); + + x=rb_lookup(low, high, rbinfo); + + return((x==RBNULL) ? NULL : x->object); +} + +/** + * finds an overlapping region with low->high and returns the pair + */ +struct pair rbfind(const void *low,const void *high, struct rbtree *rbinfo) { + struct rbnode *x; + struct pair p; + /* If we have a NULL root (empty tree) then just return NULL */ + + p.low=NULL; + p.high=NULL; + if (rbinfo==NULL || rbinfo->rb_root==NULL) + return p; + + x=rb_lookup(low, high, rbinfo); + if (x!=NULL) { + p.low=x->key; + p.high=x->high; + } + return p; +} + + +/* --------------------------------------------------------------------- */ + +/* Search for and if not found and insert is true, will add a new +** node in. Returns a pointer to the new node, or the node found +*/ +int rbinsert(const void *key, const void * high, void *object,struct rbtree *rbinfo) { + struct rbnode *x,*y,*z, *tmp; + const void *max; + int found=0; + + y=RBNULL; /* points to the parent of x */ + x=rbinfo->rb_root; + + /* walk x down the tree */ + while(x!=RBNULL && found==0) { + y=x; + /* printf("key=%s, x->key=%s\n", key, x->key); */ + + if (keykey) + x=x->left; + else if (key>x->key) + x=x->right; + else + found=1; + } + + if (found) + return RB_FALSE; + + if ((z=rb_alloc())==NULL) { + /* Whoops, no memory */ + return RB_FALSE; + } + + z->object=object; + z->high=high; + z->key=key; + z->max=high; + z->up=y; + tmp=y; + max=high; + while(tmp!=RBNULL) { + if (max>tmp->max) + tmp->max=max; + else + max=tmp->max; + tmp=tmp->up; + } + + if (y==RBNULL) { + rbinfo->rb_root=z; + } else { + if (z->keykey) + y->left=z; + else + y->right=z; + } + + z->left=RBNULL; + z->right=RBNULL; + + /* colour this new node red */ + z->colour=RED; + + /* Having added a red node, we must now walk back up the tree balancing + ** it, by a series of rotations and changing of colours + */ + x=z; + + /* While we are not at the top and our parent node is red + ** N.B. Since the root node is garanteed black, then we + ** are also going to stop if we are the child of the root + */ + + while(x != rbinfo->rb_root && (x->up->colour == RED)) { + /* if our parent is on the left side of our grandparent */ + if (x->up == x->up->up->left) { + /* get the right side of our grandparent (uncle?) */ + y=x->up->up->right; + if (y->colour == RED) { + /* make our parent black */ + x->up->colour = BLACK; + /* make our uncle black */ + y->colour = BLACK; + /* make our grandparent red */ + x->up->up->colour = RED; + + /* now consider our grandparent */ + x=x->up->up; + } else { + /* if we are on the right side of our parent */ + if (x == x->up->right) { + /* Move up to our parent */ + x=x->up; + rb_left_rotate(&rbinfo->rb_root, x); + } + + /* make our parent black */ + x->up->colour = BLACK; + /* make our grandparent red */ + x->up->up->colour = RED; + /* right rotate our grandparent */ + rb_right_rotate(&rbinfo->rb_root, x->up->up); + } + } else { + /* everything here is the same as above, but + ** exchanging left for right + */ + + y=x->up->up->left; + if (y->colour == RED) { + x->up->colour = BLACK; + y->colour = BLACK; + x->up->up->colour = RED; + + x=x->up->up; + } else { + if (x == x->up->left) { + x=x->up; + rb_right_rotate(&rbinfo->rb_root, x); + } + + x->up->colour = BLACK; + x->up->up->colour = RED; + rb_left_rotate(&rbinfo->rb_root, x->up->up); + } + } + } + + /* Set the root node black */ + (rbinfo->rb_root)->colour = BLACK; + + return RB_TRUE; +} + +/* Search for and if not found and insert is true, will add a new +** node in. Returns a pointer to the new node, or the node found +*/ +static struct rbnode * rb_traverse(const void *key, struct rbtree *rbinfo) { + struct rbnode *x,*y,*z; + int found=0; + + y=RBNULL; /* points to the parent of x */ + x=rbinfo->rb_root; + + /* walk x down the tree */ + while(x!=RBNULL && found==0) { + y=x; + if (keykey) + x=x->left; + else if (key>x->key) + x=x->right; + else + found=1; + } + + if (found) + return(x); + return NULL; +} + +/* Search for a key according (see redblack.h) +*/ +static struct rbnode * rb_lookup(const void *low, const void *high, struct rbtree *rbinfo) { + struct rbnode *x; + + x=rbinfo->rb_root; + + /* walk x down the tree */ + while(x!=RBNULL) { + if (lowhigh && + x->keyleft!=RBNULL && x->left->max>low) + x=x->left; + else + x=x->right; + } + + return(RBNULL); +} + +/* Search for a key according (see redblack.h) +*/ +int rbsearch(const void *low, const void *high, struct rbtree *rbinfo) { + struct rbnode *x; + if (rbinfo==NULL) + return RB_FALSE; + + x=rbinfo->rb_root; + + /* walk x down the tree */ + while(x!=RBNULL) { + if (lowhigh && + x->keyleft!=RBNULL && x->left->max>low) + x=x->left; + else + x=x->right; + } + + return RB_FALSE; +} + +/* + * Destroy all the elements blow us in the tree + * only useful as part of a complete tree destroy. + */ +static void rb_destroy(struct rbnode *x,void (*free_function)(void *)) { + if (x!=RBNULL) { + if (x->left!=RBNULL) + rb_destroy(x->left,free_function); + if (x->right!=RBNULL) + rb_destroy(x->right,free_function); + if (free_function!=NULL) + free_function(x->object); + rb_free(x); + } +} + +/* +** Rotate our tree thus:- +** +** X rb_left_rotate(X)---> Y +** / \ / \ +** A Y <---rb_right_rotate(Y) X C +** / \ / \ +** B C A B +** +** N.B. This does not change the ordering. +** +** We assume that neither X or Y is NULL +*/ + +static void rb_left_rotate(struct rbnode **rootp, struct rbnode *x) { + struct rbnode *y; + const void *max; + assert(x!=RBNULL); + assert(x->right!=RBNULL); + + y=x->right; /* set Y */ + + /* Turn Y's left subtree into X's right subtree (move B)*/ + x->right = y->left; + + /* If B is not null, set it's parent to be X */ + if (y->left != RBNULL) + y->left->up = x; + + /* Set Y's parent to be what X's parent was */ + y->up = x->up; + + /* if X was the root */ + if (x->up == RBNULL) { + *rootp=y; + } else { + /* Set X's parent's left or right pointer to be Y */ + if (x == x->up->left) { + x->up->left=y; + } else { + x->up->right=y; + } + } + + /* Put X on Y's left */ + y->left=x; + + /* Set X's parent to be Y */ + x->up = y; + + y->max=x->max; /* compute Y's max */ + max=NULL; + + if (x->left!=RBNULL) + max=x->left->max; + + if (x->right!=RBNULL&& + x->right->max>max) + max=x->right->max; + if (x->high>max) + max=x->high; + x->max=max; +} + +static void rb_right_rotate(struct rbnode **rootp, struct rbnode *y) { + struct rbnode *x; + const void *max; + + assert(y!=RBNULL); + assert(y->left!=RBNULL); + + x=y->left; /* set X */ + + /* Turn X's right subtree into Y's left subtree (move B) */ + y->left = x->right; + + /* If B is not null, set it's parent to be Y */ + if (x->right != RBNULL) + x->right->up = y; + + /* Set X's parent to be what Y's parent was */ + x->up = y->up; + + /* if Y was the root */ + if (y->up == RBNULL) { + *rootp=x; + } else { + /* Set Y's parent's left or right pointer to be X */ + if (y == y->up->left) { + y->up->left=x; + } else { + y->up->right=x; + } + } + + /* Put Y on X's right */ + x->right=y; + + /* Set Y's parent to be X */ + y->up = x; + + x->max=y->max; /* compute Y's max */ + max=NULL; + + if (y->left!=RBNULL) + max=y->left->max; + + if (y->right!=RBNULL&& + y->right->max>max) + max=y->right->max; + if (y->high>max) + max=y->high; + y->max=max; +} + +/* Return a pointer to the smallest key greater than x +*/ +static struct rbnode * rb_successor(const struct rbnode *x) { + struct rbnode *y; + + if (x->right!=RBNULL) { + /* If right is not NULL then go right one and + ** then keep going left until we find a node with + ** no left pointer. + */ + for (y=x->right; y->left!=RBNULL; y=y->left); + } else { + /* Go up the tree until we get to a node that is on the + ** left of its parent (or the root) and then return the + ** parent. + */ + y=x->up; + while(y!=RBNULL && x==y->right) { + x=y; + y=y->up; + } + } + return(y); +} + +/* Return a pointer to the largest key smaller than x +*/ +static struct rbnode * rb_preccessor(const struct rbnode *x) { + struct rbnode *y; + + if (x->left!=RBNULL) { + /* If left is not NULL then go left one and + ** then keep going right until we find a node with + ** no right pointer. + */ + for (y=x->left; y->right!=RBNULL; y=y->right); + } else { + /* Go up the tree until we get to a node that is on the + ** right of its parent (or the root) and then return the + ** parent. + */ + y=x->up; + while(y!=RBNULL && x==y->left) { + x=y; + y=y->up; + } + } + return(y); +} + +/* Delete the node z, and free up the space +*/ +static void rb_delete(struct rbnode **rootp, struct rbnode *z) { + struct rbnode *x, *y, *tmp; + const void *max; + + if (z->left == RBNULL || z->right == RBNULL) + y=z; + else + y=rb_successor(z); + + if (y->left != RBNULL) + x=y->left; + else + x=y->right; + + x->up = y->up; + + if (y->up == RBNULL) { + *rootp=x; + } else { + if (y==y->up->left) + y->up->left = x; + else + y->up->right = x; + } + + if (y!=z) { + z->key = y->key; + z->high=y->high; + z->object=y->object; + } + tmp=y->up; + while(tmp!=RBNULL) { + max=NULL; + if (tmp->left!=RBNULL) + max=tmp->left->max; + if (tmp->right!=RBNULL&& + tmp->right->max>max) + max=tmp->right->max; + if (tmp->high>max) + max=tmp->high; + tmp->max=max; + tmp=tmp->up; + } + if (y->colour == BLACK) + rb_delete_fix(rootp, x); + + rb_free(y); +} + +/* Restore the reb-black properties after a delete */ +static void rb_delete_fix(struct rbnode **rootp, struct rbnode *x) { + struct rbnode *w; + + while (x!=*rootp && x->colour==BLACK) { + if (x==x->up->left) { + w=x->up->right; + if (w->colour==RED) { + w->colour=BLACK; + x->up->colour=RED; + rb_left_rotate(rootp, x->up); + w=x->up->right; + } + if (w->left->colour==BLACK && w->right->colour==BLACK) { + w->colour=RED; + x=x->up; + } else { + if (w->right->colour == BLACK) { + w->left->colour=BLACK; + w->colour=RED; + rb_right_rotate(rootp, w); + w=x->up->right; + } + w->colour=x->up->colour; + x->up->colour = BLACK; + w->right->colour = BLACK; + rb_left_rotate(rootp, x->up); + x=*rootp; + } + } else { + w=x->up->left; + if (w->colour==RED) { + w->colour=BLACK; + x->up->colour=RED; + rb_right_rotate(rootp, x->up); + w=x->up->left; + } + if (w->right->colour==BLACK && w->left->colour==BLACK) { + w->colour=RED; + x=x->up; + } else { + if (w->left->colour == BLACK) { + w->right->colour=BLACK; + w->colour=RED; + rb_left_rotate(rootp, w); + w=x->up->left; + } + w->colour=x->up->colour; + x->up->colour = BLACK; + w->left->colour = BLACK; + rb_right_rotate(rootp, x->up); + x=*rootp; + } + } + } + + x->colour=BLACK; +} + +static void +rb_walk(const struct rbnode *x, void (*action)(const void *, const VISIT, const int, void *), void *arg, int level) { + if (x==RBNULL) + return; + + if (x->left==RBNULL && x->right==RBNULL) { + /* leaf */ + (*action)(x->key, leaf, level, arg); + } else { + (*action)(x->key, preorder, level, arg); + + rb_walk(x->left, action, arg, level+1); + + (*action)(x->key, postorder, level, arg); + + rb_walk(x->right, action, arg, level+1); + + (*action)(x->key, endorder, level, arg); + } +} + +static RBLIST * rb_openlist(const struct rbnode *rootp) { + RBLIST *rblistp; + + rblistp=(RBLIST *) malloc(sizeof(RBLIST)); + if (!rblistp) + return(NULL); + + rblistp->rootp=rootp; + rblistp->nextp=rootp; + + if (rootp!=RBNULL) { + while(rblistp->nextp->left!=RBNULL) { + rblistp->nextp=rblistp->nextp->left; + } + } + + return(rblistp); +} + +static const void * rb_readlist(RBLIST *rblistp) { + const void *key=NULL; + + if (rblistp!=NULL && rblistp->nextp!=RBNULL) { + key=rblistp->nextp->key; + rblistp->nextp=rb_successor(rblistp->nextp); + } + + return(key); +} + +static void rb_closelist(RBLIST *rblistp) { + if (rblistp) + free(rblistp); +} + +#if defined(USE_SBRK) +/* Allocate space for our nodes, allowing us to get space from +** sbrk in larger chucks. +*/ +static struct rbnode *rbfreep=NULL; + +#define RBNODEALLOC_CHUNK_SIZE 1000 +static struct rbnode * rb_alloc() { + struct rbnode *x; + int i; + + if (rbfreep==NULL) { + /* must grab some more space */ + rbfreep=(struct rbnode *) sbrk(sizeof(struct rbnode) * RBNODEALLOC_CHUNK_SIZE); + + if (rbfreep==(struct rbnode *) -1) { + return(NULL); + } + + /* tie them together in a linked list (use the up pointer) */ + for (i=0, x=rbfreep; iup = (x+1); + } + x->up=NULL; + } + + x=rbfreep; + rbfreep = rbfreep->up; + return(x); +} + +/* free (dealloc) an rbnode structure - add it onto the front of the list +** N.B. rbnode need not have been allocated through rb_alloc() +*/ +static void rb_free(struct rbnode *x) { + x->up=rbfreep; + rbfreep=x; +} + +#endif + +#if 0 +int rb_check(struct rbnode *rootp) { + if (rootp==NULL || rootp==RBNULL) + return(0); + + if (rootp->up!=RBNULL) { + fprintf(stderr, "Root up pointer not RBNULL"); + dumptree(rootp, 0); + return(1); + } + + if (rb_check1(rootp)) { + dumptree(rootp, 0); + return(1); + } + + if (count_black(rootp)==-1) + { + dumptree(rootp, 0); + return(-1); + } + + return(0); +} + +int +rb_check1(struct rbnode *x) +{ + if (x->left==NULL || x->right==NULL) + { + fprintf(stderr, "Left or right is NULL"); + return(1); + } + + if (x->colour==RED) + { + if (x->left->colour!=BLACK && x->right->colour!=BLACK) + { + fprintf(stderr, "Children of red node not both black, x=%ld", x); + return(1); + } + } + + if (x->left != RBNULL) + { + if (x->left->up != x) + { + fprintf(stderr, "x->left->up != x, x=%ld", x); + return(1); + } + + if (rb_check1(x->left)) + return(1); + } + + if (x->right != RBNULL) + { + if (x->right->up != x) + { + fprintf(stderr, "x->right->up != x, x=%ld", x); + return(1); + } + + if (rb_check1(x->right)) + return(1); + } + return(0); +} + +count_black(struct rbnode *x) +{ + int nleft, nright; + + if (x==RBNULL) + return(1); + + nleft=count_black(x->left); + nright=count_black(x->right); + + if (nleft==-1 || nright==-1) + return(-1); + + if (nleft != nright) + { + fprintf(stderr, "Black count not equal on left & right, x=%ld", x); + return(-1); + } + + if (x->colour == BLACK) + { + nleft++; + } + + return(nleft); +} + +dumptree(struct rbnode *x, int n) +{ + char *prkey(); + + if (x!=NULL && x!=RBNULL) + { + n++; + fprintf(stderr, "Tree: %*s %ld: left=%ld, right=%ld, colour=%s, key=%s", + n, + "", + x, + x->left, + x->right, + (x->colour==BLACK) ? "BLACK" : "RED", + prkey(x->key)); + + dumptree(x->left, n); + dumptree(x->right, n); + } +} +#endif + +/* + * $Log: redblack.c,v $ + * Revision 1.1 2004/05/06 21:16:22 bdemsky + * Moved the interpreter + * + * Revision 1.6 2003/08/06 14:34:10 droy + * test + * + * Revision 1.5 2003/06/18 18:39:05 bdemsky + * + * + * Changed header files/etc to allow dmalloc to easily be used. + * Changed some delete -> delete[] for correctness. + * Committed out parserange call. Cristian has some memory management bugs... + * + * Revision 1.4 2003/06/18 06:08:18 bdemsky + * + * + * Adding support for: + * 1) freeing the memory we use (imagine that)...will make dan's life easier & + * allow us to run cooler benchmarks. (not completed yet) + * 2) generating dot graphs of dependencies...not completed yet - the graphs aren't + * appropriately labeled. + * + * Revision 1.3 2003/06/18 06:06:18 bdemsky + * + * + * Added option to pass in function to free items in the redblack interval tree. + * + * Revision 1.5 2002/01/30 07:54:53 damo + * Fixed up the libtool versioning stuff (finally) + * Fixed bug 500600 (not detecting a NULL return from malloc) + * Fixed bug 509485 (no longer needs search.h) + * Cleaned up debugging section + * Allow multiple inclusions of redblack.h + * Thanks to Matthias Andree for reporting (and fixing) these + * + * Revision 1.4 2000/06/06 14:43:43 damo + * Added all the rbwalk & rbopenlist stuff. Fixed up malloc instead of sbrk. + * Added two new examples + * + * Revision 1.3 2000/05/24 06:45:27 damo + * Converted everything over to using const + * Added a new example1.c file to demonstrate the worst case scenario + * Minor fixups of the spec file + * + * Revision 1.2 2000/05/24 06:17:10 damo + * Fixed up the License (now the LGPL) + * + * Revision 1.1 2000/05/24 04:15:53 damo + * Initial import of files. Versions are now all over the place. Oh well + * + */ + diff --git a/Repair/RepairInterpreter/redblack.h b/Repair/RepairInterpreter/redblack.h new file mode 100755 index 0000000..c8d86b4 --- /dev/null +++ b/Repair/RepairInterpreter/redblack.h @@ -0,0 +1,120 @@ +/* + * RCS $Id: redblack.h,v 1.1 2004/05/06 21:16:22 bdemsky Exp $ + */ + +/* + Redblack balanced tree algorithm + Copyright (C) Damian Ivereigh 2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. See the file COPYING for details. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Header file for redblack.c, should be included by any code that +** uses redblack.c since it defines the functions +*/ + +/* Stop multiple includes */ +#ifndef _REDBLACK_H + +/* For rbwalk - pinched from search.h */ +typedef enum { + preorder, + postorder, + endorder, + leaf +} VISIT; + +struct rblists { + const struct rbnode *rootp; + const struct rbnode *nextp; +}; + +#define RBLIST struct rblists + +struct rbtree { + /* root of tree */ + struct rbnode *rb_root; +}; + +struct pair { + const void *low,*high; +}; + +struct rbtree *rbinit(); +int rbinsert(const void *low, const void * high, void *object,struct rbtree *rbinfo); +struct pair rbfind(const void *low,const void *high, struct rbtree *rbinfo); +const void *rbdelete(const void *, struct rbtree *); +void *rblookup(const void *, const void *,struct rbtree *); +int rbsearch(const void *low, const void *high, struct rbtree *rbinfo); +void rbdestroy(struct rbtree *,void (*free_function)(void *)); +void rbwalk(const struct rbtree *, + void (*)(const void *, const VISIT, const int, void *), + void *); +RBLIST *rbopenlist(const struct rbtree *); +const void *rbreadlist(RBLIST *); +void rbcloselist(RBLIST *); + +/* Some useful macros */ +#define rbmin(rbinfo) rblookup(RB_LUFIRST, NULL, (rbinfo)) +#define rbmax(rbinfo) rblookup(RB_LULAST, NULL, (rbinfo)) + +#define _REDBLACK_H +#endif /* _REDBLACK_H */ + +/* + * + * $Log: redblack.h,v $ + * Revision 1.1 2004/05/06 21:16:22 bdemsky + * Moved the interpreter + * + * Revision 1.4 2003/06/18 06:08:18 bdemsky + * + * + * Adding support for: + * 1) freeing the memory we use (imagine that)...will make dan's life easier & + * allow us to run cooler benchmarks. (not completed yet) + * 2) generating dot graphs of dependencies...not completed yet - the graphs aren't + * appropriately labeled. + * + * Revision 1.2 2003/06/18 06:06:18 bdemsky + * + * + * Added option to pass in function to free items in the redblack interval tree. + * + * Revision 1.5 2002/01/30 07:54:53 damo + * Fixed up the libtool versioning stuff (finally) + * Fixed bug 500600 (not detecting a NULL return from malloc) + * Fixed bug 509485 (no longer needs search.h) + * Cleaned up debugging section + * Allow multiple inclusions of redblack.h + * Thanks to Matthias Andree for reporting (and fixing) these + * + * Revision 1.4 2000/06/06 14:43:43 damo + * Added all the rbwalk & rbopenlist stuff. Fixed up malloc instead of sbrk. + * Added two new examples + * + * Revision 1.3 2000/05/24 06:45:27 damo + * Converted everything over to using const + * Added a new example1.c file to demonstrate the worst case scenario + * Minor fixups of the spec file + * + * Revision 1.2 2000/05/24 06:17:10 damo + * Fixed up the License (now the LGPL) + * + * Revision 1.1 2000/05/24 04:15:53 damo + * Initial import of files. Versions are now all over the place. Oh well + * + */ + diff --git a/Repair/RepairInterpreter/repair.cc b/Repair/RepairInterpreter/repair.cc new file mode 100755 index 0000000..fa77c24 --- /dev/null +++ b/Repair/RepairInterpreter/repair.cc @@ -0,0 +1,409 @@ +#include +#include +#include "repair.h" +#include "model.h" +#include "normalizer.h" +#include "list.h" +#include "Action.h" +#include "processobject.h" +#include "ActionInSet.h" +#include "ActionNotInSet.h" +#include "ActionGEQ1.h" +#include "ActionEQ1.h" +#include "ActionAssign.h" +#include "ActionNormal.h" +#include "Relation.h" +#include "omodel.h" +#include "dmodel.h" +#include "set.h" +#include "common.h" +#include "fieldcheck.h" +#include "Hashtable.h" + +Repair::Repair(model *m) { + globalmodel=m; + removedsentences=NULL; + List *list=new List(); + /* list->addobject(); --build action array */ + list->addobject(new ActionGEQ1(m->getdomainrelation(),m)); + list->addobject(new ActionEQ1(m->getdomainrelation(),m)); + list->addobject(new ActionAssign(m->getdomainrelation(),m)); + // list->addobject(new ActionNotAssign(m->getdomainrelation())); + list->addobject(new ActionInSet(m->getdomainrelation(),m)); + list->addobject(new ActionNotInSet(m->getdomainrelation(),m)); + numactions=list->size(); + repairactions=new Action *[list->size()]; + list->toArray((void **)repairactions); + delete(list); +} + + +void Repair::repaireleexpr(Constraint *c, processobject *po, Elementexpr *ee, Hashtable *env) { + /* We're here because we have a bad elementexpr */ + switch(ee->gettype()) { + case ELEMENTEXPR_SUB: + case ELEMENTEXPR_ADD: + case ELEMENTEXPR_MULT: + repaireleexpr(c,po,ee->getleft(),env); + repaireleexpr(c,po,ee->getright(),env); + return; + case ELEMENTEXPR_RELATION: { + /* Could have problem here */ + repaireleexpr(c,po,ee->getleft(),env); + Element *e=evaluateexpr(ee,env,globalmodel); + if (e==NULL) { + /* found bad relation */ + FieldCheck *fc=globalmodel->getfieldcheck(); + char *set=NULL; + + { + Elementexpr *left=ee->getleft(); + int tleft=left->gettype(); + if (tleft==ELEMENTEXPR_LABEL) { + set=getset(c, left->getlabel()->label()); + } else if (tleft==ELEMENTEXPR_RELATION) { + DRelation *drl=globalmodel->getdomainrelation()->getrelation(left->getrelation()->getname()); + set=drl->getrange(); + } else { + ee->print(); + printf("Can't determine domain-shouldn't be here because of static analysis...\n"); + exit(-1); + } + } + + Element *e2=evaluateexpr(ee->getleft(),env,globalmodel); + int index=fc->getindexthatprovides(ee->getrelation()->getname(), set); + Hashtable *env2=new Hashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings); + env2->setparent(env); + Constraint *crep=globalmodel->getconstraint(index); + DomainRelation *dr=globalmodel->getdomainrelation(); + for(int j=0;jnumquants();j++) { + Quantifier *qrep=crep->getquant(j); + char *label=qrep->getlabel()->label(); + char *setname=qrep->getset()->getname(); + DomainSet *dset=dr->getset(setname); + if (dset->getset()->contains(e2)) { + env2->put(label,e2); + } else { + env2->put(label,dset->getset()->firstelement()); /*This shouldn't happen right now*/ + printf("Funnyness in repair.cc\n"); + } + } + this->repairconstraint(globalmodel->getconstraint(index),po,env2); + delete(e2); + delete(env2); + } else + delete(e); + return; + } + default: + return; + } +} + + +void Repair::repairconstraint(Constraint *c, processobject *po, Hashtable *env) { + NormalForm *nf=globalmodel->getnormalform(c); + CoerceSentence *coercionstate=nf->closestmatch(removedsentences,po,env); + /* Now we just need to coerce the predicates!!!*/ + for(int i=0;igetnumpredicates();i++) { + CoercePredicate *cp=coercionstate->getpredicate(i); + int status=po->processpredicate(cp->getpredicate(),env); + while (status==PFAIL) { + /* Bad dereference...need to fix things*/ + repaireleexpr(c, po,cp->getpredicate()->geteleexpr(), env); + status=po->processpredicate(cp->getpredicate(),env); + } + + if (status!=cp->getcoercebool()) { + /*Need to coerce*/ + Action *act=findrepairaction(cp); + act->repairpredicate(env,cp); + /* Data structure fixed - well eventually*/ + } + } +} + + +// returns the action that can repair the given predicate +Action * Repair::findrepairaction(CoercePredicate *cp) { + for(int i=0;icanrepairpredicate(cp)) + return repairactions[i]; + } + return NULL; +} + + + +// returns the action that can break the given predicate +Action * Repair::findbreakaction(CoercePredicate *cp) +{ + return findrepairaction(cp); +} + + +bool Repair::analyzetermination() { + WorkRelation *wr=new WorkRelation(true); + buildmap(wr); + /* Map built */ + WorkSet *cycleset=searchcycles(wr); + if (!cycleset->isEmpty()) { + WorkSet *removeedges=new WorkSet(true); + for(int i=1;i<=cycleset->size();i++) { + if (breakcycles(removeedges, i, cycleset,wr)) { + removedsentences=removeedges; + printf("Modified constraints for repairability!\n"); + outputgraph(removeedges, wr, "cycle.dot"); + return true; + } + } + delete(removeedges); + return false; + } else { + outputgraph(NULL,wr, "cycle.dot"); + return true; + } +} + + + +bool Repair::breakcycles(WorkSet *removeedge, int number, WorkSet *cyclelinks, WorkRelation *wr) { + for(CoerceSentence *cs=(CoerceSentence *)cyclelinks->firstelement(); + cs!=NULL;cs=(CoerceSentence *)cyclelinks->getnextelement(cs)) { + if (!removeedge->contains(cs)) { + removeedge->addobject(cs); + if (number==1) { + if (!checkforcycles(removeedge, wr)) + return true; + } else { + if (breakcycles(removeedge,number-1,cyclelinks,wr)) + return true; + } + removeedge->removeobject(cs); + } + } + return false; +} + +void Repair::outputgraph(WorkSet *removededges, WorkRelation *wr, char *filename) { + FILE * dotfile=fopen(filename,"w"); + fprintf(dotfile,"digraph cyclegraph {\n"); + fprintf(dotfile,"ratio=auto\n"); + for(int i=0;igetnumconstraints();i++) { + NormalForm *nf=globalmodel->getnormalform(i); + fprintf(dotfile, "%lu[label=\"",nf); + nf->fprint(dotfile); + fprintf(dotfile,"\"];\n"); + for(int j=0;jgetnumsentences();j++) { + CoerceSentence *cs=nf->getsentence(j); + for(int i=0;igetnumpredicates();i++) { + CoercePredicate *cp=cs->getpredicate(i); + fprintf(dotfile,"%lu -> %lu [style=dashed]\n",nf,cp); + WorkSet *setofnf=wr->getset(cp); + if (setofnf!=NULL) { + NormalForm *nf2=(NormalForm*)setofnf->firstelement(); + while(nf2!=NULL) { + /* cp interferes with nf2 */ + bool removed=(removededges!=NULL)&&removededges->contains(cs); /*tells what color of edge to generate*/ + if (removed) + fprintf(dotfile,"%lu -> %lu [style=dotted]\n",cp,nf2); + else + fprintf(dotfile,"%lu -> %lu\n",cp,nf2); + nf2=(NormalForm *)setofnf->getnextelement(nf2); + } + } + } + } + } + fprintf(dotfile,"}\n"); + fclose(dotfile); +} + +bool Repair::checkforcycles(WorkSet *removededges, WorkRelation *wr) { + /* Check that there are no cycles and + that system is solvable */ + for(int i=0;igetnumconstraints();i++) { + NormalForm *nf=globalmodel->getnormalform(i); + bool good=false; + for(int j=0;jgetnumsentences();j++) { + if (!removededges->contains(nf->getsentence(j))) { + CoerceSentence *cs=nf->getsentence(j); + bool allgood=true; + for(int k=0;kgetnumpredicates();k++) { + if(cs->getpredicate(k)->isrule()&& + findrepairaction(cs->getpredicate(k))==NULL) { + allgood=false; + break; + } + } + if(allgood) { + good=true; + break; + } + } + } + if (!good) + return true; + } + WorkSet *tmpset=new WorkSet(true); + for(int i=0;igetnumconstraints();i++) { + NormalForm *nf=globalmodel->getnormalform(i); + bool good=false; + for(int j=0;jgetnumsentences();j++) { + CoerceSentence *cs=nf->getsentence(j); + if (checkcycles(cs,removededges,tmpset,wr)) { + delete(tmpset); + return true; + } + } + } + delete(tmpset); + return false; /*yeah...no cycles*/ +} + + + +bool Repair::checkcycles(CoerceSentence *cs,WorkSet *removededges, WorkSet *searchset,WorkRelation *wr) { + if (searchset->contains(cs)) { + /* found cycle */ + return true; + } + if (removededges->contains(cs)) + return false; /* this edge is removed...don't consider it*/ + + searchset->addobject(cs); + for(int i=0;igetnumpredicates();i++) { + CoercePredicate *cp=cs->getpredicate(i); + WorkSet *setofnf=wr->getset(cp); + if (setofnf!=NULL) { + /* Might not mess up anything */ + NormalForm *nf=(NormalForm*)setofnf->firstelement(); + while(nf!=NULL) { + for(int j=0;jgetnumsentences();j++) { + CoerceSentence *cssearch=nf->getsentence(j); + if (checkcycles(cssearch, removededges, searchset, wr)) + return true; + } + nf=(NormalForm *)setofnf->getnextelement(nf); + } + } + } + searchset->removeobject(cs); + return false; +} + + + +WorkSet * Repair::searchcycles(WorkRelation *wr) { + /* Do cycle search */ + WorkSet *cycleset=new WorkSet(true); + WorkSet *searchset=new WorkSet(true); + for(int i=0;igetnumconstraints();i++) { + NormalForm *nf=globalmodel->getnormalform(i); + for(int j=0;jgetnumsentences();j++) { + detectcycles(nf->getsentence(j),searchset,cycleset,wr); + } + } + delete(searchset); + return cycleset; +} + + + +void Repair::detectcycles(CoerceSentence *cs,WorkSet *searchset,WorkSet *cycleset, WorkRelation *wr) { + if (searchset->contains(cs)) { + /* found cycle */ + CoerceSentence *csptr=(CoerceSentence *)searchset->firstelement(); + while(csptr!=NULL) { + cycleset->addobject(csptr); + csptr=(CoerceSentence *)searchset->getnextelement(csptr); + } + return; + } + searchset->addobject(cs); + for(int i=0;igetnumpredicates();i++) { + CoercePredicate *cp=cs->getpredicate(i); + WorkSet *setofnf=wr->getset(cp); + if (setofnf!=NULL) { + /* Might not have any interference edges*/ + NormalForm *nf=(NormalForm*)setofnf->firstelement(); + while(nf!=NULL) { + for(int j=0;jgetnumsentences();j++) { + CoerceSentence *cssearch=nf->getsentence(j); + detectcycles(cssearch, searchset, cycleset, wr); + } + nf=(NormalForm*)setofnf->getnextelement(nf); + } + } + } + searchset->removeobject(cs); +} + + + +void Repair::buildmap(WorkRelation *wr) { + for(int i=0;igetnumconstraints();i++) { + NormalForm *nf=globalmodel->getnormalform(i); + for(int j=0;jgetnumsentences();j++) { + CoerceSentence *cs=nf->getsentence(j); + for (int k=0;kgetnumpredicates();k++) { + Action *repairaction=findrepairaction(cs->getpredicate(k)); + if (repairaction==NULL) { + /* Nothing will repair this */ + cs->getpredicate(k)->getpredicate()->print(); + printf(" can't be repaired!!!"); + exit(-1); + } + checkpredicate(repairaction,wr, globalmodel->getconstraint(i),cs->getpredicate(k)); + } + } + } + ActionNormal *repairnormal=new ActionNormal(globalmodel); + for(int i=0;igetnumrulenormal();i++) { + NormalForm *nf=globalmodel->getrulenormal(i); + CoercePredicate *cpo=nf->getsentence(0)->getpredicate(0); + /* Check for conflicts between abstraction functions */ + for(int j=0;jgetnumrulenormal();j++) { + NormalForm *nfn=globalmodel->getrulenormal(j); + CoercePredicate *cpn=nfn->getsentence(0)->getpredicate(0); + if (!cpo->istuple()&& + equivalentstrings(cpo->getrelset(),cpn->gettriggerset())) + wr->put(cpo,nfn); + } + + /* Check for conflict between abstraction functions and model constraints */ + for(int i2=0;i2getnumconstraints();i2++) { + NormalForm *nf2=globalmodel->getnormalform(i2); + for(int j2=0;j2getnumsentences();j2++) { + CoerceSentence *cs2=nf2->getsentence(j2); + for (int k2=0;k2getnumpredicates();k2++) { + if (repairnormal->conflict(NULL,cpo,globalmodel->getconstraint(i2),cs2->getpredicate(k2))) + wr->put(cpo,nf2); + } + } + } + } + delete(repairnormal); +} + + + +void Repair::checkpredicate(Action *repair,WorkRelation *wr, Constraint *c,CoercePredicate *cp) { + for(int i=0;igetnumconstraints();i++) { + NormalForm *nf=globalmodel->getnormalform(i); + for(int j=0;jgetnumsentences();j++) { + CoerceSentence *cs=nf->getsentence(j); + for (int k=0;kgetnumpredicates();k++) { + if (repair->conflict(c,cp,globalmodel->getconstraint(i),cs->getpredicate(k))) + wr->put(cp, nf); + } + } + } + for(int i=0;igetnumrulenormal();i++) { + NormalForm *nf=globalmodel->getrulenormal(i); + if (repair->conflict(c,cp,NULL, nf->getsentence(0)->getpredicate(0))) + wr->put(cp,nf); + } +} + diff --git a/Repair/RepairInterpreter/repair.h b/Repair/RepairInterpreter/repair.h new file mode 100755 index 0000000..bc90f44 --- /dev/null +++ b/Repair/RepairInterpreter/repair.h @@ -0,0 +1,31 @@ +#ifndef REPAIR_H +#define REPAIR_H +#include "classlist.h" +class Repair { + public: + Repair(model *m); + void repairconstraint(Constraint *c, processobject *po, Hashtable *env); + Action * findrepairaction(CoercePredicate *cp); + Action * findbreakaction(CoercePredicate *cp); + bool analyzetermination(); + + + private: + void outputgraph(WorkSet *removededges, WorkRelation *wr, char *filename); + void repaireleexpr(Constraint *c, processobject *po, Elementexpr *ee, Hashtable *env); + void buildmap(WorkRelation *wr); + void checkpredicate(Action *repair,WorkRelation *wr, Constraint *c,CoercePredicate *cp); + bool checkforcycles(WorkSet *removededges, WorkRelation *wr); + bool checkcycles(CoerceSentence *cs,WorkSet *removededges, WorkSet *searchset,WorkRelation *wr); + bool breakcycles(WorkSet *removeedge, int number, WorkSet *cyclelinks, WorkRelation *wr); + void detectcycles(CoerceSentence *cs,WorkSet *searchset,WorkSet *cycleset, WorkRelation *wr); + WorkSet * searchcycles(WorkRelation *wr); + model * globalmodel; + + Action ** repairactions; // the available repair actions + int numactions; + + WorkSet *removedsentences; +}; +#endif + diff --git a/Repair/RepairInterpreter/rparser.cc b/Repair/RepairInterpreter/rparser.cc new file mode 100755 index 0000000..bd36e76 --- /dev/null +++ b/Repair/RepairInterpreter/rparser.cc @@ -0,0 +1,102 @@ +#include +#include +#include +#include "rparser.h" +#include "list.h" +#include "common.h" +#include "token.h" +#include "set.h" +#include "classlist.h" + + +// class RParser + +RParser::RParser(Reader *r) +{ + reader=r; +} + + +// returns the name of the relation whose range is defined +char* RParser::parserelation() +{ + Token token = reader->peakahead(); + + while(token.token_type==TOKEN_EOL) + { + skiptoken(); + token = reader->peakahead(); + } + + if (token.token_type==TOKEN_EOF) + return NULL; + + needtoken(0); + needtoken(TOKEN_COLON); // we need a colon + + char* relation = new char[strlen(token.str)+1]; + strcpy(relation, token.str); + return relation; +} + + + +WorkSet* RParser::parseworkset() +{ +#ifdef DEBUGMANYMESSAGES + printf("Parsing a new workset... \n"); +#endif + + WorkSet *wset = new WorkSet(true); + needtoken(TOKEN_OPENBRACE); // need an open brace + + Token token = reader->readnext(); + + while (token.token_type != TOKEN_CLOSEBRACE) + { +#ifdef DEBUGMESSAGES + //printf("Adding %s...\n", token.str); + //fflush(NULL); +#endif + char* newtoken = (char*) malloc(strlen(token.str)); + strcpy(newtoken, token.str); + + wset->addobject(newtoken); + + token = reader->readnext(); + + if (token.token_type == TOKEN_COMMA) + token = reader->readnext(); + } + + return wset; +} + + + +void RParser::error() +{ + printf("ERROR\n"); + reader->error(); + exit(-1); +} + + +void RParser::skiptoken() +{ + reader->readnext(); +} + + +void RParser::needtoken(int token) +{ + Token t=reader->readnext(); + if (!(t.token_type==token)) + { + printf("Needed token: "); + tokenname(token); + printf("\n Got token: %s ",t.str); + tokenname(t.token_type); + error(); + } +} diff --git a/Repair/RepairInterpreter/rparser.h b/Repair/RepairInterpreter/rparser.h new file mode 100755 index 0000000..11fc60d --- /dev/null +++ b/Repair/RepairInterpreter/rparser.h @@ -0,0 +1,21 @@ +#ifndef RangeFileParser_H +#define RangeFileParser_H + +#include "common.h" +#include +#include +#include "classlist.h" + +class RParser { + public: + RParser(Reader *r); + char* parserelation(); + WorkSet* parseworkset(); + + private: + void skiptoken(); + void needtoken(int); + void error(); + Reader *reader; +}; +#endif diff --git a/Repair/RepairInterpreter/set.cc b/Repair/RepairInterpreter/set.cc new file mode 100755 index 0000000..a3f1c6a --- /dev/null +++ b/Repair/RepairInterpreter/set.cc @@ -0,0 +1,102 @@ +#include +#include "set.h" +#include "GenericHashtable.h" +#include "element.h" + + + +// class WorkSet + +WorkSet::WorkSet() { + ght=genallocatehashtable((unsigned int (*)(void *)) & hashelement,(int (*)(void *,void *)) & elementequals); +} + +WorkSet::WorkSet(unsigned int (*hashf)(void *),int (*equals)(void *,void *)) { + ght=genallocatehashtable(hashf,equals); +} + +WorkSet::WorkSet(bool) { + ght=genallocatehashtable(NULL,NULL); +} + +WorkSet::~WorkSet() { + genfreehashtable(ght); +} + +void WorkSet::addobject(void *obj) { + if (!contains(obj)) + { + fflush(NULL); + genputtable(ght,obj,obj); + } +} + +void WorkSet::removeobject(void *obj) { + genfreekey(ght,obj); +} + +bool WorkSet::contains(void *obj) { + return (gencontains(ght,obj)==1); +} + +void * WorkSet::firstelement() { + if (ght->list==NULL) + return NULL; + else + return ght->list->src; +} + +Iterator * WorkSet::getiterator() { + return new Iterator(ght); +} + +void * WorkSet::getnextelement(void *src) { + return getnext(ght,src); +} + +void * WorkSet::getelement(int i) { + void *v=firstelement(); + while(i>0) { + i--; + v=getnext(ght,v); + } + return v; +} + +int WorkSet::size() { + return hashsize(ght); +} + +bool WorkSet::isEmpty() { + return (size()==0); +} + +void WorkSet::print() +{ + printf("{"); + for (int i=0; iprint(); + if (i != size()-1) + printf(" "); + } + printf("}"); +} + + + + +// class Iterator + +Iterator::Iterator(struct genhashtable *ght) { + gi=gengetiterator(ght); +} + +Iterator::~Iterator() { + genfreeiterator(gi); +} + +void * Iterator::next() { + return gennext(gi); +} diff --git a/Repair/RepairInterpreter/set.h b/Repair/RepairInterpreter/set.h new file mode 100755 index 0000000..50b4ea8 --- /dev/null +++ b/Repair/RepairInterpreter/set.h @@ -0,0 +1,38 @@ +#ifndef SET_H +#define SET_H + +#include "classlist.h" + +class WorkSet { + public: + WorkSet(); + WorkSet(unsigned int (*hashf)(void *),int (*equals)(void *,void *)); + WorkSet(bool); + ~WorkSet(); + void addobject(void *obj); + void removeobject(void *obj); + bool contains(void *obj); + Iterator * getiterator(); + void *firstelement(); + void * getnextelement(void *src); + int size(); + void * getelement(int i); + bool isEmpty(); + void print(); + + private: + struct genhashtable *ght; +}; + +class Iterator { + public: + Iterator(struct genhashtable *ght); + ~Iterator(); + void * next(); + + private: + struct geniterator * gi; +}; + +#endif + diff --git a/Repair/RepairInterpreter/stack.c b/Repair/RepairInterpreter/stack.c new file mode 100755 index 0000000..ceb840a --- /dev/null +++ b/Repair/RepairInterpreter/stack.c @@ -0,0 +1,25 @@ +#include +#include +#include "stack.h" +//#include "dmalloc.h" + +void pushstack(struct StackElement **septr,void * obj) { + struct StackElement * nse=(struct StackElement *)malloc(sizeof(struct StackElement)); + nse->contents=obj; + nse->next=*septr; + *septr=nse; +} + +void * popstack(struct StackElement **septr) { + if(*septr==NULL) { + printf("Empty Stack\n"); + return NULL;/* Empty stack */ + } + { + void *obj=(*septr)->contents; + struct StackElement *ose=*septr; + (*septr)=ose->next; + free(ose); + return obj; + } +} diff --git a/Repair/RepairInterpreter/stack.h b/Repair/RepairInterpreter/stack.h new file mode 100755 index 0000000..460a32b --- /dev/null +++ b/Repair/RepairInterpreter/stack.h @@ -0,0 +1,10 @@ +#ifndef STACK_H +#define STACK_H + +struct StackElement { + struct StackElement * next; + void * contents; +}; +void pushstack(struct StackElement **septr,void * obj); +void * popstack(struct StackElement **septr); +#endif diff --git a/Repair/RepairInterpreter/test.cc b/Repair/RepairInterpreter/test.cc new file mode 100755 index 0000000..d7effe3 --- /dev/null +++ b/Repair/RepairInterpreter/test.cc @@ -0,0 +1,204 @@ +/* Defines interfaces for the applications and exports function calls that + the applications should use instead of the standard ones. */ + +#include +#include +#include "classlist.h" +#include "model.h" +#include "dmodel.h" +extern "C" { +#include "test.h" +} +#include +#include "element.h" +#include "Hashtable.h" +#include "tmap.h" + + + +model * exportmodel; + +void initializeanalysis() +{ + exportmodel=new model("testabstract", "testmodel", "testspace", "teststruct", "testconcrete", "testrange"); +} + + + + +void doanalysis() +{ + struct timeval begin,end; + unsigned long t; + gettimeofday(&begin,NULL); + exportmodel->doabstraction(); + exportmodel->getdomainrelation()->fixstuff(); + bool found = exportmodel->docheck(); + exportmodel->doconcrete(); + gettimeofday(&end,NULL); + t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec; + +#ifdef DEBUGMANYMESSAGES + +#endif + exportmodel->getdomainrelation()->print(); + printf("Time used for analysis(us): %ld\n",t); +} + + +/* This procedure invokes the tool. + If the model hasn't been initialized, it simply returns. + If a bug was constraint violation was found, displays a message + and terminates the program. */ +void doanalysisfordebugging(char* msg) +{ + if (exportmodel == NULL) { + printf("Initialize tool first...\n"); + return; + } + + printf("%s\n", msg); + exportmodel->doabstraction(); + + //exportmodel->getdomainrelation()->fixstuff(); + //bool found = exportmodel->docheck(); + + bool found = exportmodel->getdomainrelation()->fixstuff() || exportmodel->docheck(); + +#ifdef DEBUGMANYMESSAGES + exportmodel->getdomainrelation()->print(); +#endif + + if (found) + exit(1); + + resetanalysis(); + printf("\n"); +} + + + +// returns true if a violated constraint was found +unsigned long benchmark() +{ + struct timeval begin,end; + unsigned long t; + gettimeofday(&begin,NULL); + exportmodel->doabstraction(); + exportmodel->getdomainrelation()->fixstuff(); + bool found = exportmodel->docheck(); + exportmodel->doconcrete(); + gettimeofday(&end,NULL); + t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec; + return t; +} + + +// insert errors that break the specs +void doanalysis2() +{ + struct timeval begin,end; + unsigned long t; + gettimeofday(&begin,NULL); + exportmodel->doabstraction(); + exportmodel->getdomainrelation()->fixstuff(); + + + exportmodel->breakspec(); +#ifdef DEBUGMESSAGES + printf("\n\nSpecs BROKEN \n\n"); + fflush(NULL); +#endif + + exportmodel->docheck(); + exportmodel->doconcrete(); + gettimeofday(&end,NULL); + t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec; + + printf("Time used for analysis(us): %ld\n",t); +} + + +// insert errors that do not break the specs +void doanalysis3() +{ + struct timeval begin,end; + unsigned long t; + gettimeofday(&begin,NULL); + exportmodel->doabstraction(); + exportmodel->getdomainrelation()->fixstuff(); + + exportmodel->inserterrors(); + +#ifdef DEBUGMESSAGES + printf("\n\nErrors INSERTED \n\n"); + fflush(NULL); +#endif + + exportmodel->docheck(); + exportmodel->doconcrete(); + gettimeofday(&end,NULL); + t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec; + + printf("Time used for analysis(us): %ld\n",t); +} + + + +void resetanalysis() { + exportmodel->reset(); +} + +void addmapping(char *key, void * address, char *type) { + Hashtable *env=exportmodel->gethashtable(); + env->put(key,new Element(address,exportmodel->getstructure(type)));//should be of badstruct +} + +void addintmapping(char *key, int value) { + Hashtable *env=exportmodel->gethashtable(); + env->put(key,new Element(value)); //should be of badstruct +} + +void *ourcalloc(size_t nmemb, size_t size) { + typemap *tm=exportmodel->gettypemap(); + void *oc=calloc(nmemb,size); + tm->allocate(oc,size*nmemb); + return oc; +} + +void *ourmalloc(size_t size) { + typemap *tm=exportmodel->gettypemap(); + void *oc=malloc(size); + tm->allocate(oc,size); + return oc; +} + +void ourfree(void *ptr) { + typemap *tm=exportmodel->gettypemap(); + tm->deallocate(ptr); + free(ptr); +} + +void *ourrealloc(void *ptr, size_t size) { + typemap *tm=exportmodel->gettypemap(); + void *orr=realloc(ptr,size); + if (size==0) { + tm->deallocate(ptr); + return orr; + } + if (orr==NULL) { + return orr; + } + tm->deallocate(ptr); + tm->allocate(ptr,size); +} + +void alloc(void *ptr,int size) { + typemap *tm=exportmodel->gettypemap(); + tm->allocate(ptr,size); +} + +void dealloc(void *ptr) { + typemap *tm=exportmodel->gettypemap(); + tm->deallocate(ptr); +} diff --git a/Repair/RepairInterpreter/test.h b/Repair/RepairInterpreter/test.h new file mode 100755 index 0000000..cf3487a --- /dev/null +++ b/Repair/RepairInterpreter/test.h @@ -0,0 +1,21 @@ +/* Defines interfaces for the applications and exports function calls that + the applications should use instead of the standard ones. */ + +#ifndef TEST_H +#define TEST_H +void initializeanalysis(); +unsigned long benchmark(); /* do analysis */ +void doanalysis(); /* do analysis */ +void doanalysis2(); /* break the specs and do analysis */ +void doanalysis3(); /* insert errors and do analysis */ +void doanalysisfordebugging(char *msg ); +void resetanalysis(); +void addmapping(char *, void *,char *); +void addintmapping(char *key, int value); +void alloc(void *ptr,int size); +void dealloc(void *ptr); +void *ourcalloc(size_t nmemb, size_t size); +void *ourmalloc(size_t size); +void ourfree(void *ptr); +void *ourrealloc(void *ptr, size_t size); +#endif diff --git a/Repair/RepairInterpreter/testabstract b/Repair/RepairInterpreter/testabstract new file mode 100755 index 0000000..c9c5d01 --- /dev/null +++ b/Repair/RepairInterpreter/testabstract @@ -0,0 +1,19 @@ +[], true => literal(0) in SuperBlock +[], true => literal(1) in GroupBlock +[], d.g.InodeTableBlock < d.s.NumberofBlocks => d.g.InodeTableBlock in InodeTableBlock +[], d.g.InodeBitmapBlock < d.s.NumberofBlocks => d.g.InodeBitmapBlock in InodeBitmapBlock +[], d.g.BlockBitmapBlock < d.s.NumberofBlocks => d.g.BlockBitmapBlock in BlockBitmapBlock +[], d.s.RootDirectoryInode < d.s.NumberofInodes => d.s.RootDirectoryInode in RootDirectoryInode +delay [for j=literal(0) to d.s.NumberofInodes-literal(1)], !(j in UsedInode) => j in FreeInode +delay [for j=literal(0) to d.s.NumberofBlocks-literal(1)], !(j in UsedBlock) => j in FreeBlock +[forall di in DirectoryInode, forall itb in InodeTableBlock, for j=literal(0) to (d.s.blocksize/literal(128))-literal(1), for k=literal(0) to literal(11)], cast(InodeTable,d.b[itb]).itable[di].Blockptr[k] < d.s.NumberofBlocks => cast(DirectoryBlock,d.b[cast(InodeTable,d.b[itb]).itable[di].Blockptr[k]]).de[j] in DirectoryEntry +[forall i in UsedInode, forall itb in InodeTableBlock, for j=literal(0) to literal(11)], !cast(InodeTable,d.b[itb]).itable[i].Blockptr[j]=literal(0) => in contents +[forall i in UsedInode, forall itb in InodeTableBlock, for j=literal(0) to literal(11)], cast(InodeTable,d.b[itb]).itable[i].Blockptr[j] cast(InodeTable,d.b[itb]).itable[i].Blockptr[j] in FileDirectoryBlock +[for j=literal(0) to d.s.NumberofInodes-literal(1), forall ibb in InodeBitmapBlock], cast(InodeBitmap,d.b[ibb]).inodebitmap[j]=literal(false) => in inodestatus +[for j=literal(0) to d.s.NumberofInodes-literal(1), forall ibb in InodeBitmapBlock], cast(InodeBitmap,d.b[ibb]).inodebitmap[j]=literal(true) => in inodestatus +[forall de in DirectoryEntry], de.inodenumber de.inodenumber in FileInode +[forall de in DirectoryEntry], de.inodenumber in inodeof +[forall j in UsedInode, forall itb in InodeTableBlock], true => in referencecount +[forall j in UsedInode, forall itb in InodeTableBlock], true => in filesize +[for j=literal(0) to d.s.NumberofBlocks-literal(1), forall bbb in BlockBitmapBlock], cast(BlockBitmap,d.b[bbb]).blockbitmap[j]=literal(false) => in blockstatus +[for j=literal(0) to d.s.NumberofBlocks-literal(1), forall bbb in BlockBitmapBlock], cast(BlockBitmap,d.b[bbb]).blockbitmap[j]=literal(true) => in blockstatus diff --git a/Repair/RepairInterpreter/testconcrete b/Repair/RepairInterpreter/testconcrete new file mode 100755 index 0000000..e9957fa --- /dev/null +++ b/Repair/RepairInterpreter/testconcrete @@ -0,0 +1,13 @@ +[forall u in InodeTableBlock], true => d.g.InodeTableBlock=u +[forall u in InodeBitmapBlock], true => d.g.InodeBitmapBlock=u +[forall u in BlockBitmapBlock], true => d.g.BlockBitmapBlock=u +[forall u in RootDirectoryInode], true => d.s.RootDirectoryInode=u +[forall i in UsedInode, forall itb in InodeTableBlock, for j=literal(0) to literal(11)], j < sizeof(i.contents) => cast(InodeTable,d.b[itb]).itable[i].Blockptr[j]=element j of i.contents +[forall i in UsedInode, forall itb in InodeTableBlock, for j=literal(0) to literal(11)], !j cast(InodeTable,d.b[itb]).itable[i].Blockptr[j]=literal(0) +[forall ibb in InodeBitmapBlock, forall in inodestatus], status=literal(Free) => cast(InodeBitmap,d.b[ibb]).inodebitmap[j]=literal(false) +[forall ibb in InodeBitmapBlock, forall in inodestatus], status=literal(Used) => cast(InodeBitmap,d.b[ibb]).inodebitmap[j]=literal(true) +[forall in inodeof], true => de.inodenumber=u +[forall itb in InodeTableBlock, forall in referencecount], true => cast(InodeTable,d.b[itb]).itable[j].referencecount=u +[forall itb in InodeTableBlock, forall in filesize], true => cast(InodeTable,d.b[itb]).itable[j].filesize=u +[forall bbb in BlockBitmapBlock, forall in blockstatus], status=literal(Free) => cast(BlockBitmap,d.b[bbb]).blockbitmap[j] = literal(false) +[forall bbb in BlockBitmapBlock, forall in blockstatus], status=literal(Used) => cast(BlockBitmap,d.b[bbb]).blockbitmap[j] = literal(true) diff --git a/Repair/RepairInterpreter/testmodel b/Repair/RepairInterpreter/testmodel new file mode 100755 index 0000000..8a2fca0 --- /dev/null +++ b/Repair/RepairInterpreter/testmodel @@ -0,0 +1,13 @@ +[forall u in UsedInode], u.inodestatus=literal(Used) +[forall f in FreeInode], f.inodestatus=literal(Free) +[forall u in UsedBlock], u.blockstatus=literal(Used) +[forall f in FreeBlock], f.blockstatus=literal(Free) +[forall i in UsedInode], i.referencecount=sizeof(i.~inodeof) or i in RootDirectoryInode +[forall i in UsedInode], i.filesize <= sizeof(i.contents)*literal(8192) +[forall b in FileDirectoryBlock],sizeof(b.~contents)=1 +[],sizeof(SuperBlock)=1 +[],sizeof(GroupBlock)=1 +[],sizeof(InodeTableBlock)=1 +[],sizeof(InodeBitmapBlock)=1 +[],sizeof(BlockBitmapBlock)=1 +[],sizeof(RootDirectoryInode)=1 diff --git a/Repair/RepairInterpreter/testrange b/Repair/RepairInterpreter/testrange new file mode 100755 index 0000000..0cd9ba7 --- /dev/null +++ b/Repair/RepairInterpreter/testrange @@ -0,0 +1,2 @@ +inodestatus: {Free, Used} +blockstatus: {Free, Used} diff --git a/Repair/RepairInterpreter/testspace b/Repair/RepairInterpreter/testspace new file mode 100755 index 0000000..d50564a --- /dev/null +++ b/Repair/RepairInterpreter/testspace @@ -0,0 +1,24 @@ +set Block(int): partition UsedBlock | FreeBlock +set FreeBlock(int): +set Inode(int): partition UsedInode | FreeInode +set FreeInode(int): +set UsedInode(int): partition FileInode | DirectoryInode +set FileInode(int): +set DirectoryInode(int): RootDirectoryInode +set RootDirectoryInode(int): +set UsedBlock(int): partition SuperBlock | GroupBlock | FileDirectoryBlock | InodeTableBlock | InodeBitmapBlock | BlockBitmapBlock +set FileDirectoryBlock(int): DirectoryBlock | FileBlock +set SuperBlock(int): +set GroupBlock(int): +set FileBlock(int): +set DirectoryBlock(int): +set InodeTableBlock(int): +set InodeBitmapBlock(int): +set BlockBitmapBlock(int): +set DirectoryEntry(DirectoryEntry): +inodeof: DirectoryEntry -> UsedInode (many->1) +contents: UsedInode -> FileDirectoryBlock (1->many) +inodestatus: Inode -> token (many->1) +blockstatus: Block -> token (many->1) +referencecount: Inode -> int (many->1) +filesize: Inode -> int (many->1) diff --git a/Repair/RepairInterpreter/teststruct b/Repair/RepairInterpreter/teststruct new file mode 100755 index 0000000..fd4c2ff --- /dev/null +++ b/Repair/RepairInterpreter/teststruct @@ -0,0 +1,53 @@ +structure Block { + reserved byte[d.s.blocksize]; +} + +structure Disk { + Block b[d.s.NumberofBlocks]; + label b[literal(0)]: Superblock s; + label b[literal(1)]: Groupblock g; +} + +structure Superblock subtype of Block { + int FreeBlockCount; + int FreeInodeCount; + int NumberofBlocks; + int NumberofInodes; + int RootDirectoryInode; + int blocksize; +} + +structure Groupblock subtype of Block { + int BlockBitmapBlock; + int InodeBitmapBlock; + int InodeTableBlock; + int GroupFreeBlockCount; + int GroupFreeInodeCount; +} + +structure InodeTable subtype of Block { + Inode itable[d.s.NumberofInodes]; +} + +structure InodeBitmap subtype of Block { + bit inodebitmap[d.s.NumberofInodes]; +} + +structure BlockBitmap subtype of Block { + bit blockbitmap[d.s.NumberofBlocks]; +} + +structure Inode { + int filesize; + int Blockptr[literal(12)]; + int referencecount; +} + +structure DirectoryBlock subtype of Block { + DirectoryEntry de[d.s.blocksize/literal(128)]; +} + +structure DirectoryEntry { + byte name[literal(124)]; + int inodenumber; +} diff --git a/Repair/RepairInterpreter/tmap.cc b/Repair/RepairInterpreter/tmap.cc new file mode 100755 index 0000000..f0ced38 --- /dev/null +++ b/Repair/RepairInterpreter/tmap.cc @@ -0,0 +1,218 @@ +#include +#include "tmap.h" +extern "C" { +#include "redblack.h" +} +#include "tmodel.h" +#include "model.h" +#include "processabstract.h" +#include "element.h" + +#define CHECKTYPE +#define CHECKMEMORY + +typemap::typemap(model *m) { + alloctree=rbinit(); + typetree=rbinit(); + globalmodel=m; +} + +void freefunction(void *ptr) { + if(ptr!=NULL) { + delete((structuremap *)ptr); + } +} + +typemap::~typemap() { + rbdestroy(typetree,freefunction); + rbdestroy(alloctree,freefunction); +} + +void typemap::reset() { + rbdestroy(typetree,freefunction); + typetree=rbinit(); +} + +structuremap::structuremap(structure *s) { + str=s; + typetree=rbinit(); +} + +structuremap::~structuremap() { + rbdestroy(typetree,freefunction); +} + +bool typemap::asserttype(void *ptr, structure *s) { + +#ifdef CHECKTYPE + bool b=checktype(true,ptr,s); + if (!b) { + printf("Assertion failure\n"); + bool testb=checktype(true,ptr,s); + } + return b; +#endif + + return assertvalidmemory(ptr, s); +} + +bool typemap::assertvalidmemory(void* low, void* high) { + +#ifdef CHECKMEMORY + return checkmemory(low, high); +#endif + + return true; +} + +bool typemap::assertvalidmemory(void* ptr, structure* s) { + +#ifdef CHECKMEMORY + int size=s->getsize(globalmodel->getbitreader(),globalmodel,globalmodel->gethashtable()); + void *low=ptr; + void *high=((char *)low)+size; + return checkmemory(low, high); +#endif + + return true; +} + +bool typemap::istype(void *ptr, structure *s) { + +#ifdef CHECKTYPE + bool b=checktype(false,ptr,s); + if (!b) { + printf("Verify failure\n"); + bool testb=checktype(false,ptr,s); + } + return b; +#endif + + return assertvalidmemory(ptr, s); +} + +void typemap::allocate(void *ptr, int size) { + void *low=ptr; + void *high=((char *)ptr)+size; + int val=rbinsert(low,high,NULL,alloctree); + if (val==0) + printf("Error\n"); +} + +structure * typemap::findoffsetstructure(structure *s, int offset) { + int count=0; + for(int i=0;igetnumfields();i++) { + int mult=1; + ttype *ttype=s->getfield(i)->gettype(); + if (ttype->getsize()!=NULL) { + Element * number=evaluateexpr(globalmodel,ttype->getsize(),globalmodel->gethashtable(),true,false); + mult=number->intvalue(); + delete(number); + } + int increment=ttype->basesize(globalmodel->getbitreader(),globalmodel,globalmodel->gethashtable()); + + int delt=offset-count; + if (deltgetstructure(ttype->getname()); + } else + return NULL; + } + + count+=mult*increment; + } + + return NULL; +} + +void typemap::deallocate(void *ptr) { + if (rbdelete(ptr,alloctree)==NULL) + printf("Freeing unallocated memory\n"); +} + +bool typemap::checkmemory(void* low, void* high) { + struct pair allocp=rbfind(low,high,alloctree); + + if (allocp.low == NULL) { + return false; + } else if ((allocp.low > low) || (allocp.high < high)) { /* make sure this block is used */ + return false; + } else { + return true; + } +} + + +bool typemap::checktype(bool doaction,void *ptr, structure *structure) { + int size=structure->getsize(globalmodel->getbitreader(),globalmodel,globalmodel->gethashtable()); + void *low=ptr; + void *high=((char *)low)+size; + struct pair allocp=rbfind(low,high,alloctree); + if (allocp.low==NULL) + return false; + if (allocp.low>low||allocp.highsubtypeof(structre,smap->str)) { + /* narrowing cast */ + if (!doaction) + return true; + smap->str=structre; + return true; + } else if (globalmodel->subtypeof(smap->str,structre)) { + /* widening cast */ + return true; + } else + return false; /* incompatible types */ + } else if (typep.low<=low&&typep.high>=high) { + /* See if it matches up with structure inside typep */ + if (rbsearch(low,high,smap->typetree)) { + /* recurse */ + return checktype(doaction,low,high, structre, smap->typetree); + } else { + /* check to see if data lines up correctly */ + int offset=((char *)low)-((char *)typep.low); + structure * st=findoffsetstructure(smap->str,offset); + if (st==NULL) + return false; + if (globalmodel->subtypeof(structre,st)) { + if (!doaction) + return true; + structuremap *newsm=new structuremap(structre); + int flag=rbinsert(low, high, newsm, smap->typetree); + return (flag==1); + } else if (globalmodel->subtypeof(st,structre)) { + if (!doaction) + return true; + structuremap *newsm=new structuremap(st); + int flag=rbinsert(low, high, newsm, smap->typetree); + return (flag==1); + } else + return false; + } + } else + return false; +} diff --git a/Repair/RepairInterpreter/tmap.h b/Repair/RepairInterpreter/tmap.h new file mode 100755 index 0000000..e05f28d --- /dev/null +++ b/Repair/RepairInterpreter/tmap.h @@ -0,0 +1,33 @@ +#ifndef TMAP_H +#define TMAP_H +#include "classlist.h" + +class typemap { + public: + typemap(model *); + ~typemap(); + void allocate(void *, int); + void deallocate(void *); + bool assertvalidmemory(void* low, void* high); + bool assertvalidmemory(void* ptr, structure *structure); + bool asserttype(void *ptr, structure *structure); + bool istype(void *ptr, structure *structure); + void reset(); + private: + bool checkmemory(void* low, void* high); + bool checktype(bool doaction,void *ptr, structure *structure); + bool checktype(bool doaction, void *low, void *high,structure *structure, struct rbtree *ttree); + structure * findoffsetstructure(structure *s, int offset); + model *globalmodel; + struct rbtree *alloctree; + struct rbtree *typetree; +}; + +class structuremap { + public: + structuremap(structure *s); + ~structuremap(); + structure *str; + struct rbtree *typetree; +}; +#endif diff --git a/Repair/RepairInterpreter/tmodel.cc b/Repair/RepairInterpreter/tmodel.cc new file mode 100755 index 0000000..1858d4d --- /dev/null +++ b/Repair/RepairInterpreter/tmodel.cc @@ -0,0 +1,279 @@ +#include +#include +#include "tmodel.h" +#include "processabstract.h" +#include "element.h" +#include "model.h" +#include "Hashtable.h" +#include "common.h" + + +void structure::print() { + printf("\nBEGIN structure:\n"); + printf(" name=%s\n", name); + printf(" type=%d\n", type); + + if (subtype == NULL) + printf(" subtype=null\n"); + else subtype->print(); + + for (int i=0; iprint(); + + for (int i=0; iprint(); + + printf("END structure\n\n"); +} + +void ttype::print() { + printf("\nBEGIN ttype\n"); + printf(" ttype: primtype=%ld, intlength=%ld, type=%s\n", primtype, intlength, type); + printf("END ttype\n\n"); +} + +/*void tparam::print() { + }*/ + +void tlabel::print() { + printf("\nBEGIN tlabel\n"); + printf(" field=%s\n", field); + specifictype->print(); + printf("END tlabel\n\n"); +} + +void tfield::print() { + printf("\nBEGIN tfield\n"); + printf(" name=\%s\n", name); + type->print(); + printf("END tfield\n\n"); +} + +AElementexpr * ttype::getsize() { + return asize; +} + + +int ttype::getbytes(bitreader *br,model *m,Hashtable *env) { + int basesizeval=basesize(br,m,env); + int mult=1; + if (asize!=NULL) { + Element * number=evaluateexpr(m,asize,env,true,false); + mult=number->intvalue(); + delete(number); + } + if (gettype()==TTYPE_BIT) { + return ((mult-1)/8)+1; + } + return mult*basesizeval; +} + +int ttype::basesize(bitreader *br,model *m,Hashtable *env) { + if ((primtype/TTYPE_PTR)>0) + return pointersize; + if (gettype()==TTYPE_INT) + return intsize; + if (gettype()==TTYPE_SHORT) + return shortsize; + if (gettype()==TTYPE_BYTE) + return 1; + if (gettype()==TTYPE_BIT) + return 0; + if (gettype()==TTYPE_STRUCT) { + /* Element **earray=new Element *[numparamvalues]; + for(int i=0;igetstructure(type); + int size=st->getsize(br,m,env); + /* for(int i=0;iput(getparam(i)->getname(),earray[i]); + }*/ + /* loop through fields */ + if (getsubtype()!=NULL) { + return getsubtype()->getbytes(br, m,env); + } + for(int j=0;jgettype()->getbytes(br,m,env); + //delete(env); + return totalsize; +} +char * tlabel::getname() { + return specifictype->getname(); +} +ttype * tlabel::gettype() { + return specifictype->gettype(); +} + +structure::structure(char *nam) { + subtype=NULL; + name=nam; +} + +void structure::settype(int t) { + type=t; +} + +/*void structure::setparams(tparam **tp,int n) { + params=tp;numparams=n; + }*/ + +void structure::setsubtype(ttype *sub) { + subtype=sub; +} + +ttype * structure::getsubtype() { + return subtype; +} + +void structure::setfields(tfield **fieldarray, int n) { + fields=fieldarray; + numfields=n; +} + +void structure::setlabels(tlabel **lab,int n) { + labels=lab; + numlabels=n; +} + +/*int structure::getnumparams() { + return numparams; + }*/ + +/*tparam * structure::getparam(int i) { + return params[i]; + }*/ + +int structure::getnumlabels() { + return numlabels; +} + +tlabel * structure::getlabel(int i) { + return labels[i]; +} + +int structure::getnumfields() { + return numfields; +} + +tfield * structure::getfield(int i) { + return fields[i]; +} + +char * structure::getname() { + return name; +} + +ttype::ttype(int typ) { + primtype=typ; + intlength=0; + type=NULL; + // paramvalues=NULL; + //numparamvalues=0; + asize=NULL; +} + +ttype::ttype(char *t) { + primtype=TTYPE_STRUCT; + type=t; + intlength=0; + //paramvalues=NULL; + //numparamvalues=0; + asize=NULL; +} + +ttype::ttype(char *t, AElementexpr *size) { + primtype=TTYPE_STRUCT; + type=t; + intlength=0; + //paramvalues=param; + //numparamvalues=numparam; + asize=size; +} + +ttype::ttype(int type, AElementexpr * size) { + primtype=type; + intlength=0; + this->type=NULL; + //paramvalues=NULL; + //numparamvalues=0; + asize=size; +} + +void ttype::makeptr() { + primtype+=TTYPE_PTR; +} + +void ttype::setsize(AElementexpr *size) { + asize=size; +} + +bool ttype::isptr() { + if (numderef()>0) + return true; + else + return false; +} + +int ttype::numderef() { + return primtype/TTYPE_PTR; +} + +int ttype::gettype() { + return primtype%TTYPE_PTR; +} + +/*int ttype::getnumparamvalues() { + return numparamvalues; +} + +AElementexpr * ttype::getparamvalues(int i) { + return paramvalues[i]; + }*/ + +char * ttype::getname() { + return type; +} + +/*tparam::tparam(ttype *t,char * n) { + type=t;name=n; + } + char * tparam::getname() { + return name; + } +*/ +tlabel::tlabel(tfield *f, char *fld,AElementexpr *a) { + index=a; + field=fld; + specifictype=f; +} + +char *tlabel::getfield() { + return field; +} + +AElementexpr * tlabel::getindex() { + return index; +} + +tfield::tfield(ttype *tt, char *n) { + type=tt;name=n; +} + +ttype * tfield::gettype() { + return type; +} + +char * tfield::getname() { + return name; +} diff --git a/Repair/RepairInterpreter/tmodel.h b/Repair/RepairInterpreter/tmodel.h new file mode 100755 index 0000000..295acb7 --- /dev/null +++ b/Repair/RepairInterpreter/tmodel.h @@ -0,0 +1,128 @@ +// stores the structure definitions +#ifndef TMODEL_H +#define TMODEL_H + +#include "classlist.h" + +#define STYPE_STRUCT 1 +#define STYPE_INT 2 +#define STYPE_BIT 3 +#define STYPE_BYTE 4 +#define STYPE_SHORT 5 +#define STYPE_ARRAY 0x100 + + +class structure { + public: + structure(char *nam); + void settype(int t); + // void setparams(tparam **tp,int n); + void setsubtype(ttype *sub); + ttype * getsubtype(); + void setfields(tfield **fieldarray, int n); + void setlabels(tlabel **lab,int n); + /* int getnumparams(); + tparam * getparam(int i);*/ + int getnumlabels(); + tlabel * getlabel(int i); + int getnumfields(); + tfield * getfield(int i); + char * getname(); + void print(); + int getsize(bitreader *br,model *m, Hashtable *env); + + private: + int type; + char *name; + /* tparam ** params; + int numparams;*/ + ttype *subtype; + tfield ** fields; + int numfields; + tlabel ** labels; + int numlabels; +}; + +#define pointersize 4 +#define intsize 4 +#define shortsize 2 + +#define TTYPE_STRUCT 0x1 +#define TTYPE_INT 0x2 +#define TTYPE_BIT 0x3 +#define TTYPE_BYTE 0x4 +#define TTYPE_SHORT 0x5 +#define TTYPE_PTR 0x100 + + + +class ttype { + public: + void print(); + ttype(int typ); + ttype(char *t); + ttype(char *t, AElementexpr *size); + ttype(int type, AElementexpr * size); + void makeptr(); + void setsize(AElementexpr *size); + AElementexpr * getsize(); + int getbytes(bitreader *br,model *m,Hashtable *env); + + bool isptr(); + int numderef(); + int gettype(); + int basesize(bitreader *br,model *m,Hashtable *env); + /* int getnumparamvalues(); + AElementexpr * getparamvalues(int i);*/ + char * getname(); + + private: + int primtype; + int intlength; /*for variable length integers*/ + char * type; + /* AElementexpr ** paramvalues; + int numparamvalues;*/ + AElementexpr * asize; +}; + +/*class tparam { + public: + void print(); + tparam(ttype *t,char * n); + char * getname(); + + private: + ttype *type; + char *name; + };*/ + + + +class tlabel { + public: + void print(); + tlabel(tfield *f, char *fld,AElementexpr *a); + char * getname(); + ttype * gettype(); + char *getfield(); + AElementexpr * getindex(); + + private: + char *field; + AElementexpr *index; + tfield * specifictype; +}; + +class tfield { + public: + tfield(ttype *tt, char *n); + void print(); + ttype * gettype(); + char * getname(); + + private: + char *name; + ttype *type; + bool reserved; +}; +#endif diff --git a/Repair/RepairInterpreter/token.cc b/Repair/RepairInterpreter/token.cc new file mode 100755 index 0000000..1e9c8a6 --- /dev/null +++ b/Repair/RepairInterpreter/token.cc @@ -0,0 +1,448 @@ +#include +#include +#include +#include "common.h" +#include "token.h" + + +// class Token + +Token::Token(char *s, int tt) { + str=s; + token_type=tt; +} + +Token::Token(const Token & t) { + token_type=t.token_type; + str=copystr(t.str); +} + +Token::Token() { + token_type=-1; + str=NULL; +} + + +Token& Token::operator=(const Token &right) { + if (&right != this) { + token_type=right.token_type; + if (str!=NULL) + delete[](str); + str=copystr(right.str); + } + return *this; +} + + +Token::~Token() { + if (str!=NULL) + delete[](str); +} + + + + +// class Reader + +Reader::Reader(istream * is) { + readerin=is; + pos=0; +} + + +Token Reader::peakahead() { + Token t=checktoken(); + if (t.token_type!=-1) { + return t; + } + while(true) { + int nextchar=readerin->get(); + switch(nextchar) { + case ' ': + break; + case '\t': + break; + case '/': + if (readerin->peek()=='*') { + /*have comment region */ + readerin->get(); + int state=0; + for(int ch=readerin->get();ch!=EOF&&state!=2;ch=readerin->get()) { + switch(ch) { + case '*': + state=1; + break; + case '/': + if (state==1) + state=2; + break; + default: + state=0; + } + } + if (state!=2) error(); + break; + } + default: + buf[pos++]=nextchar; + Token t=checktoken(); + if (t.token_type!=-1) + return t; + } + } +} + + +Token Reader::readnext() { + Token t=peakahead(); + pos=0; + return t; +} + +Token Reader::checktoken() { + buf[pos]=0; + if (pos==0) return Token(); + switch(buf[0]) { + case '[': + return Token(copystr(buf),TOKEN_OPENBRACK); + case ']': + return Token(copystr(buf),TOKEN_CLOSEBRACK); + case '{': + return Token(copystr(buf),TOKEN_OPENBRACE); + case '}': + return Token(copystr(buf),TOKEN_CLOSEBRACE); + case '(': + return Token(copystr(buf),TOKEN_OPENPAREN); + case ')': + return Token(copystr(buf),TOKEN_CLOSEPAREN); + case ',': + return Token(copystr(buf),TOKEN_COMMA); + case ';': + return Token(copystr(buf),TOKEN_SEMI); + case ':': + return Token(copystr(buf),TOKEN_COLON); + case '=': + if (pos==1) { + if (readerin->peek()!='>') + return Token(copystr(buf),TOKEN_EQUALS); + } else + return Token(copystr(buf),TOKEN_IMPLIES); + break; + case '<': + if (pos==1) { + if (readerin->peek()!='=') + return Token(copystr(buf),TOKEN_LT); + } else + return Token(copystr(buf),TOKEN_LTE); + break; + case '>': + if (pos==1) { + if (readerin->peek()!='=') + return Token(copystr(buf),TOKEN_GT); + } else + return Token(copystr(buf),TOKEN_GTE); + break; + case '.': + if (pos==1) { + if (readerin->peek()!='~') + return Token(copystr(buf),TOKEN_DOT); + } else + return Token(copystr(buf),TOKEN_DOTINV); + break; + case '|': + return Token(copystr(buf),TOKEN_BAR); + case '!': + return Token(copystr(buf),TOKEN_NOT); + case '-': + if (pos==1) { + if (readerin->peek()!='>') + return Token(copystr(buf),TOKEN_SUB); + } else + return Token(copystr(buf),TOKEN_ARROW); + break; + case '+': + return Token(copystr(buf),TOKEN_ADD); + case '*': + return Token(copystr(buf),TOKEN_MULT); + case '/': + return Token(copystr(buf),TOKEN_DIV); + case '\n': + return Token(copystr(buf),TOKEN_EOL); + case EOF: + return Token(copystr(buf),TOKEN_EOF); + default: + if(breakchar(readerin->peek())) { + /*we've got token*/ + if (strcmp(buf,"in")==0) + return Token(copystr(buf),TOKEN_IN); + if (strcmp(buf,"isvalid")==0) + return Token(copystr(buf),TOKEN_ISVALID); + if (strcmp(buf,"and")==0) + return Token(copystr(buf),TOKEN_AND); + if (strcmp(buf,"or")==0) + return Token(copystr(buf),TOKEN_OR); + if (strcmp(buf,"crash")==0) + return Token(copystr(buf),TOKEN_CRASH); + if (strcmp(buf,"cast")==0) + return Token(copystr(buf),TOKEN_CAST); + if (strcmp(buf,"NULL")==0) + return Token(copystr(buf),TOKEN_NULL); + if (strcmp(buf,"partition")==0) + return Token(copystr(buf),TOKEN_PARTITION); + if (strcmp(buf,"many")==0) + return Token(copystr(buf),TOKEN_MANY); + if (strcmp(buf,"set")==0) + return Token(copystr(buf),TOKEN_SET); + if (strcmp(buf,"structure")==0) + return Token(copystr(buf),TOKEN_STRUCTURE); + if (strcmp(buf,"reserved")==0) + return Token(copystr(buf),TOKEN_RESERVED); + if (strcmp(buf,"label")==0) + return Token(copystr(buf),TOKEN_LABEL); + if (strcmp(buf,"int")==0) + return Token(copystr(buf),TOKEN_INT); + if (strcmp(buf,"short")==0) + return Token(copystr(buf),TOKEN_SHORT); + if (strcmp(buf,"bit")==0) + return Token(copystr(buf),TOKEN_BIT); + if (strcmp(buf,"byte")==0) + return Token(copystr(buf),TOKEN_BYTE); + if (strcmp(buf,"subtype")==0) + return Token(copystr(buf),TOKEN_SUBTYPE); + if (strcmp(buf,"of")==0) + return Token(copystr(buf),TOKEN_OF); + if (strcmp(buf,"element")==0) + return Token(copystr(buf),TOKEN_ELEMENT); + if (strcmp(buf,"forall")==0) + return Token(copystr(buf),TOKEN_FORALL); + if (strcmp(buf,"for")==0) + return Token(copystr(buf),TOKEN_FOR); + if (strcmp(buf,"sizeof")==0) + return Token(copystr(buf),TOKEN_SIZEOF); + if (strcmp(buf,"literal")==0) + return Token(copystr(buf),TOKEN_LITERAL); + if (strcmp(buf,"param")==0) + return Token(copystr(buf),TOKEN_PARAM); + if (strcmp(buf,"1")==0) + return Token(copystr(buf),TOKEN_ONE); + if (strcmp(buf,"true")==0) + return Token(copystr(buf),TOKEN_TRUE); + if (strcmp(buf,"to")==0) + return Token(copystr(buf),TOKEN_TO); + if (strcmp(buf,"delay")==0) + return Token(copystr(buf),TOKEN_DELAY); + if (strcmp(buf,"static")==0) + return Token(copystr(buf),TOKEN_STATIC); + return Token(copystr(buf),0); + } + } + return Token(); +} + + +// return true if the given char is a separator +bool Reader::breakchar(int chr) { + switch(chr) { + case ' ': + return true; + case '|': + return true; + case '-': + return true; + case '+': + return true; + case '*': + return true; + case '/': + return true; + case ']': + return true; + case ')': + return true; + case ';': + return true; + case ':': + return true; + case '}': + return true; + case '[': + return true; + case '(': + return true; + case '{': + return true; + case '<': + return true; + case '=': + return true; + case '\n': + return true; + case '>': + return true; + case '.': + return true; + case ',': + return true; + default: + return false; + } +} + + + +void Reader::error() { + printf("%s\n",buf); +} + + + +void tokenname(int t) { + switch(t) { + case TOKEN_OPENBRACK: + printf("["); + break; + case TOKEN_CLOSEBRACK: + printf("]"); + break; + case TOKEN_FORALL: + printf("forall"); + break; + case TOKEN_IN: + printf("in"); + break; + case TOKEN_OPENBRACE: + printf("{"); + break; + case TOKEN_CLOSEBRACE: + printf("}"); + break; + case TOKEN_COMMA: + printf(","); + break; + case TOKEN_SIZEOF: + printf("sizeof"); + break; + case TOKEN_OPENPAREN: + printf("("); + break; + case TOKEN_CLOSEPAREN: + printf(")"); + break; + case TOKEN_LT: + printf("<"); + break; + case TOKEN_LTE: + printf("<="); + break; + case TOKEN_EQUALS: + printf("="); + break; + case TOKEN_GTE: + printf(">="); + break; + case TOKEN_GT: + printf(">"); + break; + case TOKEN_ONE: + printf("1"); + break; + case TOKEN_DOT: + printf("."); + break; + case TOKEN_DOTINV: + printf(".~"); + break; + case TOKEN_NOT: + printf("!"); + break; + case TOKEN_LITERAL: + printf("literal"); + break; + case TOKEN_PARAM: + printf("param"); + break; + case TOKEN_SUB: + printf("-"); + break; + case TOKEN_ADD: + printf("+"); + break; + case TOKEN_MULT: + printf("*"); + break; + case TOKEN_AND: + printf("and"); + break; + case TOKEN_OR: + printf("or"); + break; + case TOKEN_EOL: + printf("EOL"); + break; + case TOKEN_EOF: + printf("EOF"); + break; + case TOKEN_IMPLIES: + printf("=>"); + break; + case TOKEN_TRUE: + printf("true"); + break; + case TOKEN_FOR: + printf("for"); + break; + case TOKEN_TO: + printf("to"); + break; + case TOKEN_STRUCTURE: + printf("structure"); + break; + case TOKEN_RESERVED: + printf("reserved"); + break; + case TOKEN_LABEL: + printf("label"); + break; + case TOKEN_INT: + printf("int"); + break; + case TOKEN_BIT: + printf("bit"); + break; + case TOKEN_BYTE: + printf("byte"); + break; + case TOKEN_SUBTYPE: + printf("subtype"); + break; + case TOKEN_OF: + printf("of"); + break; + case TOKEN_SEMI: + printf(";"); + break; + case TOKEN_COLON: + printf(":"); + break; + case TOKEN_SET: + printf("set"); + break; + case TOKEN_ARROW: + printf("->"); + break; + case TOKEN_MANY: + printf("many"); + break; + case TOKEN_BAR: + printf("|"); + break; + case TOKEN_PARTITION: + printf("partition"); + break; + case TOKEN_ELEMENT: + printf("element"); + break; + default: + printf("undefined token"); + } +} diff --git a/Repair/RepairInterpreter/token.h b/Repair/RepairInterpreter/token.h new file mode 100755 index 0000000..8b29c03 --- /dev/null +++ b/Repair/RepairInterpreter/token.h @@ -0,0 +1,97 @@ +#ifndef Token_H +#define Token_H + +#include "common.h" +#include +#include +#include "classlist.h" + +class Token { + public: + Token(char *s, int tt); + Token(const Token & t); + Token & operator=(const Token &right); + Token(); + ~Token(); + int token_type; + char* str; + + private: +}; +void tokenname(int t); + +#define TOKEN_OPENBRACK 1 +#define TOKEN_CLOSEBRACK 2 +#define TOKEN_FORALL 3 +#define TOKEN_IN 4 +#define TOKEN_OPENBRACE 5 +#define TOKEN_CLOSEBRACE 6 +#define TOKEN_COMMA 7 +#define TOKEN_SIZEOF 8 +#define TOKEN_OPENPAREN 9 +#define TOKEN_CLOSEPAREN 10 +#define TOKEN_LT 11 +#define TOKEN_LTE 12 +#define TOKEN_EQUALS 13 +#define TOKEN_GTE 14 +#define TOKEN_GT 15 +#define TOKEN_ONE 16 +#define TOKEN_DOT 17 +#define TOKEN_DOTINV 18 +#define TOKEN_NOT 19 +#define TOKEN_LITERAL 20 +#define TOKEN_PARAM 21 +#define TOKEN_SUB 22 +#define TOKEN_ADD 23 +#define TOKEN_MULT 24 +#define TOKEN_AND 25 +#define TOKEN_OR 26 +#define TOKEN_EOL 27 +#define TOKEN_EOF 28 +#define TOKEN_IMPLIES 29 +#define TOKEN_TRUE 30 +#define TOKEN_ISVALID 31 +#define TOKEN_FOR 32 +#define TOKEN_TO 33 +#define TOKEN_STRUCTURE 34 +#define TOKEN_RESERVED 35 +#define TOKEN_LABEL 36 +#define TOKEN_INT 37 +#define TOKEN_BIT 38 +#define TOKEN_BYTE 39 +#define TOKEN_SUBTYPE 40 +#define TOKEN_OF 41 +#define TOKEN_SEMI 42 +#define TOKEN_COLON 43 +#define TOKEN_SET 44 +#define TOKEN_ARROW 45 +#define TOKEN_MANY 46 +#define TOKEN_BAR 47 +#define TOKEN_PARTITION 48 +#define TOKEN_ELEMENT 49 +#define TOKEN_DELAY 50 +#define TOKEN_STATIC 51 +#define TOKEN_DIV 52 +#define TOKEN_CAST 53 +#define TOKEN_SHORT 54 +#define TOKEN_NULL 55 +#define TOKEN_CRASH 56 + + + +class Reader{ + public: + Reader(istream * is); + Token readnext(); + Token peakahead(); + void error(); + + private: + bool breakchar(int); + Token checktoken(); + istream *readerin; + char buf[200]; + int pos; +}; + +#endif diff --git a/Repair/RepairInterpreter/typeparser.cc b/Repair/RepairInterpreter/typeparser.cc new file mode 100755 index 0000000..3042339 --- /dev/null +++ b/Repair/RepairInterpreter/typeparser.cc @@ -0,0 +1,332 @@ +#include +#include "typeparser.h" +#include "list.h" +#include "common.h" +#include "token.h" +#include "tmodel.h" +#include "amodel.h" +#include "omodel.h" + +Typeparser::Typeparser(Reader *r) { + reader=r; +} + +structure * Typeparser::parsestructure() { + Token t=reader->peakahead(); + while(true) { + if (t.token_type==TOKEN_EOF) + return NULL; + if (t.token_type!=TOKEN_EOL) + break; + skiptoken(); + t=reader->peakahead(); + } + needtoken(TOKEN_STRUCTURE); + Token typenam=reader->readnext(); + structure *pstructure=new structure(copystr(typenam.str)); + /* needtoken(TOKEN_OPENPAREN); + bool continueparse=true; + List *list=new List(); + while(continueparse) { + Token t=reader->readnext(); + switch(t.token_type) { + case TOKEN_CLOSEPAREN: + continueparse=false; + break; + case TOKEN_INT: + { + Token name=reader->readnext(); + tparam * tpar=new tparam(new ttype(TTYPE_INT),copystr(name.str)); + list->addobject(tpar); + commaorcloseparen(); + break; + } + case TOKEN_BIT: + { + Token name=reader->readnext(); + tparam * tpar=new tparam(new ttype(TTYPE_BIT),copystr(name.str)); + list->addobject(tpar); + commaorcloseparen(); + break; + } + case TOKEN_BYTE: + { + Token name=reader->readnext(); + tparam * tpar=new tparam(new ttype(TTYPE_BYTE),copystr(name.str)); + list->addobject(tpar); + commaorcloseparen(); + break; + } + default: + { + Token name=reader->readnext(); + tparam *tpar=new tparam(new ttype(copystr(typenam.str)),copystr(name.str)); + list->addobject(tpar); + commaorcloseparen(); + break; + } + } + } + tparam **tp=new tparam*[list->size()]; + list->toArray((void**) tp); + pstructure->setparams(tp,list->size()); + delete(list);*/ + + Token t2=reader->peakahead(); + if (t2.token_type==TOKEN_SUBTYPE) { + skiptoken(); + needtoken(TOKEN_OF); + pstructure->setsubtype(parsettype()); + } + + List *list=new List(); + List *labellist=new List(); + needtoken(TOKEN_OPENBRACE); + while(true) { + while (reader->peakahead().token_type==TOKEN_EOL) + skiptoken(); + Token t=reader->peakahead(); + if (t.token_type==TOKEN_CLOSEBRACE) + break; + if (t.token_type==TOKEN_LABEL) { + labellist->addobject(parsetlabel()); + } else + list->addobject(parsetfield()); + } + tfield **tarray=new tfield*[list->size()]; + tlabel **larray=new tlabel*[labellist->size()]; + list->toArray((void **)tarray); + labellist->toArray((void**)larray); + pstructure->setfields(tarray,list->size()); + pstructure->setlabels(larray,labellist->size()); + needtoken(TOKEN_CLOSEBRACE); + delete(list); + delete(labellist); + return pstructure; +} + +tlabel * Typeparser::parsetlabel() { + needtoken(TOKEN_LABEL); + Token fieldname=reader->readnext(); + AElementexpr *index=NULL; + if (reader->peakahead().token_type==TOKEN_OPENBRACK) { + skiptoken(); + index=parseaelementexpr(true); + needtoken(TOKEN_CLOSEBRACK); + } + needtoken(TOKEN_COLON); + tfield *tf=parsetfield(); + return new tlabel(tf,copystr(fieldname.str),index); +} + +tfield * Typeparser::parsetfield() { + static int rcount=0; + Token t=reader->peakahead(); + bool reserved=false; + if (t.token_type==TOKEN_RESERVED) { + reserved=true; + skiptoken(); + } + ttype *tt=parsettype(); + while(true) { + Token isptr=reader->peakahead(); + if (isptr.token_type==TOKEN_MULT) { + tt->makeptr(); + skiptoken(); + break; /*Only support direct pointers right now*/ + } else + break; + } + Token fieldname; + if (!reserved) + fieldname=reader->readnext(); + AElementexpr *size=parseindex(); + tt->setsize(size); + needtoken(TOKEN_SEMI); + if (reserved) + return new tfield(tt,copystr("RESERVED"+(rcount++))); + else + return new tfield(tt,copystr(fieldname.str)); +} + +ttype * Typeparser::parsettype() { + Token name=reader->readnext(); + switch(name.token_type) { + case TOKEN_BIT: + { + return new ttype(TTYPE_BIT); + } + case TOKEN_INT: + { + return new ttype(TTYPE_INT); + } + case TOKEN_SHORT: + { + return new ttype(TTYPE_SHORT); + } + case TOKEN_BYTE: + { + return new ttype(TTYPE_BYTE); + } + default: + { + /* + needtoken(TOKEN_OPENPAREN); + List *list=new List(); + while(reader->peakahead().token_type!=TOKEN_CLOSEPAREN) { + list->addobject(parseaelementexpr(false)); + commaorcloseparen(); + } + skiptoken(); + AElementexpr **earray=new AElementexpr*[list->size()]; + list->toArray((void**)earray);*/ + ttype *ntt=new ttype(copystr(name.str),NULL); + //delete(list); + return ntt; + } + } +} + +AElementexpr * Typeparser::parseindex() { + Token t=reader->peakahead(); + if (t.token_type!=TOKEN_OPENBRACK) + return NULL; + skiptoken(); + AElementexpr * ae=parseaelementexpr(true); + needtoken(TOKEN_CLOSEBRACK); + return ae; +} + +void Typeparser::commaorcloseparen() { + Token t=reader->peakahead(); + if (t.token_type!=TOKEN_CLOSEPAREN) + needtoken(TOKEN_COMMA); +} + +AElementexpr * Typeparser::parseaelementexpr(bool isstruct) { + AElementexpr *oldee=NULL; + int joinop=-1; + while(true) { + Token t=reader->peakahead(); + switch(t.token_type) { + case TOKEN_LITERAL: + { + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + needtoken(TOKEN_OPENPAREN); + Token literal=reader->readnext(); + needtoken(TOKEN_CLOSEPAREN); + if (oldee==NULL) + oldee=new AElementexpr(new Literal(copystr(literal.str))); + else { + if (joinop!=-1) { + oldee=new AElementexpr(oldee,new AElementexpr(new Literal(copystr(literal.str))),joinop); + joinop=-1; + } else error(); + } + break; + } + + case TOKEN_OPENPAREN: + { + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + AElementexpr *ee=parseaelementexpr(false); + if (oldee==NULL) + oldee=ee; + else { + if (joinop!=-1) { + oldee=new AElementexpr(oldee,ee,joinop); + joinop=-1; + } else error(); + } + break; + } + case TOKEN_CLOSEBRACK: + if (isstruct) + return oldee; + case TOKEN_CLOSEPAREN: + skiptoken(); + return checkdot(oldee); + break; + case TOKEN_SUB: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=AELEMENTEXPR_SUB; + else + error(); + break; + case TOKEN_ADD: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=AELEMENTEXPR_ADD; + else + error(); + break; + case TOKEN_MULT: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=AELEMENTEXPR_MULT; + else + error(); + break; + case TOKEN_DIV: + skiptoken(); + if ((oldee!=NULL)&&(joinop==-1)) + joinop=AELEMENTEXPR_DIV; + else + error(); + break; + default: + if ((joinop==-1)&&(oldee!=NULL)) + return oldee; + skiptoken(); + if (oldee==NULL) + oldee=checkdot(new AElementexpr(new Label(copystr(t.str)))); + else { + if (joinop!=-1) { + oldee=new AElementexpr(oldee,checkdot(new AElementexpr(new Label(copystr(t.str)))),joinop); + joinop=-1; + } else error(); + } + } + } +} + +AElementexpr * Typeparser::checkdot(AElementexpr * incoming) { + Token tdot=reader->peakahead(); + if (tdot.token_type!=TOKEN_DOT) return incoming; + skiptoken(); + Token tfield=reader->readnext(); + Token tpeak=reader->peakahead(); + if (tpeak.token_type==TOKEN_OPENBRACK) { + skiptoken(); + AElementexpr *index=parseaelementexpr(false); + return checkdot(new AElementexpr(incoming, new Field(copystr(tfield.str)),index)); + } else { + return checkdot(new AElementexpr(incoming, new Field(copystr(tfield.str)))); + } +} + +void Typeparser::error() { + printf("ERROR\n"); + reader->error(); + exit(-1); +} + +void Typeparser::skiptoken() { + reader->readnext(); +} + +void Typeparser::needtoken(int token) { + Token t=reader->readnext(); + if (!(t.token_type==token)) { + printf("Needed token: "); + tokenname(token); + printf("\n Got token: %s ",t.str); + tokenname(t.token_type); + error(); + } +} diff --git a/Repair/RepairInterpreter/typeparser.h b/Repair/RepairInterpreter/typeparser.h new file mode 100755 index 0000000..0d2bc68 --- /dev/null +++ b/Repair/RepairInterpreter/typeparser.h @@ -0,0 +1,29 @@ +#ifndef TYPEPARSER_H +#define TYPEPARSER_H + +#include "common.h" +#include +#include +#include "classlist.h" + + +// This class defines a parser for the structure definitions + +class Typeparser { + public: + Typeparser(Reader *r); + structure * parsestructure(); + private: + void commaorcloseparen(); + AElementexpr *checkdot(AElementexpr* incoming); + AElementexpr *parseaelementexpr(bool); + tlabel * parsetlabel(); + tfield * parsetfield(); + ttype * parsettype(); + AElementexpr * parseindex(); + Reader *reader; + void skiptoken(); + void needtoken(int); + void error(); +}; +#endif