51221c3e7484901eb5a7b992c3c6397a60da01f1
[repair.git] / Repair / RepairCompiler / MCC / IR / ComputeMaxSize.java
1 package MCC.IR;
2 import MCC.State;
3 import java.util.*;
4
5 /** This class computes the maximum size of sets and relations */
6
7 public class ComputeMaxSize {
8     State state;
9     Hashtable sizemap; /* -1 means infinity */
10
11
12     public ComputeMaxSize(State state) {
13         this.state=state;
14         sizemap=new Hashtable();
15         computesizes();
16     }
17     
18     /** This method compute relation and set maximum sizes */
19     private void computesizes() {
20         Vector rules=state.vRules;
21         boolean change=true;
22         Set descriptorset=new HashSet();
23         descriptorset.addAll(state.stSets.getAllDescriptors());
24         descriptorset.addAll(state.stRelations.getAllDescriptors());
25         while(change) {
26             change=false;
27             for(Iterator dit=descriptorset.iterator();dit.hasNext();) {
28                 Descriptor d=(Descriptor)dit.next();
29                 if (d instanceof ReservedSetDescriptor)
30                     continue;
31                 int totalsize=0;
32                 for(int i=0;i<rules.size();i++) {
33                     Rule r=(Rule)rules.get(i);
34                     if (r.getInclusion().getTargetDescriptors().contains(d)) {
35                         /* This rule may add items to this set or relation */
36                         int rulesize=1;
37                         for(int j=0;j<r.numQuantifiers();j++) {
38                             Quantifier q=r.getQuantifier(j);
39                             int size=0;
40                             if (q instanceof RelationQuantifier) {
41                                 Descriptor d2=((RelationQuantifier)q).getRelation();
42                                 if (sizemap.containsKey(d2)) {
43                                     size=((Integer)sizemap.get(d2)).intValue();
44                                 }
45                                 if ((size!=0)&&(d==d2))
46                                     size=-1;
47                             } else if (q instanceof SetQuantifier) {
48                                 Descriptor d2=((SetQuantifier)q).getSet();
49                                 if (sizemap.containsKey(d2)) {
50                                     size=((Integer)sizemap.get(d2)).intValue();
51                                 }
52                                 if ((size!=0)&&(d==d2))
53                                     size=-1;
54                             } else if (q instanceof ForQuantifier) {
55                                 ForQuantifier fq=(ForQuantifier)q;
56                                 boolean lowint=OpExpr.isInt(fq.lower);
57                                 boolean highint=OpExpr.isInt(fq.upper);
58                                 if (lowint&&highint) {
59                                     size=1+OpExpr.getInt(fq.upper)-OpExpr.getInt(fq.lower);
60                                     if (size<=0) /* Catch sneaky bounds */
61                                         throw new Error("Funny bounds in: "+fq);
62                                 } else size=-1;
63                             } else {
64                                 size=-1;
65                             }
66                             if ((rulesize!=0)&&((size==-1)||(rulesize==-1)))
67                                 rulesize=-1;
68                             else
69                                 rulesize=rulesize*size;
70                         }
71                         
72                         if ((rulesize==-1)||(totalsize==-1))
73                             totalsize=-1;
74                         else
75                             totalsize+=rulesize;
76                     }
77                 }
78                 if (!sizemap.containsKey(d)||((Integer)sizemap.get(d)).intValue()!=totalsize) {
79                     change=true;
80                     sizemap.put(d,new Integer(totalsize));
81                 }
82             }
83         }
84     }
85     int getsize(Descriptor d) {
86         return ((Integer)sizemap.get(d)).intValue();
87     }
88 }
89