5 public class ConstraintDependence {
11 Termination termination;
13 ConstraintDependence(State state, Termination t) {
16 constnodes=new HashSet();
18 constonode=new Hashtable();
19 nodetonode=new Hashtable();
21 constructconjunctionnodes();
22 constructconjunctionedges();
25 public void addNode(GraphNode gn) {
26 GraphNode gn2=new GraphNode(gn.getLabel(),gn.getTextLabel(),gn);
28 nodetonode.put(gn,gn2);
31 public void associateWithConstraint(GraphNode gn, Constraint c) {
32 GraphNode ggn=(GraphNode)nodetonode.get(gn);
33 GraphNode gc=(GraphNode)constonode.get(c);
34 GraphNode.Edge e=new GraphNode.Edge("associated",ggn);
38 public void requiresConstraint(GraphNode gn, Constraint c) {
39 GraphNode ggn=(GraphNode)nodetonode.get(gn);
40 GraphNode gc=(GraphNode)constonode.get(c);
41 GraphNode.Edge e=new GraphNode.Edge("requires",gc);
45 /** Constructs a node for each Constraint */
46 private void constructnodes() {
47 for(int i=0;i<state.vConstraints.size();i++) {
48 Constraint c=(Constraint)state.vConstraints.get(i);
49 GraphNode gn=new GraphNode(c.toString(),c);
55 private void constructconjunctionnodes() {
56 for(Iterator it=termination.conjunctions.iterator();it.hasNext();) {
57 GraphNode conjnode=(GraphNode)it.next();
58 TermNode tn=(TermNode)conjnode.getOwner();
59 Conjunction conj=tn.getConjunction();
62 for(int i=0;i<state.vConstraints.size();i++) {
63 Constraint c=(Constraint)state.vConstraints.get(i);
64 Set conjset=(Set)termination.conjunctionmap.get(c);
65 for(Iterator it=conjset.iterator();it.hasNext();) {
66 GraphNode gn=(GraphNode)it.next();
67 associateWithConstraint(gn,c);
72 private void constructconjunctionedges() {
73 for(Iterator it=termination.conjunctions.iterator();it.hasNext();) {
74 GraphNode conjnode=(GraphNode)it.next();
75 TermNode tn=(TermNode)conjnode.getOwner();
76 Conjunction conj=tn.getConjunction();
77 for(int i=0;i<conj.size();i++) {
78 DNFPredicate dpred=conj.get(i);
79 Predicate pred=dpred.getPredicate();
81 if (pred instanceof InclusionPredicate) {
82 InclusionPredicate ip=(InclusionPredicate)pred;
84 } else if (pred instanceof ExprPredicate) {
85 ExprPredicate ep=(ExprPredicate)pred;
87 } else throw new Error("Unrecognized Predicate");
88 Set functions=expr.getfunctions();
91 for(Iterator fit=functions.iterator();fit.hasNext();) {
92 Function f=(Function)fit.next();
93 if (rulesensurefunction(f))
94 continue; //no constraint needed to ensure
96 Set s=providesfunction(f);
98 System.out.println("Error: No constraint ensures that [forall v in "+f.getSet()+"], size(v."+(f.isInverse()?"~":"")+f.getRelation()+")=1");
101 Constraint c=(Constraint)s.iterator().next(); //Take the first one
102 requiresConstraint(conjnode,c);
108 private boolean rulesensurefunction(Function f) {
109 boolean foundrule=false;
110 for(int i=0;i<state.vRules.size();i++) {
111 Rule r=(Rule)state.vRules.get(i);
112 if (r.getInclusion().getTargetDescriptors().contains(f.getRelation())) {
113 RelationInclusion ri=(RelationInclusion)r.getInclusion();
114 Expr e=f.isInverse()?ri.getRightExpr():ri.getLeftExpr();
115 SetDescriptor sd=e.getSet();
116 if (!(sd.isSubset(f.getSet())||f.getSet().isSubset(sd)))
117 continue; /* This rule doesn't effect the function */
118 if (foundrule) /* two different rules are a problem */
120 if (!((e instanceof VarExpr)&&(r.numQuantifiers()==1)))
122 VarExpr ve=(VarExpr)e;
123 Quantifier q=r.getQuantifier(0);
124 if (!(q instanceof SetQuantifier))
126 SetQuantifier sq=(SetQuantifier)q;
127 if (ve.getVar()!=sq.getVar())
129 if (!sq.getSet().isSubset(f.getSet()))
131 if (!((r.getGuardExpr() instanceof BooleanLiteralExpr)&&
132 ((BooleanLiteralExpr)r.getGuardExpr()).getValue()==true))
134 Expr e2=f.isInverse()?ri.getLeftExpr():ri.getRightExpr();
144 private Set providesfunction(Function f) {
145 HashSet set=new HashSet();
146 for(int i=0;i<state.vConstraints.size();i++) {
147 Constraint c=(Constraint)state.vConstraints.get(i);
148 boolean goodconstraint=true;
149 DNFConstraint dnfconst=c.dnfconstraint;
150 for(int j=0;j<dnfconst.size();j++) {
151 Conjunction conj=dnfconst.get(j);
152 boolean conjprovides=false;
153 for(int k=0;k<conj.size();k++) {
154 DNFPredicate dpred=conj.get(k);
155 if (!dpred.isNegated()&&
156 (dpred.getPredicate() instanceof ExprPredicate)&&
157 ((ExprPredicate)dpred.getPredicate()).getType()==ExprPredicate.SIZE) {
158 ExprPredicate ep=(ExprPredicate)dpred.getPredicate();
159 if (ep.isRightInt()&&
161 ep.getOp()==Opcode.EQ&&
162 ep.inverted()==f.isInverse()&&
163 ep.getDescriptor()==f.getRelation()) {
164 ImageSetExpr se=(ImageSetExpr) ((SizeofExpr) ((OpExpr)ep.expr).left).getSetExpr();
165 VarDescriptor vd=se.getVar();
166 if (c.numQuantifiers()==1) {
167 for(int l=0;l<c.numQuantifiers();l++) {
168 Quantifier q=c.getQuantifier(l);
169 if (q instanceof SetQuantifier&&
170 ((SetQuantifier)q).getVar()==vd) {
171 SetDescriptor sd=((SetQuantifier)q).getSet();
172 if (sd.isSubset(f.getSet()))
182 goodconstraint=false;
192 public static class Function {
193 private RelationDescriptor rd;
194 private SetDescriptor sd;
195 private boolean inverse;
197 public Function(RelationDescriptor r, SetDescriptor sd, boolean inverse) {
198 this.inverse=inverse;
203 public SetDescriptor getSet() {
207 public RelationDescriptor getRelation() {
211 public boolean isInverse() {