ExactSize exactsize;
ArrayAnalysis arrayanalysis;
Sources sources;
+ static String conjoption="style=bold";
+ static String absrepoption="shape=box,color=blue,style=bold";
+ static String updateoption="shape=box,color=red,style=bold";
+ static String scopeoption="color=brown";
+ static String conseqoption="style=bold,color=green";
+ static String compoption="shape=box,color=purple,style=bold";
public Termination(State state) {
this.state=state;
predtoabstractmap=new Hashtable();
if (!Compiler.REPAIR)
return;
-
+
for(int i=0;i<state.vRules.size();i++)
System.out.println(state.vRules.get(i));
generateconjunctionnodes();
constraintdependence=new ConstraintDependence(state,this);
+ debugmsg("*****Generating scope nodes*****");
generatescopenodes();
+ debugmsg("*****Generating repair nodes*****");
generaterepairnodes();
+ debugmsg("*****Generating data structure nodes*****");
generatedatastructureupdatenodes();
- generatecompensationnodes();
-
+ debugmsg("*****Generating compensation nodes*****");
+ if (!Compiler.OMITCOMP)
+ generatecompensationnodes();
+ debugmsg("*****Generating abstract edges*****");
generateabstractedges();
+ debugmsg("*****Generating scope edges*****");
generatescopeedges();
+ debugmsg("*****Generating update edges*****");
generateupdateedges();
HashSet superset=new HashSet();
superset.addAll(conjunctions);
HashSet closureset=new HashSet();
-
+ debugmsg("Computing closure");
GraphNode.computeclosure(superset,closureset);
try {
GraphNode.DOTVisitor.visit(new FileOutputStream("graph.dot"),superset);
void generatedebuggraphs() {
for (int i=0;i<Compiler.debuggraphs.size();i++) {
DebugItem di=(DebugItem) Compiler.debuggraphs.get(i);
- Constraint constr=(Constraint)state.vConstraints.get(di.constraintnum);
HashSet superset=new HashSet();
- superset.addAll((Set)conjunctionmap.get(constr));
- HashSet closureset=new HashSet();
-
- GraphNode.boundedcomputeclosure(superset,closureset,di.depth);
+ Constraint constr=(Constraint)state.vConstraints.get(di.constraintnum);
+
+ if (di.conjunctionnum==-1) {
+ superset.addAll((Set)conjunctionmap.get(constr));
+ } else {
+ DNFConstraint dnf=constr.dnfconstraint;
+ superset.add(conjtonodemap.get(dnf.get(di.conjunctionnum)));
+ }
+
+ GraphNode.boundedcomputeclosure(superset,null,di.depth);
try {
- GraphNode.DOTVisitor.visit(new FileOutputStream("graph"+di.constraintnum+"-"+di.depth+".dot"),superset);
+ GraphNode.DOTVisitor.visit(new FileOutputStream("graph"+di.constraintnum+"-"+di.depth+(di.conjunctionnum==-1?"":"-"+di.conjunctionnum)+".dot"),superset);
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
GraphNode gn=new GraphNode("Conj"+i+"A"+j,
"Conj ("+i+","+j+") "+dnf.get(j).name()
,tn);
+ gn.setOption(conjoption);
conjunctions.add(gn);
if (!conjunctionmap.containsKey(c))
conjunctionmap.put(c,new HashSet());
GraphNode gn=new GraphNode("Conj"+i+"AQ"+j,
"Conj ("+i+","+j+") "+dconst.get(0).name()
,tn);
+ gn.setOption(conjoption);
conjunctions.add(gn);
if (!conjunctionmap.containsKey(c))
conjunctionmap.put(c,new HashSet());
GraphNode gn=new GraphNode("Conj"+i+"AQ"+j,
"Conj ("+i+","+j+") "+dconst.get(0).name()
,tn);
+ gn.setOption(conjoption);
conjunctions.add(gn);
if (!conjunctionmap.containsKey(c))
conjunctionmap.put(c,new HashSet());
((Set)conjunctionmap.get(c)).add(gn);
conjtonodemap.put(dconst.get(0),gn);
-
}
}
}
TupleOfExpr toe=(TupleOfExpr)e;
if (negated) {
GraphNode agn=(GraphNode)abstractremove.get(toe.relation);
- GraphNode.Edge edge=new GraphNode.Edge("requires",agn);
+ GraphNode.Edge edge=new GraphNode.Edge("requirestupleremove",agn);
gn.addEdge(edge);
} else {
GraphNode agn=(GraphNode)abstractadd.get(toe.relation);
- GraphNode.Edge edge=new GraphNode.Edge("requires",agn);
+ GraphNode.Edge edge=new GraphNode.Edge("requirestupleadd",agn);
gn.addEdge(edge);
}
} else if (e instanceof ElementOfExpr) {
ElementOfExpr eoe=(ElementOfExpr)e;
if (negated) {
GraphNode agn=(GraphNode)abstractremove.get(eoe.set);
- GraphNode.Edge edge=new GraphNode.Edge("requires",agn);
+ GraphNode.Edge edge=new GraphNode.Edge("requireselementremove",agn);
gn.addEdge(edge);
} else {
GraphNode agn=(GraphNode)abstractadd.get(eoe.set);
- GraphNode.Edge edge=new GraphNode.Edge("requires",agn);
+ GraphNode.Edge edge=new GraphNode.Edge("requireselementadd",agn);
gn.addEdge(edge);
}
} else throw new Error("Unrecognized Abstract Update");
}
}
}
-
/* Cycle through the rules to look for possible conflicts */
for(int i=0;i<state.vRules.size();i++) {
- Rule r=(Rule) state.vRules.get(i);
+ Rule r=(Rule) state.vRules.get(i);
+ if (Compiler.DEBUGGRAPH) {
+ System.out.println(gn.getLabel()+"--->"+((GraphNode)scopesatisfy.get(r)).getLabel());
+ }
if (concreteinterferes.interferes(mun,r,true)) {
GraphNode scopenode=(GraphNode)scopesatisfy.get(r);
- GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
+ GraphNode.Edge e=new GraphNode.Edge("satisfyscopeinterferes",scopenode);
gn.addEdge(e);
}
+ if (Compiler.DEBUGGRAPH) {
+ System.out.println(gn.getLabel()+"--->"+((GraphNode)scopefalsify.get(r)).getLabel());
+ }
if (concreteinterferes.interferes(mun,r,false)) {
GraphNode scopenode=(GraphNode)scopefalsify.get(r);
- GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
+ GraphNode.Edge e=new GraphNode.Edge("falsifyscopeinterferes",scopenode);
gn.addEdge(e);
}
}
GraphNode gn=(GraphNode)absiterator.next();
TermNode tn=(TermNode)gn.getOwner();
AbstractRepair ar=(AbstractRepair)tn.getAbstract();
-
+
for(Iterator conjiterator=conjunctions.iterator();conjiterator.hasNext();) {
GraphNode gn2=(GraphNode)conjiterator.next();
TermNode tn2=(TermNode)gn2.getOwner();
Conjunction conj=tn2.getConjunction();
Constraint cons=tn2.getConstraint();
-
- for(int i=0;i<conj.size();i++) {
- DNFPredicate dp=conj.get(i);
- System.out.println("Checking "+gn.getTextLabel()+" --> "+gn2.getTextLabel());
- if (AbstractInterferes.interferes(ar,cons)||
- abstractinterferes.interferes(ar,dp)) {
- GraphNode.Edge e=new GraphNode.Edge("interferes",gn2);
- gn.addEdge(e);
- break;
- }
- }
+ /* See if this is a relation wellformedness constraint
+ that is trivially satisfied. */
+ if (abstractinterferes.checkrelationconstraint(ar, cons))
+ continue;
+ if (AbstractInterferes.interferesquantifier(ar,cons)) {
+ GraphNode.Edge e=new GraphNode.Edge("interferesquantifier",gn2);
+ gn.addEdge(e);
+ } else {
+ for(int i=0;i<conj.size();i++) {
+ DNFPredicate dp=conj.get(i);
+
+ if (!abstractinterferes.interfereswithpredicate(ar,dp))
+ continue;
+ if (getConstraint(gn)==null||
+ !abstractinterferes.interferemodifies(ar,getConstraint(gn),dp,cons)) {
+ GraphNode.Edge e=new GraphNode.Edge("interferesmodify",gn2);
+ gn.addEdge(e);
+ break;
+ }
+ }
+ }
}
-
for(Iterator scopeiterator=scopenodes.iterator();scopeiterator.hasNext();) {
GraphNode gn2=(GraphNode)scopeiterator.next();
TermNode tn2=(TermNode)gn2.getOwner();
ScopeNode sn2=tn2.getScope();
- if (AbstractInterferes.interferes(ar,sn2.getRule(),sn2.getSatisfy())) {
- GraphNode.Edge e=new GraphNode.Edge("interferes",gn2);
+ if (AbstractInterferes.interfereswithrule(ar,sn2.getRule(),sn2.getSatisfy())) {
+ GraphNode.Edge e=new GraphNode.Edge("interfereswithrule",gn2);
gn.addEdge(e);
}
}
}
}
+ Constraint getConstraint(GraphNode gn) {
+ for(Iterator it=gn.inedges();it.hasNext();) {
+ GraphNode.Edge e=(GraphNode.Edge)it.next();
+ GraphNode gnsource=e.getSource();
+ TermNode tnsource=(TermNode)gnsource.getOwner();
+ if (tnsource.getType()==TermNode.CONJUNCTION) {
+ return tnsource.getConstraint();
+ }
+ }
+ return null;
+ }
+
void generatescopenodes() {
for(int i=0;i<state.vRules.size();i++) {
Rule r=(Rule) state.vRules.get(i);
ScopeNode satisfy=new ScopeNode(r,true);
TermNode tnsatisfy=new TermNode(satisfy);
GraphNode gnsatisfy=new GraphNode("SatisfyRule"+i,tnsatisfy);
+ gnsatisfy.setOption(scopeoption);
+ if (Compiler.MERGENODES)
+ gnsatisfy.setMerge();
ConsequenceNode cnsatisfy=new ConsequenceNode();
TermNode ctnsatisfy=new TermNode(cnsatisfy);
GraphNode cgnsatisfy=new GraphNode("ConseqSatisfyRule"+i,ctnsatisfy);
+ cgnsatisfy.setOption(conseqoption);
consequence.put(satisfy,cgnsatisfy);
GraphNode.Edge esat=new GraphNode.Edge("consequencesatisfy"+i,cgnsatisfy);
gnsatisfy.addEdge(esat);
ScopeNode falsify=new ScopeNode(r,false);
TermNode tnfalsify=new TermNode(falsify);
GraphNode gnfalsify=new GraphNode("FalsifyRule"+i,tnfalsify);
+ gnfalsify.setOption(scopeoption);
+ if (Compiler.MERGENODES)
+ gnfalsify.setMerge();
ConsequenceNode cnfalsify=new ConsequenceNode();
TermNode ctnfalsify=new TermNode(cnfalsify);
GraphNode cgnfalsify=new GraphNode("ConseqFalsifyRule"+i,ctnfalsify);
+ cgnfalsify.setOption(conseqoption);
consequence.put(falsify,cgnfalsify);
GraphNode.Edge efals=new GraphNode.Edge("consequencefalsify"+i,cgnfalsify);
gnfalsify.addEdge(efals);
scopenodes.add(gnfalsify);
}
}
-
+
void generatescopeedges() {
for(Iterator scopeiterator=scopenodes.iterator();scopeiterator.hasNext();) {
GraphNode gn=(GraphNode)scopeiterator.next();
TermNode tn=(TermNode)gn.getOwner();
ScopeNode sn=tn.getScope();
-
+
/* Interference edges with conjunctions */
for(Iterator conjiterator=conjunctions.iterator();conjiterator.hasNext();) {
GraphNode gn2=(GraphNode)conjiterator.next();
Constraint constr=tn2.getConstraint();
for(int i=0;i<conj.size();i++) {
DNFPredicate dp=conj.get(i);
- if (abstractinterferes.interferes(sn,dp)||
- AbstractInterferes.interferes(sn.getDescriptor(),sn.getSatisfy(),constr)) {
- GraphNode.Edge e=new GraphNode.Edge("interferes",gn2);
+ if (abstractinterferes.scopeinterfereswithpredicate(sn,dp)||
+ AbstractInterferes.interfereswithquantifier(sn.getDescriptor(),sn.getSatisfy(),constr)) {
+ GraphNode.Edge e=new GraphNode.Edge("interferesconjunction",gn2);
GraphNode gnconseq=(GraphNode)consequence.get(sn);
gnconseq.addEdge(e);
break;
/* Now see if this could effect other model defintion rules */
for(int i=0;i<state.vRules.size();i++) {
Rule r=(Rule) state.vRules.get(i);
- if (AbstractInterferes.interferes(sn.getDescriptor(),sn.getSatisfy(),r,true)) {
+ if (AbstractInterferes.interfereswithrule(sn.getDescriptor(),sn.getSatisfy(),r,true)) {
GraphNode scopenode=(GraphNode)scopesatisfy.get(r);
- GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
+ GraphNode.Edge e=new GraphNode.Edge("interferesscopesatisfy2",scopenode);
GraphNode gnconseq=(GraphNode)consequence.get(sn);
gnconseq.addEdge(e);
}
- if (AbstractInterferes.interferes(sn.getDescriptor(),sn.getSatisfy(),r,false)) {
+ if (AbstractInterferes.interfereswithrule(sn.getDescriptor(),sn.getSatisfy(),r,false)) {
GraphNode scopenode=(GraphNode)scopefalsify.get(r);
- GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
+ GraphNode.Edge e=new GraphNode.Edge("interferesscopefalsify2",scopenode);
GraphNode gnconseq=(GraphNode)consequence.get(sn);
gnconseq.addEdge(e);
}
GraphNode gn=(GraphNode)conjiterator.next();
TermNode tn=(TermNode)gn.getOwner();
Conjunction conj=tn.getConjunction();
+ loop:
for(int i=0;i<conj.size();i++) {
DNFPredicate dp=conj.get(i);
int[] array=dp.getPredicate().getRepairs(dp.isNegated(),this);
Descriptor d=dp.getPredicate().getDescriptor();
+ if ((dp.getPredicate() instanceof ExprPredicate)&&
+ (((ExprPredicate)dp.getPredicate()).getType()==ExprPredicate.SIZE)) {
+ boolean neg=dp.isNegated();
+ Opcode op=((ExprPredicate)dp.getPredicate()).getOp();
+ int size=((ExprPredicate)dp.getPredicate()).rightSize();
+ op=Opcode.translateOpcode(neg,op);
+ if (((size==1)&&(op==Opcode.EQ))||
+ ((size!=1)&&(op==Opcode.NE))||
+ ((size<=1)&&(op==Opcode.GE))||
+ ((size<1)&&(op==Opcode.GT))||
+ ((size>1)&&(op==Opcode.LT))||
+ ((size>=1)&&(op==Opcode.LE))) {
+ for(int i2=0;i2<conj.size();i2++) {
+ DNFPredicate dp2=conj.get(i2);
+ if ((dp2.getPredicate() instanceof ExprPredicate)&&
+ (((ExprPredicate)dp2.getPredicate()).getType()==ExprPredicate.COMPARISON)) {
+ if (equivalent(((SizeofExpr)((OpExpr)((ExprPredicate)dp.getPredicate()).expr).left).setexpr,
+ (RelationExpr)((OpExpr)((ExprPredicate)dp2.getPredicate()).expr).left))
+ continue loop; // comparison predicate ensure that size expr is true - no need to generate abstract repairs...
+ }
+ }
+ }
+ }
+
for(int j=0;j<array.length;j++) {
+ if (array[j]==AbstractRepair.ADDTOSET) {
+
+ System.out.println("1");
+ if ((dp.getPredicate() instanceof ExprPredicate)&&
+ (((ExprPredicate)dp.getPredicate()).getType()==ExprPredicate.SIZE)) {
+ System.out.println("2");
+ boolean neg=dp.isNegated();
+ Opcode op=((ExprPredicate)dp.getPredicate()).getOp();
+ int size=((ExprPredicate)dp.getPredicate()).rightSize();
+ op=Opcode.translateOpcode(neg,op);
+ Descriptor des=((ExprPredicate)dp.getPredicate()).getDescriptor();
+ if (des instanceof SetDescriptor) {
+ System.out.println("3");
+
+ int minsize=exactsize.minSize((SetDescriptor)des);
+ Constraint reqc=exactsize.ensuresMinSize((SetDescriptor)des);
+ if (((size==minsize)&&(op==Opcode.EQ))||
+ ((size<=minsize)&&(op==Opcode.GE))||
+ ((size<minsize)&&(op==Opcode.GT))) {
+ System.out.println("4");
+ constraintdependence.requiresConstraint(gn,reqc);
+ //force good ordering
+ continue; //no repair action needed here...
+ }
+ }
+ }
+ }
+
AbstractRepair ar=new AbstractRepair(dp,array[j],d,sources);
TermNode tn2=new TermNode(ar);
- GraphNode gn2=new GraphNode(gn.getLabel()+"A"+i+"B"+ar.type(),gn.getTextLabel()+" #"+i+" "+ar.type(),tn2);
- GraphNode.Edge e=new GraphNode.Edge("abstract",gn2);
+ // GraphNode gn2=new GraphNode(gn.getLabel()+"A"+i+"B"+ar.type(),gn.getTextLabel()+" #"+i+" "+ar.type(),tn2);
+ GraphNode gn2=new GraphNode(gn.getLabel()+"A"+i+"B"+ar.type(),dp.name()+" "+ar.type(),tn2);
+ gn2.setOption(absrepoption);
+ GraphNode.Edge e=new GraphNode.Edge("abstractedge1",gn2);
gn.addEdge(e);
if (!predtoabstractmap.containsKey(dp))
predtoabstractmap.put(dp,new HashSet());
AbstractRepair ar=new AbstractRepair(tp, AbstractRepair.ADDTOSET, sd,sources);
TermNode tn=new TermNode(ar);
GraphNode gn=new GraphNode("AbstractAddSetRule"+i,tn);
+ gn.setOption(absrepoption);
if (!predtoabstractmap.containsKey(tp))
predtoabstractmap.put(tp,new HashSet());
((Set)predtoabstractmap.get(tp)).add(gn);
abstractrepair.add(gn);
abstractrepairadd.add(gn);
abstractadd.put(sd,gn);
-
+
DNFPredicate tp2=new DNFPredicate(true,ip);
AbstractRepair ar2=new AbstractRepair(tp2, AbstractRepair.REMOVEFROMSET, sd,sources);
TermNode tn2=new TermNode(ar2);
GraphNode gn2=new GraphNode("AbstractRemSetRule"+i,tn2);
+ gn2.setOption(absrepoption);
if (!predtoabstractmap.containsKey(tp2))
predtoabstractmap.put(tp2,new HashSet());
((Set)predtoabstractmap.get(tp2)).add(gn2);
VarExpr ve2=new VarExpr("DUMMY2");
InclusionPredicate ip=new InclusionPredicate(ve2,new ImageSetExpr(vd1, rd));
-
+
DNFPredicate tp=new DNFPredicate(false,ip);
AbstractRepair ar=new AbstractRepair(tp, AbstractRepair.ADDTORELATION, rd,sources);
TermNode tn=new TermNode(ar);
GraphNode gn=new GraphNode("AbstractAddRelRule"+i,tn);
+ gn.setOption(absrepoption);
if (!predtoabstractmap.containsKey(tp))
predtoabstractmap.put(tp,new HashSet());
((Set)predtoabstractmap.get(tp)).add(gn);
abstractrepair.add(gn);
abstractrepairadd.add(gn);
abstractadd.put(rd,gn);
-
+
DNFPredicate tp2=new DNFPredicate(true,ip);
AbstractRepair ar2=new AbstractRepair(tp2, AbstractRepair.REMOVEFROMRELATION, rd,sources);
TermNode tn2=new TermNode(ar2);
GraphNode gn2=new GraphNode("AbstractRemRelRule"+i,tn2);
+ gn2.setOption(absrepoption);
if (!predtoabstractmap.containsKey(tp2))
predtoabstractmap.put(tp2,new HashSet());
((Set)predtoabstractmap.get(tp2)).add(gn2);
MultUpdateNode mun=new MultUpdateNode(sn);
TermNode tn2=new TermNode(mun);
GraphNode gn2=new GraphNode("CompRem"+compensationcount,tn2);
+ gn2.setOption(compoption);
UpdateNode un=new UpdateNode(r);
if (j<r.numQuantifiers()) {
un.addUpdate(u);
if (abstractremove.containsKey(rq.relation)) {
GraphNode agn=(GraphNode)abstractremove.get(rq.relation);
- GraphNode.Edge e=new GraphNode.Edge("requires",agn);
+ GraphNode.Edge e=new GraphNode.Edge("requiresremove1",agn);
gn2.addEdge(e);
} else {
continue; /* Abstract repair doesn't exist */
un.addUpdate(u);
if (abstractremove.containsKey(sq.set)) {
GraphNode agn=(GraphNode)abstractremove.get(sq.set);
- GraphNode.Edge e=new GraphNode.Edge("requires",agn);
+ GraphNode.Edge e=new GraphNode.Edge("requiresremove2",agn);
gn2.addEdge(e);
} else {
continue; /* Abstract repair doesn't exist */
continue;
}
}
- if (!un.checkupdates()) /* Make sure we have a good update */
+ if (!un.checkupdates(state)) /* Make sure we have a good update */
continue;
-
+
mun.addUpdate(un);
- GraphNode.Edge e=new GraphNode.Edge("abstract"+compensationcount,gn2);
+ GraphNode.Edge e=new GraphNode.Edge("abstractcomp"+compensationcount,gn2);
compensationcount++;
gn.addEdge(e);
updatenodes.add(gn2);
void generatedatastructureupdatenodes() {
for(Iterator absiterator=abstractrepair.iterator();absiterator.hasNext();) {
GraphNode gn=(GraphNode)absiterator.next();
+ System.out.println("Analysing: "+gn.getTextLabel());
TermNode tn=(TermNode) gn.getOwner();
AbstractRepair ar=tn.getAbstract();
if (ar.getType()==AbstractRepair.ADDTOSET) {
generateremovefromsetrelation(gn,ar);
} else if (ar.getType()==AbstractRepair.MODIFYRELATION) {
/* Generate remove/add pairs */
- generateremovefromsetrelation(gn,ar);
+ if (ar.needsRemoves(state))
+ generateremovefromsetrelation(gn,ar);
generateaddtosetrelation(gn,ar);
/* Generate atomic modify */
generatemodifyrelation(gn,ar);
}
if (possiblerules.size()==0)
return;
-
+
/* Loop through different ways of falsifying each of these rules */
int[] count=new int[possiblerules.size()];
while(remains(count,possiblerules,true)) {
MultUpdateNode mun=new MultUpdateNode(ar,MultUpdateNode.REMOVE);
TermNode tn=new TermNode(mun);
GraphNode gn2=new GraphNode("UpdateRem"+removefromcount,tn);
+ gn2.setOption(updateoption);
boolean goodflag=true;
for(int i=0;i<possiblerules.size();i++) {
un.addUpdate(u);
if (abstractremove.containsKey(rq.relation)) {
GraphNode agn=(GraphNode)abstractremove.get(rq.relation);
- GraphNode.Edge e=new GraphNode.Edge("requires",agn);
+ GraphNode.Edge e=new GraphNode.Edge("requiresremove3",agn);
gn2.addEdge(e);
} else {
goodflag=false;break; /* Abstract repair doesn't exist */
un.addUpdate(u);
if (abstractremove.containsKey(sq.set)) {
GraphNode agn=(GraphNode)abstractremove.get(sq.set);
- GraphNode.Edge e=new GraphNode.Edge("requires",agn);
+ GraphNode.Edge e=new GraphNode.Edge("requiresremove4",agn);
gn2.addEdge(e);
} else {
goodflag=false;break; /* Abstract repair doesn't exist */
goodflag=false;break;
}
}
- if (!un.checkupdates()) {
+ if (!un.checkupdates(state)) {
goodflag=false;
break;
}
mun.addUpdate(un);
}
if (goodflag) {
- GraphNode.Edge e=new GraphNode.Edge("abstract"+removefromcount,gn2);
- removefromcount++;
+ GraphNode.Edge e=new GraphNode.Edge("abstract3"+(removefromcount++),gn2);
gn.addEdge(e);
updatenodes.add(gn2);
}
int rightindex=1;
if (inverted)
leftindex=2;
- else
+ else
rightindex=2;
// construct set of possible rules
while(remains(count,possiblerules,false)) {
MultUpdateNode mun=new MultUpdateNode(ar,MultUpdateNode.MODIFY);
TermNode tn=new TermNode(mun);
- GraphNode gn2=new GraphNode("UpdateMod"+removefromcount,tn);
+ GraphNode gn2=new GraphNode("UpdateMod"+modifycount,tn);
+ gn2.setOption(updateoption);
boolean goodflag=true;
for(int i=0;i<possiblerules.size();i++) {
Rule r=(Rule)possiblerules.get(i);
UpdateNode un=new UpdateNode(r);
-
+
int c=count[i];
if (!processconjunction(un,r.getDNFGuardExpr().get(c),null)) {
goodflag=false;break;
if (vd.isGlobal()) {
Updates up=new Updates(ri.getRightExpr(),rightindex,null);
un.addUpdate(up);
- } else if (!inverted)
+ } else if (!inverted)
goodflag=false;
}
-
- if (!un.checkupdates()) {
+
+ if (!un.checkupdates(state)) {
goodflag=false;
break;
}
mun.addUpdate(un);
}
if (goodflag) {
- GraphNode.Edge e=new GraphNode.Edge("abstract"+modifycount,gn2);
+ GraphNode.Edge e=new GraphNode.Edge("abstract4"+modifycount,gn2);
modifycount++;
gn.addEdge(e);
updatenodes.add(gn2);
ar.getDescriptor()==((SetInclusion)r.getInclusion()).getSet())||
(r.getInclusion() instanceof RelationInclusion&&
ar.getDescriptor()==((RelationInclusion)r.getInclusion()).getRelation())) {
-
+
/* First solve for quantifiers */
Vector bindings=new Vector();
/* Construct bindings */
Hashtable setmapping=new Hashtable();
+ System.out.println("Attempting to construct bindings");
if (!constructbindings(bindings,r,ar,setmapping,false))
continue;
+ System.out.println("Bindings constructed");
//Generate add instruction
DNFRule dnfrule=r.getDNFGuardExpr();
+ endloop:
for(int j=0;j<dnfrule.size();j++) {
Inclusion inc=r.getInclusion();
UpdateNode un=new UpdateNode(r);
/* Now build update for tuple/set inclusion condition */
if(inc instanceof SetInclusion) {
SetInclusion si=(SetInclusion)inc;
- if (!(si.elementexpr instanceof VarExpr)) {
- if (si.elementexpr.isValue(si.getSet().getType())) {
- Updates up=new Updates(si.elementexpr,0,si.getSet().getType());
+ Expr e=si.elementexpr;
+
+ while(e instanceof CastExpr) {
+ CastExpr ce=(CastExpr)e;
+ if (ce.getType()!=si.getSet().getType())
+ continue endloop;
+ e=ce.getExpr();
+ }
+ if (!(e instanceof VarExpr)) {
+ if (e.isValue(si.getSet().getType())) {
+ Updates up=new Updates(e,0,si.getSet().getType());
un.addUpdate(up);
} else {
/* We're an add to set*/
- System.out.println("Rule: "+r);
- ArrayAnalysis.AccessPath rap=arrayanalysis.analyzeExpr(r,si.elementexpr);
- System.out.println("Attempting perform array add");
+ ArrayAnalysis.AccessPath rap=arrayanalysis.analyzeExpr(r,e);
SetDescriptor set=sources.setSource(si.getSet())?
sources.getSourceSet(si.getSet()):null;
if (set==null)
continue;
- System.out.println("Non-null source set");
ArrayAnalysis.AccessPath ap=arrayanalysis.getSet(set);
if (rap==ArrayAnalysis.AccessPath.NONE)
continue;
- System.out.println("A");
if (!rap.equal(ap))
continue;
- System.out.println("B");
- if (!constructarrayupdate(un, si.elementexpr, rap, 0))
+ if (!constructarrayupdate(un, e, rap, 0))
continue;
- System.out.println("C");
}
} else {
- VarDescriptor vd=((VarExpr)si.elementexpr).getVar();
+ VarDescriptor vd=((VarExpr)e).getVar();
if (vd.isGlobal()) {
- Updates up=new Updates(si.elementexpr,0,null);
+ Updates up=new Updates(e,0,null);
un.addUpdate(up);
}
}
} else if (inc instanceof RelationInclusion) {
RelationInclusion ri=(RelationInclusion)inc;
- if (!(ri.getLeftExpr() instanceof VarExpr)) {
- if (ri.getLeftExpr().isValue(ri.getRelation().getDomain().getType())) {
- Updates up=new Updates(ri.getLeftExpr(),0,ri.getRelation().getDomain().getType());
+
+ Expr e=ri.getLeftExpr();
+
+ while(e instanceof CastExpr) {
+ CastExpr ce=(CastExpr)e;
+ if (ce.getType()!=ri.getRelation().getDomain().getType())
+ continue endloop;
+ e=ce.getExpr();
+ }
+ if (!(e instanceof VarExpr)) {
+ if (e.isValue(ri.getRelation().getDomain().getType())) {
+ Updates up=new Updates(e,0,ri.getRelation().getDomain().getType());
if (ar.getDomainSet()!=null)
- setmapping.put(ri.getLeftExpr(),ar.getDomainSet());
+ setmapping.put(e,ar.getDomainSet());
un.addUpdate(up);
} else {
/* We don't handly relation modifies */
if (ar.getType()==AbstractRepair.MODIFYRELATION)
continue;
/* We're an add to relation*/
- ArrayAnalysis.AccessPath rap=arrayanalysis.analyzeExpr(r,ri.getLeftExpr());
+ ArrayAnalysis.AccessPath rap=arrayanalysis.analyzeExpr(r,e);
SetDescriptor set=sources.relsetSource(ri.getRelation(),true /* Domain*/)?
sources.relgetSourceSet(ri.getRelation(),true):null;
if (set==null)
ArrayAnalysis.AccessPath ap=arrayanalysis.getSet(set);
if (rap==ArrayAnalysis.AccessPath.NONE||
!rap.equal(ap)||
- !constructarrayupdate(un, ri.getLeftExpr(), rap, 0))
+ !constructarrayupdate(un, e, rap, 0))
continue;
if (ar.getDomainSet()!=null)
- setmapping.put(ri.getLeftExpr(),ar.getDomainSet());
+ setmapping.put(e,ar.getDomainSet());
}
} else {
- VarDescriptor vd=((VarExpr)ri.getLeftExpr()).getVar();
+ VarDescriptor vd=((VarExpr)e).getVar();
if (vd.isGlobal()) {
- Updates up=new Updates(ri.getLeftExpr(),0,null);
+ Updates up=new Updates(e,0,null);
if (ar.getDomainSet()!=null)
- setmapping.put(ri.getLeftExpr(),ar.getDomainSet());
+ setmapping.put(e,ar.getDomainSet());
un.addUpdate(up);
}
}
- if (!(ri.getRightExpr() instanceof VarExpr)) {
- if (ri.getRightExpr().isValue(ri.getRelation().getRange().getType())) {
- Updates up=new Updates(ri.getRightExpr(),1,ri.getRelation().getRange().getType());
+
+ e=ri.getRightExpr();
+
+ while(e instanceof CastExpr) {
+ CastExpr ce=(CastExpr)e;
+ if (ce.getType()!=ri.getRelation().getRange().getType())
+ continue endloop;
+ e=ce.getExpr();
+ }
+ if (!(e instanceof VarExpr)) {
+ if (e.isValue(ri.getRelation().getRange().getType())) {
+ Updates up=new Updates(e,1,ri.getRelation().getRange().getType());
un.addUpdate(up);
} else {
/* We don't handly relation modifies */
if (ar.getType()==AbstractRepair.MODIFYRELATION)
continue;
/* We're an add to relation*/
- ArrayAnalysis.AccessPath rap=arrayanalysis.analyzeExpr(r,ri.getRightExpr());
+ ArrayAnalysis.AccessPath rap=arrayanalysis.analyzeExpr(r,e);
SetDescriptor set=sources.relsetSource(ri.getRelation(),false /* Range*/)?
sources.relgetSourceSet(ri.getRelation(),false):null;
if (set==null)
continue;
ArrayAnalysis.AccessPath ap=arrayanalysis.getSet(set);
-
+
if (rap==ArrayAnalysis.AccessPath.NONE||
!rap.equal(ap)||
- !constructarrayupdate(un, ri.getRightExpr(), rap, 1))
+ !constructarrayupdate(un, e, rap, 1))
continue;
if (ar.getRangeSet()!=null)
- setmapping.put(ri.getRightExpr(),ar.getRangeSet());
+ setmapping.put(e,ar.getRangeSet());
}
} else {
- VarDescriptor vd=((VarExpr)ri.getRightExpr()).getVar();
+ VarDescriptor vd=((VarExpr)e).getVar();
if (vd.isGlobal()) {
- Updates up=new Updates(ri.getRightExpr(),1,null);
+ Updates up=new Updates(e,1,null);
if (ar.getRangeSet()!=null)
- setmapping.put(ri.getRightExpr(),ar.getRangeSet());
+ setmapping.put(e,ar.getRangeSet());
un.addUpdate(up);
}
}
}
+ System.out.println("Built inclusion condition updates.");
//Finally build necessary updates to satisfy conjunction
RuleConjunction ruleconj=dnfrule.get(j);
MultUpdateNode mun=new MultUpdateNode(ar,MultUpdateNode.ADD);
TermNode tn=new TermNode(mun);
GraphNode gn2=new GraphNode("UpdateAdd"+addtocount,tn);
+ gn2.setOption(updateoption);
- if (processquantifiers(gn2,un, r,setmapping)&&
+ if (debugmsg("Start processing quantifiers")&&
+ processquantifiers(gn2,un, r,setmapping)&&
+ debugmsg("Finished processing quantifiers")&&
processconjunction(un,ruleconj,setmapping)&&
- un.checkupdates()) {
+ debugmsg("Finished processing conjunction")&&
+ un.checkupdates(state)&&
+ debugmsg("Updates checked")) {
mun.addUpdate(un);
- GraphNode.Edge e=new GraphNode.Edge("abstract"+addtocount,gn2);
+ GraphNode.Edge e=new GraphNode.Edge("abstract5"+addtocount,gn2);
addtocount++;
gn.addEdge(e);
updatenodes.add(gn2);
}
}
+ boolean debugmsg(String st) {
+ System.out.println(st);
+ return true;
+ }
+
boolean constructarrayupdate(UpdateNode un, Expr lexpr, ArrayAnalysis.AccessPath ap, int slotnumber) {
System.out.println("Constructing array update");
Expr e=null;
for (int i=ap.numFields()-1;i>=0;i--) {
if (e==null)
e=lexpr;
- else
+ else
e=((DotExpr)e).getExpr();
while (e instanceof CastExpr)
}
if(inc instanceof SetInclusion) {
SetInclusion si=(SetInclusion)inc;
- if ((si.elementexpr instanceof VarExpr)&&
- (((VarExpr)si.elementexpr).getVar()==vd)) {
+ Expr tmpe=si.elementexpr;
+ Expr e=si.elementexpr;
+
+ while(e instanceof CastExpr) {
+ CastExpr ce=(CastExpr)e;
+ if (ce.getType()!=si.getSet().getType())
+ return false;
+ e=ce.getExpr();
+ }
+
+ if ((e instanceof VarExpr)&&
+ (((VarExpr)e).getVar()==vd)) {
/* Can solve for v */
+ if (set==null||!si.getSet().getType().isSubtypeOf(set.getType()))
+ return false;
Binding binding=new Binding(vd,0);
bindings.add(binding);
} else {
RelationInclusion ri=(RelationInclusion)inc;
boolean f1=true;
boolean f2=true;
- if ((ri.getLeftExpr() instanceof VarExpr)&&
- (((VarExpr)ri.getLeftExpr()).getVar()==vd)) {
+
+ Expr e=ri.getLeftExpr();
+
+ while(e instanceof CastExpr) {
+ CastExpr ce=(CastExpr)e;
+ if (ce.getType()!=ri.getRelation().getDomain().getType())
+ return false;
+ e=ce.getExpr();
+ }
+
+ if ((e instanceof VarExpr)&&
+ (((VarExpr)e).getVar()==vd)) {
/* Can solve for v */
Binding binding=new Binding(vd,0);
+ if (!ri.getRelation().getDomain().getType().isSubtypeOf(set.getType()))
+ return false;
if (ar.getDomainSet()!=null)
setmapping.put(ri.getLeftExpr(),ar.getDomainSet());
bindings.add(binding);
} else f1=false;
- if ((ri.getRightExpr() instanceof VarExpr)&&
- (((VarExpr)ri.getRightExpr()).getVar()==vd)) {
+
+
+ e=ri.getRightExpr();
+
+ while(e instanceof CastExpr) {
+ CastExpr ce=(CastExpr)e;
+ if (ce.getType()!=ri.getRelation().getRange().getType())
+ return false;
+ e=ce.getExpr();
+ }
+
+ if ((e instanceof VarExpr)&&
+ (((VarExpr)e).getVar()==vd)) {
/* Can solve for v */
- Binding binding=new Binding(vd,0);
+ Binding binding=new Binding(vd,1);
+ if (!ri.getRelation().getRange().getType().isSubtypeOf(set.getType()))
+ return false;
if (ar.getRangeSet()!=null)
setmapping.put(ri.getRightExpr(),ar.getRangeSet());
bindings.add(binding);
RelationQuantifier rq=(RelationQuantifier)q;
for(int k=0;k<2;k++) {
VarDescriptor vd=(k==0)?rq.x:rq.y;
+ TypeDescriptor td=(k==0)?rq.getRelation().getDomain().getType():rq.getRelation().getRange().getType();
if(inc instanceof SetInclusion) {
SetInclusion si=(SetInclusion)inc;
- if ((si.elementexpr instanceof VarExpr)&&
- (((VarExpr)si.elementexpr).getVar()==vd)) {
+
+ Expr e=si.elementexpr;
+
+ while(e instanceof CastExpr) {
+ CastExpr ce=(CastExpr)e;
+ if (ce.getType()!=td)
+ return false;
+ e=ce.getExpr();
+ }
+
+ if ((e instanceof VarExpr)&&
+ (((VarExpr)e).getVar()==vd)) {
/* Can solve for v */
Binding binding=new Binding(vd,0);
+
+ if (!si.getSet().getType().isSubtypeOf(td))
+ return false;
bindings.add(binding);
} else
goodupdate=false;
RelationInclusion ri=(RelationInclusion)inc;
boolean f1=true;
boolean f2=true;
+
+
+ Expr e=ri.getLeftExpr();
+
+ while(e instanceof CastExpr) {
+ CastExpr ce=(CastExpr)e;
+ if (ce.getType()!=ri.getRelation().getDomain().getType())
+ return false;
+ e=ce.getExpr();
+ }
if ((ri.getLeftExpr() instanceof VarExpr)&&
(((VarExpr)ri.getLeftExpr()).getVar()==vd)) {
/* Can solve for v */
Binding binding=new Binding(vd,0);
+ if (!ri.getRelation().getDomain().getType().isSubtypeOf(td))
+ return false;
if (ar.getDomainSet()!=null)
setmapping.put(ri.getLeftExpr(),ar.getDomainSet());
bindings.add(binding);
} else f1=false;
+
+
+ e=ri.getRightExpr();
+
+ while(e instanceof CastExpr) {
+ CastExpr ce=(CastExpr)e;
+ if (ce.getType()!=ri.getRelation().getRange().getType())
+ return false;
+ e=ce.getExpr();
+ }
if ((ri.getRightExpr() instanceof VarExpr)&&
(((VarExpr)ri.getRightExpr()).getVar()==vd)) {
/* Can solve for v */
- Binding binding=new Binding(vd,0);
+ Binding binding=new Binding(vd,1);
+ if (!ri.getRelation().getRange().getType().isSubtypeOf(td))
+ return false;
if (ar.getRangeSet()!=null)
setmapping.put(ri.getRightExpr(),ar.getRangeSet());
bindings.add(binding);
}
return goodupdate;
}
-
+
/** Adds updates that add an item to the appropriate set or
* relation quantified over by the model definition rule.. */
-
+
boolean processquantifiers(GraphNode gn,UpdateNode un, Rule r,Hashtable setmapping) {
Inclusion inc=r.getInclusion();
for(Iterator iterator=r.quantifiers();iterator.hasNext();) {
Quantifier q=(Quantifier)iterator.next();
/* Add quantifier */
- /* FIXME: Analysis to determine when this update is necessary */
if (q instanceof RelationQuantifier) {
RelationQuantifier rq=(RelationQuantifier)q;
TupleOfExpr toe=new TupleOfExpr(new VarExpr(rq.x),new VarExpr(rq.y),rq.relation);
un.addUpdate(u);
if (abstractadd.containsKey(rq.relation)) {
GraphNode agn=(GraphNode)abstractadd.get(rq.relation);
- GraphNode.Edge e=new GraphNode.Edge("requires",agn);
+ GraphNode.Edge e=new GraphNode.Edge("requiresadd5",agn);
gn.addEdge(e);
} else {
return false;
}
-
} else if (q instanceof SetQuantifier) {
SetQuantifier sq=(SetQuantifier)q;
if (un.getBinding(sq.var).getType()==Binding.SEARCH) {
un.addUpdate(u);
if (abstractadd.containsKey(sq.set)) {
GraphNode agn=(GraphNode)abstractadd.get(sq.set);
- GraphNode.Edge e=new GraphNode.Edge("requires",agn);
+ GraphNode.Edge e=new GraphNode.Edge("requiresadd6",agn);
gn.addEdge(e);
} else {
return false;
} else if (e instanceof TupleOfExpr) {
Updates up=new Updates(e,de.getNegation());
un.addUpdate(up);
- } else if (e instanceof BooleanLiteralExpr) {
+ } else if (e instanceof BooleanLiteralExpr) {
boolean truth=((BooleanLiteralExpr)e).getValue();
if (de.getNegation())
truth=!truth;
return okay;
}
+ /** This method sees if when the quantifiers listed in set are
+ * fixed, whether there can be more than one unique binding for
+ * the constraint or model definition rule qs.*/
public boolean analyzeQuantifiers(Quantifiers qs,Set set) {
for(int i=0;i<qs.numQuantifiers();i++) {
Quantifier q=qs.getQuantifier(i);
}
return true;
}
+
+ boolean equivalent(SetExpr se, RelationExpr re) {
+ if (!(se instanceof ImageSetExpr))
+ return false;
+ ImageSetExpr ise=(ImageSetExpr)se;
+ while(re!=null&&ise!=null) {
+ if (re.getRelation()!=ise.getRelation())
+ return false;
+ if (re.inverted()!=ise.inverted())
+ return false;
+ if (ise.isimageset) {
+ ise=ise.getImageSetExpr();
+ if (!(re.getExpr() instanceof RelationExpr))
+ return false;
+ re=(RelationExpr)re.getExpr();
+ } else {
+ if (!(re.getExpr() instanceof VarExpr))
+ return false;
+ if (((VarExpr)re.getExpr()).getVar()==ise.getVar())
+ return true; //everything matches
+ return false;
+ }
+ }
+ return false;
+ }
}