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 ElseFn extends ValueFunction {
31 protected ValueFunction[] args = new ValueFunction[3];
32
33 public ElseFn(ValueFunction lhsArg, ValueFunction rhsArg) {
34 super(ELSE,2);
35 if ( !(lhsArg instanceof ImplyFn) )
36 throw new IllegalArgumentException("Illegal operand in \'" +
37 lhsArg + " else " + rhsArg + "\'");
38
39 args[0] = (ValueFunction)lhsArg.getArg(0);
40 args[1] = (ValueFunction)lhsArg.getArg(1);
41 args[2] = rhsArg;
42 }
43
44
45 public ElseFn(ValueFunction arg0, ValueFunction arg1, ValueFunction arg2) {
46 super(ELSE,2);
47 if ( !(arg0 instanceof LogicalFn) )
48 throw new IllegalArgumentException("Illegal operand \'" + arg0 +
49 " in \' + (if " + args[0] + " then " + args[1] + " else " +
50 args[2] + ")\'");
51 args[0] = arg0;
52 args[1] = arg1;
53 args[2] = arg2;
54 }
55
56
57 /***
58 *resolve is here to handle unification for the postcondition to precondition maps -
59 *this will allow proper use of expressions when defining tasks.
60 *@since 1.2.1
61 *@author Simon Thompson
62 */
63 public void resolve (String attrName, ValueFunction val) {
64 debug ("in resolve");
65
66 if (args[0] instanceof ArithmeticFn) {
67 debug ("recursing args[0]");
68 ArithmeticFn lhsFn = (ArithmeticFn) args[0];
69 lhsFn.resolve (attrName,val);
70 }
71
72 else if (args[0] instanceof VarFn) {
73 debug ("resolving args[0]");
74 debug (" args[0] = " + args[0].toString() + " val = " +val.toString() +" attrName = " + attrName);
75 if (args[0].toString().equals("?"+attrName)) {
76 args[0] = val; }
77 debug (" args[0] = " + args[0].toString() + " val = " +val.toString() +" attrName = " + attrName);
78 }
79
80 if (args[1] instanceof ArithmeticFn) {
81 debug ("recursing args[1]");
82 ArithmeticFn thenFn = (ArithmeticFn) args[1];
83 thenFn.resolve (attrName,val);
84 }
85
86 else if (args[1] instanceof VarFn) {
87 debug ("resolving args[1]");
88 debug (" args[1] = " + args[1].toString() + " val = " +val.toString() +" attrName = " + attrName);
89 if (args[1].toString().equals("?"+attrName)) {
90 args[1] = val; }
91 debug (" args[1] = " + args[1].toString() + " val = " +val.toString() +" attrName = " + attrName);
92 }
93
94 if (args[2] instanceof ArithmeticFn) {
95 debug ("recursing args[2");
96 ArithmeticFn elseFn = (ArithmeticFn) args[2];
97 elseFn.resolve (attrName,val);
98 }
99
100 else if (args[2] instanceof VarFn) {
101 debug ("resolving args[2]");
102 debug (" args[2] = " + args[2].toString() + " val = " +val.toString() +" attrName = " + attrName);
103 if (args[2].toString().equals("?"+attrName)) {
104 args[2] = val; }
105 debug (" args[2] = " + args[2].toString() + " val = " +val.toString() +" attrName = " + attrName);
106 }
107 }
108
109
110 public String toString() {
111 return "(if " + args[0] + " then " + args[1] + " else " + args[2] + ")";
112 }
113
114
115 ValueFunction simplify() {
116 ValueFunction a, b, c;
117 a = args[0].simplify();
118 b = args[1].simplify();
119 c = args[2].simplify();
120 return (a != args[0] || b != args[1] || c != args[2] )
121 ? new ElseFn(a,b,c) : this;
122 }
123
124
125 Object getArg(int position) {
126 return args[position];
127 }
128
129
130 public boolean references(ValueFunction var) {
131 return args[0].references(var) || args[1].references(var) ||
132 args[2].references(var);
133 }
134
135
136 public Vector variables() {
137 Vector temp = Misc.union(args[0].variables(),args[1].variables());
138 return Misc.union(temp,args[2].variables());
139 }
140
141
142 public boolean isDeterminate() {
143 return args[0].isDeterminate() && args[1].isDeterminate() &&
144 args[2].isDeterminate();
145 }
146
147
148 ValueFunction normalize() {
149 ValueFunction a, b, c;
150 a = args[0].normalize();
151 b = args[1].normalize();
152 c = args[2].normalize();
153 return (a != args[0] || b != args[1] || c != args[2] )
154 ? new ElseFn(a,b,c) : this;
155 }
156
157
158 public ValueFunction mirror() {
159 return new ElseFn(args[0].mirror(),args[1].mirror(),args[2].mirror());
160 }
161
162
163 public ValueFunction resolve(ResolutionContext c, Bindings b) {
164 ValueFunction x = args[0].resolve(c,b);
165 switch( ((LogicalFn)x).evaluate() ) {
166 case LogicalFn.TRUE:
167 return args[1].resolve(c,b);
168 case LogicalFn.FALSE:
169 return args[2].resolve(c,b);
170 case LogicalFn.UNKNOWN:
171 if ( x.equals(args[0]) )
172 return this;
173 else
174 return new ElseFn(x,args[1],args[2]);
175 }
176 return null;
177 }
178
179
180 public ValueFunction evaluationFn() {
181 debug (args[0].getClass().toString());
182 switch( ((LogicalFn)args[0]).evaluate() ) {
183 case LogicalFn.TRUE:
184 return args[1];
185 case LogicalFn.FALSE:
186 return args[2];
187 case LogicalFn.UNKNOWN:
188 return this;
189 }
190 return this;
191 }
192
193
194 public ValueFunction duplicate(DuplicationTable table) {
195 return new ElseFn(args[0].duplicate(table),args[1].duplicate(table),
196 args[2].duplicate(table));
197 }
198
199
200 public boolean equals(Object any) {
201 if ( !(any instanceof ElseFn) ) return false;
202 ElseFn fn = (ElseFn)any;
203 ValueFunction a = this.simplify();
204 ValueFunction b = fn.simplify();
205 return ((ValueFunction)a.getArg(0)).equals((ValueFunction)b.getArg(0)) &&
206 ((ValueFunction)a.getArg(1)).equals((ValueFunction)b.getArg(1)) &&
207 ((ValueFunction)a.getArg(2)).equals((ValueFunction)b.getArg(2));
208 }
209
210
211 ValueFunction unify(ValueFunction fn, Bindings b) {
212 ValueFunction x = null, y = null;
213
214 if ( (x = evaluationFn()) == null )
215 return null;
216 else if ( x != this )
217 return x.unifiesWith(fn,b);
218
219 switch( fn.getID() ) {
220 case IMPLY:
221 if ( (y = ((ImplyFn)fn).evaluationFn()) == null )
222 return null;
223 else if ( y != fn )
224 return this.unifiesWith(y,b);
225
226 x = args[1].unifiesWith(fn,b);
227 y = args[2].unifiesWith(fn,b);
228
229 if ( x == null && y == null )
230 return null;
231 else if ( y == null )
232 return new ImplyFn(args[0],x);
233 else if ( x == null )
234 return new ImplyFn(new LogicalNotFn(args[0]),y);
235 else
236 return new ElseFn(args[0],x,y);
237
238 case ELSE:
239 if ( (y = ((ElseFn)fn).evaluationFn()) == null )
240 return null;
241 else if ( y != fn )
242 return this.unifiesWith(y,b);
243
244 x = args[1].unifiesWith(fn,b);
245 y = args[2].unifiesWith(fn,b);
246
247 if ( x == null && y == null )
248 return null;
249 else if ( y == null )
250 return new ImplyFn(args[0],x);
251 else if ( x == null )
252 return new ImplyFn(new LogicalNotFn(args[0]),y);
253 else
254 return new ElseFn(args[0],x,y);
255
256 default:
257 x = args[1].unifiesWith(fn,b);
258 y = args[2].unifiesWith(fn,b);
259 if ( x == null && y == null )
260 return null;
261 else if ( y == null )
262 return new ImplyFn(args[0],x);
263 else if ( x == null )
264 return new ImplyFn(new LogicalNotFn(args[0]),y);
265 else
266 return new ElseFn(args[0],x,y);
267 }
268 }
269
270
271 public int baseID() {
272
273 int x = args[1].baseID();
274 int y = args[2].baseID();
275
276 if ( x != y )
277 throw new IllegalArgumentException("Incompatible types in " + this);
278 return x;
279 }
280
281
282 public void debug (String str) {
283
284 }
285
286 }