c711d82b6c635891a4dc78b628a7d7b74f0e6d9a
[repair.git] / Repair / RepairCompiler / MCC / IR / ConcreteInterferes.java
1 package MCC.IR;
2 import java.util.*;
3
4 class ConcreteInterferes {
5     static public boolean interferes(MultUpdateNode mun, Rule r, boolean satisfy) {
6         if (!initialinterferes(mun,r,satisfy)) /* Can't falsify a rule adding something to a set on an initial addition*/
7             return false;
8         for(int i=0;i<mun.numUpdates();i++) {
9             UpdateNode un=mun.getUpdate(i);
10             for (int j=0;j<un.numUpdates();j++) {
11                 Updates update=un.getUpdate(j);
12                 
13                 DNFRule drule=r.getDNFGuardExpr();
14                 if (satisfy)
15                     drule=r.getDNFNegGuardExpr();
16
17
18                 if (!update.isAbstract()) {
19                     Descriptor updated_des=update.getDescriptor();
20                     assert updated_des!=null;
21                     /* Update is local to this rule, and the effect is intentional */
22                     /* If we're adding something, a side effect could be to falsify some other binding
23                        If we're removing something, there is no similar side effect */
24                     if ((un.getRule()==r)&&
25                         (((mun.op==MultUpdateNode.ADD)&&satisfy)||(mun.op==MultUpdateNode.REMOVE))&&
26                         (r.numQuantifiers()==1)&&
27                         (r.getQuantifier(0) instanceof SetQuantifier)&&
28                         update.isField()&&
29                         (((DotExpr)update.getLeftExpr()).getExpr() instanceof VarExpr)&&
30                         ((SetQuantifier)r.getQuantifier(0)).getVar()==((VarExpr)((DotExpr)update.getLeftExpr()).getExpr()).getVar())
31                         continue;
32                     if ((un.getRule()==r)&&
33                         (((mun.op==MultUpdateNode.ADD)&&satisfy)||(mun.op==MultUpdateNode.REMOVE))&&
34                         (r.numQuantifiers()==0))
35                         continue;
36
37
38                     if (r.getInclusion().usesDescriptor(updated_des))
39                         return true; /* Interferes with inclusion condition */
40                     
41                     for(int k=0;k<drule.size();k++) {
42                         RuleConjunction rconj=drule.get(k);
43                         for(int l=0;l<rconj.size();l++) {
44
45
46                             DNFExpr dexpr=rconj.get(l);
47                             /* See if update interferes w/ dexpr */
48                             if (interferes(un,update, r,dexpr))
49                                 return true;
50                         }
51                     }
52                 }
53             }
54         }
55         return false;
56     }
57
58     static private boolean initialinterferes(MultUpdateNode mun, Rule r, boolean satisfy) {
59         AbstractRepair ar=mun.getRepair();
60         if (satisfy)
61             return true;
62         if (ar==null)
63             return true;
64         if (ar.getType()!=AbstractRepair.ADDTOSET)
65             return true;
66         //      if (mun.op!=MultUpdateNode.ADD)  (Redundant)
67         //    return true;
68         if (!r.getInclusion().getTargetDescriptors().contains(ar.getDescriptor()))
69             return true;
70         boolean negated=ar.getPredicate().isNegated();
71         Predicate p=ar.getPredicate().getPredicate();
72         if (!(p instanceof ExprPredicate))
73             return true;
74         ExprPredicate ep=(ExprPredicate)p;
75         if (ep.getType()!=ExprPredicate.SIZE)
76             return true;
77         if ((ep.getOp()==Opcode.EQ)&&(ep.leftsize()==1)&&!negated)
78             return false;
79         if ((ep.getOp()==Opcode.NE)&&(ep.leftsize()==1)&&negated)
80             return false;
81
82         if ((ep.getOp()==Opcode.NE)&&(ep.leftsize()==0)&&!negated)
83             return false;
84         if ((ep.getOp()==Opcode.EQ)&&(ep.leftsize()==0)&&negated)
85             return false;
86
87
88
89         if ((ep.getOp()==Opcode.GT)&&(ep.leftsize()==0)&&!negated)
90             return false;
91         if ((ep.getOp()==Opcode.LE)&&(ep.leftsize()==0)&&negated)
92             return false;
93
94         if ((ep.getOp()==Opcode.GE)&&(ep.leftsize()==1)&&!negated)
95             return false;
96         if ((ep.getOp()==Opcode.LT)&&(ep.leftsize()==1)&&negated)
97             return false;
98         
99         return true;
100
101         
102     }
103
104     static private boolean interferes(UpdateNode un,Updates update, Rule r,DNFExpr dexpr) {
105         Descriptor descriptor=update.getDescriptor();
106         if (!dexpr.getExpr().usesDescriptor(descriptor))
107             return false;
108             
109         /* We need to pair the variables */
110         if (update.isExpr()) {
111             Set vars=update.getRightExpr().freeVars();
112             Opcode op1=update.getOpcode();
113             Expr lexpr1=update.getLeftExpr();
114             Expr rexpr1=update.getRightExpr();
115             boolean good=true;
116             for(Iterator it=vars.iterator();it.hasNext();) {
117                 VarDescriptor vd=(VarDescriptor) it.next();
118                 if (un.getBinding(vd)!=null) {
119                     /* VarDescriptor isn't a global */
120                     if (update.getVar()!=vd) {
121                         good=false;
122                         break;
123                     }
124                 }
125             }
126             if (good&&(dexpr.getExpr() instanceof OpExpr)) {
127                 OpExpr expr=(OpExpr)dexpr.getExpr();
128                 Expr lexpr2=expr.getLeftExpr();
129                 Expr rexpr2=expr.getRightExpr();
130                 Opcode op2=expr.getOpcode();
131                 if (dexpr.getNegation()) {
132                     /* remove negation through opcode translation */
133                     if (op2==Opcode.GT)
134                         op2=Opcode.LE;
135                     else if (op2==Opcode.GE)
136                         op2=Opcode.LT;
137                     else if (op2==Opcode.EQ)
138                         op2=Opcode.NE;
139                     else if (op2==Opcode.NE)
140                         op2=Opcode.EQ;
141                     else if (op2==Opcode.LT)
142                         op2=Opcode.GE;
143                     else if (op2==Opcode.LE)
144                         op2=Opcode.GT;
145                 }
146                 good=true;
147                 vars=rexpr2.freeVars();
148                 VarDescriptor leftdescriptor=null;
149                 if (lexpr2 instanceof VarExpr)
150                     leftdescriptor=((VarExpr)lexpr2).getVar();
151                 else if (lexpr2 instanceof DotExpr) {
152                     Expr e=lexpr2;
153                     for(;e instanceof DotExpr;e=((DotExpr)e).getExpr()) ;
154                     leftdescriptor=((VarExpr)e).getVar();
155                 } else throw new Error("Bad Expr");
156                 
157                 for(Iterator it=vars.iterator();it.hasNext();) {
158                     VarDescriptor vd=(VarDescriptor) it.next();
159                     if (un.getBinding(vd)!=null) {
160                         /* VarDescriptor isn't a global */
161                         if (leftdescriptor!=vd) {
162                             good=false;
163                             break;
164                         }
165                     }
166                 }
167                 if (good) {
168                     HashMap remap=new HashMap();
169                     remap.put(update.getVar(),leftdescriptor);
170                     if ((op1==op2)&&
171                         lexpr1.equals(remap,lexpr2)&&
172                         rexpr1.equals(remap,rexpr2))
173                         return false;
174                 }
175             }
176         }
177         return true;
178     }
179 }