Moved the interpreter
authorbdemsky <bdemsky>
Thu, 6 May 2004 21:16:22 +0000 (21:16 +0000)
committerbdemsky <bdemsky>
Thu, 6 May 2004 21:16:22 +0000 (21:16 +0000)
104 files changed:
Repair/RepairInterpreter/Action.cc [new file with mode: 0755]
Repair/RepairInterpreter/Action.h [new file with mode: 0755]
Repair/RepairInterpreter/ActionAssign.cc [new file with mode: 0755]
Repair/RepairInterpreter/ActionAssign.h [new file with mode: 0755]
Repair/RepairInterpreter/ActionEQ1.cc [new file with mode: 0755]
Repair/RepairInterpreter/ActionEQ1.h [new file with mode: 0755]
Repair/RepairInterpreter/ActionGEQ1.cc [new file with mode: 0755]
Repair/RepairInterpreter/ActionGEQ1.h [new file with mode: 0755]
Repair/RepairInterpreter/ActionInSet.cc [new file with mode: 0755]
Repair/RepairInterpreter/ActionInSet.h [new file with mode: 0755]
Repair/RepairInterpreter/ActionNormal.cc [new file with mode: 0755]
Repair/RepairInterpreter/ActionNormal.h [new file with mode: 0755]
Repair/RepairInterpreter/ActionNotInSet.cc [new file with mode: 0755]
Repair/RepairInterpreter/ActionNotInSet.h [new file with mode: 0755]
Repair/RepairInterpreter/DefaultGuidance.cc [new file with mode: 0755]
Repair/RepairInterpreter/DefaultGuidance.h [new file with mode: 0755]
Repair/RepairInterpreter/DefaultGuidance2.cc [new file with mode: 0755]
Repair/RepairInterpreter/DefaultGuidance2.h [new file with mode: 0755]
Repair/RepairInterpreter/DefaultGuidance3.cc [new file with mode: 0755]
Repair/RepairInterpreter/DefaultGuidance3.h [new file with mode: 0755]
Repair/RepairInterpreter/GenericHashtable.cc [new file with mode: 0755]
Repair/RepairInterpreter/GenericHashtable.h [new file with mode: 0755]
Repair/RepairInterpreter/Guidance.cc [new file with mode: 0755]
Repair/RepairInterpreter/Guidance.h [new file with mode: 0755]
Repair/RepairInterpreter/Hashtable.cc [new file with mode: 0755]
Repair/RepairInterpreter/Hashtable.h [new file with mode: 0755]
Repair/RepairInterpreter/Makefile [new file with mode: 0755]
Repair/RepairInterpreter/Makefile.am [new file with mode: 0755]
Repair/RepairInterpreter/Makefile.in [new file with mode: 0755]
Repair/RepairInterpreter/Relation.cc [new file with mode: 0755]
Repair/RepairInterpreter/Relation.h [new file with mode: 0755]
Repair/RepairInterpreter/SimpleHash.cc [new file with mode: 0755]
Repair/RepairInterpreter/SimpleHash.h [new file with mode: 0755]
Repair/RepairInterpreter/amodel.cc [new file with mode: 0755]
Repair/RepairInterpreter/amodel.h [new file with mode: 0755]
Repair/RepairInterpreter/aparser.cc [new file with mode: 0755]
Repair/RepairInterpreter/aparser.h [new file with mode: 0755]
Repair/RepairInterpreter/bitreader.cc [new file with mode: 0755]
Repair/RepairInterpreter/bitreader.h [new file with mode: 0755]
Repair/RepairInterpreter/bitwriter.cc [new file with mode: 0755]
Repair/RepairInterpreter/bitwriter.h [new file with mode: 0755]
Repair/RepairInterpreter/catcherror.c [new file with mode: 0755]
Repair/RepairInterpreter/catcherror.h [new file with mode: 0755]
Repair/RepairInterpreter/classlist.h [new file with mode: 0755]
Repair/RepairInterpreter/cmemory.h [new file with mode: 0755]
Repair/RepairInterpreter/cmodel.cc [new file with mode: 0755]
Repair/RepairInterpreter/cmodel.h [new file with mode: 0755]
Repair/RepairInterpreter/common.cc [new file with mode: 0755]
Repair/RepairInterpreter/common.h [new file with mode: 0755]
Repair/RepairInterpreter/cparser.cc [new file with mode: 0755]
Repair/RepairInterpreter/cparser.h [new file with mode: 0755]
Repair/RepairInterpreter/danfile.cc [new file with mode: 0755]
Repair/RepairInterpreter/dmodel.cc [new file with mode: 0755]
Repair/RepairInterpreter/dmodel.h [new file with mode: 0755]
Repair/RepairInterpreter/dparser.cc [new file with mode: 0755]
Repair/RepairInterpreter/dparser.h [new file with mode: 0755]
Repair/RepairInterpreter/element.cc [new file with mode: 0755]
Repair/RepairInterpreter/element.h [new file with mode: 0755]
Repair/RepairInterpreter/fieldcheck.cc [new file with mode: 0755]
Repair/RepairInterpreter/fieldcheck.h [new file with mode: 0755]
Repair/RepairInterpreter/file.cc [new file with mode: 0755]
Repair/RepairInterpreter/file.h [new file with mode: 0755]
Repair/RepairInterpreter/list.cc [new file with mode: 0755]
Repair/RepairInterpreter/list.h [new file with mode: 0755]
Repair/RepairInterpreter/model.cc [new file with mode: 0755]
Repair/RepairInterpreter/model.h [new file with mode: 0755]
Repair/RepairInterpreter/normalizer.cc [new file with mode: 0755]
Repair/RepairInterpreter/normalizer.h [new file with mode: 0755]
Repair/RepairInterpreter/omodel.cc [new file with mode: 0755]
Repair/RepairInterpreter/omodel.h [new file with mode: 0755]
Repair/RepairInterpreter/oparser.cc [new file with mode: 0755]
Repair/RepairInterpreter/oparser.h [new file with mode: 0755]
Repair/RepairInterpreter/processabstract.cc [new file with mode: 0755]
Repair/RepairInterpreter/processabstract.h [new file with mode: 0755]
Repair/RepairInterpreter/processconcrete.cc [new file with mode: 0755]
Repair/RepairInterpreter/processconcrete.h [new file with mode: 0755]
Repair/RepairInterpreter/processobject.cc [new file with mode: 0755]
Repair/RepairInterpreter/processobject.h [new file with mode: 0755]
Repair/RepairInterpreter/redblack.c [new file with mode: 0755]
Repair/RepairInterpreter/redblack.h [new file with mode: 0755]
Repair/RepairInterpreter/repair.cc [new file with mode: 0755]
Repair/RepairInterpreter/repair.h [new file with mode: 0755]
Repair/RepairInterpreter/rparser.cc [new file with mode: 0755]
Repair/RepairInterpreter/rparser.h [new file with mode: 0755]
Repair/RepairInterpreter/set.cc [new file with mode: 0755]
Repair/RepairInterpreter/set.h [new file with mode: 0755]
Repair/RepairInterpreter/stack.c [new file with mode: 0755]
Repair/RepairInterpreter/stack.h [new file with mode: 0755]
Repair/RepairInterpreter/test.cc [new file with mode: 0755]
Repair/RepairInterpreter/test.h [new file with mode: 0755]
Repair/RepairInterpreter/testabstract [new file with mode: 0755]
Repair/RepairInterpreter/testconcrete [new file with mode: 0755]
Repair/RepairInterpreter/testmodel [new file with mode: 0755]
Repair/RepairInterpreter/testrange [new file with mode: 0755]
Repair/RepairInterpreter/testspace [new file with mode: 0755]
Repair/RepairInterpreter/teststruct [new file with mode: 0755]
Repair/RepairInterpreter/tmap.cc [new file with mode: 0755]
Repair/RepairInterpreter/tmap.h [new file with mode: 0755]
Repair/RepairInterpreter/tmodel.cc [new file with mode: 0755]
Repair/RepairInterpreter/tmodel.h [new file with mode: 0755]
Repair/RepairInterpreter/token.cc [new file with mode: 0755]
Repair/RepairInterpreter/token.h [new file with mode: 0755]
Repair/RepairInterpreter/typeparser.cc [new file with mode: 0755]
Repair/RepairInterpreter/typeparser.h [new file with mode: 0755]

diff --git a/Repair/RepairInterpreter/Action.cc b/Repair/RepairInterpreter/Action.cc
new file mode 100755 (executable)
index 0000000..8d96bda
--- /dev/null
@@ -0,0 +1,370 @@
+#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;
+}
diff --git a/Repair/RepairInterpreter/Action.h b/Repair/RepairInterpreter/Action.h
new file mode 100755 (executable)
index 0000000..54197c9
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef Action_H
+#define Action_H
+
+#include "classlist.h"
+class Action {
+ public:
+  virtual void repairpredicate(Hashtable *env, CoercePredicate *p)=0;
+  virtual void breakpredicate(Hashtable *env, CoercePredicate *p)=0;
+  virtual bool conflict(Constraint *c1, CoercePredicate *p1, Constraint *c2, CoercePredicate *p2)=0;
+  virtual bool canrepairpredicate(CoercePredicate *p)=0;
+
+ protected:
+  char * getset(Constraint *c, char *v);
+  char * calculatebound(Constraint *c, Label *clabel);
+  bool comparepredicates(Constraint *c1, CoercePredicate *cp1, Constraint *c2, CoercePredicate *cp2);
+  bool comparesetexpr(Setexpr *s1,char *v1,Setexpr *s2,char *v2);
+  bool compareee(Elementexpr *ee1,char *v1,Elementexpr *ee2,char *v2);
+  bool testforconflict(char *setv, char *seta, char *rel, Constraint *c, CoercePredicate *p);
+  bool testforconflictremove(char *setv, char *seta, char *rel, Constraint *c, CoercePredicate *p);
+  DomainRelation *domrelation;
+  model * globalmodel;
+  bool possiblysameset(char *v1, Constraint *c1, char *v2, Constraint *c2);
+  bool possiblysameset(char *set1, char *v2, Constraint *c2);
+  bool possiblysameset(char *set1, char *set2);
+  bool conflictwithaddtoset(char *set, Constraint *c, CoercePredicate *p);
+  bool conflictwithremovefromset(WorkSet *,char *set, Constraint *c, CoercePredicate *p);
+};
+#endif
diff --git a/Repair/RepairInterpreter/ActionAssign.cc b/Repair/RepairInterpreter/ActionAssign.cc
new file mode 100755 (executable)
index 0000000..929d04e
--- /dev/null
@@ -0,0 +1,319 @@
+// 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;
+}
diff --git a/Repair/RepairInterpreter/ActionAssign.h b/Repair/RepairInterpreter/ActionAssign.h
new file mode 100755 (executable)
index 0000000..e14b6b0
--- /dev/null
@@ -0,0 +1,18 @@
+// 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
diff --git a/Repair/RepairInterpreter/ActionEQ1.cc b/Repair/RepairInterpreter/ActionEQ1.cc
new file mode 100755 (executable)
index 0000000..215f2bf
--- /dev/null
@@ -0,0 +1,302 @@
+// 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;
+}
diff --git a/Repair/RepairInterpreter/ActionEQ1.h b/Repair/RepairInterpreter/ActionEQ1.h
new file mode 100755 (executable)
index 0000000..af61961
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef ActionEQ1_H
+#define ActionEQ1_H
+#include "classlist.h"
+#include "ActionGEQ1.h"
+class ActionEQ1:public ActionGEQ1 {
+ public:
+  ActionEQ1(DomainRelation *drel,model *);
+  void repairpredicate(Hashtable *env, CoercePredicate *p);
+  void breakpredicate(Hashtable *env, CoercePredicate *p);
+  bool conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2);
+  bool canrepairpredicate(CoercePredicate *p);
+ protected:
+};
+#endif
diff --git a/Repair/RepairInterpreter/ActionGEQ1.cc b/Repair/RepairInterpreter/ActionGEQ1.cc
new file mode 100755 (executable)
index 0000000..c072d25
--- /dev/null
@@ -0,0 +1,465 @@
+#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;
+}
diff --git a/Repair/RepairInterpreter/ActionGEQ1.h b/Repair/RepairInterpreter/ActionGEQ1.h
new file mode 100755 (executable)
index 0000000..3d52724
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef ActionGEQ1_H
+#define ActionGEQ1_H
+#include "classlist.h"
+#include "Action.h"
+class ActionGEQ1:public Action {
+ public:
+  ActionGEQ1() {
+  }
+  ActionGEQ1(DomainRelation *drel, model *);
+  void repairpredicate(Hashtable *env, CoercePredicate *p);
+  void breakpredicate(Hashtable *env, CoercePredicate *p);
+  bool conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2);
+  bool canrepairpredicate(CoercePredicate *p);
+ protected:
+};
+#endif
diff --git a/Repair/RepairInterpreter/ActionInSet.cc b/Repair/RepairInterpreter/ActionInSet.cc
new file mode 100755 (executable)
index 0000000..756816d
--- /dev/null
@@ -0,0 +1,200 @@
+#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;
+}
diff --git a/Repair/RepairInterpreter/ActionInSet.h b/Repair/RepairInterpreter/ActionInSet.h
new file mode 100755 (executable)
index 0000000..416d1cd
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef ActionInSet_H
+#define ActionInSet_H
+#include "classlist.h"
+#include "Action.h"
+class ActionInSet:public Action {
+ public:
+  ActionInSet(DomainRelation *drel,model *);
+  void repairpredicate(Hashtable *env, CoercePredicate *p);
+  void breakpredicate(Hashtable *env, CoercePredicate *p);
+  bool conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2);
+  bool canrepairpredicate(CoercePredicate *p);
+ private:
+  bool testforinvconflictwithinvsetsize(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2);
+  bool testforinvconflictwithsetsize(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2);
+  bool testforinvconflictwithinvrelset(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2);
+  bool testforinvconflictwithrelset(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2);
+  bool testforconflictwithsetsize(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2);
+  bool testforconflictwithinvsetsize(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2);
+  bool testforconflictwithrelset(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2);
+  bool testforconflictwithinvrelset(Constraint *c1,CoercePredicate *cp1, Constraint *c2,CoercePredicate *cp2);
+  bool testforconflictwithvalueexpr(Constraint *c1, CoercePredicate *cp1,Constraint *c2, CoercePredicate *cp2);
+  bool testforinvconflictwithvalueexpr(Constraint *c1, CoercePredicate *cp1,Constraint *c2, CoercePredicate *cp2);
+};
+#endif
diff --git a/Repair/RepairInterpreter/ActionNormal.cc b/Repair/RepairInterpreter/ActionNormal.cc
new file mode 100755 (executable)
index 0000000..f34bc5a
--- /dev/null
@@ -0,0 +1,140 @@
+#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 */
+}
diff --git a/Repair/RepairInterpreter/ActionNormal.h b/Repair/RepairInterpreter/ActionNormal.h
new file mode 100755 (executable)
index 0000000..e34dc45
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef ActionNormal_H
+#define ActionNormal_H
+#include "classlist.h"
+#include "Action.h"
+class ActionNormal:public Action {
+ public:
+  ActionNormal(model *);
+  void repairpredicate(Hashtable *env, CoercePredicate *p);
+  void breakpredicate(Hashtable *env, CoercePredicate *p);
+  bool conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2);
+  bool canrepairpredicate(CoercePredicate *p);
+ private:
+};
+#endif
diff --git a/Repair/RepairInterpreter/ActionNotInSet.cc b/Repair/RepairInterpreter/ActionNotInSet.cc
new file mode 100755 (executable)
index 0000000..2d5aad9
--- /dev/null
@@ -0,0 +1,121 @@
+#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;
+}
diff --git a/Repair/RepairInterpreter/ActionNotInSet.h b/Repair/RepairInterpreter/ActionNotInSet.h
new file mode 100755 (executable)
index 0000000..58e8117
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef ActionNotInSet_H
+#define ActionNotInSet_H
+#include "classlist.h"
+#include "Action.h"
+class ActionNotInSet:public Action {
+ public:
+  ActionNotInSet(DomainRelation *drel, model *);
+  void repairpredicate(Hashtable *env, CoercePredicate *p);
+  void breakpredicate(Hashtable *env, CoercePredicate *p);
+  bool conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2);
+  bool canrepairpredicate(CoercePredicate *p);
+ private:
+};
+#endif
diff --git a/Repair/RepairInterpreter/DefaultGuidance.cc b/Repair/RepairInterpreter/DefaultGuidance.cc
new file mode 100755 (executable)
index 0000000..6a322a8
--- /dev/null
@@ -0,0 +1,82 @@
+// 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;
+}
diff --git a/Repair/RepairInterpreter/DefaultGuidance.h b/Repair/RepairInterpreter/DefaultGuidance.h
new file mode 100755 (executable)
index 0000000..867bf59
--- /dev/null
@@ -0,0 +1,27 @@
+// for CIV
+
+#ifndef DefGuidance_h
+#define DefGuidance_h
+#include "classlist.h"
+#include "Guidance.h"
+
+class DefGuidance:public Guidance {
+  /* This class tells the analysis stuff */
+  /* For each set:
+     1. Source for atoms if the set is too small - can be another set or function call (assumed to be no set)
+     2. Source for atoms if relation requires atom of this set - can be another set or function call (assumed to be no set)
+     3. Removal from set - where to insert objects from this set
+     4. Insertion into set - which subset to put objects in
+  */
+ public:
+  DefGuidance(model *m);
+  Source sourceforsetsize(char *set);
+  Source sourceforrelation(char *set);
+  char * removefromset(char * set);
+  char * insertiontoset(char *set);
+ private:
+  model * globalmodel;
+};
+
+Element * allocatebytes(structure * st, model *m);
+#endif
diff --git a/Repair/RepairInterpreter/DefaultGuidance2.cc b/Repair/RepairInterpreter/DefaultGuidance2.cc
new file mode 100755 (executable)
index 0000000..b054d63
--- /dev/null
@@ -0,0 +1,92 @@
+// 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;
+}
diff --git a/Repair/RepairInterpreter/DefaultGuidance2.h b/Repair/RepairInterpreter/DefaultGuidance2.h
new file mode 100755 (executable)
index 0000000..ef61ee6
--- /dev/null
@@ -0,0 +1,27 @@
+// for the File System benchmark
+
+#ifndef DefGuidance2_h
+#define DefGuidance2_h
+#include "classlist.h"
+#include "Guidance.h"
+
+class DefGuidance2:public Guidance {
+  /* This class tells the analysis stuff */
+  /* For each set:
+     1. Source for atoms if the set is too small - can be another set or function call (assumed to be no set)
+     2. Source for atoms if relation requires atom of this set - can be another set or function call (assumed to be no set)
+     3. Removal from set - where to insert objects from this set
+     4. Insertion into set - which subset to put objects in
+  */
+ public:
+  DefGuidance2(model *m);
+  Source sourceforsetsize(char *set);
+  Source sourceforrelation(char *set);
+  char * removefromset(char * set);
+  char * insertiontoset(char *set);
+ private:
+  model * globalmodel;
+};
+
+Element * allocatebytes2(structure * st, model *m);
+#endif
diff --git a/Repair/RepairInterpreter/DefaultGuidance3.cc b/Repair/RepairInterpreter/DefaultGuidance3.cc
new file mode 100755 (executable)
index 0000000..bf0b57b
--- /dev/null
@@ -0,0 +1,84 @@
+#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();
+}
diff --git a/Repair/RepairInterpreter/DefaultGuidance3.h b/Repair/RepairInterpreter/DefaultGuidance3.h
new file mode 100755 (executable)
index 0000000..a6f9e29
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef DefGuidance3_h
+#define DefGuidance3_h
+#include "classlist.h"
+#include "Guidance.h"
+
+class DefGuidance3:public Guidance {
+  /* This class tells the analysis stuff */
+  /* For each set:
+     1. Source for atoms if the set is too small - can be another set or function call (assumed to be no set)
+     2. Source for atoms if relation requires atom of this set - can be another set or function call (assumed to be no set)
+     3. Removal from set - where to insert objects from this set
+     4. Insertion into set - which subset to put objects in
+  */
+ public:
+  DefGuidance3(model *m);
+  Source sourceforsetsize(char *set);
+  Source sourceforrelation(char *set);
+  char * removefromset(char * set);
+  char * insertiontoset(char *set);
+ private:
+  model * globalmodel;
+};
+
+#endif
diff --git a/Repair/RepairInterpreter/GenericHashtable.cc b/Repair/RepairInterpreter/GenericHashtable.cc
new file mode 100755 (executable)
index 0000000..f42c543
--- /dev/null
@@ -0,0 +1,200 @@
+#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);
+}
diff --git a/Repair/RepairInterpreter/GenericHashtable.h b/Repair/RepairInterpreter/GenericHashtable.h
new file mode 100755 (executable)
index 0000000..1dabec3
--- /dev/null
@@ -0,0 +1,50 @@
+// implements a generic hash table
+
+#ifndef GENHASHTABLE
+#define GENHASHTABLE
+#define geninitialnumbins 10
+
+struct genhashtable {
+  unsigned int (*hash_function)(void *);
+  int (*comp_function)(void *,void *);
+  struct genpointerlist ** bins;
+  long counter;
+  int currentsize;
+  struct genpointerlist *list;
+  struct genpointerlist *last;
+};
+
+
+struct genpointerlist {
+  void * src;
+  void * object;
+  struct genpointerlist * next;
+
+  struct genpointerlist * inext;
+  struct genpointerlist * iprev;
+};
+
+
+struct geniterator {
+  struct genpointerlist * ptr;
+  bool finished;
+};
+
+struct genhashtable * genallocatehashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *,void *));
+void genfreehashtable(struct genhashtable * ht);
+
+void * getnext(struct genhashtable *,void *);
+int genputtable(struct genhashtable *, void *, void *);
+void * gengettable(struct genhashtable *, void *);
+int gencontains(struct genhashtable *, void *);
+unsigned int genhashfunction(struct genhashtable *,void *);
+
+int hashsize(struct genhashtable * ht);
+void genfreekey(struct genhashtable *ht, void *);
+struct geniterator * gengetiterator(struct genhashtable *ht);
+void * gennext(struct geniterator *it);
+void genfreeiterator(struct geniterator *it);
+#endif
+
+
+
diff --git a/Repair/RepairInterpreter/Guidance.cc b/Repair/RepairInterpreter/Guidance.cc
new file mode 100755 (executable)
index 0000000..11e6f14
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include "Guidance.h"
+
+Source::Source(Element * (*fptr)(structure *,model *)) {
+  functionptr=fptr;
+  setname=NULL;
+}
+
+Source::Source(char *sname) {
+  functionptr=NULL;
+  setname=sname;
+}
diff --git a/Repair/RepairInterpreter/Guidance.h b/Repair/RepairInterpreter/Guidance.h
new file mode 100755 (executable)
index 0000000..cb0b969
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef Guidance_h
+#define Guidance_h
+#include "classlist.h"
+
+class Guidance {
+  /* This class tells the analysis stuff */
+  /* For each set:
+     1. Source for atoms if the set is too small - can be another set or function call (assumed to be no set)
+     2. Source for atoms if relation requires atom of this set - can be another set or function call (assumed to be no set)
+     3. Removal from set - where to insert objects from this set
+     4. Insertion into set - which subset to put objects in
+  */
+ public:
+  virtual Source sourceforsetsize(char *set)=0;
+  virtual Source sourceforrelation(char *set)=0;
+  virtual char * removefromset(char * set)=0;
+  virtual char * insertiontoset(char *set)=0;
+};
+
+
+class Source {
+ public:
+  Source(Element * (*fptr)(structure *, model *));
+  Source(char *sname);
+
+  Element * (*functionptr)(structure *,model *);
+  char * setname;
+};
+
+#endif
diff --git a/Repair/RepairInterpreter/Hashtable.cc b/Repair/RepairInterpreter/Hashtable.cc
new file mode 100755 (executable)
index 0000000..fb3b66c
--- /dev/null
@@ -0,0 +1,51 @@
+#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);
+}
diff --git a/Repair/RepairInterpreter/Hashtable.h b/Repair/RepairInterpreter/Hashtable.h
new file mode 100755 (executable)
index 0000000..a10ce14
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef Hashtable_H
+#define Hashtable_H
+
+#include "GenericHashtable.h"
+#include "classlist.h"
+
+class Hashtable {
+ public:
+  Hashtable();
+  Hashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *, void *));
+  ~Hashtable();
+  void put(void *key, void*object);
+  void remove(void *key);
+  void* get(void *key);
+  bool contains(void *key);
+  void setparent(Hashtable *parent);
+ private:
+  Hashtable *parent;
+  struct genhashtable *forward;
+};
+
+#endif
diff --git a/Repair/RepairInterpreter/Makefile b/Repair/RepairInterpreter/Makefile
new file mode 100755 (executable)
index 0000000..289767d
--- /dev/null
@@ -0,0 +1,544 @@
+# Makefile.in generated by automake 1.6.3 from Makefile.am.
+# checker/Makefile.  Generated from Makefile.in by configure.
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = /bin/sh
+
+srcdir = .
+top_srcdir = ..
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libexecdir = ${exec_prefix}/libexec
+datadir = ${prefix}/share
+sysconfdir = ${prefix}/etc
+sharedstatedir = ${prefix}/com
+localstatedir = ${prefix}/var
+libdir = ${exec_prefix}/lib
+infodir = ${prefix}/info
+mandir = ${prefix}/man
+includedir = ${prefix}/include
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/freeciv
+pkglibdir = $(libdir)/freeciv
+pkgincludedir = $(includedir)/freeciv
+top_builddir = ..
+
+ACLOCAL = aclocal-1.6
+AUTOCONF = autoconf
+AUTOMAKE = automake-1.6
+AUTOHEADER = autoheader
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_SCRIPT = ${INSTALL}
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = s,x,x,
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = 
+host_triplet = i686-pc-linux-gnu
+
+EXEEXT = 
+OBJEXT = o
+PATH_SEPARATOR = :
+AMTAR = tar
+ARFLAGS = 
+AWK = gawk
+BUILD_INCLUDED_LIBINTL = no
+CATALOGS =  da.gmo de.gmo en_GB.gmo es.gmo fi.gmo fr.gmo hu.gmo it.gmo ja.gmo nl.gmo no.gmo pl.gmo pt.gmo pt_BR.gmo ro.gmo ru.gmo sv.gmo
+CATOBJEXT = .gmo
+CC = gcc
+CLIENT_CFLAGS = -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/X11R6/include -I/usr/X11R6/include
+CLIENT_LIBS = -L/usr/lib -lgdk_imlib -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm
+CPP = gcc -E
+CVS_DEPS = yes
+CXX = g++
+DATADIRNAME = share
+DEPDIR = .deps
+ESD_CFLAGS = 
+ESD_CONFIG = /usr/bin/esd-config
+ESD_LIBS = -L/usr/lib -lesd -laudiofile -lm
+GDK_IMLIB_CFLAGS = -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/X11R6/include -I/usr/X11R6/include
+GDK_IMLIB_LIBS = -L/usr/lib -lgdk_imlib -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm
+GENCAT = gencat
+GLIBC21 = yes
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_CONFIG = @GLIB_CONFIG@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GMOFILES =  da.gmo de.gmo en_GB.gmo es.gmo fi.gmo fr.gmo hu.gmo it.gmo ja.gmo nl.gmo no.gmo pl.gmo pt.gmo pt_BR.gmo ro.gmo ru.gmo sv.gmo
+GMSGFMT = /usr/bin/msgfmt
+GOBJECT_QUERY = @GOBJECT_QUERY@
+GTK_CFLAGS = -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/X11R6/include
+GTK_CONFIG = /usr/bin/gtk-config
+GTK_LIBS = -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm
+IMLIB_CFLAGS = @IMLIB_CFLAGS@
+IMLIB_CONFIG = /usr/bin/imlib-config
+IMLIB_LIBS = @IMLIB_LIBS@
+INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s
+INSTOBJEXT = .mo
+INTLBISON = bison
+INTLDEPS = @INTLDEPS@
+INTLLIBS = 
+INTLOBJS = 
+INTL_LIBTOOL_SUFFIX_PREFIX = 
+LIBICONV = 
+LN_S = ln -s
+MAINT = #
+MKINSTALLDIRS = ./mkinstalldirs
+MSGFMT = /usr/bin/msgfmt
+PACKAGE = freeciv
+PKG_CONFIG = 
+POFILES =  da.po de.po en_GB.po es.po fi.po fr.po hu.po it.po ja.po nl.po no.po pl.po pt.po pt_BR.po ro.po ru.po sv.po
+POSUB = po
+RANLIB = ranlib
+SDL_CFLAGS = 
+SDL_CONFIG = no
+SDL_LIBS = 
+SERVER_LIBS = -lreadline  -lncurses -lm
+SOUND_CFLAGS =  
+SOUND_LIBS =  -L/usr/lib -lesd -laudiofile -lm
+STRIP = 
+UNAME = uname
+UP = @UP@
+USE_INCLUDED_LIBINTL = no
+USE_NLS = yes
+VERSION = 1.13.0
+X_CFLAGS = 
+X_EXTRA_LIBS = 
+X_LIBS = 
+X_PRE_LIBS = 
+am__include = include
+am__quote = 
+gui_sources = gui-gtk
+install_sh = /root/freeciv-1.13.0/install-sh
+noinst_LIBRARIES = libchecker.a
+
+libchecker_a_SOURCES = \
+ActionAssign.cc        \
+ActionAssign.h \
+Action.cc      \
+ActionEQ1.cc   \
+ActionEQ1.h    \
+ActionGEQ1.cc  \
+ActionGEQ1.h   \
+Action.h       \
+ActionInSet.cc \
+ActionInSet.h  \
+ActionNormal.cc        \
+ActionNormal.h \
+ActionNotInSet.cc      \
+ActionNotInSet.h       \
+amodel.cc      \
+amodel.h       \
+aparser.cc     \
+aparser.h      \
+bitreader.cc   \
+bitreader.h    \
+bitwriter.cc   \
+bitwriter.h    \
+classlist.h    \
+cmodel.cc      \
+cmodel.h       \
+common.c       \
+common.h       \
+cparser.cc     \
+cparser.h      \
+DefaultGuidance3.cc    \
+DefaultGuidance3.h     \
+DefaultGuidance2.cc    \
+DefaultGuidance2.h     \
+DefaultGuidance.cc     \
+DefaultGuidance.h      \
+dmodel.cc      \
+dmodel.h       \
+dparser.cc     \
+dparser.h      \
+element.cc     \
+element.h      \
+fieldcheck.cc  \
+fieldcheck.h   \
+file.cc                \
+file.h         \
+GenericHashtable.c     \
+GenericHashtable.h     \
+Guidance.cc    \
+Guidance.h     \
+Hashtable.cc   \
+Hashtable.h    \
+list.c         \
+list.h         \
+model.cc       \
+model.h                \
+normalizer.cc  \
+normalizer.h   \
+omodel.cc      \
+omodel.h       \
+oparser.cc     \
+oparser.h      \
+processabstract.cc     \
+processabstract.h      \
+processconcrete.cc     \
+processconcrete.h      \
+processobject.cc       \
+processobject.h        \
+Relation.cc    \
+Relation.h     \
+repair.cc      \
+repair.h       \
+set.cc \
+set.h  \
+test.cc        \
+test.h \
+tmodel.cc      \
+tmodel.h       \
+token.cc       \
+token.h                \
+typeparser.cc  \
+typeparser.h   \
+tmap.cc                \
+tmap.h         \
+redblack.c     \
+redblack.h     \
+cmemory.h
+
+subdir = checker
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+libchecker_a_AR = $(AR) cru
+libchecker_a_LIBADD =
+am_libchecker_a_OBJECTS = ActionAssign.$(OBJEXT) Action.$(OBJEXT) \
+       ActionEQ1.$(OBJEXT) ActionGEQ1.$(OBJEXT) ActionInSet.$(OBJEXT) \
+       ActionNormal.$(OBJEXT) ActionNotInSet.$(OBJEXT) \
+       amodel.$(OBJEXT) aparser.$(OBJEXT) bitreader.$(OBJEXT) \
+       bitwriter.$(OBJEXT) cmodel.$(OBJEXT) common.$(OBJEXT) \
+       cparser.$(OBJEXT) DefaultGuidance3.$(OBJEXT) \
+       DefaultGuidance2.$(OBJEXT) DefaultGuidance.$(OBJEXT) \
+       dmodel.$(OBJEXT) dparser.$(OBJEXT) element.$(OBJEXT) \
+       fieldcheck.$(OBJEXT) file.$(OBJEXT) GenericHashtable.$(OBJEXT) \
+       Guidance.$(OBJEXT) Hashtable.$(OBJEXT) list.$(OBJEXT) \
+       model.$(OBJEXT) normalizer.$(OBJEXT) omodel.$(OBJEXT) \
+       oparser.$(OBJEXT) processabstract.$(OBJEXT) \
+       processconcrete.$(OBJEXT) processobject.$(OBJEXT) \
+       Relation.$(OBJEXT) repair.$(OBJEXT) set.$(OBJEXT) \
+       test.$(OBJEXT) tmodel.$(OBJEXT) token.$(OBJEXT) \
+       typeparser.$(OBJEXT) tmap.$(OBJEXT) redblack.$(OBJEXT)
+libchecker_a_OBJECTS = $(am_libchecker_a_OBJECTS)
+
+DEFS = -DHAVE_CONFIG_H
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
+CPPFLAGS = 
+LDFLAGS = 
+LIBS = -lz 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+DEP_FILES = ./$(DEPDIR)/Action.Po \
+       ./$(DEPDIR)/ActionAssign.Po \
+       ./$(DEPDIR)/ActionEQ1.Po ./$(DEPDIR)/ActionGEQ1.Po \
+       ./$(DEPDIR)/ActionInSet.Po \
+       ./$(DEPDIR)/ActionNormal.Po \
+       ./$(DEPDIR)/ActionNotInSet.Po \
+       ./$(DEPDIR)/DefaultGuidance.Po \
+       ./$(DEPDIR)/DefaultGuidance2.Po \
+       ./$(DEPDIR)/DefaultGuidance3.Po \
+       ./$(DEPDIR)/GenericHashtable.Po \
+       ./$(DEPDIR)/Guidance.Po ./$(DEPDIR)/Hashtable.Po \
+       ./$(DEPDIR)/Relation.Po ./$(DEPDIR)/amodel.Po \
+       ./$(DEPDIR)/aparser.Po ./$(DEPDIR)/bitreader.Po \
+       ./$(DEPDIR)/bitwriter.Po ./$(DEPDIR)/cmodel.Po \
+       ./$(DEPDIR)/common.Po ./$(DEPDIR)/cparser.Po \
+       ./$(DEPDIR)/dmodel.Po ./$(DEPDIR)/dparser.Po \
+       ./$(DEPDIR)/element.Po ./$(DEPDIR)/fieldcheck.Po \
+       ./$(DEPDIR)/file.Po ./$(DEPDIR)/list.Po \
+       ./$(DEPDIR)/model.Po ./$(DEPDIR)/normalizer.Po \
+       ./$(DEPDIR)/omodel.Po ./$(DEPDIR)/oparser.Po \
+       ./$(DEPDIR)/processabstract.Po \
+       ./$(DEPDIR)/processconcrete.Po \
+       ./$(DEPDIR)/processobject.Po \
+       ./$(DEPDIR)/redblack.Po ./$(DEPDIR)/repair.Po \
+       ./$(DEPDIR)/set.Po ./$(DEPDIR)/test.Po \
+       ./$(DEPDIR)/tmap.Po ./$(DEPDIR)/tmodel.Po \
+       ./$(DEPDIR)/token.Po ./$(DEPDIR)/typeparser.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CFLAGS = -g -O2 -Wall
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+       -o $@
+CXXFLAGS = -g -O2
+DIST_SOURCES = $(libchecker_a_SOURCES)
+DIST_COMMON = README Makefile.am Makefile.in
+SOURCES = $(libchecker_a_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .o .obj
+$(srcdir)/Makefile.in: # Makefile.am  $(top_srcdir)/configure.ac $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  checker/Makefile
+Makefile: # $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+AR = ar
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libchecker.a: $(libchecker_a_OBJECTS) $(libchecker_a_DEPENDENCIES) 
+       -rm -f libchecker.a
+       $(libchecker_a_AR) libchecker.a $(libchecker_a_OBJECTS) $(libchecker_a_LIBADD)
+       $(RANLIB) libchecker.a
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+include ./$(DEPDIR)/Action.Po
+include ./$(DEPDIR)/ActionAssign.Po
+include ./$(DEPDIR)/ActionEQ1.Po
+include ./$(DEPDIR)/ActionGEQ1.Po
+include ./$(DEPDIR)/ActionInSet.Po
+include ./$(DEPDIR)/ActionNormal.Po
+include ./$(DEPDIR)/ActionNotInSet.Po
+include ./$(DEPDIR)/DefaultGuidance.Po
+include ./$(DEPDIR)/DefaultGuidance2.Po
+include ./$(DEPDIR)/DefaultGuidance3.Po
+include ./$(DEPDIR)/GenericHashtable.Po
+include ./$(DEPDIR)/Guidance.Po
+include ./$(DEPDIR)/Hashtable.Po
+include ./$(DEPDIR)/Relation.Po
+include ./$(DEPDIR)/amodel.Po
+include ./$(DEPDIR)/aparser.Po
+include ./$(DEPDIR)/bitreader.Po
+include ./$(DEPDIR)/bitwriter.Po
+include ./$(DEPDIR)/cmodel.Po
+include ./$(DEPDIR)/common.Po
+include ./$(DEPDIR)/cparser.Po
+include ./$(DEPDIR)/dmodel.Po
+include ./$(DEPDIR)/dparser.Po
+include ./$(DEPDIR)/element.Po
+include ./$(DEPDIR)/fieldcheck.Po
+include ./$(DEPDIR)/file.Po
+include ./$(DEPDIR)/list.Po
+include ./$(DEPDIR)/model.Po
+include ./$(DEPDIR)/normalizer.Po
+include ./$(DEPDIR)/omodel.Po
+include ./$(DEPDIR)/oparser.Po
+include ./$(DEPDIR)/processabstract.Po
+include ./$(DEPDIR)/processconcrete.Po
+include ./$(DEPDIR)/processobject.Po
+include ./$(DEPDIR)/redblack.Po
+include ./$(DEPDIR)/repair.Po
+include ./$(DEPDIR)/set.Po
+include ./$(DEPDIR)/test.Po
+include ./$(DEPDIR)/tmap.Po
+include ./$(DEPDIR)/tmodel.Po
+include ./$(DEPDIR)/token.Po
+include ./$(DEPDIR)/typeparser.Po
+
+distclean-depend:
+       -rm -rf ./$(DEPDIR)
+
+.c.o:
+       source='$<' object='$@' libtool=no \
+       depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \
+       $(CCDEPMODE) $(depcomp) \
+       $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+       source='$<' object='$@' libtool=no \
+       depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \
+       $(CCDEPMODE) $(depcomp) \
+       $(COMPILE) -c `cygpath -w $<`
+CCDEPMODE = depmode=gcc3
+
+.cc.o:
+       source='$<' object='$@' libtool=no \
+       depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \
+       $(CXXDEPMODE) $(depcomp) \
+       $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+.cc.obj:
+       source='$<' object='$@' libtool=no \
+       depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \
+       $(CXXDEPMODE) $(depcomp) \
+       $(CXXCOMPILE) -c -o $@ `cygpath -w $<`
+CXXDEPMODE = depmode=gcc3
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @list='$(DISTFILES)'; for file in $$list; do \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+
+installdirs:
+
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+       distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+uninstall-am: uninstall-info-am
+
+.PHONY: GTAGS all all-am check check-am clean clean-generic \
+       clean-noinstLIBRARIES distclean distclean-compile \
+       distclean-depend distclean-generic distclean-tags distdir dvi \
+       dvi-am info info-am install install-am install-data \
+       install-data-am install-exec install-exec-am install-info \
+       install-info-am install-man install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic tags uninstall uninstall-am \
+       uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Repair/RepairInterpreter/Makefile.am b/Repair/RepairInterpreter/Makefile.am
new file mode 100755 (executable)
index 0000000..08a717d
--- /dev/null
@@ -0,0 +1,21 @@
+noinst_LIBRARIES = libchecker.a
+
+libchecker_a_SOURCES =ActionAssign.cc    bitreader.h          DefaultGuidance.h    model.cc            repair.h\
+ActionAssign.h     bitwriter.cc         dmodel.cc            model.h             rparser.cc\
+Action.cc          bitwriter.h          dmodel.h             normalizer.cc       rparser.h\
+ActionEQ1.cc       catcherror.c         dparser.cc           normalizer.h        set.cc\
+ActionEQ1.h        catcherror.h         dparser.h            omodel.cc           set.h\
+ActionGEQ1.cc      classlist.h          element.cc           omodel.h            SimpleHash.cc\
+ActionGEQ1.h       cmemory.h            element.h            oparser.cc          SimpleHash.h\
+Action.h           cmodel.cc            fieldcheck.cc        oparser.h           stack.c\
+ActionInSet.cc     cmodel.h             fieldcheck.h         processabstract.cc  stack.h\
+ActionInSet.h      common.cc            processabstract.h   test.cc\
+ActionNormal.cc    common.h             file.h               processconcrete.cc  test.h\
+ActionNormal.h     cparser.cc           GenericHashtable.cc  processconcrete.h   tmap.cc\
+ActionNotInSet.cc  cparser.h            GenericHashtable.h   processobject.cc    tmap.h\
+ActionNotInSet.h   Guidance.cc          processobject.h     tmodel.cc\
+amodel.cc          DefaultGuidance2.cc  Guidance.h           redblack.c          tmodel.h\
+amodel.h           DefaultGuidance2.h   Hashtable.cc         redblack.h          token.cc\
+aparser.cc         DefaultGuidance3.cc  Hashtable.h          Relation.cc         token.h\
+aparser.h          DefaultGuidance3.h   list.cc              Relation.h          typeparser.cc\
+bitreader.cc       DefaultGuidance.cc   list.h               repair.cc           typeparser.h
diff --git a/Repair/RepairInterpreter/Makefile.in b/Repair/RepairInterpreter/Makefile.in
new file mode 100755 (executable)
index 0000000..cb64333
--- /dev/null
@@ -0,0 +1,544 @@
+# Makefile.in generated by automake 1.6.3 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = @program_transform_name@
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+
+EXEEXT = @EXEEXT@
+OBJEXT = @OBJEXT@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+AMTAR = @AMTAR@
+ARFLAGS = @ARFLAGS@
+AWK = @AWK@
+BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CLIENT_CFLAGS = @CLIENT_CFLAGS@
+CLIENT_LIBS = @CLIENT_LIBS@
+CPP = @CPP@
+CVS_DEPS = @CVS_DEPS@
+CXX = @CXX@
+DATADIRNAME = @DATADIRNAME@
+DEPDIR = @DEPDIR@
+ESD_CFLAGS = @ESD_CFLAGS@
+ESD_CONFIG = @ESD_CONFIG@
+ESD_LIBS = @ESD_LIBS@
+GDK_IMLIB_CFLAGS = @GDK_IMLIB_CFLAGS@
+GDK_IMLIB_LIBS = @GDK_IMLIB_LIBS@
+GENCAT = @GENCAT@
+GLIBC21 = @GLIBC21@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_CONFIG = @GLIB_CONFIG@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GOBJECT_QUERY = @GOBJECT_QUERY@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_CONFIG = @GTK_CONFIG@
+GTK_LIBS = @GTK_LIBS@
+IMLIB_CFLAGS = @IMLIB_CFLAGS@
+IMLIB_CONFIG = @IMLIB_CONFIG@
+IMLIB_LIBS = @IMLIB_LIBS@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLBISON = @INTLBISON@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
+LIBICONV = @LIBICONV@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+PACKAGE = @PACKAGE@
+PKG_CONFIG = @PKG_CONFIG@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_CONFIG = @SDL_CONFIG@
+SDL_LIBS = @SDL_LIBS@
+SERVER_LIBS = @SERVER_LIBS@
+SOUND_CFLAGS = @SOUND_CFLAGS@
+SOUND_LIBS = @SOUND_LIBS@
+STRIP = @STRIP@
+UNAME = @UNAME@
+UP = @UP@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+am__include = @am__include@
+am__quote = @am__quote@
+gui_sources = @gui_sources@
+install_sh = @install_sh@
+noinst_LIBRARIES = libchecker.a
+
+libchecker_a_SOURCES = \
+ActionAssign.cc        \
+ActionAssign.h \
+Action.cc      \
+ActionEQ1.cc   \
+ActionEQ1.h    \
+ActionGEQ1.cc  \
+ActionGEQ1.h   \
+Action.h       \
+ActionInSet.cc \
+ActionInSet.h  \
+ActionNormal.cc        \
+ActionNormal.h \
+ActionNotInSet.cc      \
+ActionNotInSet.h       \
+amodel.cc      \
+amodel.h       \
+aparser.cc     \
+aparser.h      \
+bitreader.cc   \
+bitreader.h    \
+bitwriter.cc   \
+bitwriter.h    \
+classlist.h    \
+cmodel.cc      \
+cmodel.h       \
+common.c       \
+common.h       \
+cparser.cc     \
+cparser.h      \
+DefaultGuidance3.cc    \
+DefaultGuidance3.h     \
+DefaultGuidance2.cc    \
+DefaultGuidance2.h     \
+DefaultGuidance.cc     \
+DefaultGuidance.h      \
+dmodel.cc      \
+dmodel.h       \
+dparser.cc     \
+dparser.h      \
+element.cc     \
+element.h      \
+fieldcheck.cc  \
+fieldcheck.h   \
+file.cc                \
+file.h         \
+GenericHashtable.c     \
+GenericHashtable.h     \
+Guidance.cc    \
+Guidance.h     \
+Hashtable.cc   \
+Hashtable.h    \
+list.c         \
+list.h         \
+model.cc       \
+model.h                \
+normalizer.cc  \
+normalizer.h   \
+omodel.cc      \
+omodel.h       \
+oparser.cc     \
+oparser.h      \
+processabstract.cc     \
+processabstract.h      \
+processconcrete.cc     \
+processconcrete.h      \
+processobject.cc       \
+processobject.h        \
+Relation.cc    \
+Relation.h     \
+repair.cc      \
+repair.h       \
+set.cc \
+set.h  \
+test.cc        \
+test.h \
+tmodel.cc      \
+tmodel.h       \
+token.cc       \
+token.h                \
+typeparser.cc  \
+typeparser.h   \
+tmap.cc                \
+tmap.h         \
+redblack.c     \
+redblack.h     \
+cmemory.h
+
+subdir = checker
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+libchecker_a_AR = $(AR) cru
+libchecker_a_LIBADD =
+am_libchecker_a_OBJECTS = ActionAssign.$(OBJEXT) Action.$(OBJEXT) \
+       ActionEQ1.$(OBJEXT) ActionGEQ1.$(OBJEXT) ActionInSet.$(OBJEXT) \
+       ActionNormal.$(OBJEXT) ActionNotInSet.$(OBJEXT) \
+       amodel.$(OBJEXT) aparser.$(OBJEXT) bitreader.$(OBJEXT) \
+       bitwriter.$(OBJEXT) cmodel.$(OBJEXT) common.$(OBJEXT) \
+       cparser.$(OBJEXT) DefaultGuidance3.$(OBJEXT) \
+       DefaultGuidance2.$(OBJEXT) DefaultGuidance.$(OBJEXT) \
+       dmodel.$(OBJEXT) dparser.$(OBJEXT) element.$(OBJEXT) \
+       fieldcheck.$(OBJEXT) file.$(OBJEXT) GenericHashtable.$(OBJEXT) \
+       Guidance.$(OBJEXT) Hashtable.$(OBJEXT) list.$(OBJEXT) \
+       model.$(OBJEXT) normalizer.$(OBJEXT) omodel.$(OBJEXT) \
+       oparser.$(OBJEXT) processabstract.$(OBJEXT) \
+       processconcrete.$(OBJEXT) processobject.$(OBJEXT) \
+       Relation.$(OBJEXT) repair.$(OBJEXT) set.$(OBJEXT) \
+       test.$(OBJEXT) tmodel.$(OBJEXT) token.$(OBJEXT) \
+       typeparser.$(OBJEXT) tmap.$(OBJEXT) redblack.$(OBJEXT)
+libchecker_a_OBJECTS = $(am_libchecker_a_OBJECTS)
+
+DEFS = @DEFS@
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/Action.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/ActionAssign.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/ActionEQ1.Po ./$(DEPDIR)/ActionGEQ1.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/ActionInSet.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/ActionNormal.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/ActionNotInSet.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/DefaultGuidance.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/DefaultGuidance2.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/DefaultGuidance3.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/GenericHashtable.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/Guidance.Po ./$(DEPDIR)/Hashtable.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/Relation.Po ./$(DEPDIR)/amodel.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/aparser.Po ./$(DEPDIR)/bitreader.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/bitwriter.Po ./$(DEPDIR)/cmodel.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/common.Po ./$(DEPDIR)/cparser.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/dmodel.Po ./$(DEPDIR)/dparser.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/element.Po ./$(DEPDIR)/fieldcheck.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/file.Po ./$(DEPDIR)/list.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/model.Po ./$(DEPDIR)/normalizer.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/omodel.Po ./$(DEPDIR)/oparser.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/processabstract.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/processconcrete.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/processobject.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/redblack.Po ./$(DEPDIR)/repair.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/set.Po ./$(DEPDIR)/test.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/tmap.Po ./$(DEPDIR)/tmodel.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/token.Po ./$(DEPDIR)/typeparser.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+       -o $@
+CXXFLAGS = @CXXFLAGS@
+DIST_SOURCES = $(libchecker_a_SOURCES)
+DIST_COMMON = README Makefile.am Makefile.in
+SOURCES = $(libchecker_a_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am  $(top_srcdir)/configure.ac $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  checker/Makefile
+Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+AR = ar
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libchecker.a: $(libchecker_a_OBJECTS) $(libchecker_a_DEPENDENCIES) 
+       -rm -f libchecker.a
+       $(libchecker_a_AR) libchecker.a $(libchecker_a_OBJECTS) $(libchecker_a_LIBADD)
+       $(RANLIB) libchecker.a
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Action.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionAssign.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionEQ1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionGEQ1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionInSet.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionNormal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ActionNotInSet.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultGuidance.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultGuidance2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultGuidance3.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GenericHashtable.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Guidance.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Hashtable.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Relation.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amodel.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aparser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitreader.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitwriter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmodel.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cparser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmodel.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dparser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/element.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fieldcheck.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/model.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/normalizer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omodel.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oparser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processabstract.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processconcrete.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processobject.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/redblack.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repair.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmodel.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/token.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/typeparser.Po@am__quote@
+
+distclean-depend:
+       -rm -rf ./$(DEPDIR)
+
+.c.o:
+@AMDEP_TRUE@   source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@   depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@   $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+       $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@AMDEP_TRUE@   source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@   depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@   $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+       $(COMPILE) -c `cygpath -w $<`
+CCDEPMODE = @CCDEPMODE@
+
+.cc.o:
+@AMDEP_TRUE@   source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@   depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@   $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+       $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+.cc.obj:
+@AMDEP_TRUE@   source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@   depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@   $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+       $(CXXCOMPILE) -c -o $@ `cygpath -w $<`
+CXXDEPMODE = @CXXDEPMODE@
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @list='$(DISTFILES)'; for file in $$list; do \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+
+installdirs:
+
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+       distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+uninstall-am: uninstall-info-am
+
+.PHONY: GTAGS all all-am check check-am clean clean-generic \
+       clean-noinstLIBRARIES distclean distclean-compile \
+       distclean-depend distclean-generic distclean-tags distdir dvi \
+       dvi-am info info-am install install-am install-data \
+       install-data-am install-exec install-exec-am install-info \
+       install-info-am install-man install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic tags uninstall uninstall-am \
+       uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Repair/RepairInterpreter/Relation.cc b/Repair/RepairInterpreter/Relation.cc
new file mode 100755 (executable)
index 0000000..7d5d094
--- /dev/null
@@ -0,0 +1,162 @@
+#include "Relation.h"
+#include "element.h"
+#include "GenericHashtable.h"
+#include "set.h"
+#include "stdio.h"
+
+
+// class Tuple
+
+Tuple::Tuple(void *l,void *r) {
+  left=l;
+  right=r;
+}
+Tuple::Tuple() {
+  left=NULL;right=NULL;
+}
+
+bool Tuple::isnull() {
+  if (left==NULL&&right==NULL)
+    return true;
+  else
+    return false;
+}
+
+
+// class WorkRelation
+
+WorkRelation::WorkRelation() {
+  forward=genallocatehashtable((unsigned int (*)(void *)) & hashelement,(int (*)(void *,void *)) & elementequals);
+  inverse=genallocatehashtable((unsigned int (*)(void *)) & hashelement,(int (*)(void *,void *)) & elementequals);
+  flag=false;
+}
+
+WorkRelation::WorkRelation(bool flag) {
+  forward=genallocatehashtable(NULL,NULL);
+  inverse=genallocatehashtable(NULL,NULL);
+  this->flag=true;
+}
+
+Tuple WorkRelation::firstelement() {
+  if (forward->list==NULL)
+    return Tuple();
+  void * forwardfirst=forward->list->src;
+  WorkSet *ws=getset(forwardfirst);
+  return Tuple(forwardfirst,ws->firstelement());
+}
+Tuple WorkRelation::getnextelement(void *left,void *right) {
+  WorkSet *ws=getset(left);
+  if (ws->getnextelement(right)!=NULL) {
+    return Tuple(left, ws->getnextelement(right));
+  }
+  void *leftnext=getnext(forward,left);
+  if (leftnext!=NULL) {
+    return Tuple(leftnext,getset(leftnext)->firstelement());
+  } else return Tuple();
+}
+
+bool WorkRelation::contains(void *key, void*object) {
+  /*Set up forward reference*/
+  if(!gencontains(forward,key))
+    return false;
+  WorkSet *w=(WorkSet *)gengettable(forward,key);
+  return w->contains(object);
+}
+
+void WorkRelation::put(void *key, void*object) {
+  {    /*Set up forward reference*/
+    if(!gencontains(forward,key)) {
+      WorkSet *w=flag?new WorkSet(true):new WorkSet();
+      genputtable(forward,key,w);
+    }
+    WorkSet *w=(WorkSet *)gengettable(forward,key);
+    w->addobject(object);
+  }
+  {/*Set up backwars reference*/
+    if(!gencontains(inverse,object)) {
+      WorkSet *w=flag?new WorkSet(true):new WorkSet();
+      genputtable(inverse,object,w);
+    }
+    WorkSet *w=(WorkSet *) gengettable(inverse,object);
+    w->addobject(key);
+  }
+}
+  
+void WorkRelation::remove(void *key, void *object) {
+  { /*Set up forward reference*/
+    WorkSet *w=(WorkSet *)gengettable(forward,key);
+    w->removeobject(object);
+    if (w->isEmpty()) {
+      genfreekey(forward,key);
+      delete(w);
+    }
+  }
+  { /*Set up backwards reference*/
+    WorkSet *w=(WorkSet *)gengettable(inverse,object);
+    w->removeobject(key);
+    if (w->isEmpty()) {
+      genfreekey(inverse,object);
+      delete(w);
+    }
+  }
+}
+
+WorkSet* WorkRelation::getset(void *key) {
+  if (gencontains(forward,key))
+    return (WorkSet *) gengettable(forward,key);
+  else return NULL;
+}
+
+void* WorkRelation::getobj(void *key) {
+  WorkSet *ws=getset(key);
+  if (ws==NULL)
+    return NULL;
+  return ws->firstelement();
+}
+
+WorkSet* WorkRelation::invgetset(void *key) {
+  if (gencontains(inverse,key))
+    return (WorkSet *) gengettable(inverse,key);
+  else
+    return NULL;
+}
+
+void* WorkRelation::invgetobj(void *key) {
+  WorkSet *ws=invgetset(key);
+  if (ws==NULL)
+    return NULL;
+  return ws->firstelement();
+}
+
+WorkRelation::~WorkRelation() {
+  destroyer(forward);
+  destroyer(inverse);
+}
+
+void WorkRelation::destroyer(struct genhashtable *d) {
+  struct geniterator *it=gengetiterator(d);
+  while (true) {
+    void *key=gennext(it);
+    if (key==NULL)
+      break;
+    WorkSet *ws=(WorkSet *)gengettable(d,key);
+    delete(ws);
+  }
+  genfreeiterator(it);
+  genfreehashtable(d);
+}
+
+void WorkRelation::print()
+{
+  printf("\n");
+  Tuple tuple = firstelement();
+  while (!tuple.isnull())
+    {
+      Element *l = (Element *) tuple.left;
+      Element *r = (Element *) tuple.right;
+      printf("("); l->print(); printf(", "); r->print(); printf(")\n");
+      tuple = getnextelement(tuple.left, tuple.right);
+    }
+}
diff --git a/Repair/RepairInterpreter/Relation.h b/Repair/RepairInterpreter/Relation.h
new file mode 100755 (executable)
index 0000000..7b9083f
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef Relation_H
+#define Relation_h
+#include "classlist.h"
+
+class Tuple {
+ public:
+  Tuple(void *l,void *r);
+  Tuple();
+  bool isnull();
+  void *left,*right;
+};
+
+
+
+#define WRELATION_SINGDOMAIN 0x1
+#define WRELATION_MANYDOMAIN 0x2
+#define WRELATION_SINGRANGE 0x10
+#define WRELATION_MANYRANGE 0x20
+
+class WorkRelation {
+ public:
+  WorkRelation();
+  WorkRelation(bool);
+  ~WorkRelation();
+  bool contains(void *key, void *object);
+  Tuple firstelement();
+  Tuple getnextelement(void *left, void *right);
+  void put(void *key, void *object);
+  void remove(void *key, void *object);
+  WorkSet* getset(void *key);
+  void* getobj(void *key);
+  WorkSet* invgetset(void *key);
+  void* invgetobj(void *key);
+  void print();
+
+ private:
+  void destroyer(struct genhashtable *d);
+  bool flag;
+  struct genhashtable *forward, *inverse;
+};
+#endif
+
+
+
diff --git a/Repair/RepairInterpreter/SimpleHash.cc b/Repair/RepairInterpreter/SimpleHash.cc
new file mode 100755 (executable)
index 0000000..a98b205
--- /dev/null
@@ -0,0 +1,189 @@
+#include "SimpleHash.h"
+
+/* LINKED HASH NODE ****************************************************/
+
+LinkedHashNode::LinkedHashNode(int key, int data, LinkedHashNode *next) {
+    this->key = key;
+    this->data = data;
+    this->next = next;
+}
+
+LinkedHashNode::LinkedHashNode() {
+    this->key = -1;
+    this->data = -1;
+    this->next = 0;
+}
+
+/* SIMPLE LIST ****************************************************/
+
+SimpleList::SimpleList() {
+    ptr = 0;
+    head.next = 0;
+}
+
+void SimpleList::reset() {
+    ptr = &head;
+}
+
+int SimpleList::hasMoreElements() {
+    return (ptr->next == 0);
+}
+
+int SimpleList::nextElement() {
+    ptr = ptr->next;
+    return ptr->data;
+}
+
+void SimpleList::add(int data) {
+    LinkedHashNode *cur = &head;
+    while (cur->next) {
+        cur = cur->next;
+        if (cur->data == data) {
+            return; // no duplicates
+        }
+    }
+    cur->next = new LinkedHashNode(0, data, 0);
+    return;
+}
+
+int SimpleList::contains(int data) {
+    LinkedHashNode *cur = &head;
+    while (cur->next) {
+        cur = cur->next;
+        if (cur->data == data) {
+            return 1; // found!
+        }
+    }
+    return 0;    
+}
+    
+/* SIMPLE HASH ********************************************************/
+
+SimpleHash::SimpleHash(int size) {
+    if (size <= 0) {
+        throw SimpleHashException();
+    }
+    this->size = size;
+    this->bucket = new LinkedHashNode[size];
+    this->last = &all;
+    all.next = 0;
+    this->numparents = 0;
+    this->numelements = 0;
+}
+
+SimpleHash::SimpleHash() {
+    this->size = 100;
+    this->bucket = new LinkedHashNode[size];
+    this->last = &all;
+    all.next = 0;
+    this->numparents = 0;
+    this->numelements = 0;
+}
+
+
+SimpleHash::~SimpleHash() {
+}
+
+void SimpleHash::addParent(SimpleHash* parent) {
+    parents[numparents++] = parent;    
+}
+
+int SimpleHash::add(int key, int data) {
+    unsigned int hashkey = (unsigned int)key % size;
+    
+    LinkedHashNode *ptr = &bucket[hashkey];
+
+    /* check that this key/object pair isn't already here */
+    // TBD can be optimized for set v. relation */
+    while (ptr->next) {
+        ptr = ptr->next;
+        if (ptr->key == key && ptr->data == data) {
+            return 0;
+        }
+    }
+    
+    ptr->next = new LinkedHashNode(key, data, 0);
+    last = last->next = new LinkedHashNode(key, data, 0);
+    numelements++;
+    
+    for (int i = 0; i < numparents; i++) {
+        parents[i]->add(key, data);
+    }
+
+    return key;
+}
+
+bool SimpleHash::contains(int key) {
+    unsigned int hashkey = (unsigned int)key % size;
+    
+    LinkedHashNode *ptr = &bucket[hashkey];
+    while (ptr->next) {
+        ptr = ptr->next;
+        if (ptr->key == key) {
+            // we already have this object 
+            // stored in the hash so just return
+            return true;
+        }
+    }
+    return false;
+}
+
+bool SimpleHash::contains(int key, int data) {
+    unsigned int hashkey = (unsigned int)key % size;
+    
+    LinkedHashNode *ptr = &bucket[hashkey];
+    while (ptr->next) {
+        ptr = ptr->next;
+        if (ptr->key == key && ptr->data == data) {
+            // we already have this object 
+            // stored in the hash so just return
+            return true;
+        }
+    }
+    return false;
+}
+
+int SimpleHash::count(int key) {
+    unsigned int hashkey = (unsigned int)key % size;
+    int count = 0;
+
+    LinkedHashNode *ptr = &bucket[hashkey];
+    while (ptr->next) {
+        ptr = ptr->next;
+        if (ptr->key == key) {
+            count++;
+        }
+    }
+    return count;
+}
+
+int SimpleHash::get(int key, int&data) {
+    unsigned int hashkey = (unsigned int)key % size;
+    
+    LinkedHashNode *ptr = &bucket[hashkey];
+    while (ptr->next) {
+        ptr = ptr->next;
+        if (ptr->key == key) {
+            data = ptr->data;
+            return 1; // success
+        }
+    }
+        
+    return 0; // failure
+}
+
+int SimpleHash::countdata(int data) {
+    int count = 0;
+    for (int i = 0; i < size ; i++) {
+        LinkedHashNode *ptr = &bucket[i];
+        while(ptr->next) {
+            ptr = ptr->next;
+            if (ptr->data == data) {
+                count++;
+            }
+        }
+    }
+    return count;
+}
+
+SimpleHashException::SimpleHashException() {}
diff --git a/Repair/RepairInterpreter/SimpleHash.h b/Repair/RepairInterpreter/SimpleHash.h
new file mode 100755 (executable)
index 0000000..04b128b
--- /dev/null
@@ -0,0 +1,126 @@
+#ifndef SIMPLEHASH_H
+#define SIMPLEHASH_H
+
+/* LinkedHashNode *****************************************************/
+
+class LinkedHashNode {
+    
+public:
+    LinkedHashNode *next;
+    int data;
+    int key;  
+    LinkedHashNode(int key, int data, LinkedHashNode *next);
+    LinkedHashNode();
+
+};
+
+/* SimpleList *********************************************************/
+
+class SimpleList {
+private:
+    LinkedHashNode head;
+    LinkedHashNode *ptr;
+public:
+    SimpleList();
+    void add(int data);
+    int contains(int data);
+    void reset();
+    int hasMoreElements();
+    int nextElement();
+};
+
+
+/* SimpleIterator *****************************************************/
+
+class SimpleIterator {
+
+private:
+
+    LinkedHashNode *cur;
+
+public:
+
+    inline SimpleIterator(LinkedHashNode *start) {
+        cur = start;
+    }
+
+    inline int hasNext() {
+        return (int)cur->next == 0 ? 0 : 1;
+    }
+
+    inline int next() {
+        cur = cur->next;
+        return cur->data;
+    }
+
+    inline int key() {
+        return cur->key;
+    }
+
+    inline int size() {
+        int temp = 0;
+        while (cur->next) {
+            temp++;
+            cur = cur->next;
+        }
+        return temp;
+    }
+
+};
+
+/* SimpleHash *********************************************************/
+
+class SimpleHash {
+
+private:
+    int numelements;
+
+    int size;
+    LinkedHashNode *bucket;
+    LinkedHashNode all;    
+    LinkedHashNode *last;
+
+    int numparents;
+    SimpleHash* parents[10];
+
+public:
+
+    SimpleHash();
+
+    SimpleHash(int size);
+
+    ~SimpleHash();
+
+    int add(int key, int data);
+
+    bool contains(int key);
+
+    bool contains(int key, int data);
+
+    int get(int key, int& data);
+
+    int countdata(int data);
+
+    void addParent(SimpleHash* parent);
+
+    inline SimpleIterator* iterator() {
+        return new SimpleIterator(&all);
+    }
+
+    inline int count() {
+        return numelements;
+    }
+
+    int count(int key);
+
+};
+
+/* SimpleHashExcepion  *************************************************/
+
+class SimpleHashException {
+public:
+    SimpleHashException();
+};
+
+#endif
+
diff --git a/Repair/RepairInterpreter/amodel.cc b/Repair/RepairInterpreter/amodel.cc
new file mode 100755 (executable)
index 0000000..03c1cd2
--- /dev/null
@@ -0,0 +1,510 @@
+// 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");
+}
diff --git a/Repair/RepairInterpreter/amodel.h b/Repair/RepairInterpreter/amodel.h
new file mode 100755 (executable)
index 0000000..29e74f9
--- /dev/null
@@ -0,0 +1,222 @@
+// 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
diff --git a/Repair/RepairInterpreter/aparser.cc b/Repair/RepairInterpreter/aparser.cc
new file mode 100755 (executable)
index 0000000..57b8df9
--- /dev/null
@@ -0,0 +1,591 @@
+#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)));
+}
+
diff --git a/Repair/RepairInterpreter/aparser.h b/Repair/RepairInterpreter/aparser.h
new file mode 100755 (executable)
index 0000000..a155b6d
--- /dev/null
@@ -0,0 +1,32 @@
+#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
diff --git a/Repair/RepairInterpreter/bitreader.cc b/Repair/RepairInterpreter/bitreader.cc
new file mode 100755 (executable)
index 0000000..6561bb8
--- /dev/null
@@ -0,0 +1,110 @@
+// 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;
+}
+
diff --git a/Repair/RepairInterpreter/bitreader.h b/Repair/RepairInterpreter/bitreader.h
new file mode 100755 (executable)
index 0000000..5a9c9c4
--- /dev/null
@@ -0,0 +1,16 @@
+// Interface for reading structures
+
+#ifndef BITREADER_H
+#define BITREADER_H
+#include "classlist.h"
+
+class bitreader {
+ public:
+  bitreader(model *m, Hashtable *env);
+  Element * readfieldorarray(Element *element, Field *field, Element *index);
+ private:
+  model *globalmodel;
+  Hashtable *env;
+};
+
+#endif
diff --git a/Repair/RepairInterpreter/bitwriter.cc b/Repair/RepairInterpreter/bitwriter.cc
new file mode 100755 (executable)
index 0000000..a99a3c5
--- /dev/null
@@ -0,0 +1,127 @@
+// 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;
+    }
+  }
+}
+
diff --git a/Repair/RepairInterpreter/bitwriter.h b/Repair/RepairInterpreter/bitwriter.h
new file mode 100755 (executable)
index 0000000..35a04b7
--- /dev/null
@@ -0,0 +1,17 @@
+// Interface for writing structures
+
+#ifndef BITWRITER_H
+#define BITWRITER_H
+#include "classlist.h"
+
+class bitwriter {
+ public:
+  bitwriter(model *m, Hashtable *env);
+  void writefieldorarray(Element *element, Field *field, Element *index, Element *);
+ private:
+  model *globalmodel;
+  bitreader * bitread;
+  Hashtable *env;
+};
+
+#endif
diff --git a/Repair/RepairInterpreter/catcherror.c b/Repair/RepairInterpreter/catcherror.c
new file mode 100755 (executable)
index 0000000..9fd8a31
--- /dev/null
@@ -0,0 +1,18 @@
+#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);
+}
diff --git a/Repair/RepairInterpreter/catcherror.h b/Repair/RepairInterpreter/catcherror.h
new file mode 100755 (executable)
index 0000000..f7e05e9
--- /dev/null
@@ -0,0 +1,30 @@
+#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
diff --git a/Repair/RepairInterpreter/classlist.h b/Repair/RepairInterpreter/classlist.h
new file mode 100755 (executable)
index 0000000..71b8385
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef classlist_h
+#define classlist_h
+//#include "dmalloc.h"
+//#define REPAIR
+#define DEBUGMESSAGES
+//#define DEBUGMANYMESSAGES
+#define TOOL
+
+class TypeEle;
+class Rule;
+class AQuantifier;
+class Statementa;
+class Statementb;
+class AElementexpr;
+class Type;
+class Field;
+class AParser;
+class bitreader;
+class DomainSet;
+class DRelation;
+class DomainRelation;
+class Dparser;
+class ElementWrapper;
+class Element;
+class Hashtable;
+class List;
+class model;
+class Literal;
+class Setlabel;
+class Constraint;
+class Quantifier;
+class Statement;
+class Predicate;
+class Valueexpr;
+class Elementexpr;
+class Set;
+class Setexpr;
+class Relation;
+class Label;
+class Parser;
+class processabstract;
+class processconcrete;
+class processobject;
+class RelationSet;
+class State;
+class Tuple;
+class WorkRelation;
+class WorkSet;
+class Iterator;
+class structure;
+class ttype;
+//class tparam;
+class tlabel;
+class tfield;
+class Token;
+class Reader;
+class Typeparser;
+class NormalForm;
+class SentenceArray;
+class CoerceSentence;
+class CoercePredicate;
+class Action;
+class ActionInSet;
+class ActionNotInSet;
+class ActionGEQ1;
+class ActionEQ1;
+class ActionAssign;
+class ActionNotAssign;
+class CParser;
+class CStatementb;
+class CAElementexpr;
+class Expr;
+class Repair;
+class bitwriter;
+class Guidance;
+class Source;
+class FieldCheck;
+class FieldTuple;
+class ActionNormal;
+class typemap;
+//class RParser;
+
+extern model *exportmodel;
+#endif
diff --git a/Repair/RepairInterpreter/cmemory.h b/Repair/RepairInterpreter/cmemory.h
new file mode 100755 (executable)
index 0000000..1b108cb
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef CMEMORY_H
+#define CMEMORY_H
+#include "test.h"
+#define malloc(size) ourmalloc(size)
+#define calloc(memb,size) ourcalloc(memb,size)
+#define realloc(ptr,size) ourrealloc(ptr,size)
+#define free(size) ourfree(size)
+#endif
diff --git a/Repair/RepairInterpreter/cmodel.cc b/Repair/RepairInterpreter/cmodel.cc
new file mode 100755 (executable)
index 0000000..116a3f6
--- /dev/null
@@ -0,0 +1,236 @@
+#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;
+}
diff --git a/Repair/RepairInterpreter/cmodel.h b/Repair/RepairInterpreter/cmodel.h
new file mode 100755 (executable)
index 0000000..a4eba9a
--- /dev/null
@@ -0,0 +1,78 @@
+#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
diff --git a/Repair/RepairInterpreter/common.cc b/Repair/RepairInterpreter/common.cc
new file mode 100755 (executable)
index 0000000..77b5a24
--- /dev/null
@@ -0,0 +1,59 @@
+#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;
+}
+
diff --git a/Repair/RepairInterpreter/common.h b/Repair/RepairInterpreter/common.h
new file mode 100755 (executable)
index 0000000..e9b2034
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef COMMON_H
+#define COMMON_H
+
+char * copystr(const char *buf);
+unsigned int hashstring(char *strptr);
+int equivalentstrings(char *str1, char *str2);
+#endif
diff --git a/Repair/RepairInterpreter/cparser.cc b/Repair/RepairInterpreter/cparser.cc
new file mode 100755 (executable)
index 0000000..911181a
--- /dev/null
@@ -0,0 +1,268 @@
+#include "cparser.h"
+#include "token.h"
+#include "amodel.h"
+#include "omodel.h"
+#include "cmodel.h"
+#include "element.h"
+
+CParser::CParser(Reader *r) {
+  reader=r;
+}
+
+AElementexpr * CParser::parseaelementexpr(bool isquant) {
+  CAElementexpr *oldee=NULL;
+  int joinop=-1;
+  while(true) {
+  Token t=reader->peakahead();
+  switch(t.token_type) {
+  case TOKEN_LITERAL:
+    {
+      if ((joinop==-1)&&(oldee!=NULL))
+       return oldee;
+      skiptoken();
+      needtoken(TOKEN_OPENPAREN);
+      Token literal=reader->readnext();
+      needtoken(TOKEN_CLOSEPAREN);
+      if (oldee==NULL)
+       oldee=new CAElementexpr(new Literal(copystr(literal.str)));
+      else {
+       if (joinop!=-1) {
+         oldee=new CAElementexpr(oldee,new CAElementexpr(new Literal(copystr(literal.str))),joinop);
+         joinop=-1;
+       } else error();
+      }
+      break;
+    }
+
+  case TOKEN_OPENPAREN:
+    {
+      if ((joinop==-1)&&(oldee!=NULL))
+       return oldee;
+      skiptoken();
+      CAElementexpr *ee=(CAElementexpr *)parseaelementexpr(false);
+      if (oldee==NULL)
+       oldee=ee;
+      else {
+       if (joinop!=-1) {
+         oldee=new CAElementexpr(oldee,ee,joinop);
+         joinop=-1;
+       } else error();
+      }
+      break;
+    }
+    
+  case TOKEN_CLOSEBRACK:
+    if (isquant)
+      return oldee;
+    // Otherwise fall through
+  case TOKEN_CLOSEPAREN:
+    skiptoken();
+    return checkdot(oldee);
+    break;
+  case TOKEN_SUB:
+    skiptoken();
+    if ((oldee!=NULL)&&(joinop==-1))
+      joinop=CAELEMENTEXPR_SUB;
+    else
+      error();
+    break;
+  case TOKEN_ADD:
+    skiptoken();
+    if ((oldee!=NULL)&&(joinop==-1))
+      joinop=CAELEMENTEXPR_ADD;
+    else
+      error();
+    break;
+  case TOKEN_SIZEOF: {
+    skiptoken();
+    needtoken(TOKEN_OPENPAREN);
+    Setexpr *sae=parsesetexpr();
+    needtoken(TOKEN_CLOSEPAREN);
+    return new CAElementexpr(sae);
+  }
+  case TOKEN_ELEMENT: {
+    skiptoken();
+    CAElementexpr *cae=(CAElementexpr *)parseaelementexpr(false);
+    needtoken(TOKEN_OF);
+    Setexpr *sae=parsesetexpr();
+    return new CAElementexpr(cae,sae);
+  }
+  case TOKEN_OF:
+    return oldee;
+  case TOKEN_MULT:
+    skiptoken();
+    if ((oldee!=NULL)&&(joinop==-1))
+      joinop=CAELEMENTEXPR_MULT;
+    else
+      error();
+    break;
+  case TOKEN_DIV:
+    skiptoken();
+    if ((oldee!=NULL)&&(joinop==-1))
+      joinop=CAELEMENTEXPR_DIV;
+    else
+      error();
+    break;
+  case TOKEN_NULL:
+    if ((joinop==-1)&&(oldee!=NULL))
+      return oldee;
+    skiptoken();
+    if (oldee==NULL)
+      oldee=checkdot(new CAElementexpr());
+    else {
+      if (joinop!=-1) {
+       oldee=new CAElementexpr(oldee,checkdot(new CAElementexpr()),joinop);
+       joinop=-1;
+      } else error();
+    }
+    break;
+  default:
+    if ((joinop==-1)&&(oldee!=NULL))
+      return oldee;
+    skiptoken();
+    if (oldee==NULL)
+      oldee=checkdot(new CAElementexpr(new Label(copystr(t.str))));
+    else {
+      if (joinop!=-1) {
+       oldee=new CAElementexpr(oldee,checkdot(new CAElementexpr(new Label(copystr(t.str)))),joinop);
+       joinop=-1;
+      } else error();
+    }
+  }
+  }
+}
+
+CAElementexpr * CParser::checkdot(CAElementexpr * incoming) {
+  Token tdot=reader->peakahead();
+  if (tdot.token_type!=TOKEN_DOT) return incoming;
+  skiptoken();
+  Token tfield=reader->readnext();
+  Token tpeak=reader->peakahead();
+  return new CAElementexpr(incoming, new Relation(copystr(tfield.str)));
+}
+
+Setexpr * CParser::parsesetexpr() {
+  Token label=reader->readnext();
+  Token peak=reader->peakahead();
+  if (peak.token_type==TOKEN_DOT) {
+    skiptoken();
+    return new Setexpr(new Label(copystr(label.str)),false,new Relation(copystr(reader->readnext().str)));
+  } else if (peak.token_type==TOKEN_DOTINV) {
+    skiptoken();
+    return new Setexpr(new Label(copystr(label.str)),true,new Relation(copystr(reader->readnext().str)));
+  } else
+  return new Setexpr(new Setlabel(copystr(label.str)));
+}
+
+Expr * CParser::parseexpr() {
+  Expr * oldee=NULL;
+  Field *oldf=NULL;
+  CAElementexpr *oldindex=NULL;
+  bool parselside=true;
+  while(parselside) {
+    Token t=reader->readnext();
+    switch(t.token_type) {
+    case TOKEN_DOT:
+      if (oldf!=NULL) {
+       /* do shift-pack stuff */
+       if(oldindex==NULL)
+         oldee=new Expr(oldee,oldf);
+       else
+         oldee=new Expr(oldee,oldf,oldindex);
+       oldf=NULL;
+       oldindex=NULL;
+      }
+      {
+       Token name=reader->readnext();
+       oldf=new Field(copystr(name.str));
+      }
+      break;
+    case TOKEN_OPENBRACK:
+      oldindex=(CAElementexpr *)parseaelementexpr(true);
+      needtoken(TOKEN_CLOSEBRACK);
+      break;
+    case TOKEN_CAST: {
+      if(oldee!=NULL)
+       error();
+      needtoken(TOKEN_OPENPAREN);
+      Token fld=reader->readnext();
+      needtoken(TOKEN_COMMA);
+      Expr *ex=parseexpr();
+      needtoken(TOKEN_CLOSEPAREN);
+      oldee=new Expr(copystr(fld.str),ex);
+      break;
+    }
+    case TOKEN_CLOSEPAREN:
+      if (oldf!=NULL) {
+       /* do shift-pack stuff */
+       if(oldindex==NULL)
+         oldee=new Expr(oldee,oldf);
+       else
+         oldee=new Expr(oldee,oldf,oldindex);
+       oldf=NULL;
+       oldindex=NULL;
+      }
+      return oldee;
+    default:
+      if(oldee!=NULL)
+       error();
+      oldee=new Expr(new Label(copystr(t.str)));
+    }
+  }
+  return oldee;
+}
+
+Statementb * CParser::parsestatementb() {
+  Expr * oldee=NULL;
+  Field *oldf=NULL;
+  CAElementexpr *oldindex=NULL;
+  bool parselside=true;
+  while(parselside) {
+    Token t=reader->readnext();
+    switch(t.token_type) {
+    case TOKEN_DOT:
+      if (oldf!=NULL) {
+       /* do shift-pack stuff */
+       if(oldindex==NULL)
+         oldee=new Expr(oldee,oldf);
+       else
+         oldee=new Expr(oldee,oldf,oldindex);
+       oldf=NULL;
+       oldindex=NULL;
+      }
+      {
+       Token name=reader->readnext();
+       oldf=new Field(copystr(name.str));
+      }
+      break;
+    case TOKEN_OPENBRACK:
+      oldindex=(CAElementexpr *)parseaelementexpr(true);
+      needtoken(TOKEN_CLOSEBRACK);
+      break;
+    case TOKEN_CAST: {
+      if(oldee!=NULL)
+       error();
+      needtoken(TOKEN_OPENPAREN);
+      Token fld=reader->readnext();
+      needtoken(TOKEN_COMMA);
+      Expr *ex=parseexpr();
+      oldee=new Expr(copystr(fld.str),ex);
+      break;
+    }
+    case TOKEN_EQUALS:
+      parselside=false;
+      if (oldf==NULL)
+       error();
+      break;
+    default:
+      if(oldee!=NULL)
+       error();
+      oldee=new Expr(new Label(copystr(t.str)));
+    }
+  }
+  CAElementexpr *rside=(CAElementexpr *)parseaelementexpr(false);
+  if (oldindex==NULL)
+    return new CStatementb(oldee,oldf,rside);
+  else
+    return new CStatementb(oldee,oldf,oldindex,rside);
+}
diff --git a/Repair/RepairInterpreter/cparser.h b/Repair/RepairInterpreter/cparser.h
new file mode 100755 (executable)
index 0000000..fe4306d
--- /dev/null
@@ -0,0 +1,20 @@
+#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
diff --git a/Repair/RepairInterpreter/danfile.cc b/Repair/RepairInterpreter/danfile.cc
new file mode 100755 (executable)
index 0000000..2d71d04
--- /dev/null
@@ -0,0 +1,1117 @@
+#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);
+    }
+}
+
+
diff --git a/Repair/RepairInterpreter/dmodel.cc b/Repair/RepairInterpreter/dmodel.cc
new file mode 100755 (executable)
index 0000000..f26fc78
--- /dev/null
@@ -0,0 +1,609 @@
+// 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;
+}
diff --git a/Repair/RepairInterpreter/dmodel.h b/Repair/RepairInterpreter/dmodel.h
new file mode 100755 (executable)
index 0000000..41965b9
--- /dev/null
@@ -0,0 +1,105 @@
+// defines the sets and the relations used
+
+#ifndef DMODEL_H
+#define DMODEL_H
+
+#include "common.h"
+#include "classlist.h"
+
+#define DOMAINSET_SUBSET 1
+#define DOMAINSET_PARTITION 2
+#define DOMAINSET_TYPED 0x100
+
+// represents a set
+class DomainSet {
+ public:
+  DomainSet(char *name);
+  void settype(char *type);
+  void setsubsets(char **subsets, int numsubsets);
+  void setpartition(char **subsets, int numsubsets);
+  void print();
+  char *getname();
+  WorkSet *getset();
+  int getnumsubsets();
+  char *getsubset(int i);
+  int gettype();
+  char * getelementtype();
+  void reset();
+ private:
+  WorkSet *set;   // the set itself
+  char *type;     // the type of the elements in the set 
+  char *setname;  // the name of the set
+  int flag; 
+  char ** subsets;// the subsets
+  int numsubsets; 
+};
+
+
+
+
+#define DRELATION_SINGDOMAIN 0x1
+#define DRELATION_MANYDOMAIN 0x2
+#define DRELATION_SINGRANGE 0x10
+#define DRELATION_MANYRANGE 0x20
+
+// represents a relation
+class DRelation {
+ public:
+  DRelation(char *name, char *d, char *r, int t, bool);
+  void print();
+  char *getname();
+  WorkRelation *getrelation();
+  char *getdomain();
+  char *getrange();
+  WorkSet *gettokenrange();
+  void settokenrange(WorkSet *ws);
+  bool isstatic();
+  void reset();
+ private:
+  bool staticrel;
+  char *name;
+  char *domain;
+  char *range;
+  WorkSet *tokenrange; // the actual range, if the range is of type token
+  int type;
+  WorkRelation *relation;
+};
+
+
+
+// manages the entire collection of sets and relations
+class DomainRelation {
+ public:
+  DomainRelation(DomainSet **s, int ns, DRelation **r,int nr);
+  void print();
+  DomainSet * getset(char * setname);
+  DRelation * getrelation(char * relationname);
+  ~DomainRelation();
+  WorkSet * conflictdelsets(char *setname, char *boundset);
+  WorkSet * conflictaddsets(char *setname, char *boundset, model *m);
+  WorkSet * removeconflictdelsets(char *setname);
+  WorkSet * removeconflictaddsets(char *setname, model *m);
+  DomainSet * getsuperset(DomainSet *);
+  DomainSet * getsource(DomainSet *);
+  /* Tells what set we might get objects from for a given set */
+  void delfromsetmovetoset(Element *e,DomainSet *deletefromset,model *m);
+  void abstaddtoset(Element *e,DomainSet *addtoset,model *m);
+  void addtoset(Element *e,DomainSet *addtoset,model *m);
+  bool issupersetof(DomainSet *sub,DomainSet *super);
+  int getnumrelation();
+  DRelation * getrelation(int i);
+  bool fixstuff();
+  void reset();
+
+ private:
+  bool checkrelations(DRelation *dr);
+  bool checksubset(DomainSet *ds);
+  void addallsubsets(DomainSet *ds, WorkSet *ws);
+  void removefromthisset(Element *ele, DomainSet *ds,model *m);
+  Hashtable *settable, *relationtable;
+  DomainSet ** sets;
+  int numsets;
+  DRelation **relations;
+  int numrelations;
+};
+#endif
diff --git a/Repair/RepairInterpreter/dparser.cc b/Repair/RepairInterpreter/dparser.cc
new file mode 100755 (executable)
index 0000000..c84f3b2
--- /dev/null
@@ -0,0 +1,143 @@
+#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();
+  }
+}
diff --git a/Repair/RepairInterpreter/dparser.h b/Repair/RepairInterpreter/dparser.h
new file mode 100755 (executable)
index 0000000..2ba7734
--- /dev/null
@@ -0,0 +1,20 @@
+#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
diff --git a/Repair/RepairInterpreter/element.cc b/Repair/RepairInterpreter/element.cc
new file mode 100755 (executable)
index 0000000..87fad2a
--- /dev/null
@@ -0,0 +1,258 @@
+// 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);
+}
diff --git a/Repair/RepairInterpreter/element.h b/Repair/RepairInterpreter/element.h
new file mode 100755 (executable)
index 0000000..f8987e1
--- /dev/null
@@ -0,0 +1,67 @@
+// provides an object wrapper around elementary types
+
+
+#ifndef ELEMENT_H
+#define ELEMENT_H
+#include "common.h"
+#include "classlist.h"
+
+class ElementWrapper;
+
+#define ELEMENT_INT 1
+#define ELEMENT_BIT 2
+#define ELEMENT_BYTE 3
+#define ELEMENT_TOKEN 4
+#define ELEMENT_OBJECT 5
+#define ELEMENT_FTUPLE 6
+#define ELEMENT_SHORT 7
+
+class ElementWrapper {
+ public:
+  virtual unsigned int hashCode()=0;
+  virtual bool equals(ElementWrapper *other)=0;
+  virtual int type()=0;
+ private:
+};
+
+
+class Element:public ElementWrapper {
+ public:
+  Element();
+  Element(int value);
+  Element(short value);
+  Element(bool b);
+  Element(char byte);
+  Element(char * token);
+  Element(Element * o);
+  unsigned int hashCode();
+  bool equals(ElementWrapper *other);
+  int intvalue();
+  short getshortvalue();
+  char getbytevalue();
+  bool getboolvalue();
+  bool isnumber();
+  void * getobject();
+  int type();
+  structure * getstructure();
+  Element(void * objptr, structure * str);
+  char * gettoken();
+  ~Element();
+  void print();
+
+ private:
+  char *token;
+  void *object;
+  int typevalue;
+  short shortvalue;
+  int integervalue;
+  char bytevalue;
+  bool bitvalue;
+  structure *itemtype;
+};
+
+unsigned int hashelement(ElementWrapper *e);
+
+int elementequals(ElementWrapper *e1, ElementWrapper *e2);
+
+#endif
diff --git a/Repair/RepairInterpreter/fieldcheck.cc b/Repair/RepairInterpreter/fieldcheck.cc
new file mode 100755 (executable)
index 0000000..2911fa2
--- /dev/null
@@ -0,0 +1,287 @@
+#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&&copy!=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;
+}
diff --git a/Repair/RepairInterpreter/fieldcheck.h b/Repair/RepairInterpreter/fieldcheck.h
new file mode 100755 (executable)
index 0000000..f783946
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef Fieldcheck_H
+#define Fieldcheck_H
+#include "classlist.h"
+#include "element.h"
+
+class FieldCheck {
+ public:
+  FieldCheck(model *m);
+  void analyze();
+  void buildmaps();
+  int getindexthatprovides(char *set, char *relation);
+ private:
+  bool setok(Constraint *c, char *set);
+  bool testsatisfy(WorkSet *satisfies, FieldTuple *ft);
+  WorkSet * requireswhat(Constraint *c,CoercePredicate *cp);
+  void processee(WorkSet *ws, Constraint *c, Elementexpr *ee);
+  FieldTuple * provideswhat(Constraint *c,CoercePredicate *cp);
+  model *globalmodel;
+  Hashtable *cptoreqs;
+  Hashtable *propertytonf;
+  Hashtable *nftoprovides;
+};
+
+char *getset(Constraint *c, char *var);
+
+class FieldTuple:public ElementWrapper {
+ public:
+  FieldTuple(FieldTuple *o);
+  unsigned int hashCode();
+  bool equals(ElementWrapper *other);
+  int type();
+
+  FieldTuple(char * r, char *s);
+  char * relation;
+  char * set;
+};
+#endif
+
diff --git a/Repair/RepairInterpreter/file.cc b/Repair/RepairInterpreter/file.cc
new file mode 100755 (executable)
index 0000000..0ecd6af
--- /dev/null
@@ -0,0 +1,518 @@
+#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");
+}
+
diff --git a/Repair/RepairInterpreter/file.h b/Repair/RepairInterpreter/file.h
new file mode 100755 (executable)
index 0000000..1dc3436
--- /dev/null
@@ -0,0 +1,104 @@
+#ifndef FILE_H
+#define FILE_H
+
+#define BLOCKSIZE 8192
+#define NUMBLOCK 1024
+#define LENGTH BLOCKSIZE*NUMBLOCK
+#define NUMINODES BLOCKSIZE/56
+#define NUMFILES 100
+
+struct block {
+  char array[BLOCKSIZE];
+};
+
+
+struct SuperBlock {
+  int FreeBlockCount;
+  int FreeInodeCount;
+  int NumberofBlocks;
+  int NumberofInodes;
+  int RootDirectoryInode;
+  int blocksize;
+};
+
+
+struct GroupBlock {
+  int BlockBitmapBlock;
+  int InodeBitmapBlock;
+  int InodeTableBlock;
+  int GroupFreeBlockCount;
+  int GroupFreeInodeCount;
+};
+
+
+struct BlockBitmap {
+  char blocks[NUMBLOCK/8+1];
+};
+
+
+struct InodeBitmap {
+  char inode[NUMINODES/8+1];
+};
+
+
+struct Inode {
+  int filesize;
+  int Blockptr[12];
+  int referencecount;
+};
+
+
+//the inode table
+struct InodeBlock {
+  struct Inode entries[NUMINODES];
+};
+
+
+#define DIRECTORYENTRYSIZE 128
+struct DirectoryEntry {
+  char name[124];
+  int inodenumber;
+};
+
+
+
+struct DirectoryBlock {
+  struct DirectoryEntry entries[BLOCKSIZE/128];
+};
+
+
+
+
+
+void createdisk();
+void createfile(struct block *ptr,char *filename, char *buf,int buflen);
+void addtode(struct block *ptr, int inode, char * filename);
+int getinode(struct block *ptr);
+int getblock(struct block * ptr);
+
+void removefile(char *filename, struct block *ptr);
+void createlink(struct block *ptr,char *filename, char *linkname);
+struct block * chmountdisk(char *filename);
+void chunmountdisk(struct block *vptr);
+struct block * mountdisk(char *filename);
+void unmountdisk(struct block *vptr);
+void closefile(struct block *ptr, int fd);
+bool writefile(struct block *ptr, int fd, char *s);
+int writefile(struct block *ptr, int fd, char *s, int len);
+char readfile(struct block *ptr, int fd);
+int readfile(struct block *ptr, int fd, char *buf, int len);
+int openfile(struct block *ptr, char *filename);
+
+void printdirectory(struct block *ptr);
+void printfile(char *filename, struct block *ptr);
+void printinodeblock(struct block* ptr);
+
+
+#define MAXFILES 300
+struct filedesc {
+  int inode;
+  int offset;
+  bool used;
+};
+#endif
+
diff --git a/Repair/RepairInterpreter/list.cc b/Repair/RepairInterpreter/list.cc
new file mode 100755 (executable)
index 0000000..df1371a
--- /dev/null
@@ -0,0 +1,35 @@
+#include "list.h"
+//#include "dmalloc.h"
+
+List::List() {
+  array=new void*[INITIAL_LIST_SIZE];
+  length=0;
+  arraysize=INITIAL_LIST_SIZE;
+}
+
+List::~List() {
+  delete[](array);
+}
+
+void List::addobject(void *object) {
+  if ((length+1)>arraysize) {
+    void **oldarray=array;
+    int oldarraysize=arraysize;
+    arraysize*=2;
+    array=new void*[arraysize];
+    for(int i=0;i<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;
+}
diff --git a/Repair/RepairInterpreter/list.h b/Repair/RepairInterpreter/list.h
new file mode 100755 (executable)
index 0000000..42d3105
--- /dev/null
@@ -0,0 +1,20 @@
+#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
diff --git a/Repair/RepairInterpreter/model.cc b/Repair/RepairInterpreter/model.cc
new file mode 100755 (executable)
index 0000000..05afabd
--- /dev/null
@@ -0,0 +1,532 @@
+#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*/
+}
diff --git a/Repair/RepairInterpreter/model.h b/Repair/RepairInterpreter/model.h
new file mode 100755 (executable)
index 0000000..bf2b9b1
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef MODEL_H
+#define MODEL_H
+#include "classlist.h"
+
+class model {
+ public:
+  model(char *abstractfile, char *modelfile, char *spacefile,char *structfile, char *concretefile, char *rangefile);
+  DomainRelation * getdomainrelation(); 
+  structure *getstructure(char * name);
+  void doabstraction();  // processes the model definition rules
+  bool docheck();        // processes the internal constraints
+  void doconcrete();     // processes the external constraints
+
+  void breakspec();    // inserts faults that break the specs
+  void inserterrors(); // inserts faults that do not break the specs
+
+  NormalForm * getnormalform(Constraint *c);
+  Hashtable * gethashtable();
+  bitreader * getbitreader();
+  Guidance * getguidance();
+  int getnumconstraints();
+  Constraint * getconstraint(int i);
+  NormalForm * getnormalform(int i);
+  Repair *getrepair();
+  FieldCheck * getfieldcheck();
+  void triggerrule(Element *,char *);
+  int getnumrulenormal();
+  NormalForm * getrulenormal(int i);
+  bool subtypeof(structure *sub,structure *super);
+  typemap * gettypemap();
+  void reset();
+
+  static const double prob_breakconstraint = 1;  // the probability with which each constraint is broken when inserting errors
+  static const double prob_breakpredicate = 1; // the probability with which each predicate from the selected sentences is broken
+  static const double prob_modifyconstraint = 1;  // the probability with which each constraint is modified when inserting errors
+  static const double prob_breaksatisfiedsentence = 1;  // the probability with which each satisfied sentence is modified (broken) when inserting errors
+  static const double prob_repairbrokensentence = 1;  // the probability with which each broken sentence is modified (repaired) when inserting errors
+
+ private:
+  void parsespacefile(char *spacefile);
+  void parsestructfile(char *structfile);
+  void parseabstractfile(char *abstractfile);
+  void parseconcretefile(char *concretefile);
+  void parsemodelfile(char *modelfile);
+  void parserangefile(char *rangefile);
+
+  Hashtable *env;
+  bitreader *br;
+  Guidance * guidance;
+  Repair *repair;
+  FieldCheck *fc;
+  processabstract *pa;
+
+  structure **structurearray;     // the structure definitions
+  int numstarray;
+
+  DomainRelation *domainrelation; // the sets and relations
+
+  Rule **rulearray;               // the model definition rules 
+  int numrules;              
+  NormalForm **rulenormal;        // the model definition rules in normal form
+  int numrulenormal;
+  Constraint **constraintarray;   // the internal constraints
+  int numconstraint;
+  NormalForm **constraintnormal;  // the internal constraints in normal form
+
+  Rule **concretearray;           // the external constraints
+  int numconcrete;
+
+
+  typemap * typmap;
+};
+#endif
diff --git a/Repair/RepairInterpreter/normalizer.cc b/Repair/RepairInterpreter/normalizer.cc
new file mode 100755 (executable)
index 0000000..e3d561c
--- /dev/null
@@ -0,0 +1,348 @@
+// 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;
+}
+
diff --git a/Repair/RepairInterpreter/normalizer.h b/Repair/RepairInterpreter/normalizer.h
new file mode 100755 (executable)
index 0000000..401232f
--- /dev/null
@@ -0,0 +1,80 @@
+// 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
diff --git a/Repair/RepairInterpreter/omodel.cc b/Repair/RepairInterpreter/omodel.cc
new file mode 100755 (executable)
index 0000000..e090af0
--- /dev/null
@@ -0,0 +1,1017 @@
+// 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;
+  }
+}
+
+bool Literal::getbool() {
+  if (equivalentstrings(str,"true"))
+    return true;
+  else
+    return false;
+}
+
+int Literal::number() {
+  int val;
+  sscanf(str,"%d",&val);
+  return val;
+}
+
+char * Literal::token() {
+  return str;
+}
+
+void Literal::print() {
+  printf("%s",str);
+}
+
+void Literal::fprint(FILE *f) {
+  fprintf(f,"%s",str);
+}
+
+
+
+
+
+
+// class Setlabel
+
+Setlabel::Setlabel(char *s) {
+  str=s;
+}
+
+char * Setlabel::getname() {
+  return str;
+}
+  
+void Setlabel::print() {
+  printf("%s",str);
+}
+
+void Setlabel::fprint(FILE *f) {
+  fprintf(f,"%s",str);
+}
+
+
+
+
+
+// class Set
+
+// a set is either a label or a set of literals
+
+Set::Set(Setlabel *sl) {
+  type=SET_label;
+  setlabel=sl;
+}
+
+int Set::getnumliterals() {
+  return numliterals;
+}
+
+Literal * Set::getliteral(int i) {
+  return literals[i];
+}
+
+Set::Set(Literal **l, int nl) {
+  type=SET_literal;
+  literals=l;
+  numliterals=nl;
+}
+
+Set::~Set() {
+  if (type==SET_label)
+    delete(setlabel);
+  if (type==SET_literal) {
+    for(int i=0;i<numliterals;i++)
+      delete(literals[i]);
+    delete(literals);
+  }
+}
+
+int Set::gettype() {
+  return type;
+}
+
+char * Set::getname() {
+  return setlabel->getname();
+}
+
+void Set::print() {
+  switch(type) {
+  case SET_label:
+    setlabel->print();
+    break;
+  case SET_literal:
+    printf("{");
+    for(int i=0;i<numliterals;i++) {
+      if (i!=0)
+       printf(",");
+      literals[i]->print();
+    }
+    printf("}");
+    break;
+  }
+}
+
+void Set::fprint(FILE *f) {
+  switch(type) {
+  case SET_label:
+    setlabel->fprint(f);
+    break;
+  case SET_literal:
+    fprintf(f,"{");
+    for(int i=0;i<numliterals;i++) {
+      if (i!=0)
+       fprintf(f,",");
+      literals[i]->fprint(f);
+    }
+    fprintf(f,"}");
+    break;
+  }
+}
+
+
+
+
+
+
+// class Label
+
+Label::Label(char *s) {
+  str=s;
+}
+
+void Label::print() {
+  printf("%s",str);
+}
+
+void Label::fprint(FILE *f) {
+  fprintf(f,"%s",str);
+}
+
+
+
+
+
+// class Relation
+
+Relation::Relation(char * r) {
+  str=r;
+}
+
+char * Relation::getname() {
+  return str;
+}
+
+void Relation::print() {
+  printf("%s",str);
+}
+
+void Relation::fprint(FILE *f) {
+  fprintf(f,"%s",str);
+}
+
+
+
+
+
+// class Quantifier
+
+Quantifier::Quantifier(Label *l, Set *s) {
+  label=l;
+  set=s;
+}
+
+Label * Quantifier::getlabel() {
+  return label;
+}
+
+Set * Quantifier::getset() {
+  return set;
+}
+
+void Quantifier::print() {
+  printf("forall ");
+  label->print();
+  printf(" in ");
+  set->print();
+}
+
+void Quantifier::fprint(FILE *f) {
+  fprintf(f,"forall ");
+  label->fprint(f);
+  fprintf(f," in ");
+  set->fprint(f);
+}
+
+
+
+
+
+
+// class Setexpr
+
+Setexpr::Setexpr(Setlabel *sl) {
+  setlabel=sl;
+  type=SETEXPR_LABEL;
+}
+
+Setexpr::Setexpr(Label *l, bool invert, Relation *r) {
+  label=l;
+  type=invert?SETEXPR_INVREL:SETEXPR_REL;
+  relation=r;
+}
+
+void Setexpr::print() {
+  switch(type) {
+  case SETEXPR_LABEL:
+    setlabel->print();
+    break;
+  case SETEXPR_REL:
+    label->print();
+    printf(".");
+    relation->print();
+    break;
+  case SETEXPR_INVREL:
+    label->print();
+    printf(".~");
+    relation->print();
+    break;
+  }
+}
+
+void Setexpr::fprint(FILE *f) {
+  switch(type) {
+  case SETEXPR_LABEL:
+    setlabel->fprint(f);
+    break;
+  case SETEXPR_REL:
+    label->fprint(f);
+    fprintf(f,".");
+    relation->fprint(f);
+    break;
+  case SETEXPR_INVREL:
+    label->fprint(f);
+    fprintf(f,".~");
+    relation->fprint(f);
+    break;
+  }
+}
+
+
+void Setexpr::print_size(Hashtable *stateenv, model *m) 
+{
+  switch(type) {
+  case SETEXPR_LABEL:{
+    printf("sizeof(");
+    setlabel->print();
+    printf(")=");  
+
+    DomainRelation *dr = m->getdomainrelation();
+    Hashtable *env = m->gethashtable();
+    DomainSet *dset = dr->getset(setlabel->getname());
+    WorkSet *ws = dset->getset();
+
+    if (ws != NULL)
+      printf("%d", ws->size());
+    else printf("0");
+    break;
+  }
+
+  case SETEXPR_REL:{
+    printf("sizeof(");
+    label->print();
+    printf(".");
+    relation->print();
+    printf(")=");  
+
+    Element *key = (Element *) stateenv->get(label->label());
+
+    DomainRelation *dr = m->getdomainrelation();
+    Hashtable *env = m->gethashtable();
+    DRelation *rel = dr->getrelation(relation->getname());
+    WorkRelation *wr = rel->getrelation();
+   
+    WorkSet *ws = wr->getset(key);
+
+    if (ws != NULL)
+      printf("%d", ws->size());
+    else printf("0");
+    break;
+  }
+
+  case SETEXPR_INVREL:{
+    printf("sizeof(");
+    label->print();
+    printf(".~");
+    relation->print();
+    printf(")=");  
+
+    Element *key = (Element *) stateenv->get(label->label());
+
+    DomainRelation *dr = m->getdomainrelation();
+
+    Hashtable *env = m->gethashtable();
+    DRelation *rel = dr->getrelation(relation->getname());
+    WorkRelation *wr = rel->getrelation();
+   
+    WorkSet *ws = wr->invgetset(key);
+
+    if (ws != NULL)
+      printf("%d", ws->size());
+    else printf("0");
+    break;
+  }
+  }
+}
+
+
+void Setexpr::print_value(Hashtable *stateenv, model *m) 
+{
+  switch(type) {
+  case SETEXPR_LABEL:{
+    //printf("   ");
+    setlabel->print();
+    printf("=");  
+
+    DomainRelation *dr = m->getdomainrelation();
+    Hashtable *env = m->gethashtable();
+    DomainSet *dset = dr->getset(setlabel->getname());
+
+    WorkSet *ws = dset->getset();
+    ws->print();
+    break;
+  }
+
+  case SETEXPR_REL:{
+    /*
+    printf("   sizeof(");
+    label->print();
+    printf(".");
+    relation->print();
+    printf(") = ");  
+
+    Element *key = (Element *) stateenv->get(label->label());
+
+    DomainRelation *dr = m->getdomainrelation();
+    Hashtable *env = m->gethashtable();
+    DRelation *rel = dr->getrelation(relation->getname());
+    WorkRelation *wr = rel->getrelation();
+   
+    WorkSet *ws = wr->getset(key);
+
+    printf("%d\n", ws->size());
+    */
+    break;
+  }
+
+  case SETEXPR_INVREL:{
+    /*
+    printf("   sizeof(");
+    label->print();
+    printf(".~");
+    relation->print();
+    printf(") = ");  
+
+    Element *key = (Element *) stateenv->get(label->label());
+
+    DomainRelation *dr = m->getdomainrelation();
+
+    Hashtable *env = m->gethashtable();
+    DRelation *rel = dr->getrelation(relation->getname());
+    WorkRelation *wr = rel->getrelation();
+   
+    WorkSet *ws = wr->invgetset(key);
+
+    printf("%d\n", ws->size());
+    */
+    break;
+  }
+  }
+}
+
+
+Setlabel * Setexpr::getsetlabel() {
+  return setlabel;
+}
+
+Relation * Setexpr::getrelation() {
+  return relation;
+}
+
+Label * Setexpr::getlabel() {
+  return label;
+}
+
+int Setexpr::gettype() {
+  return type;
+}
+
+
+
+
+
+// class Valueexpr
+
+Label * Valueexpr::getlabel() {
+  return label;
+}
+
+int Valueexpr::gettype() {
+  return type;
+}
+
+Relation * Valueexpr::getrelation() {
+  return relation;
+}
+
+Valueexpr::Valueexpr(Label *l,Relation *r, bool inv) {
+  label=l;relation=r;
+  type=0;inverted=inv;
+}
+
+Valueexpr::Valueexpr(Valueexpr *ve,Relation *r,bool inv) {
+  valueexpr=ve;relation=r;
+  type=1;inverted=inv;
+}
+
+bool Valueexpr::getinverted() {
+  return inverted;
+}
+
+void Valueexpr::print() {
+  switch(type) {
+  case 0:
+    label->print();
+    printf(".");
+    if (inverted)
+      printf("~");
+    relation->print();
+    break;
+  case 1:
+    valueexpr->print();
+    printf(".");
+    if (inverted)
+      printf("~");
+    relation->print();
+    break;
+  }
+}
+
+void Valueexpr::fprint(FILE *f) {
+  switch(type) {
+  case 0:
+    label->fprint(f);
+    fprintf(f,".");
+    if (inverted)
+      fprintf(f,"~");
+    relation->fprint(f);
+    break;
+  case 1:
+    valueexpr->fprint(f);
+    fprintf(f,".");
+    if (inverted)
+      fprintf(f,"~");
+    relation->fprint(f);
+    break;
+  }
+}
+
+Element * Valueexpr::get_value(Hashtable *stateenv, model *m) {
+  Element *key=NULL;
+  if (type==0) {
+    key = (Element *) stateenv->get(label->label());
+  } else
+    key = valueexpr->get_value(stateenv,m);
+
+  DomainRelation *dr = m->getdomainrelation();
+  Hashtable *env = m->gethashtable();
+  DRelation *rel = dr->getrelation(relation->getname());
+  WorkRelation *wr = rel->getrelation();
+
+  if (inverted)
+    return (Element *) wr->invgetobj(key);
+  else
+    return (Element *) wr->getobj(key);
+
+}
+
+void Valueexpr::print_value(Hashtable *stateenv, model *m) {
+  this->print();
+  printf("=");
+  Element *elem = this->get_value(stateenv,m);
+  elem->print();
+  //printf("\n");
+}
+
+Valueexpr * Valueexpr::getvalueexpr() {
+  return valueexpr;
+}
+
+
+
+
+
+// class Elementexpr
+
+int Elementexpr::gettype() {
+  return type;
+}
+
+Relation * Elementexpr::getrelation() {
+  return relation;
+}
+
+Elementexpr::Elementexpr(Elementexpr *l,Relation *r) {
+  type=ELEMENTEXPR_RELATION;
+  left=l;
+  relation=r;
+}
+
+Setexpr * Elementexpr::getsetexpr() {
+  return setexpr;
+}
+
+Elementexpr::Elementexpr(Setexpr *se) {
+  setexpr=se;
+  type=ELEMENTEXPR_SETSIZE;
+}
+
+Label * Elementexpr::getlabel() {
+  return label;
+}
+
+Elementexpr * Elementexpr::getleft() {
+  return left;
+}
+
+Elementexpr * Elementexpr::getright() {
+  return right;
+}
+
+Literal * Elementexpr::getliteral() {
+  return literal;
+}
+
+Elementexpr::Elementexpr(Elementexpr *l, Elementexpr *r, int op) {
+  left=l;right=r;type=op;
+}
+Elementexpr::Elementexpr(Literal *lit) {
+  literal=lit;
+  type=ELEMENTEXPR_LIT;
+}
+
+Elementexpr::Elementexpr(Label *lab) {
+  label=lab;
+  type=ELEMENTEXPR_LABEL;
+}
+
+void Elementexpr::print() {
+  switch(type) {
+  case ELEMENTEXPR_LABEL:
+    label->print();
+    break;
+  case ELEMENTEXPR_SUB:
+    left->print();
+    printf("-");
+    right->print();
+    break;
+  case ELEMENTEXPR_ADD:
+    left->print();
+    printf("+");
+    right->print();
+    break;
+  case ELEMENTEXPR_MULT:
+    left->print();
+    printf("*");
+    right->print();
+    break;
+  case ELEMENTEXPR_LIT:
+    literal->print();
+    break;
+  case ELEMENTEXPR_SETSIZE:
+    printf("sizeof(");
+    setexpr->print();
+    printf(")");
+    break;
+  case ELEMENTEXPR_RELATION:
+    left->print();
+    printf(".");
+    relation->print();
+    break;
+  }  
+}
+
+void Elementexpr::fprint(FILE *f) {
+  switch(type) {
+  case ELEMENTEXPR_LABEL:
+    label->fprint(f);
+    break;
+  case ELEMENTEXPR_SUB:
+    left->fprint(f);
+    fprintf(f,"-");
+    right->fprint(f);
+    break;
+  case ELEMENTEXPR_ADD:
+    left->fprint(f);
+    fprintf(f,"+");
+    right->fprint(f);
+    break;
+  case ELEMENTEXPR_MULT:
+    left->fprint(f);
+    fprintf(f,"*");
+    right->fprint(f);
+    break;
+  case ELEMENTEXPR_LIT:
+    literal->fprint(f);
+    break;
+  case ELEMENTEXPR_SETSIZE:
+    fprintf(f,"sizeof(");
+    setexpr->fprint(f);
+    fprintf(f,")");
+    break;
+  case ELEMENTEXPR_RELATION:
+    left->fprint(f);
+    fprintf(f,".");
+    relation->fprint(f);
+    break;
+  }  
+}
+
+
+void Elementexpr::print_value(Hashtable *stateenv, model *m) {
+  switch(type) {
+  case ELEMENTEXPR_SUB:
+  case ELEMENTEXPR_ADD:
+  case ELEMENTEXPR_MULT:
+    left->print_value(stateenv, m);
+    right->print_value(stateenv, m);
+    break;
+  case ELEMENTEXPR_SETSIZE:
+    setexpr->print_size(stateenv, m);
+    break;
+  case ELEMENTEXPR_RELATION:
+    /*
+    left->print();
+    printf(".");
+    relation->print();
+    */
+    break;
+  }  
+}
+
+
+
+// class Predicate 
+
+Predicate::Predicate(Valueexpr *ve, int t, Elementexpr *ee) {
+  valueexpr=ve;
+  type=t;
+  elementexpr=ee;
+}
+
+Predicate::Predicate(Label *l,Setexpr *se) {
+  label=l;
+  setexpr=se;
+  type=PREDICATE_SET;
+}
+
+Predicate::Predicate(bool greaterthan, Setexpr *se) {
+  if (greaterthan)
+    type=PREDICATE_GTE1;
+  else
+    type=PREDICATE_EQ1;
+  setexpr=se;
+}
+
+Valueexpr * Predicate::getvalueexpr() {
+  return valueexpr;
+}
+
+Elementexpr * Predicate::geteleexpr() {
+  return elementexpr;
+}
+
+Label * Predicate::getlabel() {
+  return label;
+}
+
+Setexpr * Predicate::getsetexpr() {
+  return setexpr;
+}
+
+int Predicate::gettype() {
+  return type;
+}
+
+void Predicate::print() {
+  switch(type) {
+  case PREDICATE_LT:
+    valueexpr->print();
+    printf("<");
+    elementexpr->print();
+    break;
+  case PREDICATE_LTE:
+    valueexpr->print();
+    printf("<=");
+    elementexpr->print();
+    break;
+  case PREDICATE_EQUALS:
+    valueexpr->print();
+    printf("=");
+    elementexpr->print();
+    break;
+  case PREDICATE_GTE:
+    valueexpr->print();
+    printf(">=");
+    elementexpr->print();
+    break;
+  case PREDICATE_GT:
+    valueexpr->print();
+    printf(">");
+    elementexpr->print();
+    break;
+  case PREDICATE_SET:
+    label->print();
+    printf(" in ");
+    setexpr->print();
+    break;
+  case PREDICATE_EQ1:
+  case PREDICATE_GTE1:
+    printf("sizeof(");
+    setexpr->print();
+    if (type==PREDICATE_EQ1)
+      printf(")=1");
+    if (type==PREDICATE_GTE1)
+      printf(")>=1");
+    break;
+  }
+}
+
+void Predicate::fprint(FILE *f) {
+  switch(type) {
+  case PREDICATE_LT:
+    valueexpr->fprint(f);
+    fprintf(f,"<");
+    elementexpr->fprint(f);
+    break;
+  case PREDICATE_LTE:
+    valueexpr->fprint(f);
+    fprintf(f,"<=");
+    elementexpr->fprint(f);
+    break;
+  case PREDICATE_EQUALS:
+    valueexpr->fprint(f);
+    fprintf(f,"=");
+    elementexpr->fprint(f);
+    break;
+  case PREDICATE_GTE:
+    valueexpr->fprint(f);
+    fprintf(f,">=");
+    elementexpr->fprint(f);
+    break;
+  case PREDICATE_GT:
+    valueexpr->fprint(f);
+    fprintf(f,">");
+    elementexpr->fprint(f);
+    break;
+  case PREDICATE_SET:
+    label->fprint(f);
+    fprintf(f," in ");
+    setexpr->fprint(f);
+    break;
+  case PREDICATE_EQ1:
+  case PREDICATE_GTE1:
+    fprintf(f,"sizeof(");
+    setexpr->fprint(f);
+    if (type==PREDICATE_EQ1)
+      fprintf(f,")=1");
+    if (type==PREDICATE_GTE1)
+      fprintf(f,")>=1");
+    break;
+  }
+}
+
+
+
+void Predicate::print_sets(Hashtable *stateenv, model *m) {
+  switch(type) {
+  case PREDICATE_LT:
+  case PREDICATE_LTE:
+  case PREDICATE_EQUALS:
+  case PREDICATE_GTE:
+  case PREDICATE_GT:
+    valueexpr->print_value(stateenv, m);
+    printf("; ");
+    elementexpr->print_value(stateenv, m);
+    break;
+  case PREDICATE_SET:    
+    setexpr->print_value(stateenv, m);
+    break;
+  case PREDICATE_EQ1:
+  case PREDICATE_GTE1:
+    setexpr->print_size(stateenv, m); 
+    break; 
+  }
+}
+
+
+
+
+
+// class Statement
+
+Statement::Statement(Statement *l, Statement *r, int t) {
+  left=l;
+  right=r;
+  type=t;
+}
+
+Statement::Statement(Statement *l) {
+  type=STATEMENT_NOT;
+  left=l;
+}
+Statement::Statement(Predicate *p) {
+  pred=p;
+  type=STATEMENT_PRED;
+}
+
+void Statement::print() {
+  switch(type) {
+  case STATEMENT_OR:
+    left->print();
+    printf(" OR ");
+    right->print();
+    break;
+  case STATEMENT_AND:
+    left->print();
+    printf(" AND ");
+    right->print();
+    break;
+  case STATEMENT_NOT:
+    printf("!");
+    left->print();
+    break;
+  case STATEMENT_PRED:
+    pred->print();
+    break;
+  }
+}
+
+void Statement::fprint(FILE *f) {
+  switch(type) {
+  case STATEMENT_OR:
+    left->fprint(f);
+    fprintf(f," OR ");
+    right->fprint(f);
+    break;
+  case STATEMENT_AND:
+    left->fprint(f);
+    fprintf(f," AND ");
+    right->fprint(f);
+    break;
+  case STATEMENT_NOT:
+    fprintf(f,"!");
+    left->fprint(f);
+    break;
+  case STATEMENT_PRED:
+    pred->fprint(f);
+    break;
+  }
+}
+
+
+void Statement::print_sets(Hashtable *stateenv, model *m) {
+  switch(type) {
+  case STATEMENT_OR:
+  case STATEMENT_AND:
+    left->print_sets(stateenv, m);
+    printf("; ");
+    right->print_sets(stateenv, m);
+    break;
+  case STATEMENT_NOT:
+    left->print_sets(stateenv, m);
+    break;
+  case STATEMENT_PRED:
+    pred->print_sets(stateenv, m);
+    break;
+  }
+  //printf("\n");
+}
+
+
+int Statement::gettype() {
+  return type;
+}
+
+Statement* Statement::getleft() {
+  return left;
+}
+
+Statement* Statement::getright() {
+  return right;
+}
+
+Predicate * Statement::getpredicate() {
+  return pred;
+}
+
+
+
+
+
+
+// class Constraint
+
+Constraint::Constraint() {
+  quantifiers=NULL;
+  numquantifiers=0;
+  statement=NULL;
+}
+
+void Constraint::setcrash(bool c) {
+  crash=c;
+}
+
+bool Constraint::getcrash() {
+  return crash;
+}
+
+Constraint::Constraint(Quantifier **q, int nq) {
+  quantifiers=q;
+  numquantifiers=nq;
+  statement=NULL;
+}
+
+void Constraint::setstatement(Statement *s) {
+  statement=s;
+}
+
+int Constraint::numquants() {
+  return numquantifiers;
+}
+
+Quantifier * Constraint::getquant(int i) {
+  return quantifiers[i];
+}
+
+Statement * Constraint::getstatement() {
+  return statement;
+}
+
+void Constraint::print() {
+  printf("[");
+  for(int i=0;i<numquantifiers;i++) {
+    if (i!=0)
+      printf(",");
+    quantifiers[i]->print();
+  }
+  printf("], ");
+  if (statement!=NULL) {
+    statement->print();
+  }
+  printf("\n");
+}
+
+void Constraint::fprint(FILE *f) {
+  printf("[");
+  for(int i=0;i<numquantifiers;i++) {
+    if (i!=0)
+      fprintf(f,",");
+    quantifiers[i]->fprint(f);
+  }
+  printf("],");
+  if (statement!=NULL) {
+    statement->fprint(f);
+  }
+}
diff --git a/Repair/RepairInterpreter/omodel.h b/Repair/RepairInterpreter/omodel.h
new file mode 100755 (executable)
index 0000000..8e7b616
--- /dev/null
@@ -0,0 +1,301 @@
+// Defines the Internal Constraint Language
+
+
+#ifndef ObjectModel_H
+#define ObjectModel_H
+#include<unistd.h>
+#include<stdio.h>
+#include "classlist.h"
+
+
+#define LITERAL_NUMBER 1
+#define LITERAL_TOKEN 2
+#define LITERAL_BOOL 3
+
+
+class Literal {
+ public:
+  Literal(char *s);
+  bool getbool();
+  int gettype();
+  int number();
+  char * token();
+  void print();
+  void fprint(FILE *f);
+
+ private:
+  char *str;
+};
+
+
+
+
+class Setlabel {
+ public:
+  Setlabel(char *s);
+  char * getname();
+  void print();
+  void fprint(FILE *f);
+ private:
+  char *str;
+};
+
+
+
+
+
+#define SET_label 0
+#define SET_literal 1
+
+class Set {
+ public:
+  Set(Setlabel *sl);
+  Set(Literal **l, int nl);
+  ~Set();
+  void fprint(FILE *f);
+  void print();
+  int gettype();
+  char * getname();
+  int getnumliterals();
+  Literal * getliteral(int i);
+ private:
+  int type;
+  Setlabel *setlabel;
+  int numliterals;
+  Literal **literals;
+};
+
+
+
+
+
+class Label {
+ public:
+  Label(char *s);
+  void print();
+  void fprint(FILE *f);
+  char* label() {
+    return str;
+  }
+
+ private:
+  char *str;
+};
+
+
+
+
+
+class Relation {
+ public:
+  Relation(char * r);
+  void print();  
+  void fprint(FILE *f);  
+  char * getname();
+
+ private:
+  char *str;
+};
+
+
+
+
+
+class Quantifier {
+ public:
+  Quantifier(Label *l, Set *s);
+  void print();
+  void fprint(FILE *f);
+  Label * getlabel();
+  Set * getset();
+
+ private:
+  Label *label;
+  Set *set;
+};
+
+
+
+
+
+
+#define SETEXPR_LABEL 1
+#define SETEXPR_REL 2
+#define SETEXPR_INVREL 3
+
+class Setexpr {
+ public:
+  Setexpr(Setlabel *sl);
+  Setexpr(Label *l, bool invert, Relation *r);
+  void print();
+  void fprint(FILE *f);
+  void print_size(Hashtable *stateenv, model *m);
+  void print_value(Hashtable *stateenv, model *m);
+  Setlabel * getsetlabel();
+  Relation * getrelation();
+  Label * getlabel();
+  int gettype();
+
+ private:
+  int type;
+  Setlabel *setlabel;
+  Label *label;
+  Relation *relation;
+};
+
+
+
+
+
+
+class Valueexpr {
+ public:
+  Valueexpr(Label *l,Relation *r, bool inv);
+  Valueexpr(Valueexpr *ve,Relation *r, bool inv);
+  void print();
+  void fprint(FILE *f);
+  void print_value(Hashtable *stateenv, model *m);
+  Element * get_value(Hashtable *stateenv, model *m);
+  int gettype();
+  Label * getlabel();
+  Valueexpr * getvalueexpr();
+  Relation * getrelation();
+  bool getinverted();
+  
+ private:
+  int type;
+  bool inverted;
+  Label *label;
+  Valueexpr *valueexpr;
+  Relation *relation;
+};
+
+
+
+
+
+
+#define ELEMENTEXPR_LABEL 1
+#define ELEMENTEXPR_SUB 2
+#define ELEMENTEXPR_ADD 3
+#define ELEMENTEXPR_MULT 4
+#define ELEMENTEXPR_LIT 5
+#define ELEMENTEXPR_SETSIZE 6
+#define ELEMENTEXPR_RELATION 11
+
+class Elementexpr {
+ public:
+  Elementexpr(Setexpr *se);
+  Elementexpr(Elementexpr *l, Elementexpr *r, int op);
+  Elementexpr(Literal *lit);
+  Elementexpr(Label *lab);
+  Elementexpr(Elementexpr *l,Relation *r);
+  void print();
+  void fprint(FILE *f);
+  void print_value(Hashtable *stateenv, model *m);
+
+  int gettype();
+  Label * getlabel();
+  Elementexpr *getleft();
+  Elementexpr *getright();
+  Literal * getliteral();
+  Setexpr * getsetexpr();
+  Relation * getrelation();
+
+ private:
+  int type;
+  Relation *relation;
+  Elementexpr *left, *right;
+  Label *label;
+  Literal *literal;
+  Setexpr *setexpr;
+};
+
+
+
+
+
+#define PREDICATE_LT 1
+#define PREDICATE_LTE 2
+#define PREDICATE_EQUALS 3
+#define PREDICATE_GTE 4
+#define PREDICATE_GT 5
+#define PREDICATE_SET 6
+#define PREDICATE_EQ1 7
+#define PREDICATE_GTE1 8
+
+class Predicate {
+ public:
+  Predicate(Valueexpr *ve, int t, Elementexpr *ee);
+  Predicate(Label *l,Setexpr *se);
+  Predicate(bool greaterthan, Setexpr *se);
+  void print();
+  void fprint(FILE *f);
+  void print_sets(Hashtable *stateenv, model *m);
+  int gettype();
+  Valueexpr * getvalueexpr();
+  Elementexpr * geteleexpr();
+  Label * getlabel();
+  Setexpr * getsetexpr();
+ private:
+  int type;
+  Valueexpr *valueexpr;
+  Elementexpr *elementexpr;
+  Label *label;
+  Setexpr *setexpr;
+};
+
+
+
+
+
+
+#define STATEMENT_OR 1
+#define STATEMENT_AND 2
+#define STATEMENT_NOT 3
+#define STATEMENT_PRED 4
+
+class Statement {
+ public:
+  Statement(Statement *l, Statement *r, int t);
+  Statement(Statement *l);
+  Statement(Predicate *p);
+  void print();
+  void fprint(FILE *f);
+  void print_sets(Hashtable *env, model *m); // prints the sets and the relations involved in the statement
+  int gettype();
+  Statement *getleft();
+  Statement *getright();
+  Predicate *getpredicate();
+ private:
+  int type;
+  Statement *left,*right;
+  Predicate *pred;
+};
+
+
+
+
+
+
+class Constraint {
+ public:
+  Constraint();
+  Constraint(Quantifier **q, int nq);
+  void setstatement(Statement *s);
+  void print();
+  void fprint(FILE *f);
+  int numquants();
+  Quantifier * getquant(int i);
+  Statement * getstatement();
+  void setcrash(bool c);
+  bool getcrash();
+ private:
+  bool crash;
+  int numquantifiers;
+  Quantifier **quantifiers;
+  Statement *statement;
+};
+
+
+#endif
diff --git a/Repair/RepairInterpreter/oparser.cc b/Repair/RepairInterpreter/oparser.cc
new file mode 100755 (executable)
index 0000000..ed93e45
--- /dev/null
@@ -0,0 +1,411 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "oparser.h"
+#include "omodel.h"
+#include "list.h"
+#include "common.h"
+#include "token.h"
+
+
+Constraint * Parser::parseconstraint() {
+  Token token=reader->peakahead();
+  while(token.token_type==TOKEN_EOL) {
+    skiptoken();
+    token=reader->peakahead();
+  }
+  if (token.token_type==TOKEN_EOF)
+    return NULL;
+  bool crash=false;
+  if (token.token_type==TOKEN_CRASH) {
+    crash=true;
+    skiptoken();
+  }
+  Constraint *c;
+  /*Get Quantifiers*/
+  if (token.token_type==TOKEN_OPENBRACK) {
+    skiptoken();
+    c=parsequantifiers();
+    needtoken(TOKEN_COMMA);
+  } else c=new Constraint();
+  /*Peek ahead to see if sizeof*/
+  c->setcrash(crash);
+  c->setstatement(parsestatement(false));
+  return c;
+}
+
+Statement * Parser::parsestatement(bool flag) {
+  Statement * oldst=NULL;
+  int joinflag=-1;
+  while(true) {
+    Token token=reader->peakahead();
+    switch(token.token_type) {
+    case TOKEN_EOL:
+      skiptoken();
+      return oldst;
+    case TOKEN_OPENPAREN:
+      {
+       skiptoken();
+       Statement *st=parsestatement(false);
+       if (flag)
+         return st;
+       if (oldst==NULL) {
+         oldst=st;
+       } else {
+         if (joinflag==TOKEN_AND) {
+           oldst=new Statement(oldst, st, STATEMENT_AND);
+         } else if (joinflag==TOKEN_OR) {
+           oldst=new Statement(oldst, st, STATEMENT_OR);
+         } else {
+           error();
+         }
+         joinflag=-1;
+       }
+      }
+      break;
+    case TOKEN_CLOSEPAREN:
+      skiptoken();
+      return oldst;
+    case TOKEN_AND:
+      skiptoken();
+      if (oldst==NULL) error();
+      joinflag=TOKEN_AND;
+      break;
+    case TOKEN_OR:
+      skiptoken();
+      if (oldst==NULL) error();
+      joinflag=TOKEN_OR;
+      break;
+    case TOKEN_NOT:
+      {
+       skiptoken();
+       Statement * st=new Statement(parsestatement(true));
+       if (flag)
+         return st;
+       if (oldst==NULL) {
+         oldst=st;
+       } else {
+         if (joinflag==TOKEN_AND) {
+           oldst=new Statement(oldst, st, STATEMENT_AND);
+         } else if (joinflag==TOKEN_OR) {
+           oldst=new Statement(oldst, st, STATEMENT_OR);         
+         } else {
+           error();
+         }
+         joinflag=-1;
+       }
+      }
+      break;
+    default:
+      {
+       Statement * st=new Statement(parsepredicate());
+       if (flag) return st;
+       if (oldst==NULL) {
+         oldst=st;
+       } else {
+         if (joinflag==TOKEN_AND) {
+           oldst=new Statement(oldst, st, STATEMENT_AND);
+         } else if (joinflag==TOKEN_OR) {
+           oldst=new Statement(oldst, st, STATEMENT_OR);         
+         }
+         joinflag=-1;
+       }
+      }
+    }
+  }
+}
+
+Elementexpr * Parser::parseelementexpr() {
+  Elementexpr *oldee=NULL;
+  int joinop=-1;
+  while(true) {
+  Token t=reader->peakahead();
+  switch(t.token_type) {
+  case TOKEN_SIZEOF:
+    {
+      if ((joinop==-1)&&(oldee!=NULL))
+       return oldee;
+      skiptoken();
+      needtoken(TOKEN_OPENPAREN);
+      Setexpr* se=parsesetexpr();
+      needtoken(TOKEN_CLOSEPAREN);
+      if (oldee==NULL)
+       oldee=new Elementexpr(se);
+      else {
+       if (joinop!=-1) {
+         oldee=new Elementexpr(oldee,new Elementexpr(se),joinop);
+         joinop=-1;
+       } else error();
+      }
+      break;
+    }
+  case TOKEN_LITERAL:
+    {
+      if ((joinop==-1)&&(oldee!=NULL))
+       return oldee;
+      skiptoken();
+      needtoken(TOKEN_OPENPAREN);
+      Token literal=reader->readnext();
+      needtoken(TOKEN_CLOSEPAREN);
+      if (oldee==NULL)
+       oldee=new Elementexpr(new Literal(copystr(literal.str)));
+      else {
+       if (joinop!=-1) {
+         oldee=new Elementexpr(oldee,new Elementexpr(new Literal(copystr(literal.str))),joinop);
+         joinop=-1;
+       } else error();
+      }
+      break;
+    }
+    /*  case TOKEN_PARAM:
+       {
+       if ((joinop==-1)&&(oldee!=NULL))
+       return oldee;
+       skiptoken();
+       needtoken(TOKEN_OPENPAREN);
+       Elementexpr *ee=parseelementexpr();
+       needtoken(TOKEN_COMMA);
+       Token number=reader->readnext();
+       needtoken(TOKEN_CLOSEPAREN);
+       
+       if (oldee==NULL)
+       oldee=new Elementexpr(ee,new Literal(copystr(number.str)));
+       else {
+       if (joinop!=-1) {
+       oldee=new Elementexpr(oldee,new Elementexpr(ee,new Literal(copystr(number.str))),joinop);
+       joinop=-1;
+       } else error();
+       }
+       
+       break;
+       } */
+  case TOKEN_OPENPAREN:
+    {
+      if ((joinop==-1)&&(oldee!=NULL))
+       return oldee;
+      skiptoken();
+      Elementexpr *ee=parseelementexpr();
+      if (oldee==NULL)
+       oldee=ee;
+      else {
+       if (joinop!=-1) {
+         oldee=new Elementexpr(oldee,ee,joinop);
+         joinop=-1;
+       } else error();
+      }
+      break;
+    }
+  case TOKEN_CLOSEPAREN:
+    skiptoken();
+    return oldee;
+    break;
+  case TOKEN_SUB:
+    skiptoken();
+    if ((oldee!=NULL)&&(joinop==-1))
+      joinop=ELEMENTEXPR_SUB;
+    else
+      error();
+    break;
+  case TOKEN_ADD:
+    skiptoken();
+    if ((oldee!=NULL)&&(joinop==-1))
+      joinop=ELEMENTEXPR_ADD;
+    else
+      error();
+    break;
+  case TOKEN_MULT:
+    skiptoken();
+    if ((oldee!=NULL)&&(joinop==-1))
+      joinop=ELEMENTEXPR_MULT;
+    else
+      error();
+    break;
+  default:
+    if ((joinop==-1)&&(oldee!=NULL))
+      return oldee;
+    skiptoken();
+    if (oldee==NULL)
+      oldee=checkdot(new Elementexpr(new Label(copystr(t.str))));
+    else {
+      if (joinop!=-1) {
+       oldee=new Elementexpr(oldee,new Elementexpr(new Label(copystr(t.str))),joinop);
+       joinop=-1;
+      } else error();
+    }
+  }
+  }
+}
+
+Elementexpr * Parser::checkdot(Elementexpr * incoming) {
+  Token tdot=reader->peakahead();
+  if (tdot.token_type!=TOKEN_DOT) return incoming;
+  skiptoken();
+  Token tfield=reader->readnext();
+  Token tpeak=reader->peakahead();
+  return checkdot(new Elementexpr(incoming, new Relation(copystr(tfield.str))));
+}
+
+Predicate * Parser::parsepredicate() {
+  Token label=reader->readnext();
+
+  if (label.token_type==TOKEN_SIZEOF) {
+    needtoken(TOKEN_OPENPAREN);
+    Setexpr * setexpr=parsesetexpr();
+    needtoken(TOKEN_CLOSEPAREN);
+    Token tokentest=reader->readnext();
+    bool greaterthan=false;
+    switch(tokentest.token_type) {
+    case TOKEN_EQUALS:
+      greaterthan=false;
+      break;
+    case TOKEN_GT:
+      greaterthan=true;
+      break;
+    default:
+      error();
+    }
+    needtoken(TOKEN_ONE);
+    return new Predicate(greaterthan, setexpr);
+  }
+
+  Token nexttoken=reader->readnext();
+  bool inverted=false;
+  switch(nexttoken.token_type) {
+  case TOKEN_DOTINV:
+    inverted=true;
+  case TOKEN_DOT:
+    {
+      Token relation=reader->readnext();
+      Token compareop=reader->readnext();
+      Valueexpr *ve=new Valueexpr(new Label(copystr(label.str)),
+                                new Relation(copystr(relation.str)),inverted);
+      while(compareop.token_type==TOKEN_DOT||compareop.token_type==TOKEN_DOTINV) {
+       Token nrelation=reader->readnext();
+       bool invert=(compareop.token_type==TOKEN_DOTINV);
+       compareop=reader->readnext();
+       ve=new Valueexpr(ve,
+                        new Relation(copystr(nrelation.str)),invert);
+      }
+      Elementexpr * ee=parseelementexpr();
+
+      
+      switch(compareop.token_type) {
+      case TOKEN_LT:
+       return new Predicate(ve,PREDICATE_LT,ee);
+      case TOKEN_LTE:
+       return new Predicate(ve,PREDICATE_LTE,ee);
+      case TOKEN_EQUALS:
+       return new Predicate(ve,PREDICATE_EQUALS,ee);
+      case TOKEN_GTE:
+       return new Predicate(ve,PREDICATE_GTE,ee);
+      case TOKEN_GT:
+       return new Predicate(ve,PREDICATE_GT,ee);
+      default:
+       error();
+      }
+    }
+  case TOKEN_IN:
+    {
+      Setexpr * se=parsesetexpr();
+      return new Predicate(new Label(copystr(label.str)),se);
+    }
+  default:
+    error();
+  }
+}
+
+void Parser::error() {
+  printf("ERROR\n");
+  reader->error();
+  exit(-1);
+}
+
+void Parser::skiptoken() {
+  reader->readnext();
+}
+
+void Parser::needtoken(int token) {
+  Token t=reader->readnext();
+  if (!(t.token_type==token)) {
+    printf("Needed token: ");
+    tokenname(token);
+    printf("\n Got token: %s ",t.str);
+    tokenname(t.token_type);
+    error();
+  }
+}
+
+Constraint * Parser::parsequantifiers() {
+  bool bool_continue=true;
+  List * list=new List();
+  do {
+    Token token2=reader->readnext();
+    switch(token2.token_type) {
+    case TOKEN_CLOSEBRACK:
+      bool_continue=false;
+      break;
+    case TOKEN_FORALL:
+      list->addobject(parsequantifier());
+      break;
+    case TOKEN_COMMA:
+      break;
+    default:
+      error();
+    }
+  } while(bool_continue);
+  Quantifier** qarray=new Quantifier* [list->size()];
+  list->toArray((void **)qarray);
+  Constraint *c=new Constraint(qarray,list->size());
+  delete(list);
+  return c;
+}
+
+Quantifier * Parser::parsequantifier() {
+  Token label=reader->readnext();
+  needtoken(TOKEN_IN);
+  return new Quantifier(new Label(copystr(label.str)),parseset());
+}
+
+Set * Parser::parseset() {
+  Token label=reader->readnext();
+  if (label.token_type==TOKEN_OPENBRACE) {
+    bool bool_continue=true;
+    List * list=new List();
+    do {
+      Token token2=reader->readnext();
+      switch(token2.token_type) {
+      case TOKEN_CLOSEBRACE:
+       bool_continue=false;
+       break;
+      case TOKEN_COMMA:
+       break;
+      default:
+       list->addobject(new Literal(copystr(token2.str)));
+       break;
+      }
+    } while(bool_continue);
+    int size=list->size();
+    Literal** qarray=new Literal* [size];
+    list->toArray((void **)qarray);
+    delete(list);
+    return new Set(qarray,size);
+  } else
+    return new Set(new Setlabel(copystr(label.str)));
+}
+
+Setexpr * Parser::parsesetexpr() {
+  Token label=reader->readnext();
+  Token peak=reader->peakahead();
+  if (peak.token_type==TOKEN_DOT) {
+    skiptoken();
+    return new Setexpr(new Label(copystr(label.str)),false,new Relation(copystr(reader->readnext().str)));
+  } else if (peak.token_type==TOKEN_DOTINV) {
+    skiptoken();
+    return new Setexpr(new Label(copystr(label.str)),true,new Relation(copystr(reader->readnext().str)));
+  } else
+    return new Setexpr(new Setlabel(copystr(label.str)));
+}
+
+Parser::Parser(Reader *r) {
+  reader=r;
+}
diff --git a/Repair/RepairInterpreter/oparser.h b/Repair/RepairInterpreter/oparser.h
new file mode 100755 (executable)
index 0000000..f3329c4
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef ObjectModelParser_H
+#define ObjectModelParser_H
+
+#include "common.h"
+#include <iostream.h>
+#include <stdio.h>
+#include "classlist.h"
+
+class Parser {
+ public:
+  Parser(Reader *r);
+  Constraint * parseconstraint();
+  
+ private:
+  Elementexpr * checkdot(Elementexpr * incoming);
+  Constraint * parsequantifiers();
+  Quantifier * parsequantifier();
+  Set * parseset();
+  Setexpr * parsesetexpr();
+  Statement * parsestatement(bool);
+  Elementexpr * parseelementexpr();
+  Predicate * parsepredicate();
+  void skiptoken();
+  void needtoken(int);
+  void error();
+  Reader *reader;
+};
+#endif
diff --git a/Repair/RepairInterpreter/processabstract.cc b/Repair/RepairInterpreter/processabstract.cc
new file mode 100755 (executable)
index 0000000..f2574d1
--- /dev/null
@@ -0,0 +1,982 @@
+// evaluates model definition rules
+
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "processabstract.h"
+#include "processconcrete.h"
+#include "amodel.h"
+#include "omodel.h"
+#include "dmodel.h"
+#include "Hashtable.h"
+#include "element.h"
+#include "common.h"
+#include "bitreader.h"
+#include "model.h"
+#include "set.h"
+#include "Relation.h"
+#include "tmap.h"
+
+static int abstractcheck=0;
+static int abstracttrigger=0;
+static int paircount=0;
+
+// class processabstract
+
+processabstract::processabstract(model *m) {
+  globalmodel=m;
+  br=new bitreader(globalmodel,m->gethashtable());
+  dirtyflag=false;
+}
+
+bool processabstract::dirtyflagstatus() {
+  return dirtyflag;
+}
+
+void processabstract::setclean() {
+  dirtyflag=false;
+}
+
+
+bool processabstract::evaluatestatementa(Statementa *sa, Hashtable *env) {
+  switch(sa->gettype()) {
+  case STATEMENTA_OR:
+    return evaluatestatementa(sa->getleft(),env)||evaluatestatementa(sa->getright(),env);
+  case STATEMENTA_AND:
+    return evaluatestatementa(sa->getleft(),env)&&evaluatestatementa(sa->getright(),env);
+  case STATEMENTA_NOT:
+    return !evaluatestatementa(sa->getleft(),env);
+  case STATEMENTA_EQUALS: {
+    Element *left=evaluateexpr(globalmodel,sa->getleftee(),env,true,true);
+    Element *right=evaluateexpr(globalmodel,sa->getrightee(),env,true,true);
+    bool tvalue=left->equals(right);
+    delete(left);
+    delete(right);
+    return tvalue;
+  }
+  case STATEMENTA_SET: {
+    Element *left=evaluateexpr(globalmodel,sa->getleftee(),env,true,true);
+    Set *set=sa->getset();
+    if (set->gettype()==SET_label) {
+      DomainSet *ds=globalmodel->getdomainrelation()->getset(set->getname());
+      if (ds->getset()->contains(left)) {
+       delete(left);
+       return true;
+      } else {
+       delete(left);
+       return false;
+      }
+    } else if (set->gettype()==SET_literal) {
+      for(int j=0;j<set->getnumliterals();j++) {
+       Literal *l=set->getliteral(j);
+       switch(l->gettype()) {
+       case LITERAL_NUMBER:
+         if(left->isnumber()&&
+            left->intvalue()==l->number()) {
+           delete(left);
+           return true;
+         }
+       case LITERAL_TOKEN:
+         if((left->type()==ELEMENT_TOKEN)&&
+            equivalentstrings(left->gettoken(),l->token())) {
+             delete(left);
+             return true;
+           }
+       }
+      }
+      delete(left);
+      return false;
+    }
+  }
+  case STATEMENTA_VALID: {
+    Element *left=evaluateexpr(globalmodel,sa->getleftee(),env,true,true);
+    if (left->type()!=ELEMENT_OBJECT) {
+      printf("ERROR in processabstract.cc\n");
+    }
+    if (left->getobject()==NULL) {
+      delete(left);
+      return new Element(false);
+    }
+    char *structuretype=sa->getvalidtype();
+    structure *st=(structuretype==NULL)?left->getstructure():globalmodel->getstructure(structuretype);
+    bool validity=globalmodel->gettypemap()->istype(left->getobject(),st);
+    delete(left);
+    return new Element(validity);
+  }
+
+  case STATEMENTA_LT: {
+    Element *left=evaluateexpr(globalmodel,sa->getleftee(),env,true,true);
+    Element *right=evaluateexpr(globalmodel,sa->getrightee(),env,true,true);
+    if (!left->isnumber()||
+       !right->isnumber()) {
+      printf("Bad lt compare\n");
+      exit(-1);
+    }
+    bool tvalue=left->intvalue()<right->intvalue();
+    delete(left);
+    delete(right);
+    return tvalue;
+  }
+  case STATEMENTA_TRUE:
+    return true;
+  }
+}
+
+
+/* a Statementb is of the type "E in S" or "<E,E> in R" so we just add the 
+   respective element to S or R if the statement is not satisfied */
+void processabstract::satisfystatementb(Statementb *sb, Hashtable *env) {
+  switch(sb->gettype()) {
+  case STATEMENTB_SING: {
+    Element *ele=evaluateexpr(globalmodel,sb->getleft(),env,true,true);
+    /*if (sb->gettleft()!=NULL) {
+      Element **earray=new Element *[sb->gettleft()->getnumexpr()];
+      for(int i=0;i<sb->gettleft()->getnumexpr();i++) {
+       earray[i]=evaluateexpr(br,sb->gettleft()->getexpr(i),env);
+      }
+      ele->setnewparams(earray,sb->gettleft()->getnumexpr());
+      }*/
+    if (ele==NULL)
+      break;
+    if (!globalmodel->getdomainrelation()->getset(sb->getsetlabel()->getname())->getset()->contains(ele)) {
+      dirtyflag=true;
+#ifdef DEBUGMANYMESSAGES
+      printf("element: ");
+      ele->print();
+      printf(" into %s\n",sb->getsetlabel()->getname());
+#endif
+      globalmodel->getdomainrelation()->abstaddtoset(ele,globalmodel->getdomainrelation()->getset(sb->getsetlabel()->getname()),globalmodel);
+    } else {
+      delete(ele);
+    }
+    break;
+  }
+  case STATEMENTB_TUPLE:{
+    Element *left=evaluateexpr(globalmodel,sb->getleft(),env,true,true);
+    if (left==NULL)
+      break;
+    Element *right=evaluateexpr(globalmodel,sb->getright(),env,true,true);    
+    if (right==NULL) {
+      delete(left);
+      break;
+    }
+    /*    if (sb->gettleft()!=NULL) {
+      Element **earray=new Element *[sb->gettleft()->getnumexpr()];
+      for(int i=0;i<sb->gettleft()->getnumexpr();i++) {
+       earray[i]=evaluateexpr(br,sb->gettleft()->getexpr(i),env);
+      }
+      left->setnewparams(earray,sb->gettleft()->getnumexpr());
+      }*/
+    /*    if (sb->gettright()!=NULL) {
+      Element **earray=new Element *[sb->gettright()->getnumexpr()];
+      for(int i=0;i<sb->gettright()->getnumexpr();i++) {
+       earray[i]=evaluateexpr(br,sb->gettright()->getexpr(i),env);
+      }
+      right->setnewparams(earray,sb->gettright()->getnumexpr());
+      }*/
+    if (!globalmodel->getdomainrelation()->getrelation(sb->getsetlabel()->getname())->getrelation()->contains(left,right)) {
+      dirtyflag=true;
+      paircount++;
+#ifdef DEBUGMANYMESSAGES
+      printf("element: <");
+      left->print();
+      printf(",");
+      right->print();
+      printf("> into %s\n",sb->getsetlabel()->getname());
+#endif
+      globalmodel->getdomainrelation()->getrelation(sb->getsetlabel()->getname())->getrelation()->put(left,right);
+    } else {
+      delete(left);
+      delete(right);
+    }
+    break;
+  }
+  }
+}
+
+void processabstract::printstats() {
+  printf("Abstraction Rules Checked: %d Triggered: %d\n",abstractcheck,abstracttrigger);
+  printf("Pair count: %d\n",paircount);
+}
+
+void processabstract::processrule(Rule *r) {
+  State *st=new State(r, globalmodel->gethashtable());
+  if (st->initializestate(br, globalmodel)) {
+    while(true) {
+      abstractcheck++;
+      if (evaluatestatementa(r->getstatementa(),st->env)) {
+       abstracttrigger++;
+       satisfystatementb(r->getstatementb(),st->env);
+      }
+      if (!st->increment(br, globalmodel))
+       break; /* done */
+    }
+  }
+  delete(st);
+}
+
+void processabstract::processrule(Rule *r, Element *ele, char *set) {
+  int count=-1;
+
+
+  for(int i=0;i<r->numquants();i++) {
+    AQuantifier *aq=r->getquant(i);
+    switch(aq->gettype()) {
+    case AQUANTIFIER_SING:
+      count=i;
+      break;
+    default:
+      break;
+    }
+  }
+
+  AQuantifier *aq=r->getquant(count);
+  if (!equivalentstrings(aq->getset()->getname(),set))
+    return;
+
+  Hashtable *env=new Hashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
+  env->setparent(globalmodel->gethashtable());
+    
+  RelationSet **relset=new RelationSet*[r->numquants()-1];
+  int c=0;
+  for(int i=0;i<r->numquants();i++) {
+    if (i!=count) {
+      AQuantifier *aq=r->getquant(i);
+      RelationSet *rs=new RelationSet(aq->getleft()->label(),aq->getlower(),aq->getupper());
+      rs->incrementassignment(br,env,globalmodel);
+      relset[c++]=rs;
+    }
+  }
+  
+  env->put(aq->getleft()->label(),ele);
+  bool flag=true;
+  while(flag) {
+    if (evaluatestatementa(r->getstatementa(),env))
+      satisfystatementb(r->getstatementb(),env);
+    int i=r->numquants()-2;
+    for(;i>=0;i--) {
+      if (relset[i]->incrementassignment(br,env,globalmodel)) {
+       break;
+      } else {
+       relset[i]->resetassignment(env);
+       if (!relset[i]->incrementassignment(br,env,globalmodel)) {
+         flag=false;
+         break;
+       }
+      }
+    }
+    if (i==-1)
+      flag=false;
+  }
+  for(int i=0;i<r->numquants()-1;i++) {
+    delete(relset[i]);
+  }
+  delete(relset);
+  delete(env);
+}
+
+processabstract::~processabstract() {
+  delete(br);
+}
+
+
+
+
+
+// class State
+
+State::State(Rule *r, Hashtable *oldenv) {
+  env=new Hashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);;
+  env->setparent(oldenv);
+  numrelset=r->numquants();
+  relset=new RelationSet*[numrelset];
+  for(int i=0;i<r->numquants();i++) {
+    AQuantifier *aq=r->getquant(i);
+
+    switch(aq->gettype()) {
+    case AQUANTIFIER_SING:
+      relset[i]=new RelationSet(aq->getset(),aq->getleft()->label(),aq->gettleft());
+      break;
+    case AQUANTIFIER_TUPLE:
+      relset[i]=new RelationSet(aq->getset(),aq->getleft()->label(),aq->gettleft(),aq->getright()->label(),aq->gettright());
+      break;
+    case AQUANTIFIER_RANGE:
+      relset[i]=new RelationSet(aq->getleft()->label(),aq->getlower(),aq->getupper());
+      break;
+    }
+  }
+}
+
+
+
+State::State(Constraint *c,Hashtable *oldenv) {
+  env=new Hashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);;
+  env->setparent(oldenv);
+  numrelset=c->numquants();
+  relset=new RelationSet*[numrelset];
+  for(int i=0;i<c->numquants();i++) {
+    Quantifier *q=c->getquant(i);
+    relset[i]=new RelationSet(q->getset(),q->getlabel()->label(),NULL);
+  }
+}
+
+
+
+State::~State() {
+  delete(env);
+  for(int i=0;i<numrelset;i++)
+    delete(relset[i]);
+  delete[](relset);
+}
+
+
+bool State::initializestate(bitreader *br, model * m) {
+  for(int i=0;i<numrelset;i++) {
+    if (!relset[i]->incrementassignment(br,env,m))
+      return false;
+  }
+  return true;
+}
+
+
+/* initializes all quantifiers of this constraint and returns false
+   if there exists a quantifier that cannot be initialized */
+bool State::initializestate(model * m) {
+  for(int i=0;i<numrelset;i++) {
+    if (!relset[i]->incrementassignment(env,m))
+      return false;
+  }
+  return true;
+}
+
+bool State::initializestate(processconcrete *pc,model * m) {
+  for(int i=0;i<numrelset;i++) {
+    if (!relset[i]->incrementassignment(pc,env,m))
+      return false;
+  }
+  return true;
+}
+
+bool State::increment(bitreader *br, model *m) {
+  for(int i=numrelset-1;i>=0;i--) {
+      if (relset[i]->incrementassignment(br,env,m))
+       return true;
+      else {
+       relset[i]->resetassignment(env);
+       if (!relset[i]->incrementassignment(br,env,m))
+         return false;
+      }
+  }
+  return false;
+}
+
+bool State::increment(model *m) {
+  for(int i=numrelset-1;i>=0;i--) {
+      if (relset[i]->incrementassignment(env,m))
+       return true;
+      else {
+       relset[i]->resetassignment(env);
+       if (!relset[i]->incrementassignment(env,m))
+         return false;
+      }
+  }
+  return false;
+}
+
+bool State::increment(processconcrete *pc,model *m) {
+  for(int i=numrelset-1;i>=0;i--) {
+      if (relset[i]->incrementassignment(pc,env,m))
+       return true;
+      else {
+       relset[i]->resetassignment(env);
+       if (!relset[i]->incrementassignment(pc,env,m))
+         return false;
+      }
+  }
+  return false;
+}
+
+
+
+Element * evaluateexpr(model *m,AElementexpr *ee, Hashtable *env, bool enforcetyping, bool compute) {
+  bitreader *br=m->getbitreader();
+  switch(ee->gettype()) {
+  case AELEMENTEXPR_NULL:
+    return new Element();
+  case AELEMENTEXPR_LABEL: {
+    Element *r=new Element((Element *)env->get(ee->getlabel()->label()));
+    typemap *tm=m->gettypemap();
+    if (compute)
+      if(r->type()==ELEMENT_OBJECT&&
+        r->getobject()!=NULL&&
+        !tm->asserttype(r->getobject(),r->getstructure())) {
+       delete(r);
+       return NULL;
+      }
+    return r;
+  }
+  case AELEMENTEXPR_SUB: {
+    AElementexpr *left=ee->getleft();
+    AElementexpr *right=ee->getright();
+    Element *leftval=evaluateexpr(m,left,env,true,compute);
+    if (leftval==NULL)
+      return NULL;
+    Element *rightval=evaluateexpr(m,right,env,true,compute);
+    if (rightval==NULL) {
+      delete(leftval);
+      return NULL;
+    }
+    Element *diff=new Element(leftval->intvalue()-rightval->intvalue());
+    delete(leftval);delete(rightval);
+    return diff;
+  }
+  case AELEMENTEXPR_ADD: {
+    AElementexpr *left=ee->getleft();
+    AElementexpr *right=ee->getright();
+    Element *leftval=evaluateexpr(m,left,env,true,compute);
+    if (leftval==NULL)
+      return NULL;
+    Element *rightval=evaluateexpr(m,right,env,true,compute);
+    if (rightval==NULL) {
+      delete(leftval);
+      return NULL;
+    }
+    Element *sum=new Element(leftval->intvalue()+rightval->intvalue());
+    delete(leftval);delete(rightval);
+    return sum;
+  }
+  case AELEMENTEXPR_MULT: {
+    AElementexpr *left=ee->getleft();
+    AElementexpr *right=ee->getright();
+    Element *leftval=evaluateexpr(m,left,env,true,compute);
+    if (leftval==NULL)
+      return NULL;
+    Element *rightval=evaluateexpr(m,right,env,true,compute);
+    if (rightval==NULL) {
+      delete(leftval);
+      return NULL;
+    }
+    Element *diff=new Element(leftval->intvalue()*rightval->intvalue());
+    delete(leftval);delete(rightval);
+    return diff;
+  }
+  case AELEMENTEXPR_DIV: {
+    AElementexpr *left=ee->getleft();
+    AElementexpr *right=ee->getright();
+    Element *leftval=evaluateexpr(m,left,env,true,compute);
+    if (leftval==NULL)
+      return NULL;
+    Element *rightval=evaluateexpr(m,right,env,true,compute);
+    if (rightval==NULL) {
+      delete(leftval);
+      return NULL;
+    }
+    Element *diff=new Element(leftval->intvalue()/rightval->intvalue());
+    delete(leftval);delete(rightval);
+    return diff;
+  }
+  case AELEMENTEXPR_LIT: {
+    Literal *l=ee->getliteral();
+    switch(l->gettype()) {
+    case LITERAL_NUMBER:
+      return new Element(l->number());
+    case LITERAL_TOKEN:
+      return new Element(copystr(l->token()));
+    case LITERAL_BOOL:
+      return new Element(l->getbool());
+    default:
+      printf("ERROR with lit type\n");
+      exit(-1);
+    }
+  }
+  case AELEMENTEXPR_FIELD: {
+    Element *e=evaluateexpr(m,ee->getleft(),env,true,compute);
+    if (e==NULL)
+      return NULL;
+    Element *r=br->readfieldorarray(e,ee->getfield(),NULL);
+    delete(e);
+    if (r==NULL)
+      return NULL;
+    if (enforcetyping&&compute) {
+      typemap *tm=m->gettypemap();
+      if(r->type()==ELEMENT_OBJECT&&
+        r->getobject()!=NULL&&
+        !tm->asserttype(r->getobject(),r->getstructure())) {
+       delete(r);
+       return NULL;
+      }
+    } else if (compute) {
+      typemap *tm=m->gettypemap();
+      if(r->type()==ELEMENT_OBJECT&&
+        r->getobject()!=NULL&&
+        !tm->istype(r->getobject(),r->getstructure())) {
+       delete(r);
+       return NULL;
+      }
+    }
+    return r;
+  }
+  case AELEMENTEXPR_CAST: {
+    Element *e=evaluateexpr(m,ee->getleft(),env,true,compute);
+    if (e==NULL)
+      return NULL;
+    typemap *tm=m->gettypemap();
+    if (e->getobject()!=NULL&&compute&&
+       !tm->asserttype(e->getobject(),m->getstructure(ee->getcasttype()))) {
+      delete(e);
+      return NULL;
+    }
+    Element *r=new Element(e->getobject(),m->getstructure(ee->getcasttype()));
+    delete(e);
+    return r;
+  }
+  case AELEMENTEXPR_FIELDARRAY: {
+    Element *e=evaluateexpr(m,ee->getleft(),env,true,compute);
+    if (e==NULL)
+      return NULL;
+    Element *ind=evaluateexpr(m,ee->getright(),env,true,compute);
+    if (ind==NULL) {
+      delete(e);
+      return NULL;
+    }
+    Element *r=br->readfieldorarray(e,ee->getfield(),ind);
+    delete(ind);
+    delete(e);
+    if (r==NULL)
+      return NULL;
+    if (enforcetyping&&compute) {
+      typemap *tm=m->gettypemap();
+      if(r->type()==ELEMENT_OBJECT&&
+        r->getobject()!=NULL&&
+        !tm->asserttype(r->getobject(),r->getstructure())) {
+       delete(r);
+       return NULL;
+      }
+    } else if (compute) {
+      typemap *tm=m->gettypemap();
+      if(r->type()==ELEMENT_OBJECT&&
+        r->getobject()!=NULL&&
+        !tm->istype(r->getobject(),r->getstructure())) {
+       delete(r);
+       return NULL;
+      }
+    }
+    return r;
+  }
+  }
+}
+
+
+// prints the current state
+void State::print(model *m) 
+{
+  for(int i=0; i<numrelset; i++) 
+    {
+      relset[i]->print(env, m); 
+      printf(" ");
+    }
+}
+
+
+
+
+// class RelationSet
+
+RelationSet::RelationSet(Set *s, char *l,Type *tl) {
+  set=s;
+  type=TYPE_SET;
+  left=l;
+  tleft=tl;
+  tright=NULL;
+  right=NULL;
+}
+
+RelationSet::RelationSet(Set *s,char *l, Type *tl,char *r,Type *tr) {
+  set=s;
+  type=TYPE_RELATION;
+  left=l;
+  tleft=tl;
+  tright=tr;
+  right=r;
+}
+
+RelationSet::RelationSet(char *l,AElementexpr *lower,AElementexpr*upper) {
+  this->lower=lower;
+  this->upper=upper;
+  left=l;
+  type=TYPE_RANGE;
+}
+
+int RelationSet::gettype() {
+  return type;
+}
+
+void RelationSet::resetassignment(Hashtable *env) {
+  switch(type) {
+  case TYPE_SET:
+    env->remove(left);
+    break;
+  case TYPE_RELATION:
+    env->remove(left);
+    env->remove(right);
+    break;
+  case TYPE_RANGE:
+    env->remove(left);
+    break;
+  }
+}
+
+bool RelationSet::incrementassignment(bitreader *br,Hashtable *env, model *m) {
+  switch(type) {
+  case TYPE_SET: {
+    if (set->gettype()==SET_label) {
+      DomainSet *ds=m->getdomainrelation()->getset(set->getname());
+
+      if (!env->contains(left)) {
+       Element *fele=(Element *)ds->getset()->firstelement();
+       if (fele==NULL)
+         return false;
+       env->put(left,fele);
+       /*      if (tleft!=NULL) {
+         assert(tleft->getnumlabels()==ele->getnumparams());
+         for (int i=0;i<tleft->getnumlabels();i++) {
+           env->put(tleft->getlabel(i)->label(),ele->paramvalue(i));
+         }
+         }*/
+       return true;
+      }
+      Element *ele=(Element *)env->get(left);
+      Element *nextele=(Element *)ds->getset()->getnextelement(ele);
+      if (nextele==NULL)
+       return false;
+      else {
+       /*      if (tleft!=NULL) {
+         assert(tleft->getnumlabels()==nextele->getnumparams());
+         for (int i=0;i<tleft->getnumlabels();i++) {
+           env->put(tleft->getlabel(i)->label(),nextele->paramvalue(i));
+         }
+         }*/
+       env->put(left,nextele);
+       return true;
+      }
+    } else if(set->gettype()==SET_literal) {
+
+      if (!env->contains(left)) {
+       Literal *l=set->getliteral(0);
+       switch(l->gettype()) {
+       case LITERAL_NUMBER:
+         env->put(left,new Element(l->number()));
+         break;
+       case LITERAL_TOKEN:
+         env->put(left,new Element(l->token()));
+         break;
+       }
+       return true;
+      }
+      Element *ele=(Element *)env->get(left);
+      for(int j=0;j<set->getnumliterals();j++) {
+       Literal *l=set->getliteral(j);
+       switch(l->gettype()) {
+       case LITERAL_NUMBER:
+         if(ele->isnumber()&&
+           ele->intvalue()==l->number()) {
+           if ((j+1)<set->getnumliterals()) {
+             env->put(left,new Element(set->getliteral(j+1)->number()));
+             delete(ele);
+             return true;
+           }
+           else return false;
+         }
+       case LITERAL_TOKEN:
+         if((ele->type()==ELEMENT_TOKEN)&&
+           equivalentstrings(ele->gettoken(),l->token())) {
+           if ((j+1)<set->getnumliterals()) {
+             env->put(left,new Element(set->getliteral(j+1)->token()));
+             delete(ele);
+             return true;
+           }
+           else return false;
+         }
+       }
+      }
+    }
+  }
+  case TYPE_RELATION: {
+    DRelation *dr=m->getdomainrelation()->getrelation(set->getname());
+    Element *eleleft=(Element *)env->get(left);
+    Element *eleright=(Element *)env->get(right);
+    if ((eleleft==NULL)||(eleright==NULL)) {
+      if((eleleft!=NULL)||(eleright!=NULL)) {
+       printf("ERROR in TYPE_RELATION in processabstract.cc\n");
+       exit(-1);
+      }
+      Tuple t=dr->getrelation()->firstelement();
+      if (t.isnull())
+       return false;
+      env->put(left,t.left);
+      env->put(right,t.right);
+      /*      if (tleft!=NULL) {
+       assert(tleft->getnumlabels()==((Element *)t.left)->getnumparams());
+       for (int i=0;i<tleft->getnumlabels();i++) {
+         env->put(tleft->getlabel(i)->label(),((Element *)t.left)->paramvalue(i));
+       }
+       }*/
+      /*      if (tright!=NULL) {
+       assert(tright->getnumlabels()==((Element *)t.right)->getnumparams());
+       for (int i=0;i<tright->getnumlabels();i++) {
+         env->put(tright->getlabel(i)->label(),((Element *)t.right)->paramvalue(i));
+       }
+       }*/
+
+      return true;
+    }
+    Tuple nextele=dr->getrelation()->getnextelement(eleleft,eleright);
+    if (nextele.isnull())
+      return false;
+    else {
+      env->put(left,nextele.left);
+      env->put(right,nextele.right);
+      /*      if (tleft!=NULL) {
+       assert(tleft->getnumlabels()==((Element *)nextele.left)->getnumparams());
+       for (int i=0;i<tleft->getnumlabels();i++) {
+         env->put(tleft->getlabel(i)->label(),((Element *)nextele.left)->paramvalue(i));
+       }
+       }*/
+      /*      if (tright!=NULL) {
+       assert(tright->getnumlabels()==((Element *)nextele.right)->getnumparams());
+       for (int i=0;i<tright->getnumlabels();i++) {
+         env->put(tright->getlabel(i)->label(),((Element *)nextele.right)->paramvalue(i));
+       }
+       }*/
+      return true;
+    }
+  }
+  case TYPE_RANGE: {
+
+    if (!env->contains(left)) {
+      Element *lowerele=(Element *)evaluateexpr(m,lower,env,true,true);
+      env->put(left,lowerele);
+      return true;
+    }
+    Element *val=(Element *)env->get(left);
+    Element *upperele=evaluateexpr(m,upper,env,true,true);
+    if (val->intvalue()>=upperele->intvalue()) {
+      delete(upperele);
+      return false;
+    } else {
+      Element *nval=new Element(val->intvalue()+1);
+      env->put(left,nval);
+      delete(val);
+      return true;
+    }
+  }
+  }
+}
+
+bool RelationSet::incrementassignment(processconcrete *pc,Hashtable *env, model *m) {
+  switch(type) {
+  case TYPE_SET: {
+    if (set->gettype()==SET_label) {
+      DomainSet *ds=m->getdomainrelation()->getset(set->getname());
+
+      if (!env->contains(left)) {
+       Element *fele=(Element *)ds->getset()->firstelement();
+       if (fele==NULL)
+         return false;
+       env->put(left,fele);
+       /*      if (tleft!=NULL) {
+         assert(tleft->getnumlabels()==ele->getnumparams());
+         for (int i=0;i<tleft->getnumlabels();i++) {
+           env->put(tleft->getlabel(i)->label(),ele->paramvalue(i));
+         }
+         }*/
+       return true;
+      }
+      Element *ele=(Element *)env->get(left);
+      Element *nextele=(Element *)ds->getset()->getnextelement(ele);
+      if (nextele==NULL)
+       return false;
+      else {
+       /*      if (tleft!=NULL) {
+         assert(tleft->getnumlabels()==nextele->getnumparams());
+         for (int i=0;i<tleft->getnumlabels();i++) {
+           env->put(tleft->getlabel(i)->label(),nextele->paramvalue(i));
+         }
+         }*/
+       env->put(left,nextele);
+       return true;
+      }
+    } else if(set->gettype()==SET_literal) {
+
+      if (!env->contains(left)) {
+       Literal *l=set->getliteral(0);
+       switch(l->gettype()) {
+       case LITERAL_NUMBER:
+         env->put(left,new Element(l->number()));
+         break;
+       case LITERAL_TOKEN:
+         env->put(left,new Element(l->token()));
+         break;
+       }
+       return true;
+      }
+      Element *ele=(Element *)env->get(left);
+      for(int j=0;j<set->getnumliterals();j++) {
+       Literal *l=set->getliteral(j);
+       switch(l->gettype()) {
+       case LITERAL_NUMBER:
+         if(ele->isnumber()&&
+           ele->intvalue()==l->number()) {
+           if ((j+1)<set->getnumliterals()) {
+             env->put(left,new Element(set->getliteral(j+1)->number()));
+             delete(ele);
+             return true;
+           }
+           else return false;
+         }
+       case LITERAL_TOKEN:
+         if((ele->type()==ELEMENT_TOKEN)&&
+           equivalentstrings(ele->gettoken(),l->token())) {
+           if ((j+1)<set->getnumliterals()) {
+             env->put(left,new Element(set->getliteral(j+1)->token()));
+             delete(ele);
+             return true;
+           }
+           else return false;
+         }
+       }
+      }
+    }
+  }
+  case TYPE_RELATION: {
+    DRelation *dr=m->getdomainrelation()->getrelation(set->getname());
+    Element *eleleft=(Element *)env->get(left);
+    Element *eleright=(Element *)env->get(right);
+    if ((eleleft==NULL)||(eleright==NULL)) {
+      if((eleleft!=NULL)||(eleright!=NULL)) {
+       printf("ERROR in TYPE_RELATION in processabstract.cc\n");
+       exit(-1);
+      }
+      Tuple t=dr->getrelation()->firstelement();
+      if (t.isnull())
+       return false;
+      env->put(left,t.left);
+      env->put(right,t.right);
+      /*      if (tleft!=NULL) {
+       assert(tleft->getnumlabels()==((Element *)t.left)->getnumparams());
+       for (int i=0;i<tleft->getnumlabels();i++) {
+         env->put(tleft->getlabel(i)->label(),((Element *)t.left)->paramvalue(i));
+       }
+       }*/
+      /*      if (tright!=NULL) {
+       assert(tright->getnumlabels()==((Element *)t.right)->getnumparams());
+       for (int i=0;i<tright->getnumlabels();i++) {
+         env->put(tright->getlabel(i)->label(),((Element *)t.right)->paramvalue(i));
+       }
+       }*/
+
+      return true;
+    }
+    Tuple nextele=dr->getrelation()->getnextelement(eleleft,eleright);
+    if (nextele.isnull())
+      return false;
+    else {
+      env->put(left,nextele.left);
+      env->put(right,nextele.right);
+      /*      if (tleft!=NULL) {
+       assert(tleft->getnumlabels()==((Element *)nextele.left)->getnumparams());
+       for (int i=0;i<tleft->getnumlabels();i++) {
+         env->put(tleft->getlabel(i)->label(),((Element *)nextele.left)->paramvalue(i));
+       }
+       }*/
+      /*      if (tright!=NULL) {
+       assert(tright->getnumlabels()==((Element *)nextele.right)->getnumparams());
+       for (int i=0;i<tright->getnumlabels();i++) {
+         env->put(tright->getlabel(i)->label(),((Element *)nextele.right)->paramvalue(i));
+       }
+       }*/
+      return true;
+    }
+  }
+  case TYPE_RANGE: {
+
+    if (!env->contains(left)) {
+      env->put(left,pc->evaluateexpr((CAElementexpr *)lower, env));
+      return true;
+    }
+    Element *val=(Element *)env->get(left);
+    Element *upperele=pc->evaluateexpr((CAElementexpr *)upper,env);
+    if (val->intvalue()>=upperele->intvalue()) {
+      delete(upperele);
+      return false;
+    } else {
+      Element *nval=new Element(val->intvalue()+1);
+      env->put(left,nval);
+      delete(val);
+      return true;
+    }
+  }
+  }
+}
+
+
+/* increments the value of "left" and returns "false" if this is not possible.
+   When this method is called for the first time, it simply initializes
+   the value of the quantifier ("left") */
+bool RelationSet::incrementassignment(Hashtable *env, model *m) {
+  switch(type) {
+  case TYPE_SET: {
+    if (set->gettype()==SET_label) {
+      DomainSet *ds=m->getdomainrelation()->getset(set->getname());
+
+      Element *ele=NULL;
+      if (!env->contains(left)) {
+       ele=(Element *)ds->getset()->firstelement();
+       if (ele==NULL)
+         return false;
+       env->put(left,ele);
+       /*      if (tleft!=NULL) {
+         assert(tleft->getnumlabels()==ele->getnumparams());
+         for (int i=0;i<tleft->getnumlabels();i++) {
+           env->put(tleft->getlabel(i)->label(),ele->paramvalue(i));
+         }
+         }*/
+       return true;
+      }
+
+      ele=(Element *) env->get(left);
+      Element *nextele=(Element *)ds->getset()->getnextelement(ele);
+      if (nextele==NULL)
+       return false;
+      else {
+       /*      if (tleft!=NULL) {
+         assert(tleft->getnumlabels()==nextele->getnumparams());
+         for (int i=0;i<tleft->getnumlabels();i++) {
+           env->put(tleft->getlabel(i)->label(),nextele->paramvalue(i));
+         }
+         }*/
+       env->put(left,nextele);
+       return true;
+      }
+    }
+  }
+  }
+}
+
+
+// prints the quantifier and its current state
+void RelationSet::print(Hashtable *env, model *m)
+{
+  switch(type) {
+  case TYPE_SET: {
+    if (set->gettype()==SET_label) 
+      {
+       printf("%s=", left);
+       DomainSet *ds=m->getdomainrelation()->getset(set->getname());
+       Element *ele = (Element *) env->get(left);
+       ele->print();
+       printf("\n");
+      }
+  }}
+}
diff --git a/Repair/RepairInterpreter/processabstract.h b/Repair/RepairInterpreter/processabstract.h
new file mode 100755 (executable)
index 0000000..3979245
--- /dev/null
@@ -0,0 +1,86 @@
+// evaluates model definition rules
+
+#ifndef PROCESSABSTRACT_H
+#define PROCESSABSTRACT_H
+#include "classlist.h"
+
+
+Element * evaluateexpr(model *m, AElementexpr *ee, Hashtable *env,bool enforcetyping,bool compute);
+
+
+
+class processabstract {
+ public:
+  processabstract(model *m);
+  void processrule(Rule *r);
+  void setclean();
+  void printstats();
+  bool dirtyflagstatus();
+  ~processabstract();
+  void processrule(Rule *r, Element *ele, char *set);
+ private:
+  bool evaluatestatementa(Statementa *sa, Hashtable *env);
+  void satisfystatementb(Statementb *sb, Hashtable *env);
+  model * globalmodel;
+  bool dirtyflag;
+  bitreader * br;
+};
+
+
+
+
+/* A RelationSet keeps the current state of a quantifier. 
+   There are three types of RelationSet's:
+   TYPE_SET: "for left in set"
+   TYPE_RELATION: "for <left,right> in set"
+   TYPE_RANGE: "for left=lower..upper */
+#define TYPE_SET 1
+#define TYPE_RELATION 2
+#define TYPE_RANGE 3
+
+class RelationSet {
+ public:
+  RelationSet(Set *s, char *l, Type *tl);
+  RelationSet(Set *s, char *l, Type *tl, char *r, Type *tr);
+  RelationSet(char *l,AElementexpr *lower,AElementexpr*upper);
+  int gettype();
+  bool incrementassignment(bitreader *br,Hashtable *env, model *m);
+  bool incrementassignment(Hashtable *env, model *m);
+  bool incrementassignment(processconcrete *pc,Hashtable *env, model *m);
+  void resetassignment(Hashtable *env);
+
+  void print(Hashtable *env, model *m);  // prints the quantifier and its current state
+
+  AElementexpr *lower,*upper;
+  char *left,*right;
+  Type *tleft,*tright;
+  /* char's are not the responsibility of this class to dispose of*/
+  int type;
+  Set *set;
+};
+
+
+
+
+// Keeps the current state of the quantifiers of a given rule or constraint
+class State {
+ public:
+  State(Rule *r, Hashtable *h);
+  State(Constraint *c, Hashtable *h);
+  ~State();
+  bool initializestate(bitreader *br, model *m);
+  bool increment(bitreader *br, model *m);
+  bool initializestate(model *m);
+  bool increment(model *m);
+
+  bool initializestate(processconcrete*, model *m);
+  bool increment(processconcrete*, model *m);
+
+  void print(model *m);
+  
+  Hashtable *env;
+  RelationSet **relset;
+  int numrelset;
+  
+};
+#endif
diff --git a/Repair/RepairInterpreter/processconcrete.cc b/Repair/RepairInterpreter/processconcrete.cc
new file mode 100755 (executable)
index 0000000..72af173
--- /dev/null
@@ -0,0 +1,244 @@
+#include <stdlib.h>
+#include <assert.h>
+#include "processconcrete.h"
+#include "processabstract.h"
+#include "amodel.h"
+#include "omodel.h"
+#include "dmodel.h"
+#include "cmodel.h"
+#include "Hashtable.h"
+#include "element.h"
+#include "common.h"
+#include "bitreader.h"
+#include "bitwriter.h"
+#include "model.h"
+#include "set.h"
+#include "Relation.h"
+static int concretecheck=0;
+static int concretetrigger=0;
+
+processconcrete::processconcrete(model *m) {
+  globalmodel=m;
+  bw=new bitwriter(globalmodel,m->gethashtable());
+  br=new bitreader(globalmodel,m->gethashtable());
+}
+
+void processconcrete::printstats() {
+  printf("Concretization Rules Checked: %d Triggered: %d\n",concretecheck,concretetrigger);
+}
+
+
+void processconcrete::processrule(Rule *r) {
+  State *st=new State(r,globalmodel->gethashtable());
+  if (st->initializestate(this, globalmodel)) {
+    while(true) {
+      concretecheck++;
+      if (evaluatestatementa(r->getstatementa(),st->env)) {
+       concretetrigger++;
+       satisfystatementb((CStatementb *)r->getstatementb(),st->env);
+      }
+
+      if (!st->increment(this, globalmodel))
+       break; /* done */
+    }
+  }
+  delete(st);
+}
+
+processconcrete::~processconcrete() {
+  delete(br);
+}
+
+bool processconcrete::evaluatestatementa(Statementa *sa, Hashtable *env) {
+  switch(sa->gettype()) {
+  case STATEMENTA_OR:
+    return evaluatestatementa(sa->getleft(),env)||evaluatestatementa(sa->getright(),env);
+  case STATEMENTA_AND:
+    return evaluatestatementa(sa->getleft(),env)&&evaluatestatementa(sa->getright(),env);
+  case STATEMENTA_NOT:
+    return !evaluatestatementa(sa->getleft(),env);
+  case STATEMENTA_EQUALS: {
+    Element *left=evaluateexpr((CAElementexpr *)sa->getleftee(),env);
+    Element *right=evaluateexpr((CAElementexpr *)sa->getrightee(),env);
+    bool tvalue=left->equals(right);
+    delete(left);
+    delete(right);
+    return tvalue;
+  }
+  case STATEMENTA_LT: {
+    Element *left=evaluateexpr((CAElementexpr *)sa->getleftee(),env);
+    Element *right=evaluateexpr((CAElementexpr *)sa->getrightee(),env);
+    if (!left->isnumber()||
+       !right->isnumber()) {
+      printf("Bad lt compare\n");
+      exit(-1);
+    }
+    bool tvalue=left->intvalue()<right->intvalue();
+    delete(left);
+    delete(right);
+    return tvalue;
+  }
+  case STATEMENTA_TRUE:
+    return true;
+  }
+}
+
+void processconcrete::satisfystatementb(CStatementb *sb, Hashtable *env) {
+  Element * rvalue=evaluateexpr((CAElementexpr *)sb->getright(),env);
+  Element *index=NULL;
+  if (sb->gettype()==CSTATEMENTB_ARRAYASSIGN)
+    index=evaluateexpr((CAElementexpr *)sb->getleft(),env);
+  Field *field=sb->getfield();
+  Element *src=evaluateexpr(sb->getexpr(),env);
+  bw->writefieldorarray(src,field,index,rvalue);
+  delete(rvalue);
+  if (index!=NULL)
+    delete(index);
+  delete(src);
+}
+
+Element * processconcrete::evaluateexpr(Expr *e, Hashtable *env) {
+  switch(e->gettype()) {
+  case EXPR_LABEL:
+    return new Element((Element *)env->get(e->getlabel()->label()));
+  case EXPR_FIELD: {
+    Element *old=evaluateexpr(e->getexpr(),env);
+    Element *newe=br->readfieldorarray(evaluateexpr(e->getexpr(),env),e->getfield(),NULL);
+    delete(old);
+    return newe;
+  }
+  case EXPR_CAST: {
+    Element *old=evaluateexpr(e->getexpr(),env);
+    char *type=e->getcasttype();
+    structure *st=globalmodel->getstructure(type);
+    Element *newe=new Element(old->getobject(),st);
+    delete(old);
+    return newe;
+  }
+  case EXPR_ARRAY: {
+    Element *old=evaluateexpr(e->getexpr(),env);
+    Element *index=evaluateexpr(e->getindex(),env);
+    Element *newe=br->readfieldorarray(evaluateexpr(e->getexpr(),env),e->getfield(),index);
+    delete(old);
+    delete(index);
+    return newe;
+  }
+  }
+}
+
+Element * processconcrete::evaluateexpr(CAElementexpr *ee, Hashtable *env) {
+  switch(ee->gettype()) {
+  case CAELEMENTEXPR_LABEL:
+    {
+      return new Element((Element *)env->get(ee->getlabel()->label()));
+    }
+  case CAELEMENTEXPR_NULL:
+    {
+      return new Element();
+    }
+  case CAELEMENTEXPR_SUB:
+    {
+      CAElementexpr *left=ee->getleft();
+      CAElementexpr *right=ee->getright();
+      Element *leftval=evaluateexpr(left,env);
+      Element *rightval=evaluateexpr(right,env);
+      Element *diff=new Element(leftval->intvalue()-rightval->intvalue());
+      delete(leftval);delete(rightval);
+      return diff;
+    }
+  case CAELEMENTEXPR_ADD:
+    {
+      CAElementexpr *left=ee->getleft();
+      CAElementexpr *right=ee->getright();
+      Element *leftval=evaluateexpr(left,env);
+      Element *rightval=evaluateexpr(right,env);
+      Element *sum=new Element(leftval->intvalue()+rightval->intvalue());
+      delete(leftval);delete(rightval);
+      return sum;
+    }
+  case CAELEMENTEXPR_MULT:
+    {
+      CAElementexpr *left=ee->getleft();
+      CAElementexpr *right=ee->getright();
+      Element *leftval=evaluateexpr(left,env);
+      Element *rightval=evaluateexpr(right,env);
+      Element *diff=new Element(leftval->intvalue()*rightval->intvalue());
+      delete(leftval);delete(rightval);
+      return diff;
+    }
+  case CAELEMENTEXPR_DIV:
+    {
+      CAElementexpr *left=ee->getleft();
+      CAElementexpr *right=ee->getright();
+      Element *leftval=evaluateexpr(left,env);
+      Element *rightval=evaluateexpr(right,env);
+      Element *diff=new Element(leftval->intvalue()/rightval->intvalue());
+      delete(leftval);delete(rightval);
+      return diff;
+    }
+  case CAELEMENTEXPR_LIT:
+    {
+      Literal *l=ee->getliteral();
+      switch(l->gettype()) {
+      case LITERAL_NUMBER:
+       return new Element(l->number());
+      case LITERAL_TOKEN:
+       return new Element(copystr(l->token()));
+      case LITERAL_BOOL:
+       return new Element(l->getbool());
+      default:
+       printf("ERROR with lit type\n");
+       exit(-1);
+      }
+    }
+  case CAELEMENTEXPR_SIZEOF:
+    {
+    Setexpr * setexpr=ee->getsetexpr();
+    switch(setexpr->gettype()) {
+    case SETEXPR_LABEL:
+      return new Element(globalmodel->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->size());
+    case SETEXPR_REL: {
+      Element *key=(Element *)env->get(setexpr->getlabel()->label());
+      WorkSet *ws=globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(key);
+      if (ws==NULL)
+       return new Element(0);
+      else
+       return new Element(ws->size());
+    }
+    case SETEXPR_INVREL: {
+      Element *key=(Element *)env->get(setexpr->getlabel()->label());
+      WorkSet *ws=globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(key);
+      if (ws==NULL)
+       return new Element(0);
+      else
+       return new Element(ws->size());
+    }
+    }
+    }
+  case CAELEMENTEXPR_ELEMENT: {
+    Element *index=evaluateexpr(ee->getleft(),env);
+    int ind=index->intvalue();
+    delete(index);
+
+    Setexpr * setexpr=ee->getsetexpr();
+    switch(setexpr->gettype()) {
+    case SETEXPR_LABEL:
+      return new Element((Element *)globalmodel->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->getelement(ind));
+    case SETEXPR_REL: {
+      Element *key=(Element *)env->get(setexpr->getlabel()->label());
+      return new Element((Element *)globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(key)->getelement(ind));
+    }
+    case SETEXPR_INVREL: {
+      Element *key=(Element *)env->get(setexpr->getlabel()->label());
+      return new Element((Element *)globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(key)->getelement(ind));
+    }
+    }
+  }
+  case CAELEMENTEXPR_RELATION:
+    {
+      Element *e=evaluateexpr(ee->getleft(),env);
+      Element *r=(Element *)globalmodel->getdomainrelation()->getrelation(ee->getrelation()->getname())->getrelation()->getobj(e);
+      return new Element(r);
+    }
+  }
+}
diff --git a/Repair/RepairInterpreter/processconcrete.h b/Repair/RepairInterpreter/processconcrete.h
new file mode 100755 (executable)
index 0000000..6a06bcc
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef PROCESSCONCRETE_H
+#define PROCESSCONCRETE_H
+#include "classlist.h"
+
+class processconcrete {
+ public:
+  processconcrete(model *m);
+  void processrule(Rule *r);
+  ~processconcrete();
+  Element * evaluateexpr(CAElementexpr *ee, Hashtable *env);
+  void printstats();
+ private:
+  Element * evaluateexpr(Expr *e, Hashtable *env);
+  bool evaluatestatementa(Statementa *sa, Hashtable *env);
+  void satisfystatementb(CStatementb *sb, Hashtable *env);
+  model * globalmodel;
+  bitwriter * bw;
+  bitreader * br;
+};
+
+
+#endif
diff --git a/Repair/RepairInterpreter/processobject.cc b/Repair/RepairInterpreter/processobject.cc
new file mode 100755 (executable)
index 0000000..b917f4a
--- /dev/null
@@ -0,0 +1,557 @@
+// evaluates constraints in the ICL
+
+#include <stdlib.h>
+#include "processobject.h"
+#include "processabstract.h"
+#include "omodel.h"
+#include "Hashtable.h"
+#include "element.h"
+#include "model.h"
+#include "dmodel.h"
+#include "set.h"
+#include "Relation.h"
+#include "repair.h"
+#include "normalizer.h"
+#include "Action.h"
+
+static int modelcheck=0;
+static int modeltrigger=0;
+
+processobject::processobject(model *m) {
+  globalmodel=m;
+  repair=m->getrepair();
+}
+
+void processobject::printstats() {
+  printf("Models Rules Checked: %d Triggered: %d\n",modelcheck,modeltrigger);
+}
+
+// evaluates the truth value of the given predicate
+int processobject::processpredicate(Predicate *p, Hashtable *env) {
+  switch(p->gettype()) {
+  case PREDICATE_LT: {
+    Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel);
+    Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel);
+    if (right==NULL) {
+      return PFAIL;
+    }
+    if (left==NULL) {
+      delete(right);
+      return false;
+    }
+    int t=left->intvalue()<right->intvalue();
+    delete(right);
+    return t;
+  }
+  case PREDICATE_LTE: {
+    Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel);
+    Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel);
+    if (right==NULL) {return PFAIL;}
+    if (left==NULL) {
+      delete(right);
+      return false;
+    }
+    bool t=left->intvalue()<=right->intvalue();
+    delete(right);
+    return t;
+  }
+  case PREDICATE_EQUALS: {
+    Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel);
+    Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel);
+    if (right==NULL) {return PFAIL;}
+    if (left==NULL) {
+      delete(right);
+      return false;
+    }
+    /* Can have more than just int's here */
+    bool t=left->equals(right); /*Just ask the equals method*/
+    delete(right);
+    return t;
+  }
+  case PREDICATE_GTE: {
+    Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel);
+    Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel);
+    if (right==NULL) {return PFAIL;}
+    if (left==NULL) {
+      delete(right);
+      return false;
+    }
+    bool t=left->intvalue()>=right->intvalue();
+    delete(right);
+    return t;
+  }
+  case PREDICATE_GT: {
+    Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel);
+    Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel);
+    if (right==NULL) {return PFAIL;}
+    if (left==NULL) {
+      delete(right);
+      return false;
+    }
+    bool t=left->intvalue()>right->intvalue();
+    delete(right);
+    return t;
+  }
+  case PREDICATE_SET: {
+    Label *label=p->getlabel();
+    Setexpr * setexpr=p->getsetexpr();
+    Element *labelele=(Element *) env->get(label->label());
+    switch(setexpr->gettype()) {
+      case SETEXPR_LABEL:
+       return globalmodel->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->contains(labelele);
+      case SETEXPR_REL:
+       return globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(setexpr->getlabel()->label())->contains(labelele);
+      case SETEXPR_INVREL:
+       return globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(setexpr->getlabel()->label())->contains(labelele);
+    }
+  }
+  case PREDICATE_EQ1:
+  case PREDICATE_GTE1: {
+    int setsize;
+    Setexpr * setexpr=p->getsetexpr();
+    switch(setexpr->gettype()) {
+    case SETEXPR_LABEL:
+      setsize=globalmodel->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->size();
+      break;
+    case SETEXPR_REL: {
+      Element *key=(Element *)env->get(setexpr->getlabel()->label());
+      WorkSet *ws=globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(key);
+      if (ws!=NULL)
+       setsize=ws->size();
+      else
+       setsize=0;
+      break;
+    }
+    case SETEXPR_INVREL: {
+      Element *key=(Element *)env->get(setexpr->getlabel()->label());
+      WorkSet *ws=globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(key);
+      if (ws!=NULL)
+       setsize=ws->size();
+      else
+       setsize=0;
+      break;
+    }
+    }
+    return ((p->gettype()==PREDICATE_EQ1)&&(setsize==1))||
+      ((p->gettype()==PREDICATE_GTE1)&&(setsize>=1));
+  }
+  }
+}
+
+
+// evaluates the truth value of the given statement
+int processobject::processstatement(Statement *s, Hashtable *env) {
+  switch (s->gettype()) {
+  case STATEMENT_OR: {
+    int l=processstatement(s->getleft(),env);
+    int r=processstatement(s->getright(),env);
+    if (l==PFAIL&&(r==PFAIL||r==PFALSE)) return PFAIL;
+    if ((l==PFAIL||l==PFALSE)&&r==PFAIL) return PFAIL;
+    return l||r;
+  }
+  case STATEMENT_AND: {
+    int l=processstatement(s->getleft(),env);
+    int r=processstatement(s->getright(),env);
+    if (l==PFAIL&&(r==PFAIL||r==PTRUE)) return PFAIL;
+    if (r==PFAIL&&(l==PFAIL||l==PTRUE)) return PFAIL;
+    return l&&r;
+  }
+  case STATEMENT_NOT: {
+    int l=processstatement(s->getleft(),env);
+    if (l==PFAIL) return PFAIL;
+    return !l;
+  }
+  case STATEMENT_PRED:
+    return processpredicate(s->getpredicate(),env);
+  }
+}
+
+
+// returns true if and only if the given constraint is satisfied 
+bool processobject::issatisfied(Constraint *c) 
+{
+  State *st=new State(c,globalmodel->gethashtable());
+  bool satisfied = true;
+  if (st->initializestate(globalmodel))
+    while (true)
+      {      
+       if (c->getstatement()!=NULL)
+         if (processstatement(c->getstatement(),st->env)!=PTRUE) 
+           satisfied = false;
+       if (!st->increment(globalmodel))
+           break;
+      }
+
+  delete(st);
+  return satisfied;
+}
+
+
+
+/* processed the given constraint and if it's not satisfied, 
+   displays a message and tries to repair the constraint 
+   The function returns true only if the constraint was initially
+   satisfied. */
+bool processobject::processconstraint(Constraint *c) {
+  State *st=new State(c,globalmodel->gethashtable());
+  bool clean=true;
+  if (st->initializestate(globalmodel)) {
+    while(true) {
+      if (c->getstatement()!=NULL) {
+       modelcheck++;
+       if (processstatement(c->getstatement(),st->env)!=PTRUE) {
+         modeltrigger++;
+#ifdef TOOL
+         printf("Constraint violation\n");
+         printf("   Violated constraint: "); c->print();
+         printf("   State for which it was violated: "); st->print(globalmodel);
+         printf("  Current value(s):");
+         c->getstatement()->print_sets(st->env, globalmodel);
+         printf("\n\n");
+         return false;
+#endif
+
+#ifdef REPAIR
+         printf("Repairing...\n");
+         if (c->getcrash()) {
+           printf("Fatal program error violating special constraint.\n");
+           exit(-1);
+         }
+         repair->repairconstraint(c,this,st->env);
+         clean=false;
+#endif
+       }
+      }
+
+      if (!st->increment(globalmodel))
+       break; /* done */
+    }
+  }
+  delete(st);
+  return clean;
+}
+
+
+
+/* breaks the given constraint by invalidating each of its satisfied sentences */
+void processobject::breakconstraint(Constraint *c)
+{  
+#ifdef DEBUGMESSAGES
+  printf("Constraint to be broken: ");
+  c->print();
+  printf("\n");
+  fflush(NULL);
+#endif
+
+  // first, get get the constraint in normal form
+  NormalForm *nf = globalmodel->getnormalform(c);
+
+  // for each CoerceSentence in nf, find if it's satisfied. If so, break it.
+  for (int i=0; i<nf->getnumsentences(); i++)
+    {
+#ifdef DEBUGMESSAGES
+      printf("In processobject::breakconstraint, i=%d \n", i);
+      fflush(NULL);
+#endif
+
+      CoerceSentence *s = nf->getsentence(i);
+      
+      // find if s is satisfied
+      bool satisfied = true;
+      State *st = new State(c, globalmodel->gethashtable());
+      if (st->initializestate(globalmodel))
+       while(true) 
+         {
+           if (!s->issatisfied(this, st->env))
+             satisfied=false;
+
+           if (!st->increment(globalmodel))
+             break;
+         }  
+      delete(st);
+      
+
+      // if s is satisfied, then break it
+
+      if (satisfied)
+       {
+         // first, select an arbitrary binding, for ex. the first one
+         st = new State(c, globalmodel->gethashtable());
+         
+         if (st->initializestate(globalmodel))
+           {
+#ifdef DEBUGMESSAGES
+             printf("numpredicates = %d\n", s->getnumpredicates());
+#endif
+             
+             for (int j=0; j<s->getnumpredicates(); j++)
+               {
+                 CoercePredicate *cp = s->getpredicate(j);
+                 // break this predicate with probability prob_breakpredicate
+                 if (random()<model::prob_breakpredicate*RAND_MAX)
+                   {
+#ifdef DEBUGMESSAGES
+                     printf("po::breakconstraint:  We break predicate %d\n",j);
+                     fflush(NULL);
+#endif
+                     
+                     Action *action = repair->findbreakaction(cp);
+                     action->breakpredicate(st->env, cp);
+                     
+#ifdef DEBUGMESSAGES
+                     printf("After action->breakpredicate was called\n");
+                     fflush(NULL);
+#endif
+                   }
+               }
+           }
+         
+         delete(st);
+       }
+    }
+}
+
+
+
+/* satisfies the given satisfied contraint in another way */
+void processobject::modifyconstraint(Constraint *c)
+{
+#ifdef DEBUGMESSAGES
+  printf("Constraint to be modified: ");
+  c->print();
+  printf("\n");
+  fflush(NULL);
+#endif
+
+  // first, get the constraint in normal form
+  NormalForm *nf = globalmodel->getnormalform(c);
+
+  /* for each CoerceSentence in nf, find if it's satisfied. 
+     If it's satisfied, we break it with probability prob_breaksatisfiedsentence;
+     If it's not satisfied, we repair it with probability prob_repairbrokensentence
+  */
+
+  bool still_valid = false;
+
+  for (int i=0; i<nf->getnumsentences(); i++)
+    {
+#ifdef DEBUGMESSAGES
+      printf("In processobject::modifyconstraint, i=%d \n", i);
+      fflush(NULL);
+#endif
+
+      CoerceSentence *s = nf->getsentence(i);
+      
+      // find if s is satisfied
+      bool satisfied = true;
+      State *st = new State(c, globalmodel->gethashtable());
+      if (st->initializestate(globalmodel))
+       while(true) 
+         {
+           if (!s->issatisfied(this, st->env))
+             satisfied=false;
+
+           if (!st->increment(globalmodel))
+             break;
+         }  
+      delete(st);
+      
+      // if s is satisfied, then break it
+      if  (satisfied)
+       if (random()<model::prob_breaksatisfiedsentence*RAND_MAX) // then break it
+         {
+           // first, select an arbitrary binding, for ex. the first one
+           st = new State(c, globalmodel->gethashtable());
+           
+           if (st->initializestate(globalmodel))
+             {
+               for (int j=0; j<s->getnumpredicates(); j++)
+                 {
+                   CoercePredicate *cp = s->getpredicate(j);
+                   // break this predicate with probability prob_breakpredicate
+                   if (random()<model::prob_breakpredicate*RAND_MAX)
+                     {
+#ifdef DEBUGMESSAGES
+                       printf("po::modifyconstraint:  We break predicate %d\n",j);
+                       fflush(NULL);
+#endif
+                       
+                       Action *action = repair->findbreakaction(cp);
+                       action->breakpredicate(st->env, cp);
+                       
+#ifdef DEBUGMESSAGES
+                       printf("After action->modifypredicate was called\n");
+                       fflush(NULL);
+#endif
+                     }
+                 }
+             }
+           delete(st);
+         }
+       else still_valid = true;
+      else // if not satisfied, then repair it with prob_repairbrokensentence
+       if (random()<model::prob_repairbrokensentence)
+         {
+           // first, select an arbitrary binding, for ex. the first one
+           st = new State(c, globalmodel->gethashtable());
+           
+           if (st->initializestate(globalmodel))
+             {
+               for (int j=0; j<s->getnumpredicates(); j++)
+                 {
+                   CoercePredicate *cp = s->getpredicate(j);
+                   Action *action = repair->findrepairaction(cp);
+                   action->repairpredicate(st->env, cp);
+                       
+#ifdef DEBUGMESSAGES
+                       printf("After action->repairpredicate was called\n");
+                       fflush(NULL);
+#endif
+                 }
+             }
+           
+           delete(st);     
+           still_valid = true;
+         }
+    }
+
+  if (!still_valid) // if all sentences are broken, repair the first one
+    {
+      CoerceSentence *saux = nf->getsentence(0);
+      // first, select an arbitrary binding, for ex. the first one
+      State *st = new State(c, globalmodel->gethashtable());
+      
+      if (st->initializestate(globalmodel))
+       {
+         for (int j=0; j<saux->getnumpredicates(); j++)
+           {
+             CoercePredicate *cp = saux->getpredicate(j);
+             Action *action = repair->findrepairaction(cp);
+             action->repairpredicate(st->env, cp);
+             
+#ifdef DEBUGMESSAGES
+             printf("After action->repairpredicate was called\n");
+             fflush(NULL);
+#endif
+           }
+       }
+      
+      delete(st);          
+    }
+  
+}
+
+
+processobject::~processobject() {
+}
+
+
+// computes ve = V.R
+Element * evaluatevalueexpr(Valueexpr *ve, Hashtable *env, model *m) {
+  Element *e=NULL;
+  if (ve->gettype()==0) {
+    e=(Element *) env->get(ve->getlabel()->label());
+  } else
+    e=evaluatevalueexpr(ve->getvalueexpr(),env,m);
+  if (e==NULL)
+    return e;
+  if (ve->getinverted())
+    return (Element *)m->getdomainrelation()->getrelation(ve->getrelation()->getname())->getrelation()->invgetobj(e);
+  else
+    return (Element *)m->getdomainrelation()->getrelation(ve->getrelation()->getname())->getrelation()->getobj(e);
+}
+
+
+
+// evaluates E = V | number | string | E-E | E+E | E*E | E/E | E.R |size(SE)
+Element * evaluateexpr(Elementexpr *ee, Hashtable *env, model *m) {
+  switch(ee->gettype()) {
+  case ELEMENTEXPR_LABEL: {
+    return new Element((Element *)env->get(ee->getlabel()->label()));
+  }
+  case ELEMENTEXPR_SUB: {
+    Elementexpr *left=ee->getleft();
+    Elementexpr *right=ee->getright();
+    Element *leftval=evaluateexpr(left,env,m);
+    if(leftval==NULL) return NULL;
+    Element *rightval=evaluateexpr(right,env,m);
+    if(rightval==NULL) {delete(leftval);return NULL;}
+    Element *diff=new Element(leftval->intvalue()-rightval->intvalue());
+    delete(leftval);delete(rightval);
+    return diff;
+  }
+  case ELEMENTEXPR_ADD: {
+    Elementexpr *left=ee->getleft();
+    Elementexpr *right=ee->getright();
+    Element *leftval=evaluateexpr(left,env,m);
+    if(leftval==NULL) return NULL;
+    Element *rightval=evaluateexpr(right,env,m);
+    if(rightval==NULL) {delete(leftval);return NULL;}
+    Element *sum=new Element(leftval->intvalue()+rightval->intvalue());
+    delete(leftval);delete(rightval);
+    return sum;
+  }
+  case ELEMENTEXPR_RELATION: {
+    Elementexpr *left=ee->getleft();
+    Relation *rel=ee->getrelation();
+    Element *leftval=evaluateexpr(left,env,m);
+    if(leftval==NULL) return NULL;
+    Element *retval=(Element *)m->getdomainrelation()->getrelation(rel->getname())->getrelation()->getobj(leftval);
+    delete(leftval);
+    return new Element(retval);
+  }
+  case ELEMENTEXPR_MULT: {
+    Elementexpr *left=ee->getleft();
+    Elementexpr *right=ee->getright();
+    Element *leftval=evaluateexpr(left,env,m);
+    if(leftval==NULL) return NULL;
+    Element *rightval=evaluateexpr(right,env,m);
+    if(rightval==NULL) {delete(leftval);return NULL;}
+    Element *diff=new Element(leftval->intvalue()*rightval->intvalue());
+    delete(leftval);delete(rightval);
+    return diff;
+  }
+  case ELEMENTEXPR_LIT: {
+    Literal *l=ee->getliteral();
+    switch(l->gettype()) {
+    case LITERAL_NUMBER:
+      return new Element(l->number());
+    case LITERAL_TOKEN:
+      return new Element(copystr(l->token()));
+    default:
+      printf("ERROR with lit type\n");
+      exit(-1);
+    }
+  }
+  /*  case ELEMENTEXPR_PARAM: {
+    Element *ele=evaluateexpr(ee->getleft(),env,m);
+    Element *eec=ele->paramvalue(ee->getliteral()->number());
+    Element *retval=new Element(eec);
+    delete(ele);
+    return eec;
+    }*/ //NO OBJECT PARAMETERS
+  case ELEMENTEXPR_SETSIZE:
+    Setexpr * setexpr=ee->getsetexpr();
+    switch(setexpr->gettype()) {
+    case SETEXPR_LABEL:
+      return new Element(m->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->size());
+    case SETEXPR_REL: {
+      Element *key=(Element *)env->get(setexpr->getlabel()->label());
+      WorkSet *ws=m->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(key);
+      if (ws==NULL)
+       return new Element(0);
+      else
+       return new Element(ws->size());
+    }
+    case SETEXPR_INVREL: {
+      Element *key=(Element *)env->get(setexpr->getlabel()->label());
+      WorkSet *ws=m->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(key);
+      if (ws==NULL)
+       return new Element(0);
+      else
+       return new Element(ws->size());
+    }
+    }
+    break;
+  }
+}
diff --git a/Repair/RepairInterpreter/processobject.h b/Repair/RepairInterpreter/processobject.h
new file mode 100755 (executable)
index 0000000..595433f
--- /dev/null
@@ -0,0 +1,32 @@
+// evaluates constraints in the ICL
+
+
+#ifndef PROCESSOBJECT_H
+#define PROCESSOBJECT_H
+#include "classlist.h"
+
+#define PTRUE 1
+#define PFALSE 0
+#define PFAIL -1
+
+class processobject {
+ public:
+  processobject(model *m);
+  int processpredicate(Predicate *p, Hashtable *env);
+  bool issatisfied(Constraint *c); // returns true iff c is satisfied
+  bool processconstraint(Constraint *c); // evaluates c and if it's not satisfied, calls the repair alg.
+  void breakconstraint(Constraint *c);   // breaks the given constraint by invalidating each of its satisfied sentences
+  void modifyconstraint(Constraint *c);  // modifies the given constraint
+  void setclean();
+  ~processobject();
+  void printstats();
+
+ private:
+  Repair * repair;
+  int processstatement(Statement *s, Hashtable *env);
+  model * globalmodel;
+};
+
+Element * evaluateexpr(Elementexpr *ee, Hashtable *env, model *m);
+Element * evaluatevalueexpr(Valueexpr *ve, Hashtable *env, model *m);
+#endif
diff --git a/Repair/RepairInterpreter/redblack.c b/Repair/RepairInterpreter/redblack.c
new file mode 100755 (executable)
index 0000000..1238b2a
--- /dev/null
@@ -0,0 +1,985 @@
+static char rcsid[]="$Id: redblack.c,v 1.1 2004/05/06 21:16:22 bdemsky Exp $";
+
+/*
+   Redblack balanced tree algorithm
+   Copyright (C) Damian Ivereigh 2000
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version. See the file COPYING for details.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Implement the red/black tree structure. It is designed to emulate
+** the standard tsearch() stuff. i.e. the calling conventions are
+** exactly the same
+*/
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "redblack.h"
+//#include "dmalloc.h"
+
+#define assert(expr)
+#define RB_TRUE 1
+#define RB_FALSE 0
+
+/* Uncomment this if you would rather use a raw sbrk to get memory
+** (however the memory is never released again (only re-used). Can't
+** see any point in using this these days.
+*/
+/* #define USE_SBRK */
+
+enum nodecolour { BLACK, RED };
+
+struct rbnode {
+  struct rbnode *left;         /* Left down */
+  struct rbnode *right;                /* Right down */
+  struct rbnode *up;           /* Up */
+  enum nodecolour colour;              /* Node colour */
+  const void *key;             /* Pointer to user's key (and data) */
+  const void *high;
+  const void *max;
+  void *object;
+};
+
+/* Dummy (sentinel) node, so that we can make X->left->up = X
+** We then use this instead of NULL to mean the top or bottom
+** end of the rb tree. It is a black node.
+*/
+struct rbnode rb_null={&rb_null, &rb_null, &rb_null, BLACK, NULL,NULL,NULL,NULL};
+#define RBNULL (&rb_null)
+
+#if defined(USE_SBRK)
+
+static struct rbnode *rb_alloc();
+static void rb_free(struct rbnode *);
+
+#else
+
+#define rb_alloc() ((struct rbnode *) malloc(sizeof(struct rbnode)))
+#define rb_free(x) (free(x))
+
+#endif
+
+static struct rbnode *rb_traverse(const void *, struct rbtree *);
+static struct rbnode *rb_lookup(const void *low,const void *high, struct rbtree *);
+static void rb_destroy(struct rbnode *,void (*)(void *));
+static void rb_left_rotate(struct rbnode **, struct rbnode *);
+static void rb_right_rotate(struct rbnode **, struct rbnode *);
+static void rb_delete(struct rbnode **, struct rbnode *);
+static void rb_delete_fix(struct rbnode **, struct rbnode *);
+static struct rbnode *rb_successor(const struct rbnode *);
+static struct rbnode *rb_preccessor(const struct rbnode *);
+static void rb_walk(const struct rbnode *, void (*)(const void *, const VISIT, const int, void *), void *, int);
+static RBLIST *rb_openlist(const struct rbnode *);
+static const void *rb_readlist(RBLIST *);
+static void rb_closelist(RBLIST *);
+
+/*
+** OK here we go, the balanced tree stuff. The algorithm is the
+** fairly standard red/black taken from "Introduction to Algorithms"
+** by Cormen, Leiserson & Rivest. Maybe one of these days I will
+** fully understand all this stuff.
+**
+** Basically a red/black balanced tree has the following properties:-
+** 1) Every node is either red or black (colour is RED or BLACK)
+** 2) A leaf (RBNULL pointer) is considered black
+** 3) If a node is red then its children are black
+** 4) Every path from a node to a leaf contains the same no
+**    of black nodes
+**
+** 3) & 4) above guarantee that the longest path (alternating
+** red and black nodes) is only twice as long as the shortest
+** path (all black nodes). Thus the tree remains fairly balanced.
+*/
+
+/*
+ * Initialise a tree. Identifies the comparison routine and any config
+ * data that must be sent to it when called.
+ * Returns a pointer to the top of the tree.
+ */
+struct rbtree * rbinit() {
+  struct rbtree *retval;
+  char c;
+  
+  c=rcsid[0]; /* This does nothing but shutup the -Wall */
+  
+  if ((retval=(struct rbtree *) malloc(sizeof(struct rbtree)))==NULL)
+    return(NULL);
+  
+  retval->rb_root=RBNULL;
+  
+  return(retval);
+}
+       
+void rbdestroy(struct rbtree *rbinfo, void (*free_function)(void *)) {
+  if (rbinfo==NULL)
+    return;
+  
+  if (rbinfo->rb_root!=RBNULL)
+    rb_destroy(rbinfo->rb_root,free_function);
+  
+  free(rbinfo);
+}
+
+const void * rbdelete(const void *key, struct rbtree *rbinfo) {
+  struct rbnode *x;
+  const void *y;
+  
+  if (rbinfo==NULL)
+    return(NULL);
+  
+  x=rb_traverse(key, rbinfo);
+  
+  if (x==RBNULL) {
+    return(NULL);
+  } else {
+    y=x->key;
+    rb_delete(&rbinfo->rb_root, x);
+    
+    return(y);
+  }
+}
+
+void rbwalk(const struct rbtree *rbinfo, void (*action)(const void *, const VISIT, const int, void *), void *arg) {
+  if (rbinfo==NULL)
+    return;
+
+  rb_walk(rbinfo->rb_root, action, arg, 0);
+}
+
+RBLIST * rbopenlist(const struct rbtree *rbinfo) {
+  if (rbinfo==NULL)
+    return(NULL);
+
+  return(rb_openlist(rbinfo->rb_root));
+}
+
+const void * rbreadlist(RBLIST *rblistp) {
+  if (rblistp==NULL)
+    return(NULL);
+
+  return(rb_readlist(rblistp));
+}
+
+void rbcloselist(RBLIST *rblistp) {
+  if (rblistp==NULL)
+    return;
+
+  rb_closelist(rblistp);
+}
+
+/** 
+ * finds an overlapping region with low->high and returns the object associated with
+ * that region 
+ */
+void * rblookup(const void *low,const void *high, struct rbtree *rbinfo) {
+  struct rbnode *x;
+
+  /* If we have a NULL root (empty tree) then just return NULL */
+  if (rbinfo==NULL || rbinfo->rb_root==NULL)
+    return(NULL);
+  
+  x=rb_lookup(low, high, rbinfo);
+  
+  return((x==RBNULL) ? NULL : x->object);
+}
+
+/**
+ * finds an overlapping region with low->high and returns the pair <low, high>
+ */
+struct pair rbfind(const void *low,const void *high, struct rbtree *rbinfo) {
+  struct rbnode *x;
+  struct pair p;
+  /* If we have a NULL root (empty tree) then just return NULL */
+
+  p.low=NULL;
+  p.high=NULL;
+  if (rbinfo==NULL || rbinfo->rb_root==NULL)
+    return p;
+  
+  x=rb_lookup(low, high, rbinfo);
+  if (x!=NULL) {
+    p.low=x->key;
+    p.high=x->high;
+  }
+  return p;
+}
+
+
+/* --------------------------------------------------------------------- */
+
+/* Search for and if not found and insert is true, will add a new
+** node in. Returns a pointer to the new node, or the node found
+*/
+int rbinsert(const void *key, const void * high, void *object,struct rbtree *rbinfo) {
+  struct rbnode *x,*y,*z, *tmp;
+  const void *max;
+  int found=0;
+  
+  y=RBNULL; /* points to the parent of x */
+  x=rbinfo->rb_root;
+  
+  /* walk x down the tree */
+  while(x!=RBNULL && found==0) {
+    y=x;
+    /* printf("key=%s, x->key=%s\n", key, x->key); */
+
+    if (key<x->key)
+      x=x->left;
+    else if (key>x->key)
+      x=x->right;
+    else
+      found=1;
+  }
+  
+  if (found)
+    return RB_FALSE;
+  
+  if ((z=rb_alloc())==NULL) {
+    /* Whoops, no memory */
+    return RB_FALSE;
+  }
+  
+  z->object=object;
+  z->high=high;
+  z->key=key;
+  z->max=high;
+  z->up=y;
+  tmp=y;
+  max=high;
+  while(tmp!=RBNULL) {
+    if (max>tmp->max)
+      tmp->max=max;
+    else
+      max=tmp->max;
+    tmp=tmp->up;
+  }
+
+  if (y==RBNULL) {
+      rbinfo->rb_root=z;
+  } else {
+    if (z->key<y->key)
+      y->left=z;
+    else
+      y->right=z;
+  }
+
+  z->left=RBNULL;
+  z->right=RBNULL;
+  
+  /* colour this new node red */
+  z->colour=RED;
+
+  /* Having added a red node, we must now walk back up the tree balancing
+  ** it, by a series of rotations and changing of colours
+  */
+  x=z;
+  
+  /* While we are not at the top and our parent node is red
+  ** N.B. Since the root node is garanteed black, then we
+  ** are also going to stop if we are the child of the root
+  */
+  
+  while(x != rbinfo->rb_root && (x->up->colour == RED)) {
+    /* if our parent is on the left side of our grandparent */
+    if (x->up == x->up->up->left) {
+      /* get the right side of our grandparent (uncle?) */
+      y=x->up->up->right;
+      if (y->colour == RED) {
+       /* make our parent black */
+       x->up->colour = BLACK;
+       /* make our uncle black */
+       y->colour = BLACK;
+       /* make our grandparent red */
+       x->up->up->colour = RED;
+       
+       /* now consider our grandparent */
+       x=x->up->up;
+      } else {
+       /* if we are on the right side of our parent */
+       if (x == x->up->right) {
+       /* Move up to our parent */
+         x=x->up;
+         rb_left_rotate(&rbinfo->rb_root, x);
+       }
+       
+       /* make our parent black */
+       x->up->colour = BLACK;
+       /* make our grandparent red */
+       x->up->up->colour = RED;
+       /* right rotate our grandparent */
+       rb_right_rotate(&rbinfo->rb_root, x->up->up);
+      }
+    } else {
+       /* everything here is the same as above, but
+       ** exchanging left for right
+       */
+
+      y=x->up->up->left;
+      if (y->colour == RED) {
+       x->up->colour = BLACK;
+       y->colour = BLACK;
+       x->up->up->colour = RED;
+       
+       x=x->up->up;
+      } else {
+       if (x == x->up->left) {
+         x=x->up;
+         rb_right_rotate(&rbinfo->rb_root, x);
+       }
+       
+       x->up->colour = BLACK;
+       x->up->up->colour = RED;
+       rb_left_rotate(&rbinfo->rb_root, x->up->up);
+      }
+    }
+  }
+
+  /* Set the root node black */
+  (rbinfo->rb_root)->colour = BLACK;
+
+  return RB_TRUE;
+}
+
+/* Search for and if not found and insert is true, will add a new
+** node in. Returns a pointer to the new node, or the node found
+*/
+static struct rbnode * rb_traverse(const void *key, struct rbtree *rbinfo) {
+  struct rbnode *x,*y,*z;
+  int found=0;
+  
+  y=RBNULL; /* points to the parent of x */
+  x=rbinfo->rb_root;
+  
+  /* walk x down the tree */
+  while(x!=RBNULL && found==0) {
+    y=x;
+    if (key<x->key)
+      x=x->left;
+    else if (key>x->key)
+      x=x->right;
+    else
+      found=1;
+  }
+  
+  if (found)
+    return(x);
+  return NULL;
+}
+
+/* Search for a key according (see redblack.h)
+*/
+static struct rbnode * rb_lookup(const void *low, const void *high, struct rbtree *rbinfo) {
+  struct rbnode *x;
+  
+  x=rbinfo->rb_root;
+  
+  /* walk x down the tree */
+  while(x!=RBNULL) {
+    if (low<x->high &&
+       x->key<high)
+      return x;
+    if (x->left!=RBNULL && x->left->max>low)
+      x=x->left;
+    else
+      x=x->right;
+  }
+
+  return(RBNULL);
+}
+
+/* Search for a key according (see redblack.h)
+*/
+int rbsearch(const void *low, const void *high, struct rbtree *rbinfo) {
+  struct rbnode *x;
+  if (rbinfo==NULL)
+    return RB_FALSE;
+
+  x=rbinfo->rb_root;
+  
+  /* walk x down the tree */
+  while(x!=RBNULL) {
+    if (low<x->high &&
+       x->key<high)
+      return RB_TRUE;
+    if (x->left!=RBNULL && x->left->max>low)
+      x=x->left;
+    else
+      x=x->right;
+  }
+
+  return RB_FALSE;
+}
+
+/*
+ * Destroy all the elements blow us in the tree
+ * only useful as part of a complete tree destroy.
+ */
+static void rb_destroy(struct rbnode *x,void (*free_function)(void *)) {
+  if (x!=RBNULL) {
+    if (x->left!=RBNULL)
+      rb_destroy(x->left,free_function);
+    if (x->right!=RBNULL)
+      rb_destroy(x->right,free_function);
+    if (free_function!=NULL)
+      free_function(x->object);
+    rb_free(x);
+  }
+}
+
+/*
+** Rotate our tree thus:-
+**
+**             X        rb_left_rotate(X)--->            Y
+**           /   \                                     /   \
+**          A     Y     <---rb_right_rotate(Y)        X     C
+**              /   \                               /   \
+**             B     C                             A     B
+**
+** N.B. This does not change the ordering.
+**
+** We assume that neither X or Y is NULL
+*/
+
+static void rb_left_rotate(struct rbnode **rootp, struct rbnode *x) {
+  struct rbnode *y;
+  const void *max;
+  assert(x!=RBNULL);
+  assert(x->right!=RBNULL);
+  
+  y=x->right; /* set Y */
+  
+  /* Turn Y's left subtree into X's right subtree (move B)*/
+  x->right = y->left;
+  
+  /* If B is not null, set it's parent to be X */
+  if (y->left != RBNULL)
+    y->left->up = x;
+  
+  /* Set Y's parent to be what X's parent was */
+  y->up = x->up;
+  
+  /* if X was the root */
+  if (x->up == RBNULL) {
+    *rootp=y;
+  } else {
+    /* Set X's parent's left or right pointer to be Y */
+    if (x == x->up->left) {
+      x->up->left=y;
+    } else {
+      x->up->right=y;
+    }
+  }
+
+  /* Put X on Y's left */
+  y->left=x;
+  
+  /* Set X's parent to be Y */
+  x->up = y;
+  
+  y->max=x->max; /* compute Y's max */
+  max=NULL;
+  
+  if (x->left!=RBNULL)
+    max=x->left->max;
+  
+  if (x->right!=RBNULL&&
+      x->right->max>max)
+    max=x->right->max;
+  if (x->high>max)
+    max=x->high;
+  x->max=max;
+}
+
+static void rb_right_rotate(struct rbnode **rootp, struct rbnode *y) {
+  struct rbnode *x;
+  const void *max;
+  
+  assert(y!=RBNULL);
+  assert(y->left!=RBNULL);
+  
+  x=y->left; /* set X */
+
+  /* Turn X's right subtree into Y's left subtree (move B) */
+  y->left = x->right;
+       
+  /* If B is not null, set it's parent to be Y */
+  if (x->right != RBNULL)
+    x->right->up = y;
+
+  /* Set X's parent to be what Y's parent was */
+  x->up = y->up;
+
+  /* if Y was the root */
+  if (y->up == RBNULL) {
+    *rootp=x;
+  } else {
+    /* Set Y's parent's left or right pointer to be X */
+    if (y == y->up->left) {
+      y->up->left=x;
+    } else {
+      y->up->right=x;
+    }
+  }
+  
+  /* Put Y on X's right */
+  x->right=y;
+  
+  /* Set Y's parent to be X */
+  y->up = x;
+
+  x->max=y->max; /* compute Y's max */
+  max=NULL;
+
+  if (y->left!=RBNULL)
+    max=y->left->max;
+       
+  if (y->right!=RBNULL&&
+      y->right->max>max)
+    max=y->right->max;
+  if (y->high>max)
+    max=y->high;
+  y->max=max;
+}
+
+/* Return a pointer to the smallest key greater than x
+*/
+static struct rbnode * rb_successor(const struct rbnode *x) {
+  struct rbnode *y;
+
+  if (x->right!=RBNULL) {
+    /* If right is not NULL then go right one and
+    ** then keep going left until we find a node with
+    ** no left pointer.
+    */
+    for (y=x->right; y->left!=RBNULL; y=y->left);
+  } else {
+    /* Go up the tree until we get to a node that is on the
+    ** left of its parent (or the root) and then return the
+    ** parent.
+    */
+    y=x->up;
+    while(y!=RBNULL && x==y->right) {
+      x=y;
+      y=y->up;
+    }
+  }
+  return(y);
+}
+
+/* Return a pointer to the largest key smaller than x
+*/
+static struct rbnode * rb_preccessor(const struct rbnode *x) {
+  struct rbnode *y;
+
+  if (x->left!=RBNULL) {
+    /* If left is not NULL then go left one and
+    ** then keep going right until we find a node with
+    ** no right pointer.
+    */
+    for (y=x->left; y->right!=RBNULL; y=y->right);
+  } else {
+    /* Go up the tree until we get to a node that is on the
+    ** right of its parent (or the root) and then return the
+    ** parent.
+    */
+    y=x->up;
+    while(y!=RBNULL && x==y->left) {
+      x=y;
+      y=y->up;
+    }
+  }
+  return(y);
+}
+
+/* Delete the node z, and free up the space
+*/
+static void rb_delete(struct rbnode **rootp, struct rbnode *z) {
+  struct rbnode *x, *y, *tmp;
+  const void *max;
+  
+  if (z->left == RBNULL || z->right == RBNULL)
+    y=z;
+  else
+    y=rb_successor(z);
+  
+  if (y->left != RBNULL)
+    x=y->left;
+  else
+    x=y->right;
+  
+  x->up = y->up;
+  
+  if (y->up == RBNULL) {
+    *rootp=x;
+  } else {
+    if (y==y->up->left)
+      y->up->left = x;
+    else
+      y->up->right = x;
+  }
+  
+  if (y!=z) {
+    z->key = y->key;
+    z->high=y->high;
+    z->object=y->object;
+  }
+  tmp=y->up;
+  while(tmp!=RBNULL) {
+    max=NULL;
+    if (tmp->left!=RBNULL)
+      max=tmp->left->max;
+    if (tmp->right!=RBNULL&&
+       tmp->right->max>max)
+      max=tmp->right->max;
+    if (tmp->high>max)
+      max=tmp->high;
+    tmp->max=max;
+    tmp=tmp->up;
+  }
+  if (y->colour == BLACK)
+    rb_delete_fix(rootp, x);
+  
+  rb_free(y);
+}
+
+/* Restore the reb-black properties after a delete */
+static void rb_delete_fix(struct rbnode **rootp, struct rbnode *x) {
+  struct rbnode *w;
+  
+  while (x!=*rootp && x->colour==BLACK) {
+    if (x==x->up->left) {
+      w=x->up->right;
+      if (w->colour==RED) {
+       w->colour=BLACK;
+       x->up->colour=RED;
+       rb_left_rotate(rootp, x->up);
+       w=x->up->right;
+      }
+      if (w->left->colour==BLACK && w->right->colour==BLACK) {
+       w->colour=RED;
+       x=x->up;
+      } else {
+       if (w->right->colour == BLACK) {
+         w->left->colour=BLACK;
+         w->colour=RED;
+         rb_right_rotate(rootp, w);
+         w=x->up->right;
+       }
+       w->colour=x->up->colour;
+       x->up->colour = BLACK;
+       w->right->colour = BLACK;
+       rb_left_rotate(rootp, x->up);
+       x=*rootp;
+      }
+    } else {
+      w=x->up->left;
+      if (w->colour==RED) {
+       w->colour=BLACK;
+       x->up->colour=RED;
+       rb_right_rotate(rootp, x->up);
+       w=x->up->left;
+      }
+      if (w->right->colour==BLACK && w->left->colour==BLACK) {
+       w->colour=RED;
+       x=x->up;
+      } else {
+       if (w->left->colour == BLACK) {
+         w->right->colour=BLACK;
+         w->colour=RED;
+         rb_left_rotate(rootp, w);
+         w=x->up->left;
+       }
+       w->colour=x->up->colour;
+       x->up->colour = BLACK;
+       w->left->colour = BLACK;
+       rb_right_rotate(rootp, x->up);
+       x=*rootp;
+      }
+    }
+  }
+  
+  x->colour=BLACK;
+}
+
+static void
+rb_walk(const struct rbnode *x, void (*action)(const void *, const VISIT, const int, void *), void *arg, int level) {
+  if (x==RBNULL)
+    return;
+  
+  if (x->left==RBNULL && x->right==RBNULL) {
+    /* leaf */
+    (*action)(x->key, leaf, level, arg);
+  } else {
+    (*action)(x->key, preorder, level, arg);
+    
+    rb_walk(x->left, action, arg, level+1);
+    
+    (*action)(x->key, postorder, level, arg);
+
+    rb_walk(x->right, action, arg, level+1);
+
+    (*action)(x->key, endorder, level, arg);
+  }
+}
+
+static RBLIST * rb_openlist(const struct rbnode *rootp) {
+  RBLIST *rblistp;
+  
+  rblistp=(RBLIST *) malloc(sizeof(RBLIST));
+  if (!rblistp)
+    return(NULL);
+  
+  rblistp->rootp=rootp;
+  rblistp->nextp=rootp;
+  
+  if (rootp!=RBNULL) {
+    while(rblistp->nextp->left!=RBNULL) {
+      rblistp->nextp=rblistp->nextp->left;
+    }
+  }
+
+  return(rblistp);
+}
+
+static const void * rb_readlist(RBLIST *rblistp) {
+  const void *key=NULL;
+
+  if (rblistp!=NULL && rblistp->nextp!=RBNULL) {
+    key=rblistp->nextp->key;
+    rblistp->nextp=rb_successor(rblistp->nextp);
+  }
+
+  return(key);
+}
+
+static void rb_closelist(RBLIST *rblistp) {
+  if (rblistp)
+    free(rblistp);
+}
+
+#if defined(USE_SBRK)
+/* Allocate space for our nodes, allowing us to get space from
+** sbrk in larger chucks.
+*/
+static struct rbnode *rbfreep=NULL;
+
+#define RBNODEALLOC_CHUNK_SIZE 1000
+static struct rbnode * rb_alloc() {
+  struct rbnode *x;
+  int i;
+
+  if (rbfreep==NULL) {
+    /* must grab some more space */
+    rbfreep=(struct rbnode *) sbrk(sizeof(struct rbnode) * RBNODEALLOC_CHUNK_SIZE);
+
+    if (rbfreep==(struct rbnode *) -1) {
+      return(NULL);
+    }
+
+    /* tie them together in a linked list (use the up pointer) */
+    for (i=0, x=rbfreep; i<RBNODEALLOC_CHUNK_SIZE-1; i++, x++) {
+      x->up = (x+1);
+    }
+    x->up=NULL;
+  }
+
+  x=rbfreep;
+  rbfreep = rbfreep->up;
+  return(x);
+}
+
+/* free (dealloc) an rbnode structure - add it onto the front of the list
+** N.B. rbnode need not have been allocated through rb_alloc()
+*/
+static void rb_free(struct rbnode *x) {
+  x->up=rbfreep;
+  rbfreep=x;
+}
+
+#endif
+
+#if 0
+int rb_check(struct rbnode *rootp) {
+  if (rootp==NULL || rootp==RBNULL)
+    return(0);
+  
+  if (rootp->up!=RBNULL) {
+    fprintf(stderr, "Root up pointer not RBNULL");
+    dumptree(rootp, 0);
+    return(1);
+  }
+  
+  if (rb_check1(rootp)) {
+    dumptree(rootp, 0);
+    return(1);
+  }
+
+  if (count_black(rootp)==-1)
+    {
+      dumptree(rootp, 0);
+      return(-1);
+    }
+  
+  return(0);
+}
+
+int
+rb_check1(struct rbnode *x)
+{
+  if (x->left==NULL || x->right==NULL)
+    {
+      fprintf(stderr, "Left or right is NULL");
+      return(1);
+    }
+  
+  if (x->colour==RED)
+    {
+      if (x->left->colour!=BLACK && x->right->colour!=BLACK)
+       {
+         fprintf(stderr, "Children of red node not both black, x=%ld", x);
+         return(1);
+       }
+    }
+  
+  if (x->left != RBNULL)
+    {
+      if (x->left->up != x)
+       {
+         fprintf(stderr, "x->left->up != x, x=%ld", x);
+         return(1);
+       }
+      
+      if (rb_check1(x->left))
+       return(1);
+    }          
+  
+  if (x->right != RBNULL)
+    {
+      if (x->right->up != x)
+       {
+         fprintf(stderr, "x->right->up != x, x=%ld", x);
+         return(1);
+       }
+      
+      if (rb_check1(x->right))
+       return(1);
+    }          
+  return(0);
+}
+
+count_black(struct rbnode *x)
+{
+  int nleft, nright;
+  
+  if (x==RBNULL)
+    return(1);
+  
+  nleft=count_black(x->left);
+  nright=count_black(x->right);
+  
+  if (nleft==-1 || nright==-1)
+    return(-1);
+  
+  if (nleft != nright)
+    {
+      fprintf(stderr, "Black count not equal on left & right, x=%ld", x);
+      return(-1);
+    }
+  
+  if (x->colour == BLACK)
+    {
+      nleft++;
+    }
+  
+  return(nleft);
+}
+
+dumptree(struct rbnode *x, int n)
+{
+  char *prkey();
+  
+  if (x!=NULL && x!=RBNULL)
+    {
+      n++;
+      fprintf(stderr, "Tree: %*s %ld: left=%ld, right=%ld, colour=%s, key=%s",
+             n,
+             "",
+             x,
+             x->left,
+             x->right,
+             (x->colour==BLACK) ? "BLACK" : "RED",
+             prkey(x->key));
+      
+      dumptree(x->left, n);
+      dumptree(x->right, n);
+    }  
+}
+#endif
+
+/*
+ * $Log: redblack.c,v $
+ * Revision 1.1  2004/05/06 21:16:22  bdemsky
+ * Moved the interpreter
+ *
+ * Revision 1.6  2003/08/06 14:34:10  droy
+ * test
+ *
+ * Revision 1.5  2003/06/18 18:39:05  bdemsky
+ *
+ *
+ * Changed header files/etc to allow dmalloc to easily be used.
+ * Changed some delete -> delete[] for correctness.
+ * Committed out parserange call.  Cristian has some memory management bugs...
+ *
+ * Revision 1.4  2003/06/18 06:08:18  bdemsky
+ *
+ *
+ * Adding support for:
+ * 1) freeing the memory we use (imagine that)...will make dan's life easier &
+ *    allow us to run cooler benchmarks.  (not completed yet)
+ * 2) generating dot graphs of dependencies...not completed yet - the graphs aren't
+ * appropriately labeled.
+ *
+ * Revision 1.3  2003/06/18 06:06:18  bdemsky
+ *
+ *
+ * Added option to pass in function to free items in the redblack interval tree.
+ *
+ * Revision 1.5  2002/01/30 07:54:53  damo
+ * Fixed up the libtool versioning stuff (finally)
+ * Fixed bug 500600 (not detecting a NULL return from malloc)
+ * Fixed bug 509485 (no longer needs search.h)
+ * Cleaned up debugging section
+ * Allow multiple inclusions of redblack.h
+ * Thanks to Matthias Andree for reporting (and fixing) these
+ *
+ * Revision 1.4  2000/06/06 14:43:43  damo
+ * Added all the rbwalk & rbopenlist stuff. Fixed up malloc instead of sbrk.
+ * Added two new examples
+ *
+ * Revision 1.3  2000/05/24 06:45:27  damo
+ * Converted everything over to using const
+ * Added a new example1.c file to demonstrate the worst case scenario
+ * Minor fixups of the spec file
+ *
+ * Revision 1.2  2000/05/24 06:17:10  damo
+ * Fixed up the License (now the LGPL)
+ *
+ * Revision 1.1  2000/05/24 04:15:53  damo
+ * Initial import of files. Versions are now all over the place. Oh well
+ *
+ */
+
diff --git a/Repair/RepairInterpreter/redblack.h b/Repair/RepairInterpreter/redblack.h
new file mode 100755 (executable)
index 0000000..c8d86b4
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * RCS $Id: redblack.h,v 1.1 2004/05/06 21:16:22 bdemsky Exp $
+ */
+
+/*
+   Redblack balanced tree algorithm
+   Copyright (C) Damian Ivereigh 2000
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version. See the file COPYING for details.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Header file for redblack.c, should be included by any code that 
+** uses redblack.c since it defines the functions 
+*/ 
+/* Stop multiple includes */
+#ifndef _REDBLACK_H
+
+/* For rbwalk - pinched from search.h */
+typedef enum {
+  preorder,
+  postorder,
+  endorder,
+  leaf
+} VISIT;
+
+struct rblists { 
+  const struct rbnode *rootp; 
+  const struct rbnode *nextp; 
+}; 
+#define RBLIST struct rblists 
+
+struct rbtree {
+  /* root of tree */
+  struct rbnode *rb_root;
+};
+
+struct pair {
+  const void *low,*high;
+};
+
+struct rbtree *rbinit();
+int rbinsert(const void *low, const void * high, void *object,struct rbtree *rbinfo);
+struct pair rbfind(const void *low,const void *high, struct rbtree *rbinfo);
+const void *rbdelete(const void *, struct rbtree *);
+void *rblookup(const void *, const void *,struct rbtree *);
+int rbsearch(const void *low, const void *high, struct rbtree *rbinfo);
+void rbdestroy(struct rbtree *,void (*free_function)(void *));
+void rbwalk(const struct rbtree *,
+               void (*)(const void *, const VISIT, const int, void *),
+               void *); 
+RBLIST *rbopenlist(const struct rbtree *); 
+const void *rbreadlist(RBLIST *); 
+void rbcloselist(RBLIST *); 
+
+/* Some useful macros */
+#define rbmin(rbinfo) rblookup(RB_LUFIRST, NULL, (rbinfo))
+#define rbmax(rbinfo) rblookup(RB_LULAST, NULL, (rbinfo))
+
+#define _REDBLACK_H
+#endif /* _REDBLACK_H */
+
+/*
+ *
+ * $Log: redblack.h,v $
+ * Revision 1.1  2004/05/06 21:16:22  bdemsky
+ * Moved the interpreter
+ *
+ * Revision 1.4  2003/06/18 06:08:18  bdemsky
+ *
+ *
+ * Adding support for:
+ * 1) freeing the memory we use (imagine that)...will make dan's life easier &
+ *    allow us to run cooler benchmarks.  (not completed yet)
+ * 2) generating dot graphs of dependencies...not completed yet - the graphs aren't
+ * appropriately labeled.
+ *
+ * Revision 1.2  2003/06/18 06:06:18  bdemsky
+ *
+ *
+ * Added option to pass in function to free items in the redblack interval tree.
+ *
+ * Revision 1.5  2002/01/30 07:54:53  damo
+ * Fixed up the libtool versioning stuff (finally)
+ * Fixed bug 500600 (not detecting a NULL return from malloc)
+ * Fixed bug 509485 (no longer needs search.h)
+ * Cleaned up debugging section
+ * Allow multiple inclusions of redblack.h
+ * Thanks to Matthias Andree for reporting (and fixing) these
+ *
+ * Revision 1.4  2000/06/06 14:43:43  damo
+ * Added all the rbwalk & rbopenlist stuff. Fixed up malloc instead of sbrk.
+ * Added two new examples
+ *
+ * Revision 1.3  2000/05/24 06:45:27  damo
+ * Converted everything over to using const
+ * Added a new example1.c file to demonstrate the worst case scenario
+ * Minor fixups of the spec file
+ *
+ * Revision 1.2  2000/05/24 06:17:10  damo
+ * Fixed up the License (now the LGPL)
+ *
+ * Revision 1.1  2000/05/24 04:15:53  damo
+ * Initial import of files. Versions are now all over the place. Oh well
+ *
+ */
+
diff --git a/Repair/RepairInterpreter/repair.cc b/Repair/RepairInterpreter/repair.cc
new file mode 100755 (executable)
index 0000000..fa77c24
--- /dev/null
@@ -0,0 +1,409 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "repair.h"
+#include "model.h"
+#include "normalizer.h"
+#include "list.h"
+#include "Action.h"
+#include "processobject.h"
+#include "ActionInSet.h"
+#include "ActionNotInSet.h"
+#include "ActionGEQ1.h"
+#include "ActionEQ1.h"
+#include "ActionAssign.h"
+#include "ActionNormal.h"
+#include "Relation.h"
+#include "omodel.h"
+#include "dmodel.h"
+#include "set.h"
+#include "common.h"
+#include "fieldcheck.h"
+#include "Hashtable.h"
+
+Repair::Repair(model *m) {
+  globalmodel=m;
+  removedsentences=NULL;
+  List *list=new List();
+  /*  list->addobject(); --build action array */
+  list->addobject(new ActionGEQ1(m->getdomainrelation(),m));
+  list->addobject(new ActionEQ1(m->getdomainrelation(),m));
+  list->addobject(new ActionAssign(m->getdomainrelation(),m));
+  //  list->addobject(new ActionNotAssign(m->getdomainrelation()));
+  list->addobject(new ActionInSet(m->getdomainrelation(),m));
+  list->addobject(new ActionNotInSet(m->getdomainrelation(),m));
+  numactions=list->size();
+  repairactions=new Action *[list->size()];
+  list->toArray((void **)repairactions);
+  delete(list);
+}
+
+
+void Repair::repaireleexpr(Constraint *c, processobject *po, Elementexpr *ee, Hashtable *env) {
+  /* We're here because we have a bad elementexpr */
+  switch(ee->gettype()) {
+  case ELEMENTEXPR_SUB:
+  case ELEMENTEXPR_ADD:
+  case ELEMENTEXPR_MULT:
+    repaireleexpr(c,po,ee->getleft(),env);
+    repaireleexpr(c,po,ee->getright(),env);
+    return;
+  case ELEMENTEXPR_RELATION: {
+    /* Could have problem here */
+    repaireleexpr(c,po,ee->getleft(),env);
+    Element *e=evaluateexpr(ee,env,globalmodel);
+    if (e==NULL) {
+      /* found bad relation */
+      FieldCheck *fc=globalmodel->getfieldcheck();
+      char *set=NULL;
+      
+      {
+       Elementexpr *left=ee->getleft();
+       int tleft=left->gettype();
+       if (tleft==ELEMENTEXPR_LABEL) {
+         set=getset(c, left->getlabel()->label());
+       } else if (tleft==ELEMENTEXPR_RELATION) {
+         DRelation *drl=globalmodel->getdomainrelation()->getrelation(left->getrelation()->getname());
+         set=drl->getrange();
+       } else {
+         ee->print();
+         printf("Can't determine domain-shouldn't be here because of static analysis...\n");
+         exit(-1);
+       }
+      }
+
+      Element *e2=evaluateexpr(ee->getleft(),env,globalmodel);
+      int index=fc->getindexthatprovides(ee->getrelation()->getname(), set);
+      Hashtable *env2=new Hashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
+      env2->setparent(env);
+      Constraint *crep=globalmodel->getconstraint(index);
+      DomainRelation *dr=globalmodel->getdomainrelation();
+      for(int j=0;j<crep->numquants();j++) {
+       Quantifier *qrep=crep->getquant(j);
+       char *label=qrep->getlabel()->label();
+       char *setname=qrep->getset()->getname();
+       DomainSet *dset=dr->getset(setname);
+       if (dset->getset()->contains(e2)) {
+         env2->put(label,e2);
+       } else {
+         env2->put(label,dset->getset()->firstelement()); /*This shouldn't happen right now*/
+         printf("Funnyness in repair.cc\n");
+       }
+      }
+      this->repairconstraint(globalmodel->getconstraint(index),po,env2);
+      delete(e2);
+      delete(env2);
+    } else
+      delete(e);
+    return;
+  }
+  default:
+    return;
+  }
+}
+
+
+void Repair::repairconstraint(Constraint *c, processobject *po, Hashtable *env) {
+  NormalForm *nf=globalmodel->getnormalform(c);
+  CoerceSentence *coercionstate=nf->closestmatch(removedsentences,po,env);
+  /* Now we just need to coerce the predicates!!!*/
+  for(int i=0;i<coercionstate->getnumpredicates();i++) {
+    CoercePredicate *cp=coercionstate->getpredicate(i);
+    int status=po->processpredicate(cp->getpredicate(),env);
+    while (status==PFAIL) {
+      /* Bad dereference...need to fix things*/
+      repaireleexpr(c, po,cp->getpredicate()->geteleexpr(), env);
+      status=po->processpredicate(cp->getpredicate(),env);
+    }
+
+    if (status!=cp->getcoercebool()) {
+      /*Need to coerce*/
+      Action *act=findrepairaction(cp);
+      act->repairpredicate(env,cp);
+      /* Data structure fixed - well eventually*/
+    }
+  }
+}
+
+
+// returns the action that can repair the given predicate
+Action * Repair::findrepairaction(CoercePredicate *cp) {
+  for(int i=0;i<numactions;i++) {
+    if (repairactions[i]->canrepairpredicate(cp))
+      return repairactions[i];
+  }
+  return NULL;
+}
+
+
+
+// returns the action that can break the given predicate
+Action * Repair::findbreakaction(CoercePredicate *cp) 
+{
+  return findrepairaction(cp);
+}
+
+
+bool Repair::analyzetermination() {
+  WorkRelation *wr=new WorkRelation(true);
+  buildmap(wr);
+  /* Map built */
+  WorkSet *cycleset=searchcycles(wr);
+  if (!cycleset->isEmpty()) {
+    WorkSet *removeedges=new WorkSet(true);
+    for(int i=1;i<=cycleset->size();i++) {
+      if (breakcycles(removeedges, i, cycleset,wr)) {
+       removedsentences=removeedges;
+       printf("Modified constraints for repairability!\n");
+       outputgraph(removeedges, wr, "cycle.dot");
+       return true;
+      }
+    }
+    delete(removeedges);
+    return false;
+  } else {
+    outputgraph(NULL,wr, "cycle.dot");
+    return true;
+  }
+}
+
+
+
+bool Repair::breakcycles(WorkSet *removeedge, int number, WorkSet *cyclelinks, WorkRelation *wr) {
+  for(CoerceSentence *cs=(CoerceSentence *)cyclelinks->firstelement();
+      cs!=NULL;cs=(CoerceSentence *)cyclelinks->getnextelement(cs)) {
+    if (!removeedge->contains(cs)) {
+      removeedge->addobject(cs);
+      if (number==1) {
+       if (!checkforcycles(removeedge, wr))
+         return true;
+      } else {
+       if (breakcycles(removeedge,number-1,cyclelinks,wr))
+         return true;
+      }
+      removeedge->removeobject(cs);
+    }
+  }
+  return false;
+}
+
+void Repair::outputgraph(WorkSet *removededges, WorkRelation *wr, char *filename) {
+  FILE * dotfile=fopen(filename,"w");
+  fprintf(dotfile,"digraph cyclegraph {\n");
+  fprintf(dotfile,"ratio=auto\n");
+  for(int i=0;i<globalmodel->getnumconstraints();i++) {
+    NormalForm *nf=globalmodel->getnormalform(i);
+    fprintf(dotfile, "%lu[label=\"",nf);
+    nf->fprint(dotfile);
+    fprintf(dotfile,"\"];\n");
+    for(int j=0;j<nf->getnumsentences();j++) {
+      CoerceSentence *cs=nf->getsentence(j);
+      for(int i=0;i<cs->getnumpredicates();i++) {
+       CoercePredicate *cp=cs->getpredicate(i);
+       fprintf(dotfile,"%lu -> %lu [style=dashed]\n",nf,cp);
+       WorkSet *setofnf=wr->getset(cp);
+       if (setofnf!=NULL) {
+         NormalForm *nf2=(NormalForm*)setofnf->firstelement();
+         while(nf2!=NULL) {
+           /* cp interferes with nf2 */
+           bool removed=(removededges!=NULL)&&removededges->contains(cs); /*tells what color of edge to generate*/
+           if (removed)
+             fprintf(dotfile,"%lu -> %lu [style=dotted]\n",cp,nf2);
+           else
+             fprintf(dotfile,"%lu -> %lu\n",cp,nf2);
+           nf2=(NormalForm *)setofnf->getnextelement(nf2);
+         }
+       }
+      }
+    }
+  }
+  fprintf(dotfile,"}\n");
+  fclose(dotfile);
+}
+
+bool Repair::checkforcycles(WorkSet *removededges, WorkRelation *wr) {
+  /* Check that there are no cycles and
+     that system is solvable */
+  for(int i=0;i<globalmodel->getnumconstraints();i++) {
+    NormalForm *nf=globalmodel->getnormalform(i);
+    bool good=false;
+    for(int j=0;j<nf->getnumsentences();j++) {
+      if (!removededges->contains(nf->getsentence(j))) {
+       CoerceSentence *cs=nf->getsentence(j);
+       bool allgood=true;
+       for(int k=0;k<cs->getnumpredicates();k++) {
+         if(cs->getpredicate(k)->isrule()&&
+            findrepairaction(cs->getpredicate(k))==NULL) {
+           allgood=false;
+           break;
+         }
+       }
+       if(allgood) {
+         good=true;
+         break;
+       }
+      }
+    }
+    if (!good)
+      return true;
+  }
+  WorkSet *tmpset=new WorkSet(true);
+  for(int i=0;i<globalmodel->getnumconstraints();i++) {
+    NormalForm *nf=globalmodel->getnormalform(i);
+    bool good=false;
+    for(int j=0;j<nf->getnumsentences();j++) {
+      CoerceSentence *cs=nf->getsentence(j);
+      if (checkcycles(cs,removededges,tmpset,wr)) {
+       delete(tmpset);
+       return true;
+      }
+    }
+  }
+  delete(tmpset);
+  return false; /*yeah...no cycles*/
+}
+
+
+
+bool Repair::checkcycles(CoerceSentence *cs,WorkSet *removededges, WorkSet *searchset,WorkRelation *wr) {
+  if (searchset->contains(cs)) {
+    /* found cycle */
+    return true;
+  }
+  if (removededges->contains(cs))
+    return false; /* this edge is removed...don't consider it*/
+
+  searchset->addobject(cs);
+  for(int i=0;i<cs->getnumpredicates();i++) {
+    CoercePredicate *cp=cs->getpredicate(i);
+    WorkSet *setofnf=wr->getset(cp);
+    if (setofnf!=NULL) {
+      /* Might not mess up anything */
+      NormalForm *nf=(NormalForm*)setofnf->firstelement();
+      while(nf!=NULL) {
+       for(int j=0;j<nf->getnumsentences();j++) {
+         CoerceSentence *cssearch=nf->getsentence(j);
+         if (checkcycles(cssearch, removededges, searchset, wr))
+           return true;
+       }
+       nf=(NormalForm *)setofnf->getnextelement(nf);
+      }
+    }
+  }
+  searchset->removeobject(cs);
+  return false;
+}
+
+
+
+WorkSet * Repair::searchcycles(WorkRelation *wr) {
+  /* Do cycle search */
+  WorkSet *cycleset=new WorkSet(true);
+  WorkSet *searchset=new WorkSet(true);
+  for(int i=0;i<globalmodel->getnumconstraints();i++) {
+    NormalForm *nf=globalmodel->getnormalform(i);
+    for(int j=0;j<nf->getnumsentences();j++) {
+      detectcycles(nf->getsentence(j),searchset,cycleset,wr);
+    }
+  }
+  delete(searchset);
+  return cycleset;
+}
+
+
+
+void Repair::detectcycles(CoerceSentence *cs,WorkSet *searchset,WorkSet *cycleset, WorkRelation *wr) {
+  if (searchset->contains(cs)) {
+    /* found cycle */
+    CoerceSentence *csptr=(CoerceSentence *)searchset->firstelement();
+    while(csptr!=NULL) {
+      cycleset->addobject(csptr);
+      csptr=(CoerceSentence *)searchset->getnextelement(csptr);
+    }
+    return;
+  }
+  searchset->addobject(cs);
+  for(int i=0;i<cs->getnumpredicates();i++) {
+    CoercePredicate *cp=cs->getpredicate(i);
+    WorkSet *setofnf=wr->getset(cp);
+    if (setofnf!=NULL) {
+      /* Might not have any interference edges*/
+      NormalForm *nf=(NormalForm*)setofnf->firstelement();
+      while(nf!=NULL) {
+       for(int j=0;j<nf->getnumsentences();j++) {
+         CoerceSentence *cssearch=nf->getsentence(j);
+         detectcycles(cssearch, searchset, cycleset, wr);
+       }
+       nf=(NormalForm*)setofnf->getnextelement(nf);
+      }
+    }
+  }
+  searchset->removeobject(cs);
+}
+
+
+
+void Repair::buildmap(WorkRelation *wr) {
+  for(int i=0;i<globalmodel->getnumconstraints();i++) {
+    NormalForm *nf=globalmodel->getnormalform(i);
+    for(int j=0;j<nf->getnumsentences();j++) {
+      CoerceSentence *cs=nf->getsentence(j);
+      for (int k=0;k<cs->getnumpredicates();k++) {
+       Action *repairaction=findrepairaction(cs->getpredicate(k));
+       if (repairaction==NULL) {
+         /* Nothing will repair this */
+         cs->getpredicate(k)->getpredicate()->print();
+         printf(" can't be repaired!!!");
+         exit(-1);
+       }
+       checkpredicate(repairaction,wr, globalmodel->getconstraint(i),cs->getpredicate(k));
+      }
+    }
+  }
+  ActionNormal *repairnormal=new ActionNormal(globalmodel);
+  for(int i=0;i<globalmodel->getnumrulenormal();i++) {
+    NormalForm *nf=globalmodel->getrulenormal(i);
+    CoercePredicate *cpo=nf->getsentence(0)->getpredicate(0);
+    /* Check for conflicts between abstraction functions */
+    for(int j=0;j<globalmodel->getnumrulenormal();j++) {
+      NormalForm *nfn=globalmodel->getrulenormal(j);
+      CoercePredicate *cpn=nfn->getsentence(0)->getpredicate(0);
+      if (!cpo->istuple()&&
+         equivalentstrings(cpo->getrelset(),cpn->gettriggerset()))
+       wr->put(cpo,nfn);
+    }
+
+    /* Check for conflict between abstraction functions and model constraints */
+    for(int i2=0;i2<globalmodel->getnumconstraints();i2++) {
+      NormalForm *nf2=globalmodel->getnormalform(i2);
+      for(int j2=0;j2<nf2->getnumsentences();j2++) {
+       CoerceSentence *cs2=nf2->getsentence(j2);
+       for (int k2=0;k2<cs2->getnumpredicates();k2++) {
+         if (repairnormal->conflict(NULL,cpo,globalmodel->getconstraint(i2),cs2->getpredicate(k2)))
+           wr->put(cpo,nf2);
+       }
+      }
+    }
+  }
+  delete(repairnormal);
+}
+
+
+
+void Repair::checkpredicate(Action *repair,WorkRelation *wr, Constraint *c,CoercePredicate *cp) {
+  for(int i=0;i<globalmodel->getnumconstraints();i++) {
+    NormalForm *nf=globalmodel->getnormalform(i);
+    for(int j=0;j<nf->getnumsentences();j++) {
+      CoerceSentence *cs=nf->getsentence(j);
+      for (int k=0;k<cs->getnumpredicates();k++) {
+       if (repair->conflict(c,cp,globalmodel->getconstraint(i),cs->getpredicate(k)))
+         wr->put(cp, nf);
+      }
+    }
+  }
+  for(int i=0;i<globalmodel->getnumrulenormal();i++) {
+    NormalForm *nf=globalmodel->getrulenormal(i);
+    if (repair->conflict(c,cp,NULL, nf->getsentence(0)->getpredicate(0)))
+      wr->put(cp,nf);
+  }
+}
+
diff --git a/Repair/RepairInterpreter/repair.h b/Repair/RepairInterpreter/repair.h
new file mode 100755 (executable)
index 0000000..bc90f44
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef REPAIR_H
+#define REPAIR_H
+#include "classlist.h"
+class Repair {
+ public:
+  Repair(model *m);
+  void repairconstraint(Constraint *c, processobject *po, Hashtable *env);
+  Action * findrepairaction(CoercePredicate *cp);
+  Action * findbreakaction(CoercePredicate *cp);
+  bool analyzetermination();
+
+
+ private:
+  void outputgraph(WorkSet *removededges, WorkRelation *wr, char *filename);
+  void repaireleexpr(Constraint *c, processobject *po, Elementexpr *ee, Hashtable *env);
+  void buildmap(WorkRelation *wr);
+  void checkpredicate(Action *repair,WorkRelation *wr, Constraint *c,CoercePredicate *cp);
+  bool checkforcycles(WorkSet *removededges, WorkRelation *wr);
+  bool checkcycles(CoerceSentence *cs,WorkSet *removededges, WorkSet *searchset,WorkRelation *wr);
+  bool breakcycles(WorkSet *removeedge, int number, WorkSet *cyclelinks, WorkRelation *wr);
+  void detectcycles(CoerceSentence *cs,WorkSet *searchset,WorkSet *cycleset, WorkRelation *wr);
+  WorkSet * searchcycles(WorkRelation *wr);
+  model * globalmodel;
+
+  Action ** repairactions;  // the available repair actions
+  int numactions;
+
+  WorkSet *removedsentences;
+};
+#endif
+
diff --git a/Repair/RepairInterpreter/rparser.cc b/Repair/RepairInterpreter/rparser.cc
new file mode 100755 (executable)
index 0000000..bd36e76
--- /dev/null
@@ -0,0 +1,102 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "rparser.h"
+#include "list.h"
+#include "common.h"
+#include "token.h"
+#include "set.h"
+#include "classlist.h"
+
+
+// class RParser
+
+RParser::RParser(Reader *r) 
+{
+  reader=r;
+}
+
+
+// returns the name of the relation whose range is defined
+char* RParser::parserelation()
+{
+  Token token = reader->peakahead();
+
+  while(token.token_type==TOKEN_EOL) 
+    {
+      skiptoken();
+      token = reader->peakahead();
+    }
+  
+  if (token.token_type==TOKEN_EOF)
+    return NULL;
+
+  needtoken(0);
+  needtoken(TOKEN_COLON); // we need a colon
+
+  char* relation = new char[strlen(token.str)+1];
+  strcpy(relation, token.str);
+  return relation;
+}
+
+
+
+WorkSet* RParser::parseworkset()
+{
+#ifdef DEBUGMANYMESSAGES
+  printf("Parsing a new workset... \n");
+#endif
+
+  WorkSet *wset = new WorkSet(true);
+  needtoken(TOKEN_OPENBRACE);  // need an open brace
+
+  Token token = reader->readnext();
+
+  while (token.token_type != TOKEN_CLOSEBRACE)
+    {      
+#ifdef DEBUGMESSAGES
+      //printf("Adding %s...\n", token.str);
+      //fflush(NULL);
+#endif
+      char* newtoken = (char*) malloc(strlen(token.str));
+      strcpy(newtoken, token.str);
+
+      wset->addobject(newtoken);
+      
+      token = reader->readnext();
+      
+      if (token.token_type == TOKEN_COMMA)
+       token = reader->readnext();
+    }
+
+  return wset;
+}
+
+
+
+void RParser::error() 
+{
+  printf("ERROR\n");
+  reader->error();
+  exit(-1);
+}
+
+
+void RParser::skiptoken() 
+{
+  reader->readnext();
+}
+
+
+void RParser::needtoken(int token) 
+{
+  Token t=reader->readnext();
+  if (!(t.token_type==token)) 
+    {
+      printf("Needed token: ");
+      tokenname(token);
+      printf("\n Got token: %s ",t.str);
+      tokenname(t.token_type);
+      error();
+    }
+}
diff --git a/Repair/RepairInterpreter/rparser.h b/Repair/RepairInterpreter/rparser.h
new file mode 100755 (executable)
index 0000000..11fc60d
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef RangeFileParser_H
+#define RangeFileParser_H
+
+#include "common.h"
+#include <iostream.h>
+#include <stdio.h>
+#include "classlist.h"
+
+class RParser {
+ public:
+  RParser(Reader *r);
+  char* parserelation();
+  WorkSet* parseworkset();
+  
+ private:
+  void skiptoken();
+  void needtoken(int);
+  void error();
+  Reader *reader;
+};
+#endif
diff --git a/Repair/RepairInterpreter/set.cc b/Repair/RepairInterpreter/set.cc
new file mode 100755 (executable)
index 0000000..a3f1c6a
--- /dev/null
@@ -0,0 +1,102 @@
+#include <stdio.h>
+#include "set.h"
+#include "GenericHashtable.h"
+#include "element.h"
+
+
+
+// class WorkSet
+
+WorkSet::WorkSet() {
+  ght=genallocatehashtable((unsigned int (*)(void *)) & hashelement,(int (*)(void *,void *)) & elementequals);
+}
+
+WorkSet::WorkSet(unsigned int (*hashf)(void *),int (*equals)(void *,void *)) {
+  ght=genallocatehashtable(hashf,equals);
+}
+
+WorkSet::WorkSet(bool) {
+  ght=genallocatehashtable(NULL,NULL);
+}
+
+WorkSet::~WorkSet() {
+  genfreehashtable(ght);
+}
+
+void WorkSet::addobject(void *obj) {
+  if (!contains(obj))
+    {
+      fflush(NULL);
+      genputtable(ght,obj,obj);
+    }
+}
+
+void WorkSet::removeobject(void *obj) {
+  genfreekey(ght,obj);
+}
+
+bool WorkSet::contains(void *obj) {
+  return (gencontains(ght,obj)==1);
+}
+
+void * WorkSet::firstelement() {
+  if (ght->list==NULL)
+    return NULL;
+  else
+    return ght->list->src;
+}
+
+Iterator * WorkSet::getiterator() {
+  return new Iterator(ght);
+}
+
+void * WorkSet::getnextelement(void *src) {
+  return getnext(ght,src);
+}
+
+void * WorkSet::getelement(int i) {
+  void *v=firstelement();
+  while(i>0) {
+    i--;
+    v=getnext(ght,v);
+  }
+  return v;
+}
+
+int WorkSet::size() {
+  return hashsize(ght);
+}
+
+bool WorkSet::isEmpty() {
+  return (size()==0);
+}
+
+void WorkSet::print() 
+{
+  printf("{");
+  for (int i=0; i<size(); i++)
+    {
+      Element *elem = (Element *) getelement(i);      
+      elem->print();
+      if (i != size()-1)
+       printf(" ");
+    }  
+  printf("}");
+}
+
+
+
+
+// class Iterator
+
+Iterator::Iterator(struct genhashtable *ght) {
+  gi=gengetiterator(ght);
+}
+  
+Iterator::~Iterator() {
+  genfreeiterator(gi);
+}
+  
+void * Iterator::next() {
+  return gennext(gi);
+}
diff --git a/Repair/RepairInterpreter/set.h b/Repair/RepairInterpreter/set.h
new file mode 100755 (executable)
index 0000000..50b4ea8
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef SET_H
+#define SET_H
+
+#include "classlist.h"
+
+class WorkSet {
+ public:
+  WorkSet();
+  WorkSet(unsigned int (*hashf)(void *),int (*equals)(void *,void *));
+  WorkSet(bool);
+  ~WorkSet();
+  void addobject(void *obj);
+  void removeobject(void *obj);
+  bool contains(void *obj);
+  Iterator * getiterator();
+  void *firstelement();
+  void * getnextelement(void *src);
+  int size();
+  void * getelement(int i);  
+  bool isEmpty();
+  void print();
+
+ private:
+  struct genhashtable *ght;
+};
+
+class Iterator {
+ public:
+  Iterator(struct genhashtable *ght);
+  ~Iterator();
+  void * next();
+
+ private:
+  struct geniterator * gi;
+};
+
+#endif
+
diff --git a/Repair/RepairInterpreter/stack.c b/Repair/RepairInterpreter/stack.c
new file mode 100755 (executable)
index 0000000..ceb840a
--- /dev/null
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "stack.h"
+//#include "dmalloc.h"
+
+void pushstack(struct StackElement **septr,void * obj) {
+  struct StackElement * nse=(struct StackElement *)malloc(sizeof(struct StackElement));
+  nse->contents=obj;
+  nse->next=*septr;
+  *septr=nse;
+}
+
+void * popstack(struct StackElement **septr) {
+  if(*septr==NULL) {
+    printf("Empty Stack\n");
+    return NULL;/* Empty stack */
+  }
+  {
+    void *obj=(*septr)->contents;
+    struct StackElement *ose=*septr;
+    (*septr)=ose->next;
+    free(ose);
+    return obj;
+  }
+}
diff --git a/Repair/RepairInterpreter/stack.h b/Repair/RepairInterpreter/stack.h
new file mode 100755 (executable)
index 0000000..460a32b
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef STACK_H
+#define STACK_H
+
+struct StackElement {
+  struct StackElement * next;
+  void * contents;
+};
+void pushstack(struct StackElement **septr,void * obj);
+void * popstack(struct StackElement **septr);
+#endif
diff --git a/Repair/RepairInterpreter/test.cc b/Repair/RepairInterpreter/test.cc
new file mode 100755 (executable)
index 0000000..d7effe3
--- /dev/null
@@ -0,0 +1,204 @@
+/* Defines interfaces for the applications and exports function calls that  
+   the applications should use instead of the standard ones. */
+
+#include <stdlib.h>
+#include <sys/time.h>
+#include "classlist.h"
+#include "model.h"
+#include "dmodel.h"
+extern "C" {
+#include "test.h"
+}
+#include <stdio.h>
+#include "element.h"
+#include "Hashtable.h"
+#include "tmap.h"
+
+
+
+model * exportmodel;
+
+void initializeanalysis() 
+{
+  exportmodel=new model("testabstract", "testmodel", "testspace", "teststruct", "testconcrete", "testrange");
+}
+
+
+
+
+void doanalysis() 
+{
+  struct timeval begin,end;
+  unsigned long t;
+  gettimeofday(&begin,NULL);
+  exportmodel->doabstraction();
+  exportmodel->getdomainrelation()->fixstuff();
+  bool found = exportmodel->docheck();
+  exportmodel->doconcrete();
+  gettimeofday(&end,NULL);
+  t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec;
+
+#ifdef DEBUGMANYMESSAGES
+
+#endif
+  exportmodel->getdomainrelation()->print();
+  printf("Time used for analysis(us): %ld\n",t);
+}
+
+
+/* This procedure invokes the tool.
+   If the model hasn't been initialized, it simply returns. 
+   If a bug was constraint violation was found, displays a message
+   and terminates the program. */
+void doanalysisfordebugging(char* msg)
+{ 
+  if (exportmodel == NULL) {
+    printf("Initialize tool first...\n");
+    return;
+  }
+
+  printf("%s\n", msg);
+  exportmodel->doabstraction(); 
+  
+  //exportmodel->getdomainrelation()->fixstuff();
+  //bool found = exportmodel->docheck();  
+  
+  bool found = exportmodel->getdomainrelation()->fixstuff() || exportmodel->docheck(); 
+
+#ifdef DEBUGMANYMESSAGES
+  exportmodel->getdomainrelation()->print();
+#endif
+
+  if (found)
+    exit(1);
+
+  resetanalysis();
+  printf("\n");  
+}
+
+
+
+// returns true if a violated constraint was found
+unsigned long benchmark() 
+{
+  struct timeval begin,end;
+  unsigned long t;
+  gettimeofday(&begin,NULL);
+  exportmodel->doabstraction();
+  exportmodel->getdomainrelation()->fixstuff();  
+  bool found = exportmodel->docheck();
+  exportmodel->doconcrete();
+  gettimeofday(&end,NULL);
+  t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec;
+  return t;
+}
+
+
+// insert errors that break the specs
+void doanalysis2() 
+{
+  struct timeval begin,end;
+  unsigned long t;
+  gettimeofday(&begin,NULL);
+  exportmodel->doabstraction();
+  exportmodel->getdomainrelation()->fixstuff();
+
+
+  exportmodel->breakspec();
+#ifdef DEBUGMESSAGES
+  printf("\n\nSpecs BROKEN \n\n");
+  fflush(NULL);
+#endif
+  
+  exportmodel->docheck();
+  exportmodel->doconcrete();
+  gettimeofday(&end,NULL);
+  t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec;
+
+  printf("Time used for analysis(us): %ld\n",t);
+}
+
+
+// insert errors that do not break the specs
+void doanalysis3() 
+{
+  struct timeval begin,end;
+  unsigned long t;
+  gettimeofday(&begin,NULL);
+  exportmodel->doabstraction();
+  exportmodel->getdomainrelation()->fixstuff();
+
+  exportmodel->inserterrors();
+
+#ifdef DEBUGMESSAGES
+  printf("\n\nErrors INSERTED \n\n");
+  fflush(NULL);
+#endif
+  
+  exportmodel->docheck();
+  exportmodel->doconcrete();
+  gettimeofday(&end,NULL);
+  t=(end.tv_sec-begin.tv_sec)*1000000+end.tv_usec-begin.tv_usec;
+
+  printf("Time used for analysis(us): %ld\n",t);
+}
+
+
+
+void resetanalysis() {
+  exportmodel->reset();
+}
+
+void addmapping(char *key, void * address, char *type) {
+  Hashtable *env=exportmodel->gethashtable();
+  env->put(key,new Element(address,exportmodel->getstructure(type)));//should be of badstruct
+}
+
+void addintmapping(char *key, int value) {
+  Hashtable *env=exportmodel->gethashtable();
+  env->put(key,new Element(value)); //should be of badstruct
+}
+
+void *ourcalloc(size_t nmemb, size_t size) {
+  typemap *tm=exportmodel->gettypemap();
+  void *oc=calloc(nmemb,size);
+  tm->allocate(oc,size*nmemb);
+  return oc;
+}
+
+void *ourmalloc(size_t size) {
+  typemap *tm=exportmodel->gettypemap();
+  void *oc=malloc(size);
+  tm->allocate(oc,size);
+  return oc;
+}
+
+void ourfree(void *ptr) {
+  typemap *tm=exportmodel->gettypemap();
+  tm->deallocate(ptr);
+  free(ptr);
+}
+
+void *ourrealloc(void *ptr, size_t size) {
+  typemap *tm=exportmodel->gettypemap();
+  void *orr=realloc(ptr,size);
+  if (size==0) {
+    tm->deallocate(ptr);
+    return orr;
+  }
+  if (orr==NULL) {
+    return orr;
+  }
+  tm->deallocate(ptr);
+  tm->allocate(ptr,size);
+}
+
+void alloc(void *ptr,int size) {
+  typemap *tm=exportmodel->gettypemap();
+  tm->allocate(ptr,size);
+}
+
+void dealloc(void *ptr) {
+  typemap *tm=exportmodel->gettypemap();
+  tm->deallocate(ptr);
+}
diff --git a/Repair/RepairInterpreter/test.h b/Repair/RepairInterpreter/test.h
new file mode 100755 (executable)
index 0000000..cf3487a
--- /dev/null
@@ -0,0 +1,21 @@
+/* Defines interfaces for the applications and exports function calls that  
+   the applications should use instead of the standard ones. */
+
+#ifndef TEST_H
+#define TEST_H
+void initializeanalysis();
+unsigned long benchmark();  /* do analysis */
+void doanalysis();  /* do analysis */ 
+void doanalysis2(); /* break the specs and do analysis */
+void doanalysis3(); /* insert errors and do analysis */
+void doanalysisfordebugging(char *msg );
+void resetanalysis();
+void addmapping(char *, void *,char *);
+void addintmapping(char *key, int value);
+void alloc(void *ptr,int size);
+void dealloc(void *ptr);
+void *ourcalloc(size_t nmemb, size_t size);
+void *ourmalloc(size_t size);
+void ourfree(void *ptr);
+void *ourrealloc(void *ptr, size_t size);
+#endif
diff --git a/Repair/RepairInterpreter/testabstract b/Repair/RepairInterpreter/testabstract
new file mode 100755 (executable)
index 0000000..c9c5d01
--- /dev/null
@@ -0,0 +1,19 @@
+[], true => literal(0) in SuperBlock
+[], true => literal(1) in GroupBlock
+[], d.g.InodeTableBlock < d.s.NumberofBlocks => d.g.InodeTableBlock in InodeTableBlock
+[], d.g.InodeBitmapBlock < d.s.NumberofBlocks => d.g.InodeBitmapBlock in InodeBitmapBlock
+[], d.g.BlockBitmapBlock < d.s.NumberofBlocks => d.g.BlockBitmapBlock in BlockBitmapBlock
+[], d.s.RootDirectoryInode < d.s.NumberofInodes => d.s.RootDirectoryInode in RootDirectoryInode
+delay [for j=literal(0) to d.s.NumberofInodes-literal(1)], !(j in UsedInode) => j in FreeInode
+delay [for j=literal(0) to d.s.NumberofBlocks-literal(1)], !(j in UsedBlock) => j in FreeBlock
+[forall di in DirectoryInode, forall itb in InodeTableBlock, for j=literal(0) to (d.s.blocksize/literal(128))-literal(1), for k=literal(0) to literal(11)], cast(InodeTable,d.b[itb]).itable[di].Blockptr[k] < d.s.NumberofBlocks => cast(DirectoryBlock,d.b[cast(InodeTable,d.b[itb]).itable[di].Blockptr[k]]).de[j] in DirectoryEntry
+[forall i in UsedInode, forall itb in InodeTableBlock, for j=literal(0) to literal(11)], !cast(InodeTable,d.b[itb]).itable[i].Blockptr[j]=literal(0) => <i,cast(InodeTable,d.b[itb]).itable[i].Blockptr[j]> in contents
+[forall i in UsedInode, forall itb in InodeTableBlock, for j=literal(0) to literal(11)], cast(InodeTable,d.b[itb]).itable[i].Blockptr[j]<d.s.NumberofBlocks and !cast(InodeTable,d.b[itb]).itable[i].Blockptr[j]=literal(0) => cast(InodeTable,d.b[itb]).itable[i].Blockptr[j] in FileDirectoryBlock
+[for j=literal(0) to d.s.NumberofInodes-literal(1), forall ibb in InodeBitmapBlock], cast(InodeBitmap,d.b[ibb]).inodebitmap[j]=literal(false) => <j,literal(Free)> in inodestatus
+[for j=literal(0) to d.s.NumberofInodes-literal(1), forall ibb in InodeBitmapBlock], cast(InodeBitmap,d.b[ibb]).inodebitmap[j]=literal(true) => <j,literal(Used)> in inodestatus
+[forall de in DirectoryEntry], de.inodenumber<d.s.NumberofInodes and !de.inodenumber = literal(0) => de.inodenumber in FileInode
+[forall de in DirectoryEntry], de.inodenumber<d.s.NumberofInodes => <de, de.inodenumber> in inodeof
+[forall j in UsedInode, forall itb in InodeTableBlock], true => <j,cast(InodeTable,d.b[itb]).itable[j].referencecount> in referencecount
+[forall j in UsedInode, forall itb in InodeTableBlock], true => <j,cast(InodeTable,d.b[itb]).itable[j].filesize> in filesize
+[for j=literal(0) to d.s.NumberofBlocks-literal(1), forall bbb in BlockBitmapBlock], cast(BlockBitmap,d.b[bbb]).blockbitmap[j]=literal(false) => <j,literal(Free)> in blockstatus
+[for j=literal(0) to d.s.NumberofBlocks-literal(1), forall bbb in BlockBitmapBlock], cast(BlockBitmap,d.b[bbb]).blockbitmap[j]=literal(true) => <j,literal(Used)> in blockstatus
diff --git a/Repair/RepairInterpreter/testconcrete b/Repair/RepairInterpreter/testconcrete
new file mode 100755 (executable)
index 0000000..e9957fa
--- /dev/null
@@ -0,0 +1,13 @@
+[forall u in InodeTableBlock], true => d.g.InodeTableBlock=u
+[forall u in InodeBitmapBlock], true => d.g.InodeBitmapBlock=u
+[forall u in BlockBitmapBlock], true => d.g.BlockBitmapBlock=u
+[forall u in RootDirectoryInode], true => d.s.RootDirectoryInode=u
+[forall i in UsedInode, forall itb in InodeTableBlock, for j=literal(0) to literal(11)], j < sizeof(i.contents) => cast(InodeTable,d.b[itb]).itable[i].Blockptr[j]=element j of i.contents
+[forall i in UsedInode, forall itb in InodeTableBlock, for j=literal(0) to literal(11)], !j<sizeof(i.contents) => cast(InodeTable,d.b[itb]).itable[i].Blockptr[j]=literal(0)
+[forall ibb in InodeBitmapBlock, forall <j,status> in inodestatus], status=literal(Free) => cast(InodeBitmap,d.b[ibb]).inodebitmap[j]=literal(false)
+[forall ibb in InodeBitmapBlock, forall <j,status> in inodestatus], status=literal(Used) => cast(InodeBitmap,d.b[ibb]).inodebitmap[j]=literal(true)
+[forall <de, u> in inodeof], true => de.inodenumber=u
+[forall itb in InodeTableBlock, forall <j,u> in referencecount], true => cast(InodeTable,d.b[itb]).itable[j].referencecount=u
+[forall itb in InodeTableBlock, forall <j,u> in filesize], true => cast(InodeTable,d.b[itb]).itable[j].filesize=u
+[forall bbb in BlockBitmapBlock, forall <j, status> in blockstatus], status=literal(Free) => cast(BlockBitmap,d.b[bbb]).blockbitmap[j] = literal(false)
+[forall bbb in BlockBitmapBlock, forall <j,status> in blockstatus], status=literal(Used) => cast(BlockBitmap,d.b[bbb]).blockbitmap[j] = literal(true)
diff --git a/Repair/RepairInterpreter/testmodel b/Repair/RepairInterpreter/testmodel
new file mode 100755 (executable)
index 0000000..8a2fca0
--- /dev/null
@@ -0,0 +1,13 @@
+[forall u in UsedInode], u.inodestatus=literal(Used)
+[forall f in FreeInode], f.inodestatus=literal(Free)
+[forall u in UsedBlock], u.blockstatus=literal(Used)
+[forall f in FreeBlock], f.blockstatus=literal(Free)
+[forall i in UsedInode], i.referencecount=sizeof(i.~inodeof) or i in RootDirectoryInode
+[forall i in UsedInode], i.filesize <= sizeof(i.contents)*literal(8192)
+[forall b in FileDirectoryBlock],sizeof(b.~contents)=1
+[],sizeof(SuperBlock)=1
+[],sizeof(GroupBlock)=1
+[],sizeof(InodeTableBlock)=1
+[],sizeof(InodeBitmapBlock)=1
+[],sizeof(BlockBitmapBlock)=1
+[],sizeof(RootDirectoryInode)=1
diff --git a/Repair/RepairInterpreter/testrange b/Repair/RepairInterpreter/testrange
new file mode 100755 (executable)
index 0000000..0cd9ba7
--- /dev/null
@@ -0,0 +1,2 @@
+inodestatus: {Free, Used}
+blockstatus: {Free, Used}
diff --git a/Repair/RepairInterpreter/testspace b/Repair/RepairInterpreter/testspace
new file mode 100755 (executable)
index 0000000..d50564a
--- /dev/null
@@ -0,0 +1,24 @@
+set Block(int): partition UsedBlock | FreeBlock
+set FreeBlock(int):
+set Inode(int): partition UsedInode | FreeInode
+set FreeInode(int):
+set UsedInode(int): partition FileInode | DirectoryInode 
+set FileInode(int):
+set DirectoryInode(int): RootDirectoryInode
+set RootDirectoryInode(int):
+set UsedBlock(int): partition SuperBlock | GroupBlock | FileDirectoryBlock | InodeTableBlock | InodeBitmapBlock | BlockBitmapBlock
+set FileDirectoryBlock(int): DirectoryBlock | FileBlock
+set SuperBlock(int):
+set GroupBlock(int):
+set FileBlock(int):
+set DirectoryBlock(int):
+set InodeTableBlock(int):
+set InodeBitmapBlock(int):
+set BlockBitmapBlock(int):
+set DirectoryEntry(DirectoryEntry):
+inodeof: DirectoryEntry -> UsedInode (many->1)
+contents: UsedInode -> FileDirectoryBlock (1->many)
+inodestatus: Inode -> token (many->1)
+blockstatus: Block -> token (many->1)
+referencecount: Inode -> int (many->1)
+filesize: Inode -> int (many->1)
diff --git a/Repair/RepairInterpreter/teststruct b/Repair/RepairInterpreter/teststruct
new file mode 100755 (executable)
index 0000000..fd4c2ff
--- /dev/null
@@ -0,0 +1,53 @@
+structure Block {
+     reserved byte[d.s.blocksize];
+}
+
+structure Disk {
+     Block  b[d.s.NumberofBlocks];
+     label b[literal(0)]: Superblock s;
+     label b[literal(1)]: Groupblock g;
+}
+
+structure Superblock subtype of Block {
+     int FreeBlockCount;
+     int FreeInodeCount;
+     int NumberofBlocks;
+     int NumberofInodes;
+     int RootDirectoryInode;
+     int blocksize;
+}
+
+structure Groupblock subtype of Block {
+     int BlockBitmapBlock;
+     int InodeBitmapBlock;
+     int InodeTableBlock; 
+     int GroupFreeBlockCount;
+     int GroupFreeInodeCount;
+}
+
+structure InodeTable subtype of Block {
+     Inode itable[d.s.NumberofInodes];
+}
+
+structure InodeBitmap subtype of Block {
+     bit inodebitmap[d.s.NumberofInodes];
+}
+
+structure BlockBitmap subtype of Block {
+     bit blockbitmap[d.s.NumberofBlocks];
+}
+
+structure Inode {
+     int filesize;
+     int Blockptr[literal(12)];
+     int referencecount;
+}
+
+structure DirectoryBlock subtype of Block {
+     DirectoryEntry de[d.s.blocksize/literal(128)];
+}
+
+structure DirectoryEntry {
+     byte name[literal(124)];
+     int inodenumber;
+}
diff --git a/Repair/RepairInterpreter/tmap.cc b/Repair/RepairInterpreter/tmap.cc
new file mode 100755 (executable)
index 0000000..f0ced38
--- /dev/null
@@ -0,0 +1,218 @@
+#include <stdio.h>
+#include "tmap.h"
+extern "C" {
+#include "redblack.h"
+}
+#include "tmodel.h"
+#include "model.h"
+#include "processabstract.h"
+#include "element.h"
+
+#define CHECKTYPE
+#define CHECKMEMORY
+
+typemap::typemap(model *m) {
+  alloctree=rbinit();
+  typetree=rbinit();
+  globalmodel=m;
+}
+
+void freefunction(void *ptr) {
+  if(ptr!=NULL) {
+    delete((structuremap *)ptr);
+  }
+}
+
+typemap::~typemap() {
+  rbdestroy(typetree,freefunction);
+  rbdestroy(alloctree,freefunction);
+}
+
+void typemap::reset() {
+  rbdestroy(typetree,freefunction);
+  typetree=rbinit();
+}
+
+structuremap::structuremap(structure *s) {
+  str=s;
+  typetree=rbinit();
+}
+
+structuremap::~structuremap() {
+  rbdestroy(typetree,freefunction);
+}
+
+bool typemap::asserttype(void *ptr, structure *s) {
+
+#ifdef CHECKTYPE
+  bool b=checktype(true,ptr,s);
+  if (!b) {
+    printf("Assertion failure\n");
+    bool testb=checktype(true,ptr,s);
+  }
+  return b;
+#endif
+
+  return assertvalidmemory(ptr, s);
+}
+
+bool typemap::assertvalidmemory(void* low, void* high) {
+
+#ifdef CHECKMEMORY
+  return checkmemory(low, high);
+#endif
+
+  return true;
+}
+
+bool typemap::assertvalidmemory(void* ptr, structure* s) {
+
+#ifdef CHECKMEMORY
+  int size=s->getsize(globalmodel->getbitreader(),globalmodel,globalmodel->gethashtable());
+  void *low=ptr;
+  void *high=((char *)low)+size;
+  return checkmemory(low, high);
+#endif
+  
+  return true;
+}
+
+bool typemap::istype(void *ptr, structure *s) {
+
+#ifdef CHECKTYPE
+  bool b=checktype(false,ptr,s);
+  if (!b) {
+    printf("Verify failure\n");
+    bool testb=checktype(false,ptr,s);
+  }
+  return b;
+#endif
+
+  return assertvalidmemory(ptr, s);
+}
+
+void typemap::allocate(void *ptr, int size) {
+  void *low=ptr;
+  void *high=((char *)ptr)+size;
+  int val=rbinsert(low,high,NULL,alloctree);
+  if (val==0)
+    printf("Error\n");
+}
+
+structure * typemap::findoffsetstructure(structure *s, int offset) {
+  int count=0;
+  for(int i=0;i<s->getnumfields();i++) {
+    int mult=1;
+    ttype *ttype=s->getfield(i)->gettype();
+    if (ttype->getsize()!=NULL) {
+      Element * number=evaluateexpr(globalmodel,ttype->getsize(),globalmodel->gethashtable(),true,false);
+      mult=number->intvalue();
+      delete(number);
+    }
+    int increment=ttype->basesize(globalmodel->getbitreader(),globalmodel,globalmodel->gethashtable());
+
+    int delt=offset-count;
+    if (delt<mult*increment) {
+      if (delt%increment==0) {
+       return globalmodel->getstructure(ttype->getname());
+      } else
+       return NULL;
+    }
+
+    count+=mult*increment;
+  }
+  
+  return NULL;
+}
+
+void typemap::deallocate(void *ptr) {
+  if (rbdelete(ptr,alloctree)==NULL)
+    printf("Freeing unallocated memory\n");
+}
+
+bool typemap::checkmemory(void* low, void* high) {
+  struct pair allocp=rbfind(low,high,alloctree);
+
+  if (allocp.low == NULL) {
+      return false; 
+  } else if ((allocp.low > low) || (allocp.high < high)) { /* make sure this block is used */
+      return false;
+  } else {
+      return true;
+  }
+}
+
+
+bool typemap::checktype(bool doaction,void *ptr, structure *structure) {
+  int size=structure->getsize(globalmodel->getbitreader(),globalmodel,globalmodel->gethashtable());
+  void *low=ptr;
+  void *high=((char *)low)+size;
+  struct pair allocp=rbfind(low,high,alloctree);
+  if (allocp.low==NULL)
+    return false;
+  if (allocp.low>low||allocp.high<high) /* make sure this block is used */
+    return false;
+  struct pair typep=rbfind(low,high,typetree);
+  structuremap *smap=(structuremap *)rblookup(low,high,typetree);
+  
+  if (typep.low==NULL) {
+    if(!doaction)
+      return true;
+    structuremap *sm=new structuremap(structure);
+    int flag=rbinsert(low, high, sm, typetree);
+    if (flag==0) {
+      printf("Error in asserttype\n");
+      return false;
+    } else
+      return true;
+  }
+
+  return checktype(doaction, low,high, structure, typetree);
+}
+
+bool typemap::checktype(bool doaction, void *low, void *high,structure *structre, struct rbtree *ttree) {
+  struct pair typep=rbfind(low,high,ttree);
+  structuremap *smap=(structuremap *)rblookup(low,high,ttree);
+  
+  if (typep.low==low&&typep.high==high) {
+    /* Recast */
+    if (globalmodel->subtypeof(structre,smap->str)) {
+      /* narrowing cast */
+      if (!doaction)
+       return true;
+      smap->str=structre;
+      return true;
+    } else if (globalmodel->subtypeof(smap->str,structre)) {
+      /* widening cast */
+      return true;
+    } else
+      return false; /* incompatible types */
+  } else if (typep.low<=low&&typep.high>=high) {
+    /* See if it matches up with structure inside typep */
+    if (rbsearch(low,high,smap->typetree)) {
+      /* recurse */
+      return checktype(doaction,low,high, structre, smap->typetree);
+    } else {
+      /* check to see if data lines up correctly */
+      int offset=((char *)low)-((char *)typep.low);
+      structure * st=findoffsetstructure(smap->str,offset);
+      if (st==NULL)
+       return false;
+      if (globalmodel->subtypeof(structre,st)) {
+       if (!doaction)
+         return true;
+       structuremap *newsm=new structuremap(structre);
+       int flag=rbinsert(low, high, newsm, smap->typetree);
+       return (flag==1);
+      } else if (globalmodel->subtypeof(st,structre)) {
+       if (!doaction)
+         return true;
+       structuremap *newsm=new structuremap(st);
+       int flag=rbinsert(low, high, newsm, smap->typetree);
+       return (flag==1);
+      } else
+       return false;
+    }
+  } else
+    return false;
+}
diff --git a/Repair/RepairInterpreter/tmap.h b/Repair/RepairInterpreter/tmap.h
new file mode 100755 (executable)
index 0000000..e05f28d
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef TMAP_H
+#define TMAP_H
+#include "classlist.h"
+
+class typemap {
+ public:
+  typemap(model *);
+  ~typemap();
+  void allocate(void *, int);
+  void deallocate(void *);
+  bool assertvalidmemory(void* low, void* high);
+  bool assertvalidmemory(void* ptr, structure *structure);
+  bool asserttype(void *ptr, structure *structure);
+  bool istype(void *ptr, structure *structure);
+  void reset();
+ private:
+  bool checkmemory(void* low, void* high);
+  bool checktype(bool doaction,void *ptr, structure *structure);
+  bool checktype(bool doaction, void *low, void *high,structure *structure, struct rbtree *ttree);
+  structure * findoffsetstructure(structure *s, int offset);
+  model *globalmodel;
+  struct rbtree *alloctree;
+  struct rbtree *typetree;
+};
+
+class structuremap {
+  public:
+  structuremap(structure *s);
+  ~structuremap();
+  structure *str;
+  struct rbtree *typetree;
+};
+#endif
diff --git a/Repair/RepairInterpreter/tmodel.cc b/Repair/RepairInterpreter/tmodel.cc
new file mode 100755 (executable)
index 0000000..1858d4d
--- /dev/null
@@ -0,0 +1,279 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "tmodel.h"
+#include "processabstract.h"
+#include "element.h"
+#include "model.h"
+#include "Hashtable.h"
+#include "common.h"
+
+
+void structure::print() {
+  printf("\nBEGIN structure:\n");
+  printf("   name=%s\n", name);
+  printf("   type=%d\n", type);
+  
+  if (subtype == NULL)
+    printf("   subtype=null\n");
+  else subtype->print();
+
+  for (int i=0; i<getnumfields(); i++)
+    getfield(i)->print();
+
+  for (int i=0; i<getnumlabels(); i++)
+    getlabel(i)->print();
+  
+  printf("END structure\n\n");
+}
+
+void ttype::print() {
+  printf("\nBEGIN ttype\n");
+  printf("   ttype: primtype=%ld, intlength=%ld, type=%s\n", primtype, intlength, type);
+  printf("END ttype\n\n");
+}
+
+/*void tparam::print() {
+  }*/
+
+void tlabel::print() {
+  printf("\nBEGIN tlabel\n");
+  printf("   field=%s\n", field);
+  specifictype->print();
+  printf("END tlabel\n\n");
+}
+
+void tfield::print() {
+  printf("\nBEGIN tfield\n");
+  printf("   name=\%s\n", name);
+  type->print();
+  printf("END tfield\n\n");
+}
+
+AElementexpr * ttype::getsize() {
+  return asize;
+}
+
+
+int ttype::getbytes(bitreader *br,model *m,Hashtable *env) {
+  int basesizeval=basesize(br,m,env);
+  int mult=1;
+  if (asize!=NULL) {
+    Element * number=evaluateexpr(m,asize,env,true,false);
+    mult=number->intvalue();
+    delete(number);
+  }
+  if (gettype()==TTYPE_BIT) {
+    return ((mult-1)/8)+1;
+  }
+  return mult*basesizeval;
+}
+
+int ttype::basesize(bitreader *br,model *m,Hashtable *env) {
+  if ((primtype/TTYPE_PTR)>0)
+    return pointersize;
+  if (gettype()==TTYPE_INT)
+    return intsize;
+  if (gettype()==TTYPE_SHORT)
+    return shortsize;
+  if (gettype()==TTYPE_BYTE)
+    return 1;
+  if (gettype()==TTYPE_BIT)
+    return 0;
+  if (gettype()==TTYPE_STRUCT) {
+    /*    Element **earray=new Element *[numparamvalues];
+         for(int i=0;i<numparamvalues;i++) {
+         earray[i]=evaluateexpr(br,paramvalues[i],env);
+         }*/
+    structure *st=m->getstructure(type);
+    int size=st->getsize(br,m,env);
+    /*    for(int i=0;i<numparamvalues;i++)
+         delete(earray[i]);
+         delete earray;*/
+    return size;
+  }
+}
+
+int structure::getsize(bitreader *br,model *m, Hashtable *env) {
+  int totalsize=0;
+  /* build parameter mapping */
+  /*  for(int i=0;i<getnumparams();i++) {
+    env->put(getparam(i)->getname(),earray[i]);
+    }*/
+  /* loop through fields */
+  if (getsubtype()!=NULL) {
+    return getsubtype()->getbytes(br, m,env);
+  }
+  for(int j=0;j<getnumfields();j++)
+    totalsize+=getfield(j)->gettype()->getbytes(br,m,env);
+  //delete(env);
+  return totalsize;
+}
+char * tlabel::getname() {
+  return specifictype->getname();
+}
+ttype * tlabel::gettype() {
+  return specifictype->gettype();
+}
+
+structure::structure(char *nam) {
+  subtype=NULL;
+  name=nam;
+}
+
+void structure::settype(int t) {
+  type=t;
+}
+
+/*void structure::setparams(tparam **tp,int n) {
+  params=tp;numparams=n;
+  }*/
+
+void structure::setsubtype(ttype *sub) {
+  subtype=sub;
+}
+
+ttype * structure::getsubtype() {
+  return subtype;
+}
+
+void structure::setfields(tfield **fieldarray, int n) {
+  fields=fieldarray;
+  numfields=n;
+}
+
+void structure::setlabels(tlabel **lab,int n) {
+  labels=lab;
+  numlabels=n;
+}
+
+/*int structure::getnumparams() {
+  return numparams;
+  }*/
+
+/*tparam * structure::getparam(int i) {
+  return params[i];
+  }*/
+
+int structure::getnumlabels() {
+  return numlabels;
+}
+
+tlabel * structure::getlabel(int i) {
+  return labels[i];
+}
+
+int structure::getnumfields() {
+  return numfields;
+}
+
+tfield * structure::getfield(int i) {
+  return fields[i];
+}
+
+char * structure::getname() {
+  return name;
+}
+
+ttype::ttype(int typ) {
+  primtype=typ;
+  intlength=0;
+  type=NULL;
+  //  paramvalues=NULL;
+  //numparamvalues=0;
+  asize=NULL;
+}
+
+ttype::ttype(char *t) {
+  primtype=TTYPE_STRUCT;
+  type=t;
+  intlength=0;
+  //paramvalues=NULL;
+  //numparamvalues=0;
+  asize=NULL;
+}
+
+ttype::ttype(char *t, AElementexpr *size) {
+  primtype=TTYPE_STRUCT;
+  type=t;
+  intlength=0;
+  //paramvalues=param;
+  //numparamvalues=numparam;
+  asize=size;
+}
+
+ttype::ttype(int type, AElementexpr * size) {
+  primtype=type;
+  intlength=0;
+  this->type=NULL;
+  //paramvalues=NULL;
+  //numparamvalues=0;
+  asize=size;
+}
+
+void ttype::makeptr() {
+  primtype+=TTYPE_PTR;
+}
+void ttype::setsize(AElementexpr *size) {
+  asize=size;
+}
+
+bool ttype::isptr() {
+  if (numderef()>0)
+    return true;
+  else
+    return false;
+}
+
+int ttype::numderef() {
+  return primtype/TTYPE_PTR;
+}
+
+int ttype::gettype() {
+  return primtype%TTYPE_PTR;
+}
+/*int ttype::getnumparamvalues() {
+  return numparamvalues;
+}
+
+AElementexpr * ttype::getparamvalues(int i) {
+  return paramvalues[i];
+  }*/
+char * ttype::getname() {
+  return type;
+}
+
+/*tparam::tparam(ttype *t,char * n) {
+  type=t;name=n;
+  }
+  char * tparam::getname() {
+  return name;
+  }
+*/
+tlabel::tlabel(tfield *f, char *fld,AElementexpr *a) {
+  index=a;
+  field=fld;
+  specifictype=f;
+}
+
+char *tlabel::getfield() {
+  return field;
+}
+AElementexpr * tlabel::getindex() {
+  return index;
+}
+
+tfield::tfield(ttype *tt, char *n) {
+  type=tt;name=n;
+}
+
+ttype * tfield::gettype() {
+  return type;
+}
+
+char * tfield::getname() {
+  return name;
+}
diff --git a/Repair/RepairInterpreter/tmodel.h b/Repair/RepairInterpreter/tmodel.h
new file mode 100755 (executable)
index 0000000..295acb7
--- /dev/null
@@ -0,0 +1,128 @@
+// stores the structure definitions
+#ifndef TMODEL_H
+#define TMODEL_H
+
+#include "classlist.h"
+
+#define STYPE_STRUCT 1
+#define STYPE_INT 2
+#define STYPE_BIT 3
+#define STYPE_BYTE 4
+#define STYPE_SHORT 5
+#define STYPE_ARRAY 0x100
+
+
+class structure {
+  public:
+  structure(char *nam);
+  void settype(int t);
+  //  void setparams(tparam **tp,int n);
+  void setsubtype(ttype *sub);
+  ttype * getsubtype();
+  void setfields(tfield **fieldarray, int n);
+  void setlabels(tlabel **lab,int n);
+  /*  int getnumparams();
+      tparam * getparam(int i);*/
+  int getnumlabels();
+  tlabel * getlabel(int i);
+  int getnumfields();
+  tfield * getfield(int i);
+  char * getname();
+  void print();
+  int getsize(bitreader *br,model *m, Hashtable *env);
+
+  private:
+  int type;
+  char *name;
+  /*  tparam ** params;
+      int numparams;*/
+  ttype *subtype;
+  tfield ** fields;
+  int numfields;
+  tlabel ** labels;
+  int numlabels;
+};
+
+#define pointersize 4
+#define intsize 4
+#define shortsize 2
+
+#define TTYPE_STRUCT 0x1
+#define TTYPE_INT 0x2
+#define TTYPE_BIT 0x3
+#define TTYPE_BYTE 0x4
+#define TTYPE_SHORT 0x5
+#define TTYPE_PTR 0x100
+
+
+
+class ttype {
+ public:
+  void print();
+  ttype(int typ);
+  ttype(char *t);
+  ttype(char *t,  AElementexpr *size);
+  ttype(int type, AElementexpr * size);
+  void makeptr();
+  void setsize(AElementexpr *size);
+  AElementexpr * getsize();
+  int getbytes(bitreader *br,model *m,Hashtable *env);
+
+  bool isptr();
+  int numderef();
+  int gettype();
+  int basesize(bitreader *br,model *m,Hashtable *env);
+  /*  int getnumparamvalues();
+      AElementexpr * getparamvalues(int i);*/
+  char * getname();
+
+ private:
+  int primtype;
+  int intlength; /*for variable length integers*/
+  char * type;
+  /*  AElementexpr ** paramvalues;
+      int numparamvalues;*/
+  AElementexpr * asize;
+};
+
+/*class tparam {
+ public:
+  void print();
+  tparam(ttype *t,char * n);
+  char * getname();
+
+ private:
+  ttype *type;
+  char *name;
+  };*/
+
+
+
+class tlabel {
+ public:
+  void print();
+  tlabel(tfield *f, char *fld,AElementexpr *a);
+  char * getname();
+  ttype * gettype();
+  char *getfield();
+  AElementexpr * getindex();
+
+ private:
+  char *field;
+  AElementexpr *index;
+  tfield * specifictype;
+};
+
+class tfield {
+ public:
+  tfield(ttype *tt, char *n);
+  void print();
+  ttype * gettype();
+  char * getname();
+
+ private:
+  char *name;
+  ttype *type;
+  bool reserved;
+};
+#endif
diff --git a/Repair/RepairInterpreter/token.cc b/Repair/RepairInterpreter/token.cc
new file mode 100755 (executable)
index 0000000..1e9c8a6
--- /dev/null
@@ -0,0 +1,448 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "common.h"
+#include "token.h"
+
+
+// class Token
+
+Token::Token(char *s, int tt) {
+  str=s;
+  token_type=tt;
+}
+
+Token::Token(const Token & t) {
+  token_type=t.token_type;
+  str=copystr(t.str);
+}
+
+Token::Token() {
+  token_type=-1;
+  str=NULL;
+}
+
+
+Token& Token::operator=(const Token &right) {
+  if (&right != this) {
+    token_type=right.token_type;
+    if (str!=NULL)
+    delete[](str);
+    str=copystr(right.str);
+  }
+  return *this;
+}
+
+
+Token::~Token() {
+  if (str!=NULL)
+    delete[](str);
+}
+
+
+
+
+// class Reader
+
+Reader::Reader(istream * is) {
+  readerin=is;
+  pos=0;
+}
+
+
+Token Reader::peakahead() {
+  Token t=checktoken();
+  if (t.token_type!=-1) {
+    return t;
+  }
+  while(true) {
+    int nextchar=readerin->get();
+    switch(nextchar) {
+    case ' ':
+      break;
+    case '\t':
+      break;
+    case '/':
+      if (readerin->peek()=='*') {
+       /*have comment region */
+       readerin->get();
+       int state=0;
+       for(int ch=readerin->get();ch!=EOF&&state!=2;ch=readerin->get()) {
+         switch(ch) {
+         case '*':
+           state=1;
+           break;
+         case '/':
+           if (state==1)
+             state=2;
+           break;
+         default:
+           state=0;
+         }
+       }
+       if (state!=2) error();
+       break;
+      }
+    default:
+      buf[pos++]=nextchar;
+      Token t=checktoken();
+      if (t.token_type!=-1)
+       return t;
+    }
+  }
+}
+
+
+Token Reader::readnext() {
+  Token t=peakahead();  
+  pos=0;
+  return t;
+}
+
+Token Reader::checktoken() {
+  buf[pos]=0;
+  if (pos==0) return Token();
+  switch(buf[0]) {
+  case '[':
+    return Token(copystr(buf),TOKEN_OPENBRACK);
+  case ']':
+    return Token(copystr(buf),TOKEN_CLOSEBRACK);
+  case '{':
+    return Token(copystr(buf),TOKEN_OPENBRACE);
+  case '}':
+    return Token(copystr(buf),TOKEN_CLOSEBRACE);
+  case '(':
+    return Token(copystr(buf),TOKEN_OPENPAREN);
+  case ')':
+    return Token(copystr(buf),TOKEN_CLOSEPAREN);
+  case ',':
+    return Token(copystr(buf),TOKEN_COMMA);
+  case ';':
+    return Token(copystr(buf),TOKEN_SEMI);
+  case ':':
+    return Token(copystr(buf),TOKEN_COLON);
+  case '=':
+    if (pos==1) {
+      if (readerin->peek()!='>')
+       return Token(copystr(buf),TOKEN_EQUALS);
+    } else
+      return Token(copystr(buf),TOKEN_IMPLIES);
+    break;
+  case '<':
+    if (pos==1) {
+      if (readerin->peek()!='=')
+       return Token(copystr(buf),TOKEN_LT);
+    } else 
+      return Token(copystr(buf),TOKEN_LTE);
+    break;
+  case '>':
+    if (pos==1) {
+      if (readerin->peek()!='=')
+       return Token(copystr(buf),TOKEN_GT);
+    } else 
+      return Token(copystr(buf),TOKEN_GTE);
+    break;
+  case '.':
+    if (pos==1) {
+      if (readerin->peek()!='~')
+       return Token(copystr(buf),TOKEN_DOT);
+    } else 
+      return Token(copystr(buf),TOKEN_DOTINV);
+    break;
+  case '|':
+    return Token(copystr(buf),TOKEN_BAR);
+  case '!':
+    return Token(copystr(buf),TOKEN_NOT);
+  case '-':
+    if (pos==1) {
+      if (readerin->peek()!='>')
+       return Token(copystr(buf),TOKEN_SUB);
+    } else
+      return Token(copystr(buf),TOKEN_ARROW);
+    break;
+  case '+':
+    return Token(copystr(buf),TOKEN_ADD);
+  case '*':
+    return Token(copystr(buf),TOKEN_MULT);
+  case '/':
+    return Token(copystr(buf),TOKEN_DIV);
+  case '\n':
+    return Token(copystr(buf),TOKEN_EOL);
+  case EOF:
+    return Token(copystr(buf),TOKEN_EOF);
+  default:
+    if(breakchar(readerin->peek())) {
+      /*we've got token*/
+      if (strcmp(buf,"in")==0)
+       return Token(copystr(buf),TOKEN_IN);
+      if (strcmp(buf,"isvalid")==0)
+       return Token(copystr(buf),TOKEN_ISVALID);
+      if (strcmp(buf,"and")==0)
+       return Token(copystr(buf),TOKEN_AND);
+      if (strcmp(buf,"or")==0)
+       return Token(copystr(buf),TOKEN_OR);
+      if (strcmp(buf,"crash")==0)
+       return Token(copystr(buf),TOKEN_CRASH);
+      if (strcmp(buf,"cast")==0)
+       return Token(copystr(buf),TOKEN_CAST);
+      if (strcmp(buf,"NULL")==0)
+       return Token(copystr(buf),TOKEN_NULL);
+      if (strcmp(buf,"partition")==0)
+       return Token(copystr(buf),TOKEN_PARTITION);
+      if (strcmp(buf,"many")==0)
+       return Token(copystr(buf),TOKEN_MANY);
+      if (strcmp(buf,"set")==0)
+       return Token(copystr(buf),TOKEN_SET);
+      if (strcmp(buf,"structure")==0)
+       return Token(copystr(buf),TOKEN_STRUCTURE);
+      if (strcmp(buf,"reserved")==0)
+       return Token(copystr(buf),TOKEN_RESERVED);
+      if (strcmp(buf,"label")==0)
+       return Token(copystr(buf),TOKEN_LABEL);
+      if (strcmp(buf,"int")==0)
+       return Token(copystr(buf),TOKEN_INT);
+      if (strcmp(buf,"short")==0)
+       return Token(copystr(buf),TOKEN_SHORT);
+      if (strcmp(buf,"bit")==0)
+       return Token(copystr(buf),TOKEN_BIT);
+      if (strcmp(buf,"byte")==0)
+       return Token(copystr(buf),TOKEN_BYTE);
+      if (strcmp(buf,"subtype")==0)
+       return Token(copystr(buf),TOKEN_SUBTYPE);
+      if (strcmp(buf,"of")==0)
+       return Token(copystr(buf),TOKEN_OF);
+      if (strcmp(buf,"element")==0)
+       return Token(copystr(buf),TOKEN_ELEMENT);
+      if (strcmp(buf,"forall")==0)
+       return Token(copystr(buf),TOKEN_FORALL);
+      if (strcmp(buf,"for")==0)
+       return Token(copystr(buf),TOKEN_FOR);
+      if (strcmp(buf,"sizeof")==0)
+       return Token(copystr(buf),TOKEN_SIZEOF);
+      if (strcmp(buf,"literal")==0)
+       return Token(copystr(buf),TOKEN_LITERAL);
+      if (strcmp(buf,"param")==0)
+       return Token(copystr(buf),TOKEN_PARAM);
+      if (strcmp(buf,"1")==0)
+       return Token(copystr(buf),TOKEN_ONE);
+      if (strcmp(buf,"true")==0)
+       return Token(copystr(buf),TOKEN_TRUE);
+      if (strcmp(buf,"to")==0)
+       return Token(copystr(buf),TOKEN_TO);
+      if (strcmp(buf,"delay")==0)
+       return Token(copystr(buf),TOKEN_DELAY);
+      if (strcmp(buf,"static")==0)
+       return Token(copystr(buf),TOKEN_STATIC);
+      return Token(copystr(buf),0);
+    }
+  }
+  return Token();
+}
+
+
+// return true if the given char is a separator
+bool Reader::breakchar(int chr) {
+  switch(chr) {
+  case ' ':
+    return true;
+  case '|':
+    return true;
+  case '-':
+    return true;
+  case '+':
+    return true;
+  case '*':
+    return true;
+  case '/':
+    return true;
+  case ']':
+    return true;
+  case ')':
+    return true;
+  case ';':
+    return true;
+  case ':':
+    return true;
+  case '}':
+    return true;
+  case '[':
+    return true;
+  case '(':
+    return true;
+  case '{':
+    return true;
+  case '<':
+    return true;
+  case '=':
+    return true;
+  case '\n':
+    return true;
+  case '>':
+    return true;
+  case '.':
+    return true;
+  case ',':
+      return true;
+  default:
+    return false;
+  }
+}
+
+
+
+void Reader::error() {
+  printf("%s\n",buf);
+}
+
+
+
+void tokenname(int t) {
+  switch(t) {
+  case TOKEN_OPENBRACK:
+    printf("[");
+    break;
+  case TOKEN_CLOSEBRACK:
+    printf("]");
+    break;
+  case TOKEN_FORALL:
+    printf("forall");
+    break;
+  case TOKEN_IN:
+    printf("in");
+    break;
+  case TOKEN_OPENBRACE:
+    printf("{");
+    break;
+  case TOKEN_CLOSEBRACE:
+    printf("}");
+    break;
+  case TOKEN_COMMA:
+    printf(",");
+    break;
+  case TOKEN_SIZEOF:
+    printf("sizeof");
+    break;
+  case TOKEN_OPENPAREN:
+    printf("(");
+    break;
+  case TOKEN_CLOSEPAREN:
+    printf(")");
+    break;
+  case TOKEN_LT:
+    printf("<");
+    break;
+  case TOKEN_LTE:
+    printf("<=");
+    break;
+  case TOKEN_EQUALS:
+    printf("=");
+    break;
+  case TOKEN_GTE:
+    printf(">=");
+    break;
+  case TOKEN_GT:
+    printf(">");
+    break;
+  case TOKEN_ONE:
+    printf("1");
+    break;
+  case TOKEN_DOT:
+    printf(".");
+    break;
+  case TOKEN_DOTINV:
+    printf(".~");
+    break;
+  case TOKEN_NOT:
+    printf("!");
+    break;
+  case TOKEN_LITERAL:
+    printf("literal");
+    break;
+  case TOKEN_PARAM:
+    printf("param");
+    break;
+  case TOKEN_SUB:
+    printf("-");
+    break;
+  case TOKEN_ADD:
+    printf("+");
+    break;
+  case TOKEN_MULT:
+    printf("*");
+    break;
+  case TOKEN_AND:
+    printf("and");
+    break;
+  case TOKEN_OR:
+    printf("or");
+    break;
+  case TOKEN_EOL:
+    printf("EOL");
+    break;
+  case TOKEN_EOF:
+    printf("EOF");
+    break;
+  case TOKEN_IMPLIES:
+    printf("=>");
+    break;
+  case TOKEN_TRUE:
+    printf("true");
+    break;
+  case TOKEN_FOR:
+    printf("for");
+    break;
+  case TOKEN_TO:
+    printf("to");
+    break;
+  case TOKEN_STRUCTURE:
+    printf("structure");
+    break;
+  case TOKEN_RESERVED:
+    printf("reserved");
+    break;
+  case TOKEN_LABEL:
+    printf("label");
+    break;
+  case TOKEN_INT:
+    printf("int");
+    break;
+  case TOKEN_BIT:
+    printf("bit");
+    break;
+  case TOKEN_BYTE:
+    printf("byte");
+    break;
+  case TOKEN_SUBTYPE:
+    printf("subtype");
+    break;
+  case TOKEN_OF:
+    printf("of");
+    break;
+  case TOKEN_SEMI:
+    printf(";");
+    break;
+  case TOKEN_COLON:
+    printf(":");
+    break;
+  case TOKEN_SET:
+    printf("set");
+    break;
+  case TOKEN_ARROW:
+    printf("->");
+    break;
+  case TOKEN_MANY:
+    printf("many");
+    break;
+  case TOKEN_BAR:
+    printf("|");
+    break;
+  case TOKEN_PARTITION:
+    printf("partition");
+    break;
+  case TOKEN_ELEMENT:
+    printf("element");
+    break;
+  default:
+    printf("undefined token");
+  }
+}
diff --git a/Repair/RepairInterpreter/token.h b/Repair/RepairInterpreter/token.h
new file mode 100755 (executable)
index 0000000..8b29c03
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef Token_H
+#define Token_H
+
+#include "common.h"
+#include <iostream.h>
+#include <stdio.h>
+#include "classlist.h"
+
+class Token {
+ public:
+  Token(char *s, int tt);
+  Token(const Token & t);
+   Token & operator=(const Token &right);
+  Token();
+  ~Token();
+  int token_type;
+  char* str;
+
+ private:
+};
+void tokenname(int t);
+
+#define TOKEN_OPENBRACK 1
+#define TOKEN_CLOSEBRACK 2
+#define TOKEN_FORALL 3
+#define TOKEN_IN 4
+#define TOKEN_OPENBRACE 5
+#define TOKEN_CLOSEBRACE 6
+#define TOKEN_COMMA 7
+#define TOKEN_SIZEOF 8
+#define TOKEN_OPENPAREN 9
+#define TOKEN_CLOSEPAREN 10
+#define TOKEN_LT 11
+#define TOKEN_LTE 12
+#define TOKEN_EQUALS 13
+#define TOKEN_GTE 14
+#define TOKEN_GT 15
+#define TOKEN_ONE 16
+#define TOKEN_DOT 17
+#define TOKEN_DOTINV 18
+#define TOKEN_NOT 19
+#define TOKEN_LITERAL 20
+#define TOKEN_PARAM 21
+#define TOKEN_SUB 22
+#define TOKEN_ADD 23
+#define TOKEN_MULT 24
+#define TOKEN_AND 25
+#define TOKEN_OR 26
+#define TOKEN_EOL 27
+#define TOKEN_EOF 28
+#define TOKEN_IMPLIES 29
+#define TOKEN_TRUE 30
+#define TOKEN_ISVALID 31
+#define TOKEN_FOR 32
+#define TOKEN_TO 33
+#define TOKEN_STRUCTURE 34
+#define TOKEN_RESERVED 35
+#define TOKEN_LABEL 36
+#define TOKEN_INT 37
+#define TOKEN_BIT 38
+#define TOKEN_BYTE 39
+#define TOKEN_SUBTYPE 40
+#define TOKEN_OF 41
+#define TOKEN_SEMI 42
+#define TOKEN_COLON 43
+#define TOKEN_SET 44
+#define TOKEN_ARROW 45
+#define TOKEN_MANY 46
+#define TOKEN_BAR 47
+#define TOKEN_PARTITION 48
+#define TOKEN_ELEMENT 49
+#define TOKEN_DELAY 50
+#define TOKEN_STATIC 51
+#define TOKEN_DIV 52
+#define TOKEN_CAST 53
+#define TOKEN_SHORT 54
+#define TOKEN_NULL 55
+#define TOKEN_CRASH 56
+
+
+
+class Reader{
+ public:
+  Reader(istream * is);
+  Token readnext();
+  Token peakahead();
+  void error();
+
+ private:
+  bool breakchar(int);
+  Token checktoken();
+  istream *readerin;
+  char buf[200];
+  int pos;
+};
+
+#endif
diff --git a/Repair/RepairInterpreter/typeparser.cc b/Repair/RepairInterpreter/typeparser.cc
new file mode 100755 (executable)
index 0000000..3042339
--- /dev/null
@@ -0,0 +1,332 @@
+#include <stdlib.h>
+#include "typeparser.h"
+#include "list.h"
+#include "common.h"
+#include "token.h"
+#include "tmodel.h"
+#include "amodel.h"
+#include "omodel.h"
+
+Typeparser::Typeparser(Reader *r) {
+  reader=r;
+}
+
+structure * Typeparser::parsestructure() {
+  Token t=reader->peakahead();
+  while(true) {
+    if (t.token_type==TOKEN_EOF)
+      return NULL;
+    if (t.token_type!=TOKEN_EOL)
+      break;
+    skiptoken();
+    t=reader->peakahead();
+  }
+  needtoken(TOKEN_STRUCTURE);
+  Token typenam=reader->readnext();
+  structure *pstructure=new structure(copystr(typenam.str));
+  /*  needtoken(TOKEN_OPENPAREN);
+  bool continueparse=true;
+  List *list=new List();
+  while(continueparse) {
+    Token t=reader->readnext();
+    switch(t.token_type) {
+    case TOKEN_CLOSEPAREN:
+      continueparse=false;
+      break;
+    case TOKEN_INT:
+      {
+       Token name=reader->readnext();
+       tparam * tpar=new tparam(new ttype(TTYPE_INT),copystr(name.str));
+       list->addobject(tpar);
+       commaorcloseparen();
+       break;
+      }
+    case TOKEN_BIT:
+      {
+       Token name=reader->readnext();
+       tparam * tpar=new tparam(new ttype(TTYPE_BIT),copystr(name.str));
+       list->addobject(tpar);
+       commaorcloseparen();
+       break;
+      }
+    case TOKEN_BYTE:
+      {
+       Token name=reader->readnext();
+       tparam * tpar=new tparam(new ttype(TTYPE_BYTE),copystr(name.str));
+       list->addobject(tpar);
+       commaorcloseparen();
+       break;
+      }
+    default:
+      {
+       Token name=reader->readnext();
+       tparam *tpar=new tparam(new ttype(copystr(typenam.str)),copystr(name.str));
+       list->addobject(tpar);
+       commaorcloseparen();
+       break;
+      }
+    }
+  }
+  tparam **tp=new tparam*[list->size()];
+  list->toArray((void**) tp);
+  pstructure->setparams(tp,list->size());
+  delete(list);*/
+
+  Token t2=reader->peakahead();
+  if (t2.token_type==TOKEN_SUBTYPE) {
+    skiptoken();
+    needtoken(TOKEN_OF);
+    pstructure->setsubtype(parsettype());
+  }
+
+  List *list=new List();
+  List *labellist=new List();
+  needtoken(TOKEN_OPENBRACE);
+  while(true) {
+    while (reader->peakahead().token_type==TOKEN_EOL)
+      skiptoken();
+    Token t=reader->peakahead();
+    if (t.token_type==TOKEN_CLOSEBRACE)
+      break;
+    if (t.token_type==TOKEN_LABEL) {
+      labellist->addobject(parsetlabel());
+    } else  
+      list->addobject(parsetfield());
+  }
+  tfield **tarray=new tfield*[list->size()];
+  tlabel **larray=new tlabel*[labellist->size()];
+  list->toArray((void **)tarray);
+  labellist->toArray((void**)larray);
+  pstructure->setfields(tarray,list->size());
+  pstructure->setlabels(larray,labellist->size());
+  needtoken(TOKEN_CLOSEBRACE);
+  delete(list);
+  delete(labellist);
+  return pstructure;
+}
+
+tlabel * Typeparser::parsetlabel() {
+  needtoken(TOKEN_LABEL);
+  Token fieldname=reader->readnext();
+  AElementexpr *index=NULL;
+  if (reader->peakahead().token_type==TOKEN_OPENBRACK) {
+    skiptoken();
+    index=parseaelementexpr(true);
+    needtoken(TOKEN_CLOSEBRACK);
+  }
+  needtoken(TOKEN_COLON);
+  tfield *tf=parsetfield();
+  return new tlabel(tf,copystr(fieldname.str),index);
+}
+
+tfield * Typeparser::parsetfield() {
+  static int rcount=0;
+  Token t=reader->peakahead();
+  bool reserved=false;
+  if (t.token_type==TOKEN_RESERVED) {
+    reserved=true;
+    skiptoken();
+  }
+  ttype *tt=parsettype();
+  while(true) {
+    Token isptr=reader->peakahead();
+    if (isptr.token_type==TOKEN_MULT) {
+      tt->makeptr();
+      skiptoken();
+      break; /*Only support direct pointers right now*/
+    } else
+      break;
+  }
+  Token fieldname;
+  if (!reserved)
+    fieldname=reader->readnext();
+  AElementexpr *size=parseindex();
+  tt->setsize(size);
+  needtoken(TOKEN_SEMI);
+  if (reserved) 
+    return new tfield(tt,copystr("RESERVED"+(rcount++)));
+  else
+    return new tfield(tt,copystr(fieldname.str));
+}
+
+ttype * Typeparser::parsettype() {
+  Token name=reader->readnext();
+  switch(name.token_type) {
+  case TOKEN_BIT:
+    {
+      return new ttype(TTYPE_BIT);
+    }
+  case TOKEN_INT:
+    {
+      return new ttype(TTYPE_INT);
+    }
+  case TOKEN_SHORT:
+    {
+      return new ttype(TTYPE_SHORT);
+    }
+  case TOKEN_BYTE:
+    {
+      return new ttype(TTYPE_BYTE);
+    }
+  default:
+    {
+      /*
+      needtoken(TOKEN_OPENPAREN);
+      List *list=new List();
+      while(reader->peakahead().token_type!=TOKEN_CLOSEPAREN) {
+       list->addobject(parseaelementexpr(false));
+       commaorcloseparen();
+      }
+      skiptoken();
+      AElementexpr **earray=new AElementexpr*[list->size()];
+      list->toArray((void**)earray);*/
+      ttype *ntt=new ttype(copystr(name.str),NULL);
+      //delete(list);
+      return ntt;
+    }
+  }
+}
+
+AElementexpr * Typeparser::parseindex() {
+  Token t=reader->peakahead();
+  if (t.token_type!=TOKEN_OPENBRACK)
+    return NULL;
+  skiptoken();
+  AElementexpr * ae=parseaelementexpr(true);
+  needtoken(TOKEN_CLOSEBRACK);
+  return ae;
+}
+
+void Typeparser::commaorcloseparen() {
+  Token t=reader->peakahead();
+  if (t.token_type!=TOKEN_CLOSEPAREN)
+    needtoken(TOKEN_COMMA);
+}
+
+AElementexpr * Typeparser::parseaelementexpr(bool isstruct) {
+  AElementexpr *oldee=NULL;
+  int joinop=-1;
+  while(true) {
+  Token t=reader->peakahead();
+  switch(t.token_type) {
+  case TOKEN_LITERAL:
+    {
+      if ((joinop==-1)&&(oldee!=NULL))
+       return oldee;
+      skiptoken();
+      needtoken(TOKEN_OPENPAREN);
+      Token literal=reader->readnext();
+      needtoken(TOKEN_CLOSEPAREN);
+      if (oldee==NULL)
+       oldee=new AElementexpr(new Literal(copystr(literal.str)));
+      else {
+       if (joinop!=-1) {
+         oldee=new AElementexpr(oldee,new AElementexpr(new Literal(copystr(literal.str))),joinop);
+         joinop=-1;
+       } else error();
+      }
+      break;
+    }
+
+  case TOKEN_OPENPAREN:
+    {
+      if ((joinop==-1)&&(oldee!=NULL))
+       return oldee;
+      skiptoken();
+      AElementexpr *ee=parseaelementexpr(false);
+      if (oldee==NULL)
+       oldee=ee;
+      else {
+       if (joinop!=-1) {
+         oldee=new AElementexpr(oldee,ee,joinop);
+         joinop=-1;
+       } else error();
+      }
+      break;
+    }
+  case TOKEN_CLOSEBRACK:
+    if (isstruct)
+      return oldee;
+  case TOKEN_CLOSEPAREN:
+    skiptoken();
+    return checkdot(oldee);
+    break;
+  case TOKEN_SUB:
+    skiptoken();
+    if ((oldee!=NULL)&&(joinop==-1))
+      joinop=AELEMENTEXPR_SUB;
+    else
+      error();
+    break;
+  case TOKEN_ADD:
+    skiptoken();
+    if ((oldee!=NULL)&&(joinop==-1))
+      joinop=AELEMENTEXPR_ADD;
+    else
+      error();
+    break;
+  case TOKEN_MULT:
+    skiptoken();
+    if ((oldee!=NULL)&&(joinop==-1))
+      joinop=AELEMENTEXPR_MULT;
+    else
+      error();
+    break;
+  case TOKEN_DIV:
+    skiptoken();
+    if ((oldee!=NULL)&&(joinop==-1))
+      joinop=AELEMENTEXPR_DIV;
+    else
+      error();
+    break;
+  default:
+    if ((joinop==-1)&&(oldee!=NULL))
+      return oldee;
+    skiptoken();
+    if (oldee==NULL)
+      oldee=checkdot(new AElementexpr(new Label(copystr(t.str))));
+    else {
+      if (joinop!=-1) {
+       oldee=new AElementexpr(oldee,checkdot(new AElementexpr(new Label(copystr(t.str)))),joinop);
+       joinop=-1;
+      } else error();
+    }
+  }
+  }
+}
+
+AElementexpr * Typeparser::checkdot(AElementexpr * incoming) {
+  Token tdot=reader->peakahead();
+  if (tdot.token_type!=TOKEN_DOT) return incoming;
+  skiptoken();
+  Token tfield=reader->readnext();
+  Token tpeak=reader->peakahead();
+  if (tpeak.token_type==TOKEN_OPENBRACK) {
+    skiptoken();
+    AElementexpr *index=parseaelementexpr(false);
+    return checkdot(new AElementexpr(incoming, new Field(copystr(tfield.str)),index));
+  } else {
+    return checkdot(new AElementexpr(incoming, new Field(copystr(tfield.str))));
+  }
+}
+
+void Typeparser::error() {
+  printf("ERROR\n");
+  reader->error();
+  exit(-1);
+}
+
+void Typeparser::skiptoken() {
+  reader->readnext();
+}
+
+void Typeparser::needtoken(int token) {
+  Token t=reader->readnext();
+  if (!(t.token_type==token)) {
+    printf("Needed token: ");
+    tokenname(token);
+    printf("\n Got token: %s ",t.str);
+    tokenname(t.token_type);
+    error();
+  }
+}
diff --git a/Repair/RepairInterpreter/typeparser.h b/Repair/RepairInterpreter/typeparser.h
new file mode 100755 (executable)
index 0000000..0d2bc68
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef TYPEPARSER_H
+#define TYPEPARSER_H
+
+#include "common.h"
+#include <iostream.h>
+#include <stdio.h>
+#include "classlist.h"
+
+
+// This class defines a parser for the structure definitions
+
+class Typeparser {
+ public:
+  Typeparser(Reader *r);
+  structure * parsestructure();
+ private:
+  void commaorcloseparen();
+  AElementexpr *checkdot(AElementexpr* incoming);
+  AElementexpr *parseaelementexpr(bool);
+  tlabel * parsetlabel();
+  tfield * parsetfield();
+  ttype * parsettype();
+  AElementexpr * parseindex();
+  Reader *reader;
+  void skiptoken();
+  void needtoken(int);
+  void error();
+};
+#endif