X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Repair%2FRepairCompiler%2FMCC%2FIR%2FTermination.java;h=5e4bc91aac5f1013dcebf2e16b89e81fa31fd535;hb=94f62079ed1aec461df5e3e493664abe38cf61f9;hp=7f9adc08e8ace7d684e15effdc8be5f7e2c6cfd3;hpb=818e376c5aeeeb458febe75f3d6273a94f3bcf7d;p=repair.git diff --git a/Repair/RepairCompiler/MCC/IR/Termination.java b/Repair/RepairCompiler/MCC/IR/Termination.java index 7f9adc0..5e4bc91 100755 --- a/Repair/RepairCompiler/MCC/IR/Termination.java +++ b/Repair/RepairCompiler/MCC/IR/Termination.java @@ -1,45 +1,267 @@ package MCC.IR; import java.util.*; +import java.io.*; import MCC.State; +import MCC.Compiler; public class Termination { HashSet conjunctions; Hashtable conjunctionmap; HashSet abstractrepair; + HashSet abstractrepairadd; + + HashSet updatenodes; + HashSet consequencenodes; HashSet scopenodes; Hashtable scopesatisfy; Hashtable scopefalsify; - + Hashtable consequence; + Hashtable abstractadd; + Hashtable abstractremove; + Hashtable conjtonodemap; + Hashtable predtoabstractmap; + Set removedset; + ComputeMaxSize maxsize; State state; + AbstractInterferes abstractinterferes; + ConcreteInterferes concreteinterferes; + ConstraintDependence constraintdependence; + ExactSize exactsize; + ArrayAnalysis arrayanalysis; + Sources sources; public Termination(State state) { this.state=state; conjunctions=new HashSet(); conjunctionmap=new Hashtable(); abstractrepair=new HashSet(); + abstractrepairadd=new HashSet(); scopenodes=new HashSet(); scopesatisfy=new Hashtable(); scopefalsify=new Hashtable(); + consequence=new Hashtable(); + updatenodes=new HashSet(); + consequencenodes=new HashSet(); + abstractadd=new Hashtable(); + abstractremove=new Hashtable(); + conjtonodemap=new Hashtable(); + predtoabstractmap=new Hashtable(); + if (!Compiler.REPAIR) + return; + + + for(int i=0;i=num) { + count[i+1]++; + count[i]=0; + } else break; + } + } + + + /** This method test if there remain any possibilities to loop + * through. */ + static private boolean remains(int count[], Vector rules, boolean isremove) { + for(int i=0;i=num) { + return false; + } + } + return true; + } + + /** This method generates data structure updates to implement the + * abstract atomic modification specified by ar. */ + + int modifycount=0; + void generatemodifyrelation(GraphNode gn, AbstractRepair ar) { + RelationDescriptor rd=(RelationDescriptor)ar.getDescriptor(); + ExprPredicate exprPredicate=(ExprPredicate)ar.getPredicate().getPredicate(); + boolean inverted=exprPredicate.inverted(); + int leftindex=0; + int rightindex=1; + if (inverted) + leftindex=2; + else + rightindex=2; + + // construct set of possible rules + Vector possiblerules=new Vector(); for(int i=0;i=0;i--) { + if (e==null) + e=lexpr; + else + e=((DotExpr)e).getExpr(); + + while (e instanceof CastExpr) + e=((CastExpr)e).getExpr(); + + DotExpr de=(DotExpr)e; + FieldDescriptor fd=ap.getField(i); + if (fd instanceof ArrayDescriptor) { + // We have an ArrayDescriptor! + Expr index=de.getIndex(); + if (!index.isValue(null)) {/* Not assignable */ + System.out.println("ERROR:Index isn't assignable"); + return false; + } + Updates updates=new Updates(index,i,ap,lexpr,slotnumber); + un.addUpdate(updates); + } + } + return true; + } + + /** This method constructs bindings for an update using rule + * r. The boolean flag isremoval indicates that the update + * performs a removal. The function returns true if it is able to + * generate a valid set of bindings and false otherwise. */ + + boolean constructbindings(Vector bindings, Rule r, AbstractRepair ar, Hashtable setmapping, boolean isremoval) { + boolean goodupdate=true; + Inclusion inc=r.getInclusion(); + + for(Iterator iterator=r.quantifiers();iterator.hasNext();) { + Quantifier q=(Quantifier)iterator.next(); + if ((q instanceof SetQuantifier)||(q instanceof ForQuantifier)) { + VarDescriptor vd=null; + SetDescriptor set=null; + if (q instanceof SetQuantifier) { + vd=((SetQuantifier)q).getVar(); + set=((SetQuantifier)q).getSet(); + } else { + vd=((ForQuantifier)q).getVar(); + } + if(inc instanceof SetInclusion) { + SetInclusion si=(SetInclusion)inc; + 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 (!si.getSet().getType().isSubtypeOf(set.getType())) + return false; + Binding binding=new Binding(vd,0); + bindings.add(binding); + } else { + goodupdate=false; + } + } else if (inc instanceof RelationInclusion) { + 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 ((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; + + + 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,1); + if (!ri.getRelation().getRange().getType().isSubtypeOf(set.getType())) + return false; + if (ar.getRangeSet()!=null) + setmapping.put(ri.getRightExpr(),ar.getRangeSet()); + bindings.add(binding); + } else f2=false; + if (!(f1||f2)) + goodupdate=false; + } else throw new Error("Inclusion not recognized"); + if (!goodupdate) + if (isremoval) { + /* Removals don't need bindings anymore + Binding binding=new Binding(vd); + bindings.add(binding);*/ + goodupdate=true; + } else if (q instanceof SetQuantifier) { + /* Create new element to bind to */ + // search if the set 'set' has a size + Binding binding=new Binding(vd,set,exactsize.getsize(set)==1); + bindings.add(binding); + goodupdate=true; + + } else + goodupdate=false; + } else if (q instanceof RelationQuantifier) { + 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; + + 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; + } else if (inc instanceof RelationInclusion) { + 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,1); + if (!ri.getRelation().getRange().getType().isSubtypeOf(td)) + return false; + if (ar.getRangeSet()!=null) + setmapping.put(ri.getRightExpr(),ar.getRangeSet()); + bindings.add(binding); + } else f2=false; + if (!(f1||f2)) + goodupdate=false; + } else throw new Error("Inclusion not recognized"); + if (!goodupdate) + if (isremoval) { + /* Removals don't need bindings anymore + Binding binding=new Binding(vd); + bindings.add(binding);*/ + goodupdate=true; + } else + break; + } + if (!goodupdate) + break; + } else throw new Error("Quantifier not recognized"); + } + 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 */ + if (q instanceof RelationQuantifier) { + RelationQuantifier rq=(RelationQuantifier)q; + TupleOfExpr toe=new TupleOfExpr(new VarExpr(rq.x),new VarExpr(rq.y),rq.relation); + toe.td=ReservedTypeDescriptor.INT; + Updates u=new Updates(toe,false); + un.addUpdate(u); + if (abstractadd.containsKey(rq.relation)) { + GraphNode agn=(GraphNode)abstractadd.get(rq.relation); + GraphNode.Edge e=new GraphNode.Edge("requires",agn); + gn.addEdge(e); + } else { + return false; + } + } else if (q instanceof SetQuantifier) { + SetQuantifier sq=(SetQuantifier)q; + if (un.getBinding(sq.var).getType()==Binding.SEARCH) { + Binding b=un.getBinding(sq.var); + Constraint reqc=exactsize.getConstraint(b.getSet()); + constraintdependence.requiresConstraint(gn,reqc); + continue; /* Don't need to ensure addition for search */ + } + VarExpr ve=new VarExpr(sq.var); + SetDescriptor sd=findExpr(setmapping, ve); + if (sd!=null&&sd.isSubset(sq.set)) + continue; /* this update is trivially true */ + + ElementOfExpr eoe=new ElementOfExpr(ve,sq.set); + eoe.td=ReservedTypeDescriptor.INT; + Updates u=new Updates(eoe,false); + un.addUpdate(u); + if (abstractadd.containsKey(sq.set)) { + GraphNode agn=(GraphNode)abstractadd.get(sq.set); + GraphNode.Edge e=new GraphNode.Edge("requires",agn); + gn.addEdge(e); + } else { + return false; + } + } else return false; + } + return true; + } + + static SetDescriptor findExpr(Hashtable setmapping, Expr e) { + if (setmapping==null) + return null; + Set kset=setmapping.keySet(); + for(Iterator it=kset.iterator();it.hasNext();) { + Expr expr=(Expr)it.next(); + if (expr.equals(null,e)) { + return (SetDescriptor)setmapping.get(expr); + } + } + return null; + } + + /** This method generates the necessary updates to satisfy the + * conjunction ruleconj. */ + + boolean processconjunction(UpdateNode un,RuleConjunction ruleconj,Hashtable setmapping) { + boolean okay=true; + for(int k=0;k=0) + continue; + } else if (q instanceof RelationQuantifier) { + RelationDescriptor rd=((RelationQuantifier)q).getRelation(); + if (maxsize.getsize(rd)<=1&& + maxsize.getsize(rd)>=0) + continue; + } + return false; + } + return true; + } + + public boolean mutuallyexclusive(SetDescriptor sd1, SetDescriptor sd2) { + if (mutualexclusive(sd1,sd2)|| + mutualexclusive(sd2,sd1)) + return true; + else + return false; + } + + private boolean mutualexclusive(SetDescriptor sd1, SetDescriptor sd2) { + Vector rules=state.vRules; + for(int i=0;i