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 ComparisonFn extends LogicalFn {
31 static final int EQ = 0;
32 static final int NE = 1;
33 static final int LE = 2;
34 static final int GE = 3;
35 static final int LT = 4;
36 static final int GT = 5;
37
38 static final String[] comparators = {
39 "==", "!=", "<=", ">=", "<", ">"
40 };
41
42 final static int[] illegal_operands = {
43 AND, OR, ELSE, IMPLY
44 };
45
46 protected ValueFunction[] args = new ValueFunction[2];
47 protected int op = -1;
48
49 public ComparisonFn(ValueFunction lhs, ValueFunction rhs, String op) {
50 super(COMP,4);
51 if ( (this.op = Misc.whichPosition(op,comparators)) == -1)
52 throw new IllegalArgumentException("Unknown operator in \'" +
53 lhs + " " + op + " " + rhs + "\'");
54 int ltype = lhs.getID();
55 int rtype = rhs.getID();
56 if ( Misc.member(ltype,illegal_operands) ||
57 Misc.member(rtype,illegal_operands) ) {
58 throw new IllegalArgumentException("Illegal operands in " +
59 " function \'" + lhs + " " + op + " " + rhs + "\'");
60 }
61 if ( lhs.isDeterminate() && rhs.isDeterminate() ) {
62 if ( lhs instanceof LogicalFn ) {
63 if ( !(rhs instanceof LogicalFn) && !(rhs instanceof DefinedFn) )
64 throw new IllegalArgumentException("Illegal operands in " +
65 " function \'" + lhs + " " + op + " " + rhs + "\'");
66 }
67 else if ( lhs instanceof NumericFn ) {
68 if ( !(rhs instanceof NumericFn) && !(rhs instanceof DefinedFn) )
69 throw new IllegalArgumentException("Illegal operands in " +
70 " function \'" + lhs + " " + op + " " + rhs + "\'");
71 }
72 else if ( ltype != rtype ) {
73 throw new IllegalArgumentException("Illegal operands in " +
74 " function \'" + lhs + " " + op + " " + rhs + "\'");
75 }
76 }
77
78 args[0] = lhs;
79 args[1] = rhs;
80 }
81
82
83 public ValueFunction mirror() {
84 return new ComparisonFn(args[0].mirror(),args[1].mirror(),comparators[op]);
85 }
86
87
88 public String toString() {
89 return "(" + args[0] + " " + comparators[op] + " " + args[1] + ")";
90 }
91
92
93 int getOperator() {
94 return op;
95 }
96
97
98 ValueFunction simplify() {
99 ValueFunction a, b;
100 a = args[0].simplify();
101 b = args[1].simplify();
102 return (a != args[0] || b != args[1])
103 ? new ComparisonFn(a,b,comparators[op]) : this;
104 }
105
106
107 Object getArg(int position) {
108 return args[position];
109 }
110
111
112 public boolean references(ValueFunction var) {
113 return args[0].references(var) || args[1].references(var);
114 }
115
116
117 public Vector variables() {
118 return Misc.union(args[0].variables(),args[1].variables());
119 }
120
121
122 public boolean isDeterminate() {
123
124 return args[0].isDeterminate() && args[1].isDeterminate();
125 }
126
127
128 public ValueFunction resolve(ResolutionContext c, Bindings b) {
129 ValueFunction x = args[0].resolve(c,b);
130 ValueFunction y = args[1].resolve(c,b);
131 return (new ComparisonFn(x,y,comparators[op])).evaluationFn();
132 }
133
134
135 ValueFunction normalize() {
136 ValueFunction a, b;
137 a = args[0].normalize();
138 b = args[1].normalize();
139 return (a != args[0] || b != args[1] )
140 ? new ComparisonFn(a,b,comparators[op]) : this;
141 }
142
143
144 public int evaluate() {
145 ValueFunction fn = evaluationFn();
146 if ( fn == this ) return UNKNOWN;
147 else if ( fn == BoolFn.trueFn ) return TRUE;
148 else return FALSE;
149 }
150
151
152 public ValueFunction evaluationFn() {
153 if ( !isDeterminate() ) return this;
154
155 ValueFunction a, b;
156 a = args[0];
157 b = args[1];
158
159 if ( a instanceof LogicalFn )
160 a = ((LogicalFn)a).evaluationFn();
161 else if ( a instanceof ArithmeticFn)
162 a = ((ArithmeticFn)a).evaluationFn();
163
164 if ( b instanceof LogicalFn )
165 b = ((LogicalFn)b).evaluationFn();
166 else if ( b instanceof ArithmeticFn)
167 b = ((ArithmeticFn)b).evaluationFn();
168
169 if ( !(a instanceof PrimitiveFn) || !(b instanceof PrimitiveFn) )
170 throw new IllegalArgumentException(this.toString());
171
172 PrimitiveFn x = (PrimitiveFn)a;
173 PrimitiveFn y = (PrimitiveFn)b;
174
175 int xid = a.getID();
176 int yid = b.getID();
177
178 if ( xid != yid ) {
179 if ( xid == INT && yid == REAL )
180 ;
181 else if ( xid == REAL && yid == INT )
182 ;
183 else {
184 throw new IllegalArgumentException(this.toString());
185 }
186 }
187
188
189 switch( op ) {
190 case EQ:
191 return x.equals(y)
192 ? BoolFn.trueFn : BoolFn.falseFn;
193 case LE:
194 return ( x.less(y) || x.equals(y) )
195 ? BoolFn.trueFn : BoolFn.falseFn;
196
197 case GE:
198 return !x.less(y)
199 ? BoolFn.trueFn : BoolFn.falseFn;
200
201 case NE:
202 return !x.equals(y)
203 ? BoolFn.trueFn : BoolFn.falseFn;
204
205 case GT:
206 return ( !x.less(y) && !x.equals(y) )
207 ? BoolFn.trueFn : BoolFn.falseFn;
208
209 case LT:
210 return x.less(y)
211 ? BoolFn.trueFn : BoolFn.falseFn;
212
213 default:
214 throw new IllegalArgumentException("Unknown operator in \'" +
215 this + "\'");
216 }
217 }
218
219 public ValueFunction duplicate(DuplicationTable table) {
220 return new ComparisonFn(args[0].duplicate(table),args[1].duplicate(table),
221 comparators[op]);
222 }
223 public boolean equals(Object any) {
224 if ( !(any instanceof ComparisonFn) ) return false;
225 ComparisonFn fn = (ComparisonFn)any;
226 if ( op != fn.getOperator() ) return false;
227
228 ValueFunction a = this.simplify();
229 ValueFunction b = fn.simplify();
230 return ((ValueFunction)a.getArg(0)).equals((ValueFunction)b.getArg(0)) &&
231 ((ValueFunction)a.getArg(1)).equals((ValueFunction)b.getArg(1));
232 }
233 }