76cb5182f1095f4ca6adbd785ef97553bbc2c976
[IRC.git] / Robust / src / Analysis / Disjoint / ExistPredSet.java
1 package Analysis.Disjoint;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6 import java.io.*;
7
8 ///////////////////////////////////////////
9 //  IMPORTANT
10 //  This class is an immutable Canonical, so
11 //
12 //  0) construct them with a factory pattern
13 //  to ensure only canonical versions escape
14 //
15 //  1) any operation that modifies a Canonical
16 //  is a static method in the Canonical class
17 //
18 //  2) operations that just read this object
19 //  should be defined here
20 //
21 //  3) every Canonical subclass hashCode should
22 //  throw an error if the hash ever changes
23 //
24 ///////////////////////////////////////////
25
26 // a set of existence predicates that are
27 // OR'ed terms, if any predicate is true
28 // then the set evaluates to true
29
30 public class ExistPredSet extends Canonical {
31
32   protected Set<ExistPred> preds;
33
34   public static boolean debug = false;
35
36
37   public static ExistPredSet factory() {
38     ExistPredSet out = new ExistPredSet();
39     out = (ExistPredSet) Canonical.makeCanonical(out);
40     return out;
41   }
42
43   public static ExistPredSet factory(ExistPred pred) {
44     ExistPredSet out = new ExistPredSet();
45     out.preds.add(pred);
46     out = (ExistPredSet) Canonical.makeCanonical(out);
47     return out;
48   }
49
50   protected ExistPredSet() {
51     preds = new HashSet<ExistPred>();
52   }
53
54
55   public Iterator<ExistPred> iterator() {
56     return preds.iterator();
57   }
58
59
60   // only consider the subest of the caller elements that
61   // are reachable by callee when testing predicates
62   public ExistPredSet isSatisfiedBy(ReachGraph rg,
63                                     Set<Integer> calleeReachableNodes,
64                                     Set<RefSrcNode> callerSrcMatches
65                                     ) {
66     ExistPredSet predsOut = null;
67
68     Iterator<ExistPred> predItr = preds.iterator();
69     while( predItr.hasNext() ) {
70       ExistPredSet predsFromSatisfier =
71         predItr.next().isSatisfiedBy(rg,
72                                      calleeReachableNodes,
73                                      callerSrcMatches);
74
75       if( predsFromSatisfier != null ) {
76         if( predsOut == null ) {
77           predsOut = predsFromSatisfier;
78         } else {
79           predsOut = Canonical.join(predsOut,
80                                     predsFromSatisfier);
81         }
82       }
83     }
84
85     return predsOut;
86   }
87
88
89   // this method returns the source node of any
90   // edge predicates in the set for the given graph
91   public Set<RefSrcNode> getEdgeSources( ReachGraph rg ) {
92     Set<RefSrcNode> out = new HashSet<RefSrcNode>();
93     
94     for( ExistPred pred: preds ) {
95       RefSrcNode rsn = pred.getEdgeSource( rg );
96       if( rsn != null ) {
97         out.add( rsn );
98       }
99     }
100
101     return out;
102   }
103
104
105
106   public boolean isEmpty() {
107     return preds.isEmpty();
108   }
109
110
111   public boolean equalsSpecific(Object o) {
112     if( o == null ) {
113       return false;
114     }
115
116     if( !(o instanceof ExistPredSet) ) {
117       return false;
118     }
119
120     ExistPredSet eps = (ExistPredSet) o;
121
122     return preds.equals(eps.preds);
123   }
124
125
126   public int hashCodeSpecific() {
127     return preds.hashCode();
128   }
129
130
131   public String toStringEscNewline() {
132     String s = "P[";
133
134     Iterator<ExistPred> predItr = preds.iterator();
135     while( predItr.hasNext() ) {
136       ExistPred pred = predItr.next();
137       s += pred.toString();
138       if( predItr.hasNext() ) {
139         s += " ||\\n";
140       }
141     }
142     s += "]";
143     return s;
144   }
145
146
147   public String toString() {
148     String s = "P[";
149     Iterator<ExistPred> predItr = preds.iterator();
150     while( predItr.hasNext() ) {
151       ExistPred pred = predItr.next();
152       s += pred.toString();
153       if( predItr.hasNext() ) {
154         s += " || ";
155       }
156     }
157     s += "]";
158     return s;
159   }
160
161 }