Random typos.
[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
19     State state;
20
21     public Termination(State state) {
22         this.state=state;
23         conjunctions=new HashSet();
24         conjunctionmap=new Hashtable();
25         abstractrepair=new HashSet();
26         scopenodes=new HashSet();
27         scopesatisfy=new Hashtable();
28         scopefalsify=new Hashtable();
29         consequence=new Hashtable();
30         updatenodes=new HashSet();
31         consequencenodes=new HashSet();
32
33         generateconjunctionnodes();
34         generatescopenodes();
35         generaterepairnodes();
36         generatedatastructureupdatenodes();
37
38         generateabstractedges();
39         generatescopeedges();
40         generateupdateedges();
41
42         HashSet superset=new HashSet();
43         superset.addAll(conjunctions);
44         superset.addAll(abstractrepair);
45         superset.addAll(updatenodes);
46         superset.addAll(scopenodes);
47         superset.addAll(consequencenodes);
48         try {
49             GraphNode.DOTVisitor.visit(new FileOutputStream("graph.dot"),superset);
50         } catch (Exception e) {
51             e.printStackTrace();
52             System.exit(-1);
53         }
54     }
55     
56     void generateconjunctionnodes() {
57         Vector constraints=state.vConstraints;
58         for(int i=0;i<constraints.size();i++) {
59             Constraint c=(Constraint)constraints.get(i);
60             DNFConstraint dnf=c.dnfconstraint;
61             for(int j=0;j<dnf.size();j++) {
62                 TermNode tn=new TermNode(c,dnf.get(j));
63                 GraphNode gn=new GraphNode("Conjunction"+i+"B"+j,tn);
64                 conjunctions.add(gn);
65                 conjunctionmap.put(c,gn);
66             }
67         }
68     }
69
70     void generateupdateedges() {
71         for(Iterator updateiterator=updatenodes.iterator();updateiterator.hasNext();) {
72             GraphNode gn=(GraphNode)updateiterator.next();
73             TermNode tn=(TermNode)gn.getOwner();
74             MultUpdateNode mun=tn.getUpdate();
75             /* Cycle through the rules to look for possible conflicts */
76             for(int i=0;i<state.vRules.size();i++) {
77                 Rule r=(Rule) state.vRules.get(i);  
78                 if (ConcreteInterferes.interferes(mun,r,true)) {
79                     GraphNode scopenode=(GraphNode)scopesatisfy.get(r);
80                     GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
81                     gn.addEdge(e);
82                 }
83                 if (ConcreteInterferes.interferes(mun,r,false)) {
84                     GraphNode scopenode=(GraphNode)scopefalsify.get(r);
85                     GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
86                     gn.addEdge(e);
87                 }
88             }
89         }
90     }
91
92     void generateabstractedges() {
93         for(Iterator absiterator=abstractrepair.iterator();absiterator.hasNext();) {
94             GraphNode gn=(GraphNode)absiterator.next();
95             TermNode tn=(TermNode)gn.getOwner();
96             AbstractRepair ar=(AbstractRepair)tn.getAbstract();
97         
98             for(Iterator conjiterator=conjunctions.iterator();conjiterator.hasNext();) {
99                 GraphNode gn2=(GraphNode)conjiterator.next();
100                 TermNode tn2=(TermNode)gn2.getOwner();
101                 Conjunction conj=tn2.getConjunction();
102                 for(int i=0;i<conj.size();i++) {
103                     DNFPredicate dp=conj.get(i);
104                     if (AbstractInterferes.interferes(ar,dp)) {
105                         GraphNode.Edge e=new GraphNode.Edge("interferes",gn2);
106                         gn.addEdge(e);
107                         break;
108                     }
109                 }
110             }
111         }
112     }
113     
114     void generatescopeedges() {
115         for(Iterator scopeiterator=scopenodes.iterator();scopeiterator.hasNext();) {
116             GraphNode gn=(GraphNode)scopeiterator.next();
117             TermNode tn=(TermNode)gn.getOwner();
118             ScopeNode sn=tn.getScope();
119             
120             /* Interference edges with conjunctions */
121             for(Iterator conjiterator=conjunctions.iterator();conjiterator.hasNext();) {
122                 GraphNode gn2=(GraphNode)conjiterator.next();
123                 TermNode tn2=(TermNode)gn2.getOwner();
124                 Conjunction conj=tn2.getConjunction();
125                 for(int i=0;i<conj.size();i++) {
126                     DNFPredicate dp=conj.get(i);
127                     if (AbstractInterferes.interferes(sn.getDescriptor(),sn.getSatisfy(),dp)) {
128                         GraphNode.Edge e=new GraphNode.Edge("interferes",gn2);
129                         GraphNode gnconseq=(GraphNode)consequence.get(sn);
130                         gnconseq.addEdge(e);
131                         break;
132                     }
133                 }
134             }
135
136             /* Now see if this could effect other model defintion rules */
137             for(int i=0;i<state.vRules.size();i++) {
138                 Rule r=(Rule) state.vRules.get(i);
139                 if (AbstractInterferes.interferes(sn.getDescriptor(),sn.getSatisfy(),r,true)) {
140                     GraphNode scopenode=(GraphNode)scopesatisfy.get(r);
141                     GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
142                     GraphNode gnconseq=(GraphNode)consequence.get(sn);
143                     gnconseq.addEdge(e);
144                 }
145                 if (AbstractInterferes.interferes(sn.getDescriptor(),sn.getSatisfy(),r,false)) {
146                     GraphNode scopenode=(GraphNode)scopefalsify.get(r);
147                     GraphNode.Edge e=new GraphNode.Edge("interferes",scopenode);
148                     GraphNode gnconseq=(GraphNode)consequence.get(sn);
149                     gnconseq.addEdge(e);
150                 }
151             }
152         }
153     }
154
155
156     void generaterepairnodes() {
157         for(Iterator conjiterator=conjunctions.iterator();conjiterator.hasNext();) {
158             GraphNode gn=(GraphNode)conjiterator.next();
159             TermNode tn=(TermNode)gn.getOwner();
160             Conjunction conj=tn.getConjunction();
161             for(int i=0;i<conj.size();i++) {
162                 DNFPredicate dp=conj.get(i);
163                 int[] array=dp.getPredicate().getRepairs(dp.isNegated());
164                 Descriptor d=dp.getPredicate().getDescriptor();
165                 for(int j=0;j<array.length;j++) {
166                     AbstractRepair ar=new AbstractRepair(dp,array[j],d);
167                     TermNode tn2=new TermNode(ar);
168                     GraphNode gn2=new GraphNode(gn.getLabel()+"A"+i+"B"+j,tn2);
169                     GraphNode.Edge e=new GraphNode.Edge("abstract",gn2);
170                     gn.addEdge(e);
171                     abstractrepair.add(gn2);
172                 }
173             }
174         }
175     }
176
177     void generatedatastructureupdatenodes() {
178         for(Iterator absiterator=abstractrepair.iterator();absiterator.hasNext();) {
179             GraphNode gn=(GraphNode)absiterator.next();
180             TermNode tn=(TermNode) gn.getOwner();
181             AbstractRepair ar=tn.getAbstract();
182             if (ar.getType()==AbstractRepair.ADDTOSET) {
183                 generateaddtoset(gn,ar);
184             } else if (ar.getType()==AbstractRepair.REMOVEFROMSET) {
185                 generateremovefromset(gn,ar);
186             } else if (ar.getType()==AbstractRepair.ADDTORELATION) {
187                 generateaddtorelation(gn,ar);
188             } else if (ar.getType()==AbstractRepair.REMOVEFROMRELATION) {
189                 generateremovefromrelation(gn,ar);
190             } else if (ar.getType()==AbstractRepair.MODIFYRELATION) {
191                 generatemodifyrelation(gn,ar);
192             }
193         }
194     }
195
196     void generateremovefromset(GraphNode gn,AbstractRepair ar) {
197         Vector possiblerules=new Vector();
198         for(int i=0;i<state.vRules.size();i++) {
199             Rule r=(Rule) state.vRules.get(i);
200             if ((r.getInclusion() instanceof SetInclusion)&&
201                 (ar.getDescriptor()==((SetInclusion)r.getInclusion()).getSet()))
202                 possiblerules.add(r);
203         }
204         int[] count=new int[possiblerules.size()];
205         while(remains(count,possiblerules)) {
206             MultUpdateNode mun=new MultUpdateNode(ar);
207             for(int i=0;i<possiblerules.size();i++) {
208                 UpdateNode un=new UpdateNode();
209                 mun.addUpdate(un);
210                 /* CODE HERE*/
211             }
212             increment(count,possiblerules);
213         }
214     }
215
216     static void increment(int count[], Vector rules) {
217         count[0]++;
218         for(int i=0;i<(rules.size()-1);i++) {
219             if (count[i]>=(((Rule)rules.get(i)).numQuantifiers()+(((Rule)rules.get(i)).getDNFNegGuardExpr().size()))) {
220                 count[i+1]++;
221                 count[i]=0;
222             } else break;
223         }
224     }
225
226     static boolean remains(int count[], Vector rules) {
227         for(int i=0;i<rules.size();i++) {
228             if (count[i]>=(((Rule)rules.get(i)).numQuantifiers()+(((Rule)rules.get(i)).getDNFNegGuardExpr().size()))) {
229                 return false;
230             }
231         }
232         return true;
233     }
234
235     void generateremovefromrelation(GraphNode gn,AbstractRepair ar) {}
236     void generateaddtorelation(GraphNode gn,AbstractRepair ar) {}
237     void generatemodifyrelation(GraphNode gn, AbstractRepair ar) {}
238
239     static int addtocount=0;
240     void generateaddtoset(GraphNode gn, AbstractRepair ar) {
241         for(int i=0;i<state.vRules.size();i++) {
242             Rule r=(Rule) state.vRules.get(i);
243             if (r.getInclusion() instanceof SetInclusion) {
244                 if (ar.getDescriptor()==((SetInclusion)r.getInclusion()).getSet()) {
245                     //Generate add instruction
246                     DNFRule dnfrule=r.getDNFGuardExpr();
247                     for(int j=0;j<dnfrule.size();j++) {
248                         Inclusion inc=r.getInclusion();
249                         UpdateNode un=new UpdateNode();
250                         /* First solve for quantifiers */
251                         boolean goodupdate=true;
252                         for(Iterator iterator=r.quantifiers();iterator.hasNext();) {
253                             Quantifier q=(Quantifier)iterator.next();
254                             boolean foundall=true;
255                             if ((q instanceof SetQuantifier)||(q instanceof ForQuantifier)) {
256                                 VarDescriptor vd=null;
257                                 if (q instanceof SetQuantifier)
258                                     vd=((SetQuantifier)q).getVar();
259                                 else
260                                     vd=((ForQuantifier)q).getVar();
261                                 if(inc instanceof SetInclusion) {
262                                     SetInclusion si=(SetInclusion)inc;
263                                     if ((si.elementexpr instanceof VarExpr)&&
264                                         (((VarExpr)si.elementexpr).getVar()==vd)) {
265                                         /* Can solve for v */
266                                         Binding binding=new Binding(vd,0);
267                                         un.addBinding(binding);
268                                     } else
269                                         foundall=false;
270                                 } else if (inc instanceof RelationInclusion) {
271                                     RelationInclusion ri=(RelationInclusion)inc;
272                                     boolean f1=true;
273                                     boolean f2=true;
274                                     if ((ri.getLeftExpr() instanceof VarExpr)&&
275                                         (((VarExpr)ri.getLeftExpr()).getVar()==vd)) {
276                                         /* Can solve for v */
277                                         Binding binding=new Binding(vd,0);
278                                         un.addBinding(binding);
279                                     } else f1=false;
280                                     if ((ri.getRightExpr() instanceof VarExpr)&&
281                                         (((VarExpr)ri.getRightExpr()).getVar()==vd)) {
282                                         /* Can solve for v */
283                                         Binding binding=new Binding(vd,0);
284                                         un.addBinding(binding);
285                                     } else f2=false;
286                                     if (!(f1||f2))
287                                         foundall=false;
288                                 } else throw new Error("Inclusion not recognized");
289                             } else if (q instanceof RelationQuantifier) {
290                                 RelationQuantifier rq=(RelationQuantifier)q;
291                                 for(int k=0;k<2;k++) {
292                                     VarDescriptor vd=(k==0)?rq.x:rq.y;
293                                     if(inc instanceof SetInclusion) {
294                                         SetInclusion si=(SetInclusion)inc;
295                                         if ((si.elementexpr instanceof VarExpr)&&
296                                             (((VarExpr)si.elementexpr).getVar()==vd)) {
297                                             /* Can solve for v */
298                                             Binding binding=new Binding(vd,0);
299                                             un.addBinding(binding);
300                                         } else
301                                             foundall=false;
302                                     } else if (inc instanceof RelationInclusion) {
303                                         RelationInclusion ri=(RelationInclusion)inc;
304                                         boolean f1=true;
305                                         boolean f2=true;
306                                         if ((ri.getLeftExpr() instanceof VarExpr)&&
307                                             (((VarExpr)ri.getLeftExpr()).getVar()==vd)) {
308                                             /* Can solve for v */
309                                             Binding binding=new Binding(vd,0);
310                                             un.addBinding(binding);
311                                         } else f1=false;
312                                         if ((ri.getRightExpr() instanceof VarExpr)&&
313                                                    (((VarExpr)ri.getRightExpr()).getVar()==vd)) {
314                                             /* Can solve for v */
315                                             Binding binding=new Binding(vd,0);
316                                             un.addBinding(binding);
317                                         } else f2=false;
318                                         if (!(f1||f2))
319                                             foundall=false;
320                                     } else throw new Error("Inclusion not recognized");
321                                 }
322                             } else throw new Error("Quantifier not recognized");
323                             if (!foundall) {
324                                 goodupdate=false;
325                                 break;
326                             }
327                             /* Now build update for tuple/set inclusion condition */
328                             if(inc instanceof SetInclusion) {
329                                 SetInclusion si=(SetInclusion)inc;
330                                 if (!(si.elementexpr instanceof VarExpr)) {
331                                     Updates up=new Updates(si.elementexpr,0);
332                                     un.addUpdate(up);
333                                 }
334                             } 
335                             if (inc instanceof RelationInclusion) {
336                                 RelationInclusion ri=(RelationInclusion)inc;
337                                 if (!(ri.getLeftExpr() instanceof VarExpr)) {
338                                     Updates up=new Updates(ri.getLeftExpr(),0);
339                                     un.addUpdate(up);
340                                 }
341                                 if (!(ri.getRightExpr() instanceof VarExpr)) {
342                                     Updates up=new Updates(ri.getRightExpr(),0);
343                                     un.addUpdate(up);
344                                 }
345                             }
346                             //Finally build necessary updates to satisfy conjunction
347                             RuleConjunction ruleconj=dnfrule.get(j);
348                             for(int k=0;k<ruleconj.size();k++) {
349                                 DNFExpr de=ruleconj.get(k);
350                                 Expr e=de.getExpr();
351                                 if (e instanceof OpExpr) {
352                                     OpExpr ex=(OpExpr)de.getExpr();
353                                     Opcode op=ex.getOpcode();
354                                     if (de.getNegation()) {
355                                         /* remove negation through opcode translation */
356                                         if (op==Opcode.GT)
357                                             op=Opcode.LE;
358                                         else if (op==Opcode.GE)
359                                             op=Opcode.LT;
360                                         else if (op==Opcode.EQ)
361                                             op=Opcode.NE;
362                                         else if (op==Opcode.NE)
363                                             op=Opcode.EQ;
364                                         else if (op==Opcode.LT)
365                                             op=Opcode.GE;
366                                         else if (op==Opcode.LE)
367                                             op=Opcode.GT;
368                                     }
369                                     Updates up=new Updates(ex.left,ex.right,op);
370                                     un.addUpdate(up);
371                                 } else if (e instanceof ElementOfExpr) {
372                                     Updates up=new Updates(e,de.getNegation());
373                                     un.addUpdate(up);
374                                 } else if (e instanceof TupleOfExpr) {
375                                     Updates up=new Updates(e,de.getNegation());
376                                     un.addUpdate(up);
377                                 } else throw new Error("Error #213");
378                             }
379                         }
380                         MultUpdateNode mun=new MultUpdateNode(ar);
381                         mun.addUpdate(un);
382                         TermNode tn=new TermNode(mun);
383                         GraphNode gn2=new GraphNode("Update"+addtocount,tn);
384                         GraphNode.Edge e=new GraphNode.Edge("abstract"+addtocount,gn2);
385                         addtocount++;
386                         gn.addEdge(e);
387                         updatenodes.add(gn2);
388                     }
389                 }
390             }
391         }
392     }
393
394     void generatescopenodes() {
395         for(int i=0;i<state.vRules.size();i++) {
396             Rule r=(Rule) state.vRules.get(i);
397             ScopeNode satisfy=new ScopeNode(r,true);
398             TermNode tnsatisfy=new TermNode(satisfy);
399             GraphNode gnsatisfy=new GraphNode("SatisfyRule"+i,tnsatisfy);
400             ConsequenceNode cnsatisfy=new ConsequenceNode();
401             TermNode ctnsatisfy=new TermNode(cnsatisfy);
402             GraphNode cgnsatisfy=new GraphNode("ConseqSatisfyRule"+i,ctnsatisfy);
403             consequence.put(satisfy,cgnsatisfy);
404             GraphNode.Edge esat=new GraphNode.Edge("consequencesatisfy"+i,cgnsatisfy);
405             gnsatisfy.addEdge(esat);
406             consequencenodes.add(cgnsatisfy);
407             scopesatisfy.put(r,gnsatisfy);
408             scopenodes.add(gnsatisfy);
409
410             ScopeNode falsify=new ScopeNode(r,false);
411             TermNode tnfalsify=new TermNode(falsify);
412             GraphNode gnfalsify=new GraphNode("FalsifyRule"+i,tnfalsify);
413             ConsequenceNode cnfalsify=new ConsequenceNode();
414             TermNode ctnfalsify=new TermNode(cnfalsify);
415             GraphNode cgnfalsify=new GraphNode("ConseqFalsifyRule"+i,ctnfalsify);
416             consequence.put(falsify,cgnfalsify);
417             GraphNode.Edge efals=new GraphNode.Edge("consequencefalsify"+i,cgnfalsify);
418             gnfalsify.addEdge(efals);
419             consequencenodes.add(cgnfalsify);
420             scopefalsify.put(r,gnfalsify);
421             scopenodes.add(gnfalsify);
422         }
423     }
424 }