4 class ConcreteInterferes {
6 static public boolean interferesinclusion(UpdateNode un, Updates update, Rule r) {
7 Descriptor updated_des=update.getDescriptor();
8 Inclusion inclusion=r.getInclusion();
9 if (inclusion instanceof RelationInclusion) {
10 RelationInclusion ri=(RelationInclusion)inclusion;
11 if (ri.getLeftExpr().usesDescriptor(updated_des)&&interferesinclusion(un,update,r,ri.getLeftExpr()))
13 if (ri.getRightExpr().usesDescriptor(updated_des)&&interferesinclusion(un,update,r,ri.getRightExpr()))
15 } else if (inclusion instanceof SetInclusion) {
16 SetInclusion si=(SetInclusion)inclusion;
17 if (si.getExpr().usesDescriptor(updated_des)&&interferesinclusion(un,update,r,si.getExpr()))
19 } else throw new Error();
23 static public boolean interferesinclusion(UpdateNode un, Updates update, Rule r, Expr inclusionexpr) {
24 Descriptor updated_des=update.getDescriptor();
25 if (updated_des instanceof FieldDescriptor) {
26 /* Build variable correspondance */
27 HashSet set=new HashSet();
28 inclusionexpr.findmatch(updated_des,set);
30 for(Iterator matchit=set.iterator();matchit.hasNext();) {
31 DotExpr dotexpr=(DotExpr)matchit.next();
32 DotExpr updateexpr=(DotExpr)update.getLeftExpr();
34 if (dotexpr.getField()!=updateexpr.getField())
36 Expr de=dotexpr.getExpr();
37 Expr ue=updateexpr.getExpr();
38 if ((de instanceof DotExpr)&&(ue instanceof DotExpr)) {
40 updateexpr=(DotExpr)ue;
41 } else if ((de instanceof VarExpr)&&(ue instanceof VarExpr)) {
42 VarDescriptor dvd=((VarExpr)de).getVar();
43 VarDescriptor uvd=((VarExpr)ue).getVar();
44 if (interferesinclusion(un,r,dvd,uvd))
52 } else if (updated_des instanceof VarDescriptor) {
53 /* We have a VarDescriptor - no correspondance necessary */
54 VarDescriptor vd=(VarDescriptor)updated_des;
55 if (interferesinclusion(un,r,vd,vd))
57 } else throw new Error();
61 static public boolean interferesinclusion(UpdateNode un, Rule r, VarDescriptor dvd, VarDescriptor uvd) {
62 DNFRule negrule=r.getDNFNegGuardExpr();
63 HashMap remap=new HashMap();
66 for(int i=0;i<negrule.size();i++) {
67 RuleConjunction rconj=negrule.get(i);
69 for(int j=0;j<rconj.size();j++) {
70 DNFExpr dexpr=rconj.get(j);
71 if (dexpr.getExpr() instanceof OpExpr) {
72 OpExpr expr=(OpExpr)dexpr.getExpr();
73 Expr lexpr=expr.getLeftExpr();
74 Expr rexpr=expr.getRightExpr();
77 Set vars=rexpr.freeVars();
79 for(Iterator it=vars.iterator();it.hasNext();) {
80 VarDescriptor vd=(VarDescriptor) it.next();
82 /* VarDescriptor isn't a global */
95 Opcode op=expr.getOpcode();
96 op=Opcode.translateOpcode(dexpr.getNegation(),op);
99 for(int k=0;k<un.numUpdates();k++) {
100 Updates update=un.getUpdate(k);
101 if(update.isExpr()) {
102 Set uvars=update.getRightExpr().freeVars();
103 boolean freevarok=true;
105 for(Iterator it=uvars.iterator();it.hasNext();) {
106 VarDescriptor vd=(VarDescriptor) it.next();
107 if (!vd.isGlobal()) {
108 /* VarDescriptor isn't a global */
118 Opcode op2=update.getOpcode();
120 ((op2==Opcode.GT)&&(op==Opcode.GE))||
121 ((op2==Opcode.LT)&&(op==Opcode.LE))||
122 ((op2==Opcode.EQ)&&((op==Opcode.GE)||(op==Opcode.LE)))) {
123 /* Operations match*/
124 if (lexpr.equals(remap,update.getLeftExpr())&&
125 rexpr.equals(remap,update.getRightExpr())) {
137 /* TODO: Check to see if there is an abstract repair */
139 break; /* try next conjunction */
148 /** Returns true if the data structure updates performed by mun may increase (or decrease if satisfy=false)
149 * the scope of the model definition rule r. */
151 static public boolean interferes(MultUpdateNode mun, Rule r, boolean satisfy) {
152 if (!initialinterferes(mun,r,satisfy)) /* Can't falsify a rule adding something to a set on an initial addition*/
154 for(int i=0;i<mun.numUpdates();i++) {
155 UpdateNode un=mun.getUpdate(i);
156 for (int j=0;j<un.numUpdates();j++) {
157 Updates update=un.getUpdate(j);
159 DNFRule drule=r.getDNFGuardExpr();
161 drule=r.getDNFNegGuardExpr();
164 if (!update.isAbstract()) {
165 Descriptor updated_des=update.getDescriptor();
166 assert updated_des!=null;
167 /* Update is local to this rule, and the effect is intentional */
168 /* If we're adding something, a side effect could be to falsify some other binding
169 If we're removing something, there is no similar side effect */
171 /* ISSUE: Rules need to be updated if we allow concrete expression of the form x.f.g */
172 if ((un.getRule()==r)&&
173 (((mun.op==MultUpdateNode.ADD)&&satisfy)||((mun.op==MultUpdateNode.REMOVE)&&!satisfy)||(mun.op==MultUpdateNode.MODIFY))&&
174 (r.numQuantifiers()==1)&&
175 (r.getQuantifier(0) instanceof SetQuantifier)&&
177 (((DotExpr)update.getLeftExpr()).getExpr() instanceof VarExpr)&&
178 ((SetQuantifier)r.getQuantifier(0)).getVar()==((VarExpr)((DotExpr)update.getLeftExpr()).getExpr()).getVar())
181 if ((un.getRule()==r)&&
182 (((mun.op==MultUpdateNode.ADD)&&satisfy)||((mun.op==MultUpdateNode.REMOVE)&&!satisfy)||(mun.op==MultUpdateNode.MODIFY))&&
183 (r.numQuantifiers()==0))
187 if (r.getInclusion().usesDescriptor(updated_des)) {
189 if (interferesinclusion(un, update, r))
192 return true; /* Interferes with inclusion condition */
195 for(int k=0;k<drule.size();k++) {
196 RuleConjunction rconj=drule.get(k);
197 for(int l=0;l<rconj.size();l++) {
200 DNFExpr dexpr=rconj.get(l);
201 /* See if update interferes w/ dexpr */
202 if (interferes(un,update, r,dexpr))
212 static private boolean initialinterferes(MultUpdateNode mun, Rule r, boolean satisfy) {
213 AbstractRepair ar=mun.getRepair();
218 if (ar.getType()!=AbstractRepair.ADDTOSET)
220 // if (mun.op!=MultUpdateNode.ADD) (Redundant)
222 if (!r.getInclusion().getTargetDescriptors().contains(ar.getDescriptor()))
224 boolean negated=ar.getPredicate().isNegated();
225 Predicate p=ar.getPredicate().getPredicate();
226 if (!(p instanceof ExprPredicate))
228 ExprPredicate ep=(ExprPredicate)p;
229 if (ep.getType()!=ExprPredicate.SIZE)
231 if ((ep.getOp()==Opcode.EQ)&&(ep.rightSize()==1)&&!negated)
233 if ((ep.getOp()==Opcode.NE)&&(ep.rightSize()==1)&&negated)
236 if ((ep.getOp()==Opcode.NE)&&(ep.rightSize()==0)&&!negated)
238 if ((ep.getOp()==Opcode.EQ)&&(ep.rightSize()==0)&&negated)
243 if ((ep.getOp()==Opcode.GT)&&(ep.rightSize()==0)&&!negated)
245 if ((ep.getOp()==Opcode.LE)&&(ep.rightSize()==0)&&negated)
248 if ((ep.getOp()==Opcode.GE)&&(ep.rightSize()==1)&&!negated)
250 if ((ep.getOp()==Opcode.LT)&&(ep.rightSize()==1)&&negated)
258 static private boolean interferes(UpdateNode un,Updates update, Rule r,DNFExpr dexpr) {
259 Descriptor descriptor=update.getDescriptor();
260 if (!dexpr.getExpr().usesDescriptor(descriptor))
263 /* We need to pair the variables */
264 if (update.isExpr()) {
265 Set vars=update.getRightExpr().freeVars();
266 Opcode op1=update.getOpcode();
267 Expr lexpr1=update.getLeftExpr();
268 Expr rexpr1=update.getRightExpr();
271 for(Iterator it=vars.iterator();it.hasNext();) {
272 VarDescriptor vd=(VarDescriptor) it.next();
273 if (!vd.isGlobal()) {
274 /* VarDescriptor isn't a global */
275 if (update.getVar()!=vd) {
281 if (good&&(dexpr.getExpr() instanceof OpExpr)) {
282 OpExpr expr=(OpExpr)dexpr.getExpr();
283 Expr lexpr2=expr.getLeftExpr();
284 Expr rexpr2=expr.getRightExpr();
285 Opcode op2=expr.getOpcode();
286 op2=Opcode.translateOpcode(dexpr.getNegation(),op2);
289 vars=rexpr2.freeVars();
290 VarDescriptor leftdescriptor=null;
291 if (lexpr2 instanceof VarExpr)
292 leftdescriptor=((VarExpr)lexpr2).getVar();
293 else if (lexpr2 instanceof DotExpr) {
296 for(;e instanceof DotExpr;e=((DotExpr)e).getExpr()) ;
297 if (e instanceof VarExpr)
299 if (e instanceof CastExpr)
300 e=((CastExpr)e).getExpr();
301 else throw new Error("Bad Expr Type:"+e.name());
303 leftdescriptor=((VarExpr)e).getVar();
304 } else throw new Error("Bad Expr");
307 for(Iterator it=vars.iterator();it.hasNext();) {
308 VarDescriptor vd=(VarDescriptor) it.next();
309 if (!vd.isGlobal()) {
310 /* VarDescriptor isn't a global */
311 if (leftdescriptor!=vd) {
318 HashMap remap=new HashMap();
319 remap.put(update.getVar(),leftdescriptor);
321 lexpr1.equals(remap,lexpr2)&&
322 rexpr1.equals(remap,rexpr2))