*** empty log message ***
[repair.git] / Repair / RepairCompiler / MCC / IR / Termination.java
1 package MCC.IR;
2 import java.util.*;
3 import java.io.*;
4 import MCC.State;
5
6 public class Termination {
7     HashSet conjunctions;
8     Hashtable conjunctionmap;
9
10     HashSet abstractrepair;
11     HashSet updatenodes;
12     HashSet consequencenodes;
13
14     HashSet scopenodes;
15     Hashtable scopesatisfy;
16     Hashtable scopefalsify;
17     Hashtable consequence;
18     Hashtable abstractadd;
19     Hashtable abstractremove;
20     Hashtable conjtonodemap;
21     Set removedset;
22
23     State state;
24
25     public Termination(State state) {
26         this.state=state;
27         conjunctions=new HashSet();
28         conjunctionmap=new Hashtable();
29         abstractrepair=new HashSet();
30         scopenodes=new HashSet();
31         scopesatisfy=new Hashtable();
32         scopefalsify=new Hashtable();
33         consequence=new Hashtable();
34         updatenodes=new HashSet();
35         consequencenodes=new HashSet();
36         abstractadd=new Hashtable();
37         abstractremove=new Hashtable();
38         conjtonodemap=new Hashtable();
39
40         generateconjunctionnodes();
41         generatescopenodes();
42         generaterepairnodes();
43         generatedatastructureupdatenodes();
44         generatecompensationnodes();
45
46         generateabstractedges();
47         generatescopeedges();
48         generateupdateedges();
49
50         HashSet superset=new HashSet();
51         superset.addAll(conjunctions);
52         //superset.addAll(abstractrepair);
53         //superset.addAll(updatenodes);
54         //superset.addAll(scopenodes);
55         //superset.addAll(consequencenodes);
56         GraphNode.computeclosure(superset,null);
57         try {
58             GraphNode.DOTVisitor.visit(new FileOutputStream("graph.dot"),superset);
59         } catch (Exception e) {
60             e.printStackTrace();
61             System.exit(-1);
62         }
63         for(Iterator it=updatenodes.iterator();it.hasNext();) {
64             GraphNode gn=(GraphNode)it.next();
65             TermNode tn=(TermNode)gn.getOwner();
66             MultUpdateNode mun=tn.getUpdate();
67             System.out.println(gn.getTextLabel());
68             System.out.println(mun.toString());
69         }
70         GraphAnalysis ga=new GraphAnalysis(this);
71         removedset=ga.doAnalysis();
72         System.out.println("Removing:");
73         for(Iterator it=removedset.iterator();it.hasNext();) {
74             GraphNode gn=(GraphNode)it.next();
75             System.out.println(gn.getTextLabel());
76         }
77     }
78     
79     void generateconjunctionnodes() {
80         Vector constraints=state.vConstraints;
81         for(int i=0;i<constraints.size();i++) {
82             Constraint c=(Constraint)constraints.get(i);
83             DNFConstraint dnf=c.dnfconstraint;
84             for(int j=0;j<dnf.size();j++) {
85                 TermNode tn=new TermNode(c,dnf.get(j));
86                 GraphNode gn=new GraphNode("Conj"+i+"A"+j,
87                                            "Conj ("+i+","+j+") "+dnf.get(j).name()
88                                            ,tn);
89                 conjunctions.add(gn);
90                 if (!conjunctionmap.containsKey(c))
91                     conjunctionmap.put(c,new HashSet());
92                 ((Set)conjunctionmap.get(c)).add(gn);
93                 conjtonodemap.put(dnf.get(j),gn);
94             }
95         }
96     }
97
98     void generateupdateedges() {
99         for(Iterator updateiterator=updatenodes.iterator();updateiterator.hasNext();) {
100             GraphNode gn=(GraphNode)updateiterator.next();
101             TermNode tn=(TermNode)gn.getOwner();
102             MultUpdateNode mun=tn.getUpdate();
103             /* Cycle through the rules to look for possible conflicts */
104             for(int i=0;i<state.vRules.size();i++) {
105                 Rule r=(Rule) state.vRules.get(i);  
106                 if (ConcreteInterferes.interferes(mun,r,true)) {
107                     GraphNode scopenode=(GraphNode)scopesatisfy.get(r);
108                     GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
109                     gn.addEdge(e);
110                 }
111                 if (ConcreteInterferes.interferes(mun,r,false)) {
112                     GraphNode scopenode=(GraphNode)scopefalsify.get(r);
113                     GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
114                     gn.addEdge(e);
115                 }
116             }
117         }
118     }
119
120     void generateabstractedges() {
121         for(Iterator absiterator=abstractrepair.iterator();absiterator.hasNext();) {
122             GraphNode gn=(GraphNode)absiterator.next();
123             TermNode tn=(TermNode)gn.getOwner();
124             AbstractRepair ar=(AbstractRepair)tn.getAbstract();
125         
126             for(Iterator conjiterator=conjunctions.iterator();conjiterator.hasNext();) {
127                 GraphNode gn2=(GraphNode)conjiterator.next();
128                 TermNode tn2=(TermNode)gn2.getOwner();
129                 Conjunction conj=tn2.getConjunction();
130                 Constraint cons=tn2.getConstraint();
131
132                 for(int i=0;i<conj.size();i++) {
133                     DNFPredicate dp=conj.get(i);
134                     if (AbstractInterferes.interferes(ar,cons)||
135                         AbstractInterferes.interferes(ar,dp)) {
136                         GraphNode.Edge e=new GraphNode.Edge("interferes",gn2);
137                         gn.addEdge(e);
138                         break;
139                     }
140                 }
141             }
142
143             for(Iterator scopeiterator=scopenodes.iterator();scopeiterator.hasNext();) {
144                 GraphNode gn2=(GraphNode)scopeiterator.next();
145                 TermNode tn2=(TermNode)gn2.getOwner();
146                 ScopeNode sn2=tn2.getScope();
147                 if (AbstractInterferes.interferes(ar,sn2.getRule(),sn2.getSatisfy())) {
148                     GraphNode.Edge e=new GraphNode.Edge("interferes",gn2);
149                     gn.addEdge(e);
150                 }
151             }
152         }
153     }
154     
155     void generatescopeedges() {
156         for(Iterator scopeiterator=scopenodes.iterator();scopeiterator.hasNext();) {
157             GraphNode gn=(GraphNode)scopeiterator.next();
158             TermNode tn=(TermNode)gn.getOwner();
159             ScopeNode sn=tn.getScope();
160             
161             /* Interference edges with conjunctions */
162             for(Iterator conjiterator=conjunctions.iterator();conjiterator.hasNext();) {
163                 GraphNode gn2=(GraphNode)conjiterator.next();
164                 TermNode tn2=(TermNode)gn2.getOwner();
165                 Conjunction conj=tn2.getConjunction();
166                 Constraint constr=tn2.getConstraint();
167                 for(int i=0;i<conj.size();i++) {
168                     DNFPredicate dp=conj.get(i);
169                     if (AbstractInterferes.interferes(sn.getDescriptor(),sn.getSatisfy(),dp)||
170                         AbstractInterferes.interferes(sn.getDescriptor(),sn.getSatisfy(),constr)) {
171                         GraphNode.Edge e=new GraphNode.Edge("interferes",gn2);
172                         GraphNode gnconseq=(GraphNode)consequence.get(sn);
173                         gnconseq.addEdge(e);
174                         break;
175                     }
176                 }
177             }
178
179             /* Now see if this could effect other model defintion rules */
180             for(int i=0;i<state.vRules.size();i++) {
181                 Rule r=(Rule) state.vRules.get(i);
182                 if (AbstractInterferes.interferes(sn.getDescriptor(),sn.getSatisfy(),r,true)) {
183                     GraphNode scopenode=(GraphNode)scopesatisfy.get(r);
184                     GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
185                     GraphNode gnconseq=(GraphNode)consequence.get(sn);
186                     gnconseq.addEdge(e);
187                 }
188                 if (AbstractInterferes.interferes(sn.getDescriptor(),sn.getSatisfy(),r,false)) {
189                     GraphNode scopenode=(GraphNode)scopefalsify.get(r);
190                     GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
191                     GraphNode gnconseq=(GraphNode)consequence.get(sn);
192                     gnconseq.addEdge(e);
193                 }
194             }
195         }
196     }
197
198     /* Generates the abstract repair nodes */
199     void generaterepairnodes() {
200         /* Generate repairs of conjunctions */
201         for(Iterator conjiterator=conjunctions.iterator();conjiterator.hasNext();) {
202             GraphNode gn=(GraphNode)conjiterator.next();
203             TermNode tn=(TermNode)gn.getOwner();
204             Conjunction conj=tn.getConjunction();
205             for(int i=0;i<conj.size();i++) {
206                 DNFPredicate dp=conj.get(i);
207                 int[] array=dp.getPredicate().getRepairs(dp.isNegated());
208                 Descriptor d=dp.getPredicate().getDescriptor();
209                 for(int j=0;j<array.length;j++) {
210                     AbstractRepair ar=new AbstractRepair(dp,array[j],d);
211                     TermNode tn2=new TermNode(ar);
212                     GraphNode gn2=new GraphNode(gn.getLabel()+"A"+i+"B"+ar.type(),gn.getTextLabel()+" #"+i+" "+ar.type(),tn2);
213                     GraphNode.Edge e=new GraphNode.Edge("abstract",gn2);
214                     gn.addEdge(e);
215                     abstractrepair.add(gn2);
216                 }
217             }
218         }
219         /* Generate additional abstract repairs */
220         Vector setdescriptors=state.stSets.getAllDescriptors();
221         for(int i=0;i<setdescriptors.size();i++) {
222             SetDescriptor sd=(SetDescriptor)setdescriptors.get(i);
223
224             /* XXXXXXX: Not sure what to do here */
225             VarExpr ve=new VarExpr("DUMMY");
226             InclusionPredicate ip=new InclusionPredicate(ve,new SetExpr(sd));
227             
228             DNFPredicate tp=new DNFPredicate(false,ip);
229             AbstractRepair ar=new AbstractRepair(tp, AbstractRepair.ADDTOSET, sd);
230             TermNode tn=new TermNode(ar);
231             GraphNode gn=new GraphNode("AbstractAddSetRule"+i,tn);
232             abstractrepair.add(gn);
233             abstractadd.put(sd,gn);
234             
235             DNFPredicate tp2=new DNFPredicate(true,ip);
236             AbstractRepair ar2=new AbstractRepair(tp2, AbstractRepair.REMOVEFROMSET, sd);
237             TermNode tn2=new TermNode(ar2);
238             GraphNode gn2=new GraphNode("AbstractRemSetRule"+i,tn2);
239             abstractrepair.add(gn2);
240             abstractremove.put(sd,gn2);
241         }
242
243         Vector relationdescriptors=state.stRelations.getAllDescriptors();
244         for(int i=0;i<relationdescriptors.size();i++) {
245             RelationDescriptor rd=(RelationDescriptor)relationdescriptors.get(i);
246
247             /* XXXXXXX: Not sure what to do here */
248             VarDescriptor vd1=new VarDescriptor("DUMMY1");
249             VarExpr ve2=new VarExpr("DUMMY2");
250
251             InclusionPredicate ip=new InclusionPredicate(ve2,new ImageSetExpr(vd1, rd));
252             
253             DNFPredicate tp=new DNFPredicate(false,ip);
254             AbstractRepair ar=new AbstractRepair(tp, AbstractRepair.ADDTORELATION, rd);
255             TermNode tn=new TermNode(ar);
256             GraphNode gn=new GraphNode("AbstractAddRelRule"+i,tn);
257             abstractrepair.add(gn);
258             abstractadd.put(rd,gn);
259             
260             DNFPredicate tp2=new DNFPredicate(true,ip);
261             AbstractRepair ar2=new AbstractRepair(tp2, AbstractRepair.REMOVEFROMRELATION, rd);
262             TermNode tn2=new TermNode(ar2);
263             GraphNode gn2=new GraphNode("AbstractRemRelRule"+i,tn2);
264             abstractrepair.add(gn2);
265             abstractremove.put(rd,gn2);
266         }
267         
268     }
269
270     int compensationcount=0;
271     void generatecompensationnodes() {
272         for(int i=0;i<state.vRules.size();i++) {
273             Rule r=(Rule) state.vRules.get(i);
274             Vector possiblerules=new Vector();
275             /* Construct bindings */
276             /* No need to construct bindings on remove
277                Vector bindings=new Vector();
278                constructbindings(bindings, r,true);
279             */
280             for(int j=0;j<(r.numQuantifiers()+r.getDNFNegGuardExpr().size());j++) {
281                 GraphNode gn=(GraphNode)scopesatisfy.get(r);
282                 TermNode tn=(TermNode) gn.getOwner();
283                 ScopeNode sn=tn.getScope();
284                 MultUpdateNode mun=new MultUpdateNode(sn);
285                 TermNode tn2=new TermNode(mun);
286                 GraphNode gn2=new GraphNode("CompRem"+compensationcount,tn2);
287                 UpdateNode un=new UpdateNode(r);
288                 //              un.addBindings(bindings);
289                 // Not necessary
290                 if (j<r.numQuantifiers()) {
291                     /* Remove quantifier */
292                     Quantifier q=r.getQuantifier(j);
293                     if (q instanceof RelationQuantifier) {
294                         RelationQuantifier rq=(RelationQuantifier)q;
295                         TupleOfExpr toe=new TupleOfExpr(new VarExpr(rq.x),new VarExpr(rq.y),rq.relation);
296                         toe.td=ReservedTypeDescriptor.INT;
297                         Updates u=new Updates(toe,true);
298                         un.addUpdate(u);
299                         if (abstractremove.containsKey(rq.relation)) {
300                             GraphNode agn=(GraphNode)abstractremove.get(rq.relation);
301                             GraphNode.Edge e=new GraphNode.Edge("requires",agn);
302                             gn2.addEdge(e);
303                         } else {
304                             continue; /* Abstract repair doesn't exist */
305                         }
306                     } else if (q instanceof SetQuantifier) {
307                         SetQuantifier sq=(SetQuantifier)q;
308                         ElementOfExpr eoe=new ElementOfExpr(new VarExpr(sq.var),sq.set);
309                         eoe.td=ReservedTypeDescriptor.INT;
310                         Updates u=new Updates(eoe,true);
311                         un.addUpdate(u);
312                         if (abstractremove.containsKey(sq.set)) {
313                             GraphNode agn=(GraphNode)abstractremove.get(sq.set);
314                             GraphNode.Edge e=new GraphNode.Edge("requires",agn);
315                             gn2.addEdge(e);
316                         } else {
317                             continue; /* Abstract repair doesn't exist */
318                         }
319                     } else {
320                         continue;
321                     }
322                 } else {
323                     int c=j-r.numQuantifiers();
324                     if (!processconjunction(un,r.getDNFNegGuardExpr().get(c))) {
325                         continue;
326                     }
327                 }
328                 if (!un.checkupdates()) /* Make sure we have a good update */
329                     continue;
330                 
331                 mun.addUpdate(un);
332
333                 GraphNode.Edge e=new GraphNode.Edge("abstract"+compensationcount,gn2);
334                 compensationcount++;
335                 gn.addEdge(e);
336                 updatenodes.add(gn2);
337             }
338         }
339     }
340
341     void generatedatastructureupdatenodes() {
342         for(Iterator absiterator=abstractrepair.iterator();absiterator.hasNext();) {
343             GraphNode gn=(GraphNode)absiterator.next();
344             TermNode tn=(TermNode) gn.getOwner();
345             AbstractRepair ar=tn.getAbstract();
346             if (ar.getType()==AbstractRepair.ADDTOSET) {
347                 generateaddtosetrelation(gn,ar);
348             } else if (ar.getType()==AbstractRepair.REMOVEFROMSET) {
349                 generateremovefromsetrelation(gn,ar);
350             } else if (ar.getType()==AbstractRepair.ADDTORELATION) {
351                 generateaddtosetrelation(gn,ar);
352             } else if (ar.getType()==AbstractRepair.REMOVEFROMRELATION) {
353                 generateremovefromsetrelation(gn,ar);
354             } else if (ar.getType()==AbstractRepair.MODIFYRELATION) {
355                 /* Generate remove/add pairs */
356                 generateremovefromsetrelation(gn,ar);
357                 generateaddtosetrelation(gn,ar);
358                 /* Generate atomic modify */
359                 generatemodifyrelation(gn,ar);
360             }
361         }
362     }
363
364     int removefromcount=0;
365     void generateremovefromsetrelation(GraphNode gn,AbstractRepair ar) {
366         Vector possiblerules=new Vector();
367         for(int i=0;i<state.vRules.size();i++) {
368             Rule r=(Rule) state.vRules.get(i);
369             if ((r.getInclusion() instanceof SetInclusion)&&
370                 (ar.getDescriptor()==((SetInclusion)r.getInclusion()).getSet()))
371                 possiblerules.add(r);
372             if ((r.getInclusion() instanceof RelationInclusion)&&
373                 (ar.getDescriptor()==((RelationInclusion)r.getInclusion()).getRelation()))
374                 possiblerules.add(r);
375         }
376         if (possiblerules.size()==0)
377             return;
378         int[] count=new int[possiblerules.size()];
379         while(remains(count,possiblerules)) {
380             MultUpdateNode mun=new MultUpdateNode(ar,MultUpdateNode.REMOVE);
381             TermNode tn=new TermNode(mun);
382             GraphNode gn2=new GraphNode("UpdateRem"+removefromcount,tn);
383
384             boolean goodflag=true;
385             for(int i=0;i<possiblerules.size();i++) {
386                 Rule r=(Rule)possiblerules.get(i);
387                 UpdateNode un=new UpdateNode(r);
388                 /* Construct bindings */
389                 /* No Need to construct bindings on remove
390                    Vector bindings=new Vector();
391                    constructbindings(bindings, r,true);
392                   un.addBindings(bindings);*/
393                 if (count[i]<r.numQuantifiers()) {
394                     /* Remove quantifier */
395                     Quantifier q=r.getQuantifier(count[i]);
396                     if (q instanceof RelationQuantifier) {
397                         RelationQuantifier rq=(RelationQuantifier)q;
398                         TupleOfExpr toe=new TupleOfExpr(new VarExpr(rq.x),new VarExpr(rq.y),rq.relation);
399                         toe.td=ReservedTypeDescriptor.INT;
400                         Updates u=new Updates(toe,true);
401                         un.addUpdate(u);
402                         if (abstractremove.containsKey(rq.relation)) {
403                             GraphNode agn=(GraphNode)abstractremove.get(rq.relation);
404                             GraphNode.Edge e=new GraphNode.Edge("requires",agn);
405                             gn2.addEdge(e);
406                         } else {
407                             goodflag=false;break; /* Abstract repair doesn't exist */
408                         }
409                     } else if (q instanceof SetQuantifier) {
410                         SetQuantifier sq=(SetQuantifier)q;
411                         ElementOfExpr eoe=new ElementOfExpr(new VarExpr(sq.var),sq.set);
412                         eoe.td=ReservedTypeDescriptor.INT;
413                         Updates u=new Updates(eoe,true);
414                         un.addUpdate(u);
415                         if (abstractremove.containsKey(sq.set)) {
416                             GraphNode agn=(GraphNode)abstractremove.get(sq.set);
417                             GraphNode.Edge e=new GraphNode.Edge("requires",agn);
418                             gn2.addEdge(e);
419                         } else {
420                             goodflag=false;break; /* Abstract repair doesn't exist */
421                         }
422                     } else {goodflag=false;break;}
423                 } else {
424                     int c=count[i]-r.numQuantifiers();
425                     if (!processconjunction(un,r.getDNFNegGuardExpr().get(c))) {
426                         goodflag=false;break;
427                     }
428                 }
429                 if (!un.checkupdates()) {
430                     goodflag=false;
431                     break;
432                 }
433                 mun.addUpdate(un);
434             }
435             if (goodflag) {
436                 GraphNode.Edge e=new GraphNode.Edge("abstract"+removefromcount,gn2);
437                 removefromcount++;
438                 gn.addEdge(e);
439                 updatenodes.add(gn2);
440             }
441             increment(count,possiblerules);
442         }
443     }
444
445     static void increment(int count[], Vector rules) {
446         count[0]++;
447         for(int i=0;i<(rules.size()-1);i++) {
448             if (count[i]>=(((Rule)rules.get(i)).numQuantifiers()+(((Rule)rules.get(i)).getDNFNegGuardExpr().size()))) {
449                 count[i+1]++;
450                 count[i]=0;
451             } else break;
452         }
453     }
454
455     static boolean remains(int count[], Vector rules) {
456         for(int i=0;i<rules.size();i++) {
457             if (count[i]>=(((Rule)rules.get(i)).numQuantifiers()+(((Rule)rules.get(i)).getDNFNegGuardExpr().size()))) {
458                 return false;
459             }
460         }
461         return true;
462     }
463
464     void generatemodifyrelation(GraphNode gn, AbstractRepair ar) {
465     }
466
467
468     boolean constructbindings(Vector bindings, Rule r, boolean isremoval) {
469         boolean goodupdate=true;
470         Inclusion inc=r.getInclusion();
471         for(Iterator iterator=r.quantifiers();iterator.hasNext();) {
472             Quantifier q=(Quantifier)iterator.next();
473             if ((q instanceof SetQuantifier)||(q instanceof ForQuantifier)) {
474                 VarDescriptor vd=null;
475                 SetDescriptor set=null;
476                 if (q instanceof SetQuantifier) {
477                     vd=((SetQuantifier)q).getVar();
478                 } else
479                     vd=((ForQuantifier)q).getVar();
480                 if(inc instanceof SetInclusion) {
481                     SetInclusion si=(SetInclusion)inc;
482                     if ((si.elementexpr instanceof VarExpr)&&
483                         (((VarExpr)si.elementexpr).getVar()==vd)) {
484                         /* Can solve for v */
485                         Binding binding=new Binding(vd,0);
486                         bindings.add(binding);
487                     } else
488                         goodupdate=false;
489                 } else if (inc instanceof RelationInclusion) {
490                     RelationInclusion ri=(RelationInclusion)inc;
491                     boolean f1=true;
492                     boolean f2=true;
493                     if ((ri.getLeftExpr() instanceof VarExpr)&&
494                         (((VarExpr)ri.getLeftExpr()).getVar()==vd)) {
495                                 /* Can solve for v */
496                         Binding binding=new Binding(vd,0);
497                         bindings.add(binding);
498                     } else f1=false;
499                     if ((ri.getRightExpr() instanceof VarExpr)&&
500                         (((VarExpr)ri.getRightExpr()).getVar()==vd)) {
501                                 /* Can solve for v */
502                         Binding binding=new Binding(vd,0);
503                         bindings.add(binding);
504                     } else f2=false;
505                     if (!(f1||f2))
506                         goodupdate=false;
507                 } else throw new Error("Inclusion not recognized");
508                 if (!goodupdate)
509                     if (isremoval) {
510                         Binding binding=new Binding(vd);
511                         bindings.add(binding);
512                         goodupdate=true;
513                     } else
514                         break;
515             } else if (q instanceof RelationQuantifier) {
516                 RelationQuantifier rq=(RelationQuantifier)q;
517                 for(int k=0;k<2;k++) {
518                     VarDescriptor vd=(k==0)?rq.x:rq.y;
519                     if(inc instanceof SetInclusion) {
520                         SetInclusion si=(SetInclusion)inc;
521                         if ((si.elementexpr instanceof VarExpr)&&
522                             (((VarExpr)si.elementexpr).getVar()==vd)) {
523                             /* Can solve for v */
524                             Binding binding=new Binding(vd,0);
525                             bindings.add(binding);
526                         } else
527                             goodupdate=false;
528                     } else if (inc instanceof RelationInclusion) {
529                         RelationInclusion ri=(RelationInclusion)inc;
530                         boolean f1=true;
531                         boolean f2=true;
532                         if ((ri.getLeftExpr() instanceof VarExpr)&&
533                             (((VarExpr)ri.getLeftExpr()).getVar()==vd)) {
534                             /* Can solve for v */
535                             Binding binding=new Binding(vd,0);
536                             bindings.add(binding);
537                         } else f1=false;
538                         if ((ri.getRightExpr() instanceof VarExpr)&&
539                             (((VarExpr)ri.getRightExpr()).getVar()==vd)) {
540                             /* Can solve for v */
541                             Binding binding=new Binding(vd,0);
542                             bindings.add(binding);
543                         } else f2=false;
544                         if (!(f1||f2))
545                             goodupdate=false;
546                     } else throw new Error("Inclusion not recognized");
547                     if (!goodupdate)
548                         if (isremoval) {
549                             Binding binding=new Binding(vd);
550                             bindings.add(binding);
551                             goodupdate=true;
552                         } else
553                             break;
554                 }
555                 if (!goodupdate)
556                     break;
557             } else throw new Error("Quantifier not recognized");
558         }
559         return goodupdate;
560     }
561
562     static int addtocount=0;
563     void generateaddtosetrelation(GraphNode gn, AbstractRepair ar) {
564         //      System.out.println("Attempting to generate add to set");
565         //System.out.println(ar.getPredicate().getPredicate().name());
566         //System.out.println(ar.getPredicate().isNegated());
567         for(int i=0;i<state.vRules.size();i++) {
568             Rule r=(Rule) state.vRules.get(i);
569             /* See if this is a good rule*/
570             //System.out.println(r.getGuardExpr().name());
571             if ((r.getInclusion() instanceof SetInclusion&&
572                 ar.getDescriptor()==((SetInclusion)r.getInclusion()).getSet())||
573                 (r.getInclusion() instanceof RelationInclusion&&
574                  ar.getDescriptor()==((RelationInclusion)r.getInclusion()).getRelation())) {
575
576                 /* First solve for quantifiers */
577                 Vector bindings=new Vector();
578                 /* Construct bindings */
579                 //System.out.println("Attempting to generate add to set: #2");
580                 if (!constructbindings(bindings,r,false))
581                     continue;
582                 //System.out.println("Attempting to generate add to set: #3");
583                 //Generate add instruction
584                 DNFRule dnfrule=r.getDNFGuardExpr();
585                 for(int j=0;j<dnfrule.size();j++) {
586                     Inclusion inc=r.getInclusion();
587                     UpdateNode un=new UpdateNode(r);
588                     un.addBindings(bindings);
589                     /* Now build update for tuple/set inclusion condition */
590                     if(inc instanceof SetInclusion) {
591                         SetInclusion si=(SetInclusion)inc;
592                         if (!(si.elementexpr instanceof VarExpr)) {
593                             Updates up=new Updates(si.elementexpr,0);
594                             un.addUpdate(up);
595                         } else {
596                             VarDescriptor vd=((VarExpr)si.elementexpr).getVar();
597                             if (un.getBinding(vd)==null) {
598                                 Updates up=new Updates(si.elementexpr,0);
599                                 un.addUpdate(up);
600                             }
601                         }
602                     } else if (inc instanceof RelationInclusion) {
603                         RelationInclusion ri=(RelationInclusion)inc;
604                         if (!(ri.getLeftExpr() instanceof VarExpr)) {
605                             Updates up=new Updates(ri.getLeftExpr(),0);
606                             un.addUpdate(up);
607                         } else {
608                             VarDescriptor vd=((VarExpr)ri.getLeftExpr()).getVar();
609                             if (un.getBinding(vd)==null) {
610                                 Updates up=new Updates(ri.getLeftExpr(),0);
611                                 un.addUpdate(up);
612                             }
613                         }
614                         if (!(ri.getRightExpr() instanceof VarExpr)) {
615                             Updates up=new Updates(ri.getRightExpr(),1);
616                             un.addUpdate(up);
617                         } else {
618                             VarDescriptor vd=((VarExpr)ri.getRightExpr()).getVar();
619                             if (un.getBinding(vd)==null) {
620                                 Updates up=new Updates(ri.getRightExpr(),1);
621                                 un.addUpdate(up);
622                             }
623                         }
624                     }
625                     //Finally build necessary updates to satisfy conjunction
626                     RuleConjunction ruleconj=dnfrule.get(j);
627                     /* Add in updates for quantifiers */
628                     //System.out.println("Attempting to generate add to set #4");
629                     MultUpdateNode mun=new MultUpdateNode(ar,MultUpdateNode.ADD);
630                     TermNode tn=new TermNode(mun);
631                     GraphNode gn2=new GraphNode("UpdateAdd"+addtocount,tn);
632
633                     if (processquantifers(gn2,un, r)&&debugdd()&&
634                         processconjunction(un,ruleconj)&&
635                         un.checkupdates()) {
636                         //System.out.println("Attempting to generate add to set #5");
637                         mun.addUpdate(un);
638                         GraphNode.Edge e=new GraphNode.Edge("abstract"+addtocount,gn2);
639                         addtocount++;
640                         gn.addEdge(e);
641                         updatenodes.add(gn2);}
642                 }
643             }
644         }
645     }
646
647     boolean debugdd() {
648         //System.out.println("Attempting to generate add to set DD");
649         return true;
650     }
651
652     boolean processquantifers(GraphNode gn,UpdateNode un, Rule r) {
653         Inclusion inc=r.getInclusion();
654         for(Iterator iterator=r.quantifiers();iterator.hasNext();) {
655             Quantifier q=(Quantifier)iterator.next();
656             /* Add quantifier */
657             /* FIXME: Analysis to determine when this update is necessary */
658             if (q instanceof RelationQuantifier) {
659                 RelationQuantifier rq=(RelationQuantifier)q;
660                 TupleOfExpr toe=new TupleOfExpr(new VarExpr(rq.x),new VarExpr(rq.y),rq.relation);
661                 toe.td=ReservedTypeDescriptor.INT;
662                 Updates u=new Updates(toe,false);
663                 un.addUpdate(u);
664                 if (abstractremove.containsKey(rq.relation)) {
665                     GraphNode agn=(GraphNode)abstractadd.get(rq.relation);
666                     GraphNode.Edge e=new GraphNode.Edge("requires",agn);
667                     gn.addEdge(e);
668                 } else {
669                     return false;
670                 }
671
672             } else if (q instanceof SetQuantifier) {
673                 SetQuantifier sq=(SetQuantifier)q;
674                 ElementOfExpr eoe=new ElementOfExpr(new VarExpr(sq.var),sq.set);
675                 eoe.td=ReservedTypeDescriptor.INT;
676                 Updates u=new Updates(eoe,false);
677                 un.addUpdate(u);
678                 if (abstractremove.containsKey(sq.set)) {
679                     GraphNode agn=(GraphNode)abstractadd.get(sq.set);
680                     GraphNode.Edge e=new GraphNode.Edge("requires",agn);
681                     gn.addEdge(e);
682                 } else {
683                     return false;
684                 }
685             } else return false;
686         }
687         return true;
688     }
689
690     boolean  processconjunction(UpdateNode un,RuleConjunction ruleconj){
691         boolean okay=true;
692         for(int k=0;k<ruleconj.size();k++) {
693             DNFExpr de=ruleconj.get(k);
694             Expr e=de.getExpr();
695             if (e instanceof OpExpr) {
696                 OpExpr ex=(OpExpr)de.getExpr();
697                 Opcode op=ex.getOpcode();
698                 Updates up=new Updates(ex.left,ex.right,op, de.getNegation());
699                 un.addUpdate(up);
700             } else if (e instanceof ElementOfExpr) {
701                 Updates up=new Updates(e,de.getNegation());
702                 un.addUpdate(up);
703             } else if (e instanceof TupleOfExpr) {
704                 Updates up=new Updates(e,de.getNegation());
705                 un.addUpdate(up);
706             } else if (e instanceof BooleanLiteralExpr) { 
707                 boolean truth=((BooleanLiteralExpr)e).getValue();
708                 if (de.getNegation())
709                     truth=!truth;
710                 if (!truth) {
711                     okay=false;
712                     break;
713                 }
714             } else {
715                 System.out.println(e.getClass().getName());
716                 throw new Error("Error #213");
717             }
718         }
719         return okay;
720     }
721
722     void generatescopenodes() {
723         for(int i=0;i<state.vRules.size();i++) {
724             Rule r=(Rule) state.vRules.get(i);
725             ScopeNode satisfy=new ScopeNode(r,true);
726             TermNode tnsatisfy=new TermNode(satisfy);
727             GraphNode gnsatisfy=new GraphNode("SatisfyRule"+i,tnsatisfy);
728             ConsequenceNode cnsatisfy=new ConsequenceNode();
729             TermNode ctnsatisfy=new TermNode(cnsatisfy);
730             GraphNode cgnsatisfy=new GraphNode("ConseqSatisfyRule"+i,ctnsatisfy);
731             consequence.put(satisfy,cgnsatisfy);
732             GraphNode.Edge esat=new GraphNode.Edge("consequencesatisfy"+i,cgnsatisfy);
733             gnsatisfy.addEdge(esat);
734             consequencenodes.add(cgnsatisfy);
735             scopesatisfy.put(r,gnsatisfy);
736             scopenodes.add(gnsatisfy);
737
738             ScopeNode falsify=new ScopeNode(r,false);
739             TermNode tnfalsify=new TermNode(falsify);
740             GraphNode gnfalsify=new GraphNode("FalsifyRule"+i,tnfalsify);
741             ConsequenceNode cnfalsify=new ConsequenceNode();
742             TermNode ctnfalsify=new TermNode(cnfalsify);
743             GraphNode cgnfalsify=new GraphNode("ConseqFalsifyRule"+i,ctnfalsify);
744             consequence.put(falsify,cgnfalsify);
745             GraphNode.Edge efals=new GraphNode.Edge("consequencefalsify"+i,cgnfalsify);
746             gnfalsify.addEdge(efals);
747             consequencenodes.add(cgnfalsify);
748             scopefalsify.put(r,gnfalsify);
749             scopenodes.add(gnfalsify);
750         }
751     }
752 }