--- /dev/null
+#include <stdlib.h>
+#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;i<c->numquants();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;i<c->numquants();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;i<domrelation->getnumrelation();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;i<domrelation->getnumrelation();i++) {
+ DRelation *drelation=domrelation->getrelation(i);
+ char *range=drelation->getrange();
+ if (equivalentstrings(range,set)) {
+ testforconflictremove(NULL,set,drelation->getname(),c,p);
+ }
+ }
+ return false;
+}
+
+/* remove <v,a> 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 <v,a> 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;
+}
--- /dev/null
+#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
--- /dev/null
+// handles prediate of the following forms: VE<E, VE<=E, VE=E, VE>=E, VE>E
+
+#include <stdlib.h>
+#include <assert.h>
+#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()) {
+ // VE<E
+ case PREDICATE_LT:
+ {
+ // set VE=E which breaks VE<E
+ Element *newele=new Element(ele->intvalue());
+ 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 <v,?> 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;
+}
--- /dev/null
+// handles prediate of the following forms: VE<E, VE<=E, VE=E, 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
--- /dev/null
+// Repairs and destroys size propositions of the form "size(SE)=1"
+
+#include <assert.h>
+#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 <v,a> 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 <a,v> 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;
+}
--- /dev/null
+#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
--- /dev/null
+#include <stdlib.h>
+#include <assert.h>
+#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; i<size; i++)
+ {
+ void *objtoremove=ws->firstelement();
+ 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; i<size; i++)
+ {
+ void *objtoremove = ws->firstelement();
+ 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 <v,a> 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 <a,v> 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;
+}
--- /dev/null
+#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
--- /dev/null
+#include <assert.h>
+#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 <v,a> 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 <a,v> 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;
+}
--- /dev/null
+#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
--- /dev/null
+#include <assert.h>
+#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 <v,a> 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 */
+}
--- /dev/null
+#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
--- /dev/null
+#include <assert.h>
+#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 <v,a> 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 <v,a> 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;
+}
--- /dev/null
+#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
--- /dev/null
+// for CIV
+
+#include <stdlib.h>
+#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;i<ss->getnumsubsets();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;
+}
--- /dev/null
+// 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
--- /dev/null
+// for the File System benchmark
+
+#include <stdlib.h>
+#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;i<ss->getnumsubsets();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;
+}
--- /dev/null
+// 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
--- /dev/null
+#include <stdlib.h>
+#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;i<ss->getnumsubsets();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();
+}
--- /dev/null
+#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
--- /dev/null
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <values.h>
+#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;j<newcurrentsize;j++) newbins[j]=NULL;
+ long i;
+ ht->currentsize=newcurrentsize;
+ for(i=0;i<oldcurrentsize;i++) {
+ struct genpointerlist * tmpptr=oldbins[i];
+ while(tmpptr!=NULL) {
+ int hashcode=genhashfunction(ht, tmpptr->src);
+ 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;i<geninitialnumbins;i++)
+ gpl[i]=NULL;
+ ght->hash_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;i<ht->currentsize;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);
+}
--- /dev/null
+// 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
+
+
+
--- /dev/null
+#include <stdlib.h>
+#include "Guidance.h"
+
+Source::Source(Element * (*fptr)(structure *,model *)) {
+ functionptr=fptr;
+ setname=NULL;
+}
+
+Source::Source(char *sname) {
+ functionptr=NULL;
+ setname=sname;
+}
--- /dev/null
+#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
--- /dev/null
+#include <stdlib.h>
+#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);
+}
--- /dev/null
+#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
--- /dev/null
+# 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:
--- /dev/null
+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
--- /dev/null
+# 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:
--- /dev/null
+#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);
+ }
+}
--- /dev/null
+#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
+
+
+
--- /dev/null
+#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() {}
--- /dev/null
+#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
+
--- /dev/null
+// Defines the Model Definition Language (MDL)
+
+#include <stdio.h>
+#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;i<numexpr;i++) {
+ exprs[i]->print();
+ }
+ 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;i<numquantifiers;i++) {
+ if (i!=0)
+ printf(",");
+ quantifiers[i]->print();
+ }
+ printf("],");
+ statementa->print();
+ printf(" => ");
+ statementb->print();
+ printf("\n");
+}
--- /dev/null
+// Defines the Model Definition Language (MDL)
+
+#ifndef Abstract_H
+#define Abstract_H
+#include<unistd.h>
+#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
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#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;i<c->numquants();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)));
+}
+
--- /dev/null
+#ifndef AbstractParser_H
+#define AbstractParser_H
+
+#include "common.h"
+#include <iostream.h>
+#include <stdio.h>
+#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
--- /dev/null
+// Interface for reading structures
+
+#include <assert.h>
+#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;i<type->getnumparams();i++) {
+ env->put(type->getparam(i)->getname(),element->paramvalue(i));
+ }*/
+ char *fieldname=field->field();
+ ttype *typeoffield=NULL;
+ AElementexpr *lindex=NULL;
+ for(int i=0;i<type->getnumlabels();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;i<type->getnumfields();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<<bitoffset))!=0));
+ break;
+ }
+ case TTYPE_BYTE:
+ {
+ char c=*((char *)addr);
+ ele=new Element(c);
+ break;
+ }
+ case TTYPE_STRUCT:
+ {
+ /* Element **earray=new Element *[typeoffield->getnumparamvalues()];
+ for(int i=0;i<typeoffield->getnumparamvalues();i++) {
+ earray[i]=evaluateexpr(this,typeoffield->getparamvalues(i),env);
+ }*/
+ ele=new Element(addr,globalmodel->getstructure(typeoffield->getname()));
+ break;
+ }
+ }
+ return ele;
+}
+
--- /dev/null
+// 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
--- /dev/null
+// Interface for writing structures
+
+#include <assert.h>
+#include <stdio.h>
+#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;i<type->getnumparams();i++) {
+ env->put(type->getparam(i)->getname(),element->paramvalue(i));
+ }*/
+ char *fieldname=field->field();
+ ttype *typeoffield=NULL;
+ AElementexpr *lindex=NULL;
+ for(int i=0;i<type->getnumlabels();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;i<type->getnumfields();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<<bitoffset);
+ if (b)
+ c=(c&mask)|(1<<bitoffset);
+ else
+ c=c&mask;
+ *((char *)addr)=c;
+ /*
+ if (co!=c)
+ printf("Change: %hhd %hhd\n",co,c);
+ */
+ break;
+ }
+ case TTYPE_BYTE:
+ {
+ *((char *)addr)=target->getbytevalue();
+ break;
+ }
+ case TTYPE_STRUCT:
+ {
+ assert(typeoffield->isptr());
+ *((void **)(((char *) element->getobject())+offset))=target->getobject();
+ break;
+ }
+ }
+}
+
--- /dev/null
+// 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
--- /dev/null
+#include <stdlib.h>
+#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);
+}
--- /dev/null
+#ifndef CATCHERROR_H
+#define CATCHERROR_H
+
+#include "stack.h"
+#include <signal.h>
+#include <setjmp.h>
+#include <stdio.h>
+
+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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#include <stdio.h>
+#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;
+}
--- /dev/null
+#ifndef Cmodel_H
+#define Cmodel_H
+#include<unistd.h>
+#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
--- /dev/null
+#include<string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#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;
+}
+
--- /dev/null
+#ifndef COMMON_H
+#define COMMON_H
+
+char * copystr(const char *buf);
+unsigned int hashstring(char *strptr);
+int equivalentstrings(char *str1, char *str2);
+#endif
--- /dev/null
+#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);
+}
--- /dev/null
+#ifndef CParser_H
+#define CParser_H
+
+#include "common.h"
+#include <iostream.h>
+#include <stdio.h>
+#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
--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <assert.h>
+
+#include <errno.h>
+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 <de, de.inodenumber> 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("<bad inode,%d>", 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("<bad block,%d>", 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;i<MAXFILES;i++)
+ files[i].used=false;
+
+
+ if (argc <= 1) {
+ printf("Filesystem Repair:\n\tusage: main [0..9]\n\n");
+ printf("\t 0 : creates disk\n");
+ printf("\t 1 : mount disk, creates files and writes test data\n");
+ printf("\t 2 : \n");
+ printf("\t 3 : inserts errors to break specs\n");
+ printf("\t 4 : \n");
+ printf("\t 5 : \n");
+ printf("\t 6 : \n");
+ printf("\t 7 : \n");
+ printf("\t 8 : \n");
+ printf("\t 9 : \n");
+ exit(-1);
+ }
+
+ switch(argv[1][0]) {
+
+ case '0':
+ //creates a disk
+ createdisk();
+ return 1;
+
+
+ case '1': {
+ /* mounts the disk, creates NUMFILES files, and writes "buf" in each file
+ for 90 times */
+ struct block * ptr=mountdisk("disk");
+
+ for(int i=0; i<NUMFILES; i++) {
+ char filename[10];
+ sprintf(filename,"file_%d",i);
+ openfile(ptr,filename);
+ }
+
+ for(int j=0; j<90; j++) {
+ for(int i=0; i<NUMFILES; i++) {
+ char *buf="01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123";
+ writefile(ptr,i,buf,122);
+ }
+ }
+
+ for(int i=0; i<NUMFILES; i++) {
+ closefile(ptr,i);
+ }
+
+ printdirectory(ptr);
+ printinodeblock(ptr);
+
+ unmountdisk(ptr);
+ break;
+ }
+
+
+ case 'r': {
+ struct block * ptr=mountdisk("disk");
+
+ initializeanalysis();
+
+ alloc(ptr,LENGTH);
+ addmapping(dstring,ptr,"Disk");
+
+ printdirectory(ptr);
+ printinodeblock(ptr);
+
+ // check the DSs
+ unsigned long time = 0;
+ for (int i = 0; i < 50; i++) {
+ time += benchmark();
+ }
+
+ printf("\ninterpreted: %u us\n", (time/50));
+
+ dealloc(ptr);
+ unmountdisk(ptr);
+ break;
+ }
+
+ case 's': {
+ struct block * ptr=mountdisk("disk");
+
+ initializeanalysis();
+
+ alloc(ptr,LENGTH);
+ addmapping(dstring,ptr,"Disk");
+
+ printdirectory(ptr);
+ printinodeblock(ptr);
+
+ // check the DSs
+ selfcheck(ptr);
+
+
+ dealloc(ptr);
+ unmountdisk(ptr);
+ break;
+ }
+
+ case 'x': {
+ struct block * ptr=mountdisk("disk");
+
+ initializeanalysis();
+
+ alloc(ptr,LENGTH);
+ addmapping(dstring,ptr,"Disk");
+
+ printdirectory(ptr);
+ printinodeblock(ptr);
+
+ // check the DSs
+ // check the DSs
+ unsigned long time = 0;
+ for (int i = 0; i < 50; i++) {
+ time += selfcheck2(ptr);
+ }
+
+ printf("\ncompiled: %u us\n", (time/50));
+
+ dealloc(ptr);
+ unmountdisk(ptr);
+ break;
+ }
+
+
+ // insert errors that break the specs
+ case '3': {
+ struct block * ptr=mountdisk("disk");
+ initializeanalysis();
+ Hashtable *env=exportmodel->gethashtable();
+ 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; i<NUMFILES; i++) {
+ char filename[10];
+ sprintf(filename,"file_%d",i);
+ printfile(filename,ptr);
+ }
+ unmountdisk(ptr);
+ break;
+ }
+
+ case '6': {
+ // the same as "case '1'" only that the files are accessed in reversed order
+ struct block * ptr=mountdisk("disk");
+ for(int i=NUMFILES; i>1; 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;i<MAXFILES;i++)
+ files[i].used=false;
+
+
+ struct block * ptr=mountdisk("disk");
+
+ for(int i=0; i<NUMFILES; i++)
+ {
+ char filename[10];
+ sprintf(filename,"file_%d", i);
+ openfile(ptr,filename);
+ }
+
+ for(int i=0; i<NUMFILES; i++)
+ {
+ char buf[100];
+ sprintf(buf,"This is file_%d.", i);
+ writefile(ptr,i,buf,strlen(buf));
+ }
+
+
+ createlink(ptr, "file_1", "link_1");
+ createlink(ptr, "file_1", "link_2");
+
+ removefile("file_1", ptr);
+
+ int fd = openfile(ptr, "new");
+ writefile(ptr, fd, "new", 3);
+
+ printfile("file_1", ptr);
+ printfile("link_1", ptr);
+ printfile("link_2", ptr);
+
+ for(int i=0; i<NUMFILES; 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);
+ if (val!=0)
+ printf("Error!\n");
+}
+
+
+
+// mounts the disk from the file "filename"
+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);
+
+ // droy: debugging
+ if ((int)ptr == -1) {
+ perror("mountdisk\0");
+ exit(-1);
+ }
+
+
+ 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];
+
+ 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;j<BLOCKSIZE/128;j++) {
+ if (db->entries[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;j<BLOCKSIZE/DIRECTORYENTRYSIZE;j++) {
+ if (db->entries[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)<len)
+ len=12*BLOCKSIZE-tfd->offset;
+ for(int i=0;i<len;i++) {
+ int nbuffer=tfd->offset/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].filesize<files[fd].offset)
+ itb->entries[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].filesize<files[fd].offset)
+ itb->entries[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)<len)
+ len=filelen-tfd->offset;
+
+ for(int i=0;i<len;) {
+ int nbuffer=tfd->offset/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;k<MAXFILES;k++) {
+ if(!files[k].used) {
+ /* Found file */
+ fd=k;
+ files[fd].used=true;
+ break;
+ }
+ }
+ if (fd==-1) return fd;
+
+ /* Check to see if file exists*/
+ 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;j<BLOCKSIZE/DIRECTORYENTRYSIZE;j++)
+ {
+ if (db->entries[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;j<BLOCKSIZE/DIRECTORYENTRYSIZE;j++) {
+ if (db->entries[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;i<NUMINODES;i++) {
+ if (!(ib.inode[i/8]&(1<<(i%8)))) {
+ ib.inode[i/8]=ib.inode[i/8]|(1<<(i%8));
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+int getblock(struct block * ptr) {
+ for(int i=0;i<NUMBLOCK;i++) {
+ if (!(bb.blocks[i/8]&(1<<(i%8)))) {
+ bb.blocks[i/8]=bb.blocks[i/8]|(1<<(i%8));
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+
+void createdisk()
+{
+ int blocksize=BLOCKSIZE;
+ int numblocks=NUMBLOCK;
+
+ int fd=open("disk",O_CREAT|O_RDWR|O_TRUNC, S_IREAD|S_IWRITE);
+
+ // creates numblocks and initializes them with 0
+ char *buf=(char *)calloc(1,blocksize);
+ for(int i=0;i<numblocks;i++) {
+ write(fd,buf,blocksize);
+ }
+ free(buf);
+
+ // maps the file 'disk' into memory
+ void *vptr=mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0);
+
+ // added by dan roy for debugging
+ if ((int)vptr == -1) {
+ perror("createdisk()\0");
+ exit(-1);
+ }
+ // end dan roy
+
+ struct block *ptr=(struct block *)vptr;
+ {
+ struct SuperBlock * sb=(struct SuperBlock*) &ptr[0];
+ sb->FreeBlockCount=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;j<BLOCKSIZE/DIRECTORYENTRYSIZE;j++) {
+ if (db->entries[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;j<BLOCKSIZE/DIRECTORYENTRYSIZE;j++) {
+ if (db->entries[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; i<NUMINODES; i++)
+ {
+ Inode inode = itb->entries[i];
+ printf("inode %d: (filesize %d), (referencecount %d)\n", i, inode.filesize, inode.referencecount);
+ }
+}
+
+
--- /dev/null
+// defines the sets and the relations used
+
+#include <stdlib.h>
+#include <stdio.h>
+#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;i<numsubsets;i++)
+ if (i==0)
+ printf("%s ",subsets[i]);
+ else
+ printf("| %s",subsets[i]);
+ printf("Size: %d",set->size());
+}
+
+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;i<numsets;i++)
+ settable->put(sets[i]->getname(),sets[i]);
+ for(int i=0;i<numrelations;i++)
+ relationtable->put(relations[i]->getname(),relations[i]);
+}
+
+void DomainRelation::reset() {
+ for(int i=0;i<numsets;i++) {
+ sets[i]->reset();
+ }
+ for(int i=0;i<numrelations;i++) {
+ relations[i]->reset();
+ }
+}
+
+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;i<numsets;i++) {
+ sets[i]->print();
+ printf("\n");
+ }
+ printf("\n");
+ for(int i=0;i<numrelations;i++) {
+ relations[i]->print();
+ 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;i<numsets;i++)
+ delete(sets[i]);
+ for(int i=0;i<numrelations;i++)
+ delete(relations[i]);
+ delete(sets);
+ delete(relations);
+}
+
+void DomainRelation::addallsubsets(DomainSet *ds, WorkSet *ws) {
+ WorkSet *tmp=new WorkSet(true);
+ tmp->addobject(ds);
+ while(!tmp->isEmpty()) {
+ DomainSet *s=(DomainSet *)tmp->firstelement();
+ tmp->removeobject(s);
+ ws->addobject(s);
+ for(int j=0;j<s->getnumsubsets();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;i<bs->getnumsubsets();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;i<cs->getnumsubsets();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;i<numsets;i++)
+ for (int j=0;j<sets[i]->getnumsubsets();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;j<s->getnumsubsets();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;i<ptr->getnumsubsets();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;j<ds->getnumsubsets();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;i<numrelations;i++) {
+ DRelation * relation=relations[i];
+ if (equivalentstrings(relation->getdomain(),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;j<ds->getnumsubsets();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;i<numsets;i++) {
+ if(checksubset(sets[i])) {
+ changed=true;
+ anychange=true;
+ }
+ }
+ for(int i=0;i<numrelations;i++) {
+ if(checkrelations(relations[i])) {
+ changed=true;
+ anychange=true;
+ }
+ }
+#ifdef REPAIR
+ /* Fix point only necessary if repairing */
+ if(!changed)
+#endif
+ break;
+ }
+ return anychange;
+}
+
+
+
+
+/* propagate the changes so that all the subset inclusion and partition
+ constraints are satisfied. */
+bool DomainRelation::checksubset(DomainSet *ds) {
+ // remove all elements in ds that are not contained by its superset
+ bool changed=false;
+ DomainSet *superset=getsuperset(ds);
+ WorkSet *ws=ds->getset();
+ 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;i<ds->getnumsubsets();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;
+}
--- /dev/null
+// 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
--- /dev/null
+#include <stdlib.h>
+#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();
+ }
+}
--- /dev/null
+#ifndef DPARSER_H
+#define DPARSER_H
+#include "common.h"
+#include <iostream.h>
+#include <stdio.h>
+#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
--- /dev/null
+// provides an object wrapper around elementary types
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#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);
+}
--- /dev/null
+// 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
--- /dev/null
+#include <stdlib.h>
+#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;i<globalmodel->getnumconstraints();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;i<globalmodel->getnumconstraints();i++) {
+ NormalForm *nf=globalmodel->getnormalform(i);
+ bool gotallreqs=true;
+ for(int j=0;j<nf->getnumsentences();j++) {
+ CoerceSentence *cs=nf->getsentence(j);
+ for (int k=0;k<cs->getnumpredicates();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;i<globalmodel->getnumconstraints();i++) {
+ NormalForm *nf=globalmodel->getnormalform(i);
+ Constraint *c=globalmodel->getconstraint(i);
+ WorkSet *old=NULL;
+ for(int j=0;j<nf->getnumsentences();j++) {
+ WorkSet *curr=new WorkSet();
+ CoerceSentence *cs=nf->getsentence(j);
+ for (int k=0;k<cs->getnumpredicates();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;i<c->numquants();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;i<c->numquants();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;
+}
--- /dev/null
+#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
+
--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#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;i<MAXFILES;i++)
+ files[i].used=false;
+ switch(argv[1][0]) {
+ case '0': createdisk();
+ return 1;
+ case '1': {
+ struct block * ptr=mountdisk("disk");
+ for(int i=0;i<145;i++) {
+ char filename[10];
+ sprintf(filename,"fil%d",i);
+ openfile(ptr,filename);
+ }
+ for(int j=0;j<90;j++) {
+ for(int i=0;i<145;i++) {
+ char *buf="01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123";
+ writefile(ptr,i,buf,122);
+ }
+ }
+ for(int i=0;i<145;i++) {
+ closefile(ptr,i);
+ }
+ unmountdisk(ptr);
+ break;
+ }
+ case '2': {
+ struct block * ptr=chmountdisk("disk");
+ initializeanalysis();
+ Hashtable *env=exportmodel->gethashtable();
+ 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;j<BLOCKSIZE/128;j++) {
+ if (db->entries[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;j<BLOCKSIZE/128;j++) {
+ if (db->entries[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;j<BLOCKSIZE/128;j++) {
+ if (db->entries[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;j<BLOCKSIZE/128;j++) {
+ if (db->entries[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)<len)
+ len=12*BLOCKSIZE-tfd->offset;
+ for(int i=0;i<len;i++) {
+ int nbuffer=tfd->offset/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].filesize<files[fd].offset)
+ itb->entries[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].filesize<files[fd].offset)
+ itb->entries[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)<len)
+ len=filelen-tfd->offset;
+ for(int i=0;i<len;) {
+ int nbuffer=tfd->offset/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;k<MAXFILES;k++) {
+ /* Found file */
+ if(!files[k].used) {
+ fd=k;
+ files[fd].used=true;
+ break;
+ }
+ }
+ if (fd==-1) return fd;
+
+ /* Check to see if file exists*/
+ 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;j<BLOCKSIZE/128;j++) {
+ if (db->entries[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;j<BLOCKSIZE/128;j++) {
+ if (db->entries[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;i<NUMINODES;i++) {
+ if (!(ib.inode[i/8]&(1<<(i%8)))) {
+ ib.inode[i/8]=ib.inode[i/8]|(1<<(i%8));
+ return i;
+ }
+ }
+ return -1;
+}
+
+int getblock(struct block * ptr) {
+ for(int i=0;i<NUMBLOCK;i++) {
+ if (!(bb.blocks[i/8]&(1<<(i%8)))) {
+ bb.blocks[i/8]=bb.blocks[i/8]|(1<<(i%8));
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+
+void createdisk() {
+ int blocksize=BLOCKSIZE;
+ int numblocks=NUMBLOCK;
+ int fd=open("disk",O_CREAT|O_RDWR|O_TRUNC);
+ char *buf=(char *)calloc(1,blocksize);
+ for(int i=0;i<numblocks;i++) {
+ write(fd,buf,blocksize);
+ }
+ free(buf);
+ void *vptr=mmap(NULL,LENGTH,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0);
+ struct block *ptr=(struct block *)vptr;
+ {
+ struct SuperBlock * sb=(struct SuperBlock*) &ptr[0];
+ sb->FreeBlockCount=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");
+}
+
--- /dev/null
+#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
+
--- /dev/null
+#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<length;i++)
+ array[i]=oldarray[i];
+ delete[](oldarray);
+ }
+ array[length++]=object;
+}
+
+void List::toArray(void **writearray) {
+ for(int i=0;i<length;i++) {
+ writearray[i]=array[i];
+ }
+}
+
+unsigned int List::size() {
+ return length;
+}
--- /dev/null
+#ifndef LIST_H
+#define LIST_H
+
+class List {
+ public:
+ List();
+ ~List();
+ void addobject(void *);
+ void toArray(void **);
+ unsigned int size();
+
+
+ private:
+ void **array;
+ unsigned int arraysize;
+ unsigned int length;
+};
+
+#define INITIAL_LIST_SIZE 10
+#endif
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <fstream.h>
+#include <iostream.h>
+#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 <sys/time.h>
+
+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;i<numconstraint;i++) {
+ if (c==constraintarray[i])
+ return constraintnormal[i];
+ }
+ printf("Error finding normal form\n");
+ exit(-1);
+}
+
+int model::getnumconstraints() {
+ return numconstraint;
+}
+
+NormalForm * model::getnormalform(int i) {
+ return constraintnormal[i];
+}
+
+Constraint * model::getconstraint(int i) {
+ return constraintarray[i];
+}
+
+
+// processes the model definition rules
+void model::doabstraction() {
+ struct timeval begin,end;
+ unsigned long time;
+ gettimeofday(&begin,NULL);
+
+ pa=new processabstract(this);
+ bool clean=false;
+ /* Process rules until we reach a fixpoint*/
+ /* First the normal rules */
+ do {
+ clean=false;
+ for(int i=0;i<numrules;i++) {
+ if(!rulearray[i]->isdelayed()) {
+ pa->setclean();
+ pa->processrule(rulearray[i]);
+ if (pa->dirtyflagstatus())
+ clean=true;
+ }
+ }
+ } while(clean);
+
+ /* Then the delayed rules */
+ do {
+ clean=false;
+ for(int i=0;i<numrules;i++) {
+ if(rulearray[i]->isdelayed()) {
+ 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;i<numrules;i++) {
+ if(rulearray[i]->isstatic()) {
+ 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;i<numconcrete;i++) {
+ pr->processrule(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; i<numconstraint; i++)
+ {
+ Constraint *c = getconstraint(i);
+ if (po->issatisfied(c))
+ if (random()<prob_breakconstraint*RAND_MAX)
+ po->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; i<numconstraint; i++)
+ {
+ Constraint *c = getconstraint(i);
+#ifdef DEBUGMESSAGES
+ printf("Constraint: ");
+ c->print();
+ 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 (r<prob_modifyconstraint*RAND_MAX)
+ po->modifyconstraint(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;i<numconstraint;i++) {
+ if (!po->processconstraint(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;i<numrules;i++) {
+ if(rulearray[i]->isstatic()) {
+ 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;i<list->size();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;i<numstarray;i++) {
+ if (equivalentstrings(name,structurearray[i]->getname())) {
+ /* 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*/
+}
--- /dev/null
+#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
--- /dev/null
+// converts constraints into disjunctive normal form
+
+#include <stdlib.h>
+#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; i<getnumpredicates(); i++)
+ {
+ CoercePredicate *cp = getpredicate(i);
+ Predicate *p = cp->getpredicate();
+ 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;i<numpreds;i++) {
+ CoercePredicate *cp=predicates[i];
+ bool pvalue;
+ if (cp->getpredicate()!=NULL)
+ pvalue=po->processpredicate(cp->getpredicate(),env);
+ if (pvalue!=cp->getcoercebool())
+ cost+=costfunction(cp);
+ }
+ return cost;
+}
+
+
+CoerceSentence::~CoerceSentence() {
+ for(int i=0;i<numpreds;i++)
+ delete(predicates[i]);
+ delete predicates;
+}
+
+
+
+
+// class NormalForm
+
+NormalForm::NormalForm(Constraint *c) {
+ SentenceArray *sa=computesentences(c->getstatement(),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;i<r->numquants();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;i<length;i++) {
+ if (badsentences==NULL || !badsentences->contains(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;i<left->length;i++)
+ combine[i]=left->sentences[i];
+ for(int i=0;i<right->length;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;i<left->length;i++)
+ for(int j=0;j<right->length;j++) {
+ CoerceSentence *leftsent=left->sentences[i];
+ CoerceSentence *rightsent=right->sentences[j];
+ CoercePredicate **preds=new CoercePredicate *[leftsent->getnumpredicates()+rightsent->getnumpredicates()];
+ for(int il=0;il<leftsent->getnumpredicates();il++)
+ preds[il]=new CoercePredicate(leftsent->getpredicate(il)->getcoercebool(),leftsent->getpredicate(il)->getpredicate());
+ for(int ir=0;ir<rightsent->getnumpredicates();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;i<left->length;i++)
+ delete(left->sentences[i]);
+ for(int i=0;i<right->length;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;i<left->length;i++)
+ for(int j=0;j<right->length;j++) {
+ CoerceSentence *leftsent=left->sentences[i];
+ CoerceSentence *rightsent=right->sentences[j];
+ CoercePredicate **preds=new CoercePredicate *[leftsent->getnumpredicates()+rightsent->getnumpredicates()];
+ for(int il=0;il<leftsent->getnumpredicates();il++)
+ preds[il]=new CoercePredicate(leftsent->getpredicate(il)->getcoercebool(),leftsent->getpredicate(il)->getpredicate());
+ for(int ir=0;ir<rightsent->getnumpredicates();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;i<left->length;i++)
+ delete(left->sentences[i]);
+ for(int i=0;i<right->length;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;i<left->length;i++)
+ combine[i]=left->sentences[i];
+ for(int i=0;i<right->length;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;
+}
+
--- /dev/null
+// converts constraints into disjunctive normal form
+
+#ifndef NORMALIZER_H
+#define NORMALIZER_H
+#include "classlist.h"
+#include<stdio.h>
+
+
+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
--- /dev/null
+// Defines the Internal Constraint Language
+
+#include <stdio.h>
+#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;