//Abstract updates don't have concrete interference1
if (update.isAbstract())
continue;
-
+
DNFRule drule=satisfy?r.getDNFNegGuardExpr():r.getDNFGuardExpr();
Descriptor updated_des=update.getDescriptor();
assert updated_des!=null;
+ /* Test to see if the update only effects new
+ objects and we're only testing for falsifying
+ model definition rules. */
+
+ if ((!satisfy)&&updateonlytonewobject(mun,un,update))
+ continue;
+
+
// See if the update interferes with the inclusion
// condition for the rule
if (r.getInclusion().usesDescriptor(updated_des)) {
} else throw new Error();
}
+ if ((un.getRule()==r)&&
+ ((mun.op==MultUpdateNode.ADD)&&!satisfy)&&
+ modifiesremoves(mun,un,r)) {
+ Inclusion inclusion=r.getInclusion();
+ if (inclusion instanceof RelationInclusion) {
+ RelationInclusion ri=(RelationInclusion)inclusion;
+ if ((!testdisjoint(update,r,ri.getLeftExpr()))&&
+ (!testdisjoint(update,r,ri.getRightExpr())))
+ ok=true; /* Update is specific to
+ given binding of the rule,
+ and adds are only performed
+ if the removal is desired or
+ the tuple doesn't exist.*/
+ }
+ }
if (!ok) {
if (satisfy) {
intended one, so we're
okay */
}
+ if ((un.getRule()==r)&&
+ ((mun.op==MultUpdateNode.ADD)&&!satisfy)&&
+ modifiesremoves(mun,un,r)) {
+ if (!testdisjoint(update,r,dexpr.getExpr()))
+ continue; /* Update is specific to
+ given binding of the
+ rule, and adds are only
+ performed if the removal
+ is desired or the tuple
+ doesn't exist.*/
+ }
+
if (interferes(update,dexpr))
return true;
}
return false;
}
+
+ static private boolean modifiesremoves(MultUpdateNode mun,UpdateNode un, Rule r) {
+ AbstractRepair ar=mun.getRepair();
+ boolean inverted=ar.getPredicate().getPredicate().inverted();
+
+ if (ar.getType()!=AbstractRepair.MODIFYRELATION)
+ return false;
+ RelationInclusion ri=(RelationInclusion)r.getInclusion();
+ Expr e=inverted?ri.getRightExpr():ri.getLeftExpr();
+ while(e instanceof CastExpr) {
+ e=((CastExpr)e).getExpr();
+ }
+ if (!(e instanceof VarExpr))
+ return false;
+ VarExpr ve=(VarExpr)e;
+ if (ve.isValue())
+ return false;
+ return true;
+ }
+
+ static private boolean updateonlytonewobject(MultUpdateNode mun, UpdateNode un, Updates updates) {
+ AbstractRepair ar=mun.getRepair();
+ if ((ar!=null)&&(ar.getType()==AbstractRepair.ADDTOSET||ar.getType()==AbstractRepair.ADDTORELATION))
+ for(int i=0;i<un.numUpdates();i++) {
+ Updates u=un.getUpdate(i);
+ if (u.getType()==Updates.POSITION&&
+ ar.isNewObject(u.getRightPos()==0)) {
+ Expr newleftexpr=u.getLeftExpr();
+ Expr leftexpr=updates.getLeftExpr();
+ boolean foundfield=false;
+ while(true) {
+ if (leftexpr.equals(null,newleftexpr)) {
+ if (foundfield)
+ return true;
+ else
+ break;
+ } else if (leftexpr instanceof DotExpr) {
+ if (!foundfield) {
+ foundfield=true;
+ } else {
+ if (((DotExpr)leftexpr).isPtr())
+ break; //if its not a pointer, we're still in the structure
+ }
+ leftexpr=((DotExpr)leftexpr).getExpr();
+ } else if (leftexpr instanceof CastExpr) {
+ leftexpr=((CastExpr)leftexpr).getExpr();
+ } else
+ break;
+ }
+ }
+ }
+
+ return false;
+ }
+
/** This method tries to show that if the Update update from the
* UpdateNode un changes the value of the inclusion constraint
* that it falsifies the guard of model definition rule. */
return null;
}
-
/** This function checks to see if an update is only performed if
- * a given set is empty, and the algorithm is computing whether
- * the update may falsify a rule that adds something to the set */
+ * a given set (or image set produced by a relation) is empty, and
+ * the algorithm is computing whether the update may falsify a
+ * rule that adds something to the set */
- static private boolean initialinterferes(MultUpdateNode mun, Rule r, boolean satisfy) {
+ private boolean initialinterferes(MultUpdateNode mun, Rule r, boolean satisfy) {
AbstractRepair ar=mun.getRepair();
if ((!satisfy)&&(ar!=null)&&(ar.getType()==AbstractRepair.ADDTOSET)) {
if (!r.getInclusion().getTargetDescriptors().contains(ar.getDescriptor()))
((op==Opcode.GT)&&(ep.rightSize()==0))|| //(>0)
((op==Opcode.GE)&&(ep.rightSize()==1))) //(>=1)
return false;
- }
+ } else if ((!satisfy)&&(ar!=null)&&(ar.getType()==AbstractRepair.ADDTORELATION)) {
+ /* This test is for image sets of relations. */
+ if (!r.getInclusion().getTargetDescriptors().contains(ar.getDescriptor()))
+ return true;
+ boolean negated=ar.getPredicate().isNegated();
+ Predicate p=ar.getPredicate().getPredicate();
+ if (!(p instanceof ExprPredicate))
+ return true;
+ ExprPredicate ep=(ExprPredicate)p;
+ if (ep.getType()!=ExprPredicate.SIZE)
+ return true;
+
+ Opcode op=Opcode.translateOpcode(negated,ep.getOp());
+ if (!(((op==Opcode.EQ)&&(ep.rightSize()==1))|| //(=1)
+ ((op==Opcode.NE)&&(ep.rightSize()==0))|| //(!=0)
+ ((op==Opcode.GT)&&(ep.rightSize()==0))|| //(>0)
+ ((op==Opcode.GE)&&(ep.rightSize()==1)))) //(>=1)
+ return true;
+
+ RelationInclusion ri=(RelationInclusion)r.getInclusion();
+ Expr tmpve=ep.inverted()?ri.getRightExpr():ri.getLeftExpr();
+ if (!(tmpve instanceof VarExpr))
+ return true;
+ for(int i=0;i<mun.numUpdates();i++) {
+ UpdateNode un=mun.getUpdate(i);
+ for (int j=0;j<un.numUpdates();j++) {
+ Updates update=un.getUpdate(j);
+ //Abstract updates don't have concrete interference1
+ if (update.isAbstract())
+ continue;
+ if (testdisjoint(update, r, r.getGuardExpr()))
+ return true;
+ }
+ }
+ return false;
+ }
return true;
}