Moved the interpreter
[repair.git] / Repair / RepairInterpreter / model.cc
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*/
+}