5 /** This class computes the maximum size of sets and relations */
7 public class ComputeMaxSize {
9 Hashtable sizemap; /* -1 means infinity */
10 static int KBOUND=100;
12 public ComputeMaxSize(State state) {
14 sizemap=new Hashtable();
20 /** This method compute relation and set maximum sizes */
21 private void computesizes() {
22 Vector rules=state.vRules;
24 Set descriptorset=new HashSet();
25 descriptorset.addAll(state.stSets.getAllDescriptors());
26 descriptorset.addAll(state.stRelations.getAllDescriptors());
29 for(Iterator dit=descriptorset.iterator();dit.hasNext();) {
30 Descriptor d=(Descriptor)dit.next();
31 if (d instanceof ReservedSetDescriptor)
36 for(int i=0;i<rules.size();i++) {
37 Rule r=(Rule)rules.get(i);
38 if (r.getInclusion().getTargetDescriptors().contains(d)) {
39 /* This rule may add items to this set or relation */
42 for(int j=0;j<r.numQuantifiers();j++) {
43 Quantifier q=r.getQuantifier(j);
45 if (q instanceof RelationQuantifier) {
46 Descriptor d2=((RelationQuantifier)q).getRelation();
47 if (sizemap.containsKey(d2)) {
57 } else if (q instanceof SetQuantifier) {
58 Descriptor d2=((SetQuantifier)q).getSet();
59 if (sizemap.containsKey(d2)) {
69 } else if (q instanceof ForQuantifier) {
70 ForQuantifier fq=(ForQuantifier)q;
71 boolean lowint=OpExpr.isInt(fq.lower);
72 boolean highint=OpExpr.isInt(fq.upper);
73 if (lowint&&highint) {
74 size=1+OpExpr.getInt(fq.upper)-OpExpr.getInt(fq.lower);
75 if (size<=0) /* Catch sneaky bounds */
76 throw new Error("Funny bounds in: "+fq);
79 throw new Error("Unrecognized Quantifier");
81 if ((rulesize!=0)&&((size==-1)||(rulesize==-1)))
84 rulesize=rulesize*size;
88 if ((rulesize==-1)||(totalstarts==-1))
91 totalstarts+=rulesize;
97 if ((rulesize==-1)||(totalchains==-1))
100 totalchains+=rulesize;
104 if (totalstarts>=KBOUND)
106 if (totalchains>=KBOUND)
109 if (!sizemap.containsKey(d)||getstarts(d)!=totalstarts||getchains(d)!=totalchains) {
111 MaxSizeObject so=new MaxSizeObject(totalstarts,totalchains,chainrule);
119 Set descriptorset=new HashSet();
120 descriptorset.addAll(state.stSets.getAllDescriptors());
121 descriptorset.addAll(state.stRelations.getAllDescriptors());
122 for(Iterator dit=descriptorset.iterator();dit.hasNext();) {
123 Descriptor d=(Descriptor)dit.next();
124 if (d instanceof ReservedSetDescriptor)
126 System.out.println("size("+d+")="+getsize(d));
130 private void postprocess() {
131 Vector rules=state.vRules;
133 Set descriptorset=new HashSet();
134 descriptorset.addAll(state.stSets.getAllDescriptors());
135 descriptorset.addAll(state.stRelations.getAllDescriptors());
138 for(Iterator dit=descriptorset.iterator();dit.hasNext();) {
139 Descriptor d=(Descriptor)dit.next();
140 if (d instanceof ReservedSetDescriptor)
145 for(int i=0;i<rules.size();i++) {
146 Rule r=(Rule)rules.get(i);
147 if (r.getInclusion().getTargetDescriptors().contains(d)) {
148 /* This rule may add items to this set or relation */
151 for(int j=0;j<r.numQuantifiers();j++) {
152 Quantifier q=r.getQuantifier(j);
154 if (q instanceof RelationQuantifier) {
155 Descriptor d2=((RelationQuantifier)q).getRelation();
156 if (sizemap.containsKey(d2)) {
166 if (getchainrule(d2)!=null) {
167 if (isMutuallyExclusive(r, getchainrule(d2)))
171 } else if (q instanceof SetQuantifier) {
172 Descriptor d2=((SetQuantifier)q).getSet();
173 if (sizemap.containsKey(d2)) {
183 if (getchainrule(d2)!=null) {
184 if (isMutuallyExclusive(r, getchainrule(d2)))
188 } else if (q instanceof ForQuantifier) {
189 ForQuantifier fq=(ForQuantifier)q;
190 boolean lowint=OpExpr.isInt(fq.lower);
191 boolean highint=OpExpr.isInt(fq.upper);
192 if (lowint&&highint) {
193 size=1+OpExpr.getInt(fq.upper)-OpExpr.getInt(fq.lower);
194 if (size<=0) /* Catch sneaky bounds */
195 throw new Error("Funny bounds in: "+fq);
198 throw new Error("Unrecognized Quantifier");
200 if ((rulesize!=0)&&((size==-1)||(rulesize==-1)))
203 rulesize=rulesize*size;
207 if ((rulesize==-1)||(totalstarts==-1))
210 totalstarts+=rulesize;
216 if ((rulesize==-1)||(totalchains==-1))
219 totalchains+=rulesize;
223 if (totalstarts>=KBOUND)
225 if (totalchains>=KBOUND)
228 if (!sizemap.containsKey(d)||getstarts(d)!=totalstarts||getchains(d)!=totalchains) {
230 MaxSizeObject so=new MaxSizeObject(totalstarts,totalchains,chainrule);
238 int getstarts(Descriptor d) {
239 MaxSizeObject so=(MaxSizeObject)sizemap.get(d);
242 int getchains(Descriptor d) {
243 MaxSizeObject so=(MaxSizeObject)sizemap.get(d);
244 return so.numberchains;
246 int getsize(Descriptor d) {
247 MaxSizeObject so=(MaxSizeObject)sizemap.get(d);
250 if (so.numberchains!=0)
255 private Rule getchainrule(Descriptor d) {
256 MaxSizeObject so=(MaxSizeObject)sizemap.get(d);
260 public static boolean isMutuallyExclusive(Rule r1,Rule r2) {
261 // Building a map between quantifier variables
262 if (r1.numQuantifiers()!=r2.numQuantifiers())
264 Set usedDescriptors=new HashSet();
265 Hashtable varmap=new Hashtable();
268 for(int i=0;i<r1.numQuantifiers();i++) {
269 Quantifier q1=r1.getQuantifier(i);
270 if (!(q1 instanceof SetQuantifier))
272 if (usedDescriptors.contains(((SetQuantifier)q1).getSet()))
274 usedDescriptors.add(((SetQuantifier)q1).getSet());
275 for(int j=0;j<r2.numQuantifiers();j++) {
276 Quantifier q2=r2.getQuantifier(j);
277 if (!(q2 instanceof SetQuantifier))
279 if (((SetQuantifier)q1).getSet()==((SetQuantifier)q2).getSet()) {
280 varmap.put(((SetQuantifier)q1).getVar(),((SetQuantifier)q2).getVar());
286 DNFRule dr1=r1.getDNFGuardExpr();
287 DNFRule dr2=r2.getDNFGuardExpr();
288 for(int i=0;i<dr1.size();i++) {
289 for(int j=0;j<dr2.size();j++) {
290 RuleConjunction rc1=dr1.get(i);
291 RuleConjunction rc2=dr2.get(j);
292 if (!exclusive(varmap,rc1,rc2))
299 private static boolean exclusive(Hashtable varmap, RuleConjunction rc1, RuleConjunction rc2) {
300 for (int i=0;i<rc1.size();i++) {
301 for (int j=0;j<rc2.size();j++) {
302 DNFExpr de1=rc1.get(i);
303 DNFExpr de2=rc2.get(j);
304 if ((de1.getNegation()!=de2.getNegation())&&
305 (de1.getExpr().equals(varmap,de2.getExpr())))
312 class MaxSizeObject {
317 public MaxSizeObject(int start,int chain, Rule r) {