1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package zeus.concepts.fn;
25
26 import java.util.*;
27 import zeus.util.*;
28 import zeus.concepts.*;
29
30 public class AndFn extends ValueFunction {
31 protected ValueFunction[] args = new ValueFunction[2];
32
33 public AndFn(ValueFunction lhsArg, ValueFunction rhsArg) {
34 super(AND,5);
35 args[0] = lhsArg;
36 args[1] = rhsArg;
37 }
38 public String toString() {
39 String out = "(" + args[0] + "&" + args[1] + ")";
40 return out;
41 }
42 ValueFunction simplify() {
43 Hashtable cache = new Hashtable();
44 Vector data = new Vector();
45 this.expand(data,cache);
46 Misc.sort(data);
47 return concatenate(data,cache);
48 }
49 protected ValueFunction concatenate(Vector data, Hashtable cache) {
50 return concatenate(data,0,cache);
51 }
52 protected ValueFunction concatenate(Vector data, int i, Hashtable cache) {
53 if ( i + 1 == data.size() )
54 return (ValueFunction)cache.get(data.elementAt(i));
55 else if ( i + 2 == data.size() )
56 return new AndFn((ValueFunction)cache.get(data.elementAt(i)),
57 (ValueFunction)cache.get(data.elementAt(i+1)));
58 else
59 return new AndFn((ValueFunction)cache.get(data.elementAt(i)),
60 concatenate(data,i+1,cache));
61 }
62 void expand(Vector data) {
63 Hashtable cache = new Hashtable();
64 expand(data,cache);
65 }
66 protected void expand(Vector data, Hashtable cache) {
67 for( int i = 0; i < args.length; i++ ) {
68 if ( args[i].getID() == AND )
69 ((AndFn)args[i]).expand(data,cache);
70 else {
71 ValueFunction fn = args[i].simplify();
72 String s = fn.toString();
73 if ( !data.contains(s) ) {
74 data.addElement(s);
75 cache.put(s,fn);
76 }
77 }
78 }
79 }
80 boolean subsumes(AndFn fn) {
81 Vector superset = new Vector();
82 Vector subset = new Vector();
83 this.expand(superset);
84 fn.expand(subset);
85 return Misc.isSubset(subset,superset);
86 }
87 Object getArg(int position) {
88 return args[position];
89 }
90 public boolean isDeterminate() {
91 return args[0].isDeterminate() && args[1].isDeterminate();
92 }
93 ValueFunction normalize() {
94 return new AndFn(args[0].normalize(),args[1].normalize());
95 }
96 public boolean references(ValueFunction var) {
97 return args[0].references(var) || args[1].references(var);
98 }
99 public Vector variables() {
100 return Misc.union(args[0].variables(),args[1].variables());
101 }
102 public ValueFunction mirror() {
103 return new AndFn(args[0].mirror(),args[1].mirror());
104 }
105 public ValueFunction resolve(ResolutionContext c, Bindings b) {
106 ValueFunction x = args[0].resolve(c,b);
107 ValueFunction y = args[1].resolve(c,b);
108 return x.equals(y) ? x : new AndFn(x,y);
109 }
110 public ValueFunction duplicate(DuplicationTable table) {
111 return new AndFn(args[0].duplicate(table),args[1].duplicate(table));
112 }
113 public boolean equals(Object any) {
114 if ( !(any instanceof AndFn) ) return false;
115 AndFn fn = (AndFn)any;
116
117 ValueFunction a = this.simplify();
118 ValueFunction b = fn.simplify();
119 return ((ValueFunction)a.getArg(0)).equals((ValueFunction)b.getArg(0)) &&
120 ((ValueFunction)a.getArg(1)).equals((ValueFunction)b.getArg(1));
121 }
122 ValueFunction unify(ValueFunction fn, Bindings b) {
123 ValueFunction x = null, y = null;
124
125 if ( fn instanceof AndFn &&
126 ((AndFn)fn).subsumes(this) ) return fn;
127
128 if ( (x = args[0].unifiesWith(fn,b)) != null &&
129 (y = args[1].unifiesWith(fn,b)) != null ) {
130 if ( x.equals(y) ) return x;
131 else return new AndFn(x,y);
132 }
133 return null;
134 }
135
136 public int baseID() {
137
138 int x = args[0].baseID();
139 int y = args[1].baseID();
140
141 if ( x != y )
142 throw new IllegalArgumentException("Incompatible types in " + this);
143 return x;
144 }
145 }