Fix some of Dan's bugs (code generation for relation quantifiers misstyped), didn...
[repair.git] / Repair / RepairCompiler / MCC / IR / ImplicitSchema.java
1 package MCC.IR;
2 import MCC.State;
3 import java.util.*;
4
5 public class ImplicitSchema {
6     State state;
7     SetAnalysis setanalysis;
8     public ImplicitSchema(State state) {
9         this.state=state;
10         this.setanalysis=new SetAnalysis(state);
11     }
12
13     public void update() {
14         //      updaterules();
15         updateconstraints();
16         updaterelationconstraints();
17     }
18
19     boolean needDomain(RelationDescriptor rd) {
20         return needDR(rd, true);
21     }
22
23     boolean needDR(RelationDescriptor rd,boolean isdomain) {
24         Vector rules=state.vRules;
25         SetDescriptor sd=isdomain?rd.getDomain():rd.getRange();
26         for(int i=0;i<rules.size();i++) {
27             Rule r=(Rule)rules.get(i);
28             if ((r.numQuantifiers()==1)&&
29                 (r.getQuantifier(0) instanceof RelationQuantifier)&&
30                 (((RelationQuantifier)r.getQuantifier(0)).getRelation()==rd)&&
31                 r.getInclusion().getTargetDescriptors().contains(sd)) {
32                 SetInclusion rinc=(SetInclusion)r.getInclusion();
33                 RelationQuantifier rq=(RelationQuantifier)r.getQuantifier(0);
34                 VarDescriptor vd=isdomain?rq.x:rq.y;
35                 if ((rinc.getExpr() instanceof VarExpr)&&
36                     (((VarExpr)rinc.getExpr()).getVar()==vd)&&
37                     (r.getGuardExpr() instanceof BooleanLiteralExpr)&&
38                     (((BooleanLiteralExpr)r.getGuardExpr()).getValue()))
39                     return false;
40             }
41         }
42
43
44         for(int i=0;i<rules.size();i++) {
45             Rule r=(Rule)rules.get(i);
46             Inclusion inc=r.getInclusion();
47             if (inc.getTargetDescriptors().contains(rd)) {
48                 /* Need to check this rule */
49                 boolean good=false;
50                 RelationInclusion rinc=(RelationInclusion)inc;
51                 Expr expr=isdomain?rinc.getLeftExpr():rinc.getRightExpr();
52                 if (expr instanceof VarExpr) {
53                     VarDescriptor vd=((VarExpr)expr).getVar();
54                     assert vd!=null;
55                     for (int j=0;j<r.numQuantifiers();j++) {
56                         Quantifier q=r.getQuantifier(j);
57                         if ((q instanceof SetQuantifier)&&
58                             (((SetQuantifier)q).getVar()==vd)&&
59                             (sd.allSubsets().contains(((SetQuantifier)q).getSet()))) {
60                             good=true;
61                             break;
62                         }
63                         if ((q instanceof RelationQuantifier)&&
64                             (
65                             ((((RelationQuantifier)q).x==vd)&&
66                             (sd.allSubsets().contains(((RelationQuantifier)q).getRelation().getDomain())))
67                             ||
68                             ((((RelationQuantifier)q).y==vd)&&
69                             (sd.allSubsets().contains(((RelationQuantifier)q).getRelation().getRange())))
70                             )) {
71                             good=true;
72                             break;
73                         }
74                         
75                     }
76                     if (good)
77                         continue; /* Proved for this case */
78                 }
79                 for(int j=0;j<rules.size();j++) {
80                     Rule r2=(Rule)rules.get(j);
81                     Inclusion inc2=r2.getInclusion();
82                     
83                     if (checkimplication(r,r2,isdomain)) {
84                         good=true;
85                         break;
86                     }
87                 }
88                 if (good)
89                     continue;
90
91                 return true; /* Couldn't prove we didn't need */
92             }
93         }
94         return false;
95     }
96
97     boolean checkimplication(Rule r1, Rule r2, boolean isdomain) {
98         /* r1 is the relation */
99         /* See if this rule guarantees relation */
100         /* Steps:
101            1. match up quantifiers
102            2. check inclusion condition
103            3. see if guard expr of set rule is more general */
104
105         RelationInclusion inc1=(RelationInclusion) r1.getInclusion();
106         RelationDescriptor rd=inc1.getRelation();
107         SetDescriptor sd=isdomain?rd.getDomain():rd.getRange();
108         Expr expr=isdomain?inc1.getLeftExpr():inc1.getRightExpr();
109
110         Inclusion inc2=r2.getInclusion();
111         if (!(inc2 instanceof SetInclusion))
112             return false;
113         SetInclusion sinc2=(SetInclusion)inc2;
114         if (sinc2.getSet()!=sd)
115             return false;
116         if (r1.numQuantifiers()!=r2.numQuantifiers())
117             return false; 
118         /* Construct a mapping between quantifiers */
119         int[] mapping=new int[r2.numQuantifiers()];
120         HashMap map=new HashMap();
121         for(int i=0;i<r1.numQuantifiers();i++) {
122             Quantifier q1=r1.getQuantifier(i);
123             boolean foundmapping=false;
124             for (int j=0;j<r2.numQuantifiers();j++) {
125                 if (mapping[j]==1)
126                     continue; /* Its already used */
127                 Quantifier q2=r2.getQuantifier(j);
128                 if (q1 instanceof SetQuantifier && q2 instanceof SetQuantifier&&
129                     ((SetQuantifier)q1).getSet()==((SetQuantifier)q2).getSet()) {
130                     mapping[j]=1;
131                     map.put(((SetQuantifier)q1).getVar(),((SetQuantifier)q2).getVar());
132                     foundmapping=true;
133                     break;
134                 }
135                 if (q1 instanceof RelationQuantifier && q2 instanceof RelationQuantifier &&
136                     ((RelationQuantifier)q1).getRelation()==((RelationQuantifier)q2).getRelation()) {
137                     mapping[j]=1;
138                     map.put(((RelationQuantifier)q1).x,((RelationQuantifier)q2).x);
139                     map.put(((RelationQuantifier)q1).y,((RelationQuantifier)q2).y);
140                     foundmapping=true;
141                     break;
142                 }
143             }
144             if (!foundmapping)
145                 return false;
146         }
147         /* Built mapping */
148         Expr sexpr=sinc2.getExpr();
149         if (!expr.equals(map,sexpr))
150             return false;  /* This rule doesn't add the right thing */
151         DNFRule drule1=r1.getDNFGuardExpr();
152         DNFRule drule2=r2.getDNFGuardExpr();
153         for (int i=0;i<drule1.size();i++) {
154             RuleConjunction rconj1=drule1.get(i);
155             boolean foundmatch=false;
156             for (int j=0;j<drule2.size();j++) {
157                 RuleConjunction rconj2=drule2.get(j);
158                 /* Need to show than rconj2 is true if rconj1 is true */
159                 if (implication(map,rconj1,rconj2)) {
160                     foundmatch=true;
161                     break;
162                 }
163             }
164             if (!foundmatch)
165                 return false;
166         }
167         return true;
168     }
169
170     boolean implication(HashMap map, RuleConjunction rc1, RuleConjunction rc2) {
171         for(int i=0;i<rc2.size();i++) {
172             /* Check that rc1 has all predicates that rc2 has */
173             DNFExpr de2=rc2.get(i);
174             boolean havematch=false;
175             for(int j=0;j<rc1.size();j++) {
176                 DNFExpr de1=rc1.get(i);
177                 if (de1.getNegation()!=de2.getNegation())
178                     continue;
179                 if (de1.getExpr().equals(map,de2.getExpr())) {
180                     havematch=true;
181                     break;
182                 }
183             }
184             if (!havematch)
185                 return false;
186         }
187         return true;
188     }
189
190     boolean needRange(RelationDescriptor rd) {
191         return needDR(rd, false);
192     }
193
194     void updaterelationconstraints() {
195         Vector reldescriptors=state.stRelations.getAllDescriptors();
196         for(int i=0;i<reldescriptors.size();i++) {
197             RelationDescriptor rd=(RelationDescriptor) reldescriptors.get(i);
198             if (needDomain(rd)||needRange(rd)) {
199                 
200                 Constraint c=new Constraint();
201                 /* Construct quantifier */
202                 LogicStatement ls=null;
203
204                 RelationQuantifier rq=new RelationQuantifier();
205                 String varname1=new String("relationvar1");
206                 VarDescriptor var1=new VarDescriptor(varname1);
207                 String varname2=new String("relationvar2");
208                 VarDescriptor var2=new VarDescriptor(varname2);
209                 rq.setTuple(var1,var2);
210                 rq.setRelation(rd);
211                 c.addQuantifier(rq);
212                 c.getSymbolTable().add(var1);
213                 c.getSymbolTable().add(var2);
214                 var1.setType(rd.getDomain().getType());
215                 var2.setType(rd.getRange().getType());
216
217                 if (needDomain(rd)) {
218                     VarExpr ve1=new VarExpr(var1);
219                     SetExpr se1=new SetExpr(rd.getDomain());
220                     se1.td=rd.getDomain().getType();
221                     ls=new InclusionPredicate(ve1,se1);
222                 }
223
224
225                 if (needRange(rd)) {
226                     VarExpr ve2=new VarExpr(var2);
227                     SetExpr se2=new SetExpr(rd.getRange());
228                     se2.td=rd.getRange().getType();
229                     LogicStatement incpred2=new InclusionPredicate(ve2,se2);
230                     if (ls==null) ls=incpred2;
231                     else ls=new LogicStatement(LogicStatement.AND,ls,incpred2);
232                 }
233                 rd.addUsage(RelationDescriptor.IMAGE);
234
235                 c.setLogicStatement(ls);
236                 state.vConstraints.add(c);
237             }
238         }
239     }
240
241     void updateconstraints() {
242         Vector setdescriptors=state.stSets.getAllDescriptors();
243         for(int i=0;i<setdescriptors.size();i++) {
244             SetDescriptor sd=(SetDescriptor) setdescriptors.get(i);
245             if(sd.isPartition()) {
246                 Constraint c=new Constraint();
247                 /* Construct quantifier */
248                 SetQuantifier sq=new SetQuantifier();
249                 String varname=new String("partitionvar");
250                 VarDescriptor var=new VarDescriptor(varname);
251                 c.getSymbolTable().add(var);
252                 var.setType(sd.getType());
253                 sq.setVar(var);
254                 sq.setSet(sd);
255                 c.addQuantifier(sq);
256
257                 /*Construct logic statement*/
258                 LogicStatement ls=null;
259                 for(int j=0;j<sd.getSubsets().size();j++) {
260                     LogicStatement conj=null;
261                     for(int k=0;k<sd.getSubsets().size();k++) {
262                         VarExpr ve=new VarExpr(var);
263                         SetExpr se=new SetExpr((SetDescriptor) sd.getSubsets().get(k));
264                         se.td=sd.getType();
265                         LogicStatement incpred=new InclusionPredicate(ve,se);
266                         if (j!=k) {
267                             incpred=new LogicStatement(LogicStatement.NOT ,incpred);
268                         }
269                         if (conj==null)
270                             conj=incpred;
271                         else 
272                             conj=new LogicStatement(LogicStatement.AND, conj, incpred);
273                     }
274                     if (ls==null)
275                         ls=conj;
276                     else 
277                         ls=new LogicStatement(LogicStatement.OR, ls, conj);
278                 }
279                 c.setLogicStatement(ls);
280                 state.vConstraints.add(c);
281             }
282         }
283     }
284     
285     void updaterules() {
286         Vector oldrules=state.vRules;
287         Vector newrules=new Vector();
288         for(int i=0;i<oldrules.size();i++) {
289             Rule r=(Rule)oldrules.get(i);
290             if (r.inclusion instanceof SetInclusion) {
291                 SetDescriptor sd=((SetInclusion)r.inclusion).getSet();
292                 Set supersets=setanalysis.getSuperset(sd);
293                 if (supersets!=null)
294                     for(Iterator superit=supersets.iterator();superit.hasNext();) {
295                         SetDescriptor sd1=(SetDescriptor)superit.next();
296                         Rule nr=new Rule();
297                         nr.guard=r.guard;
298                         nr.quantifiers=r.quantifiers;
299                         nr.isstatic=r.isstatic;
300                         nr.isdelay=r.isdelay;
301                         nr.inclusion=new SetInclusion(((SetInclusion)r.inclusion).elementexpr,sd1);
302                         nr.st=r.st;
303                         newrules.add(nr);
304                     }
305             }
306         }
307         oldrules.addAll(newrules);
308     }
309 }