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