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 OrFn extends ValueFunction {
31 protected ValueFunction[] args = new ValueFunction[2];
32
33 public OrFn(ValueFunction lhsArg, ValueFunction rhsArg) {
34 super(OR,6);
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 OrFn((ValueFunction)cache.get(data.elementAt(i)),
57 (ValueFunction)cache.get(data.elementAt(i+1)));
58 else
59 return new OrFn((ValueFunction)cache.get(data.elementAt(i)),
60 concatenate(data,i+1,cache));
61 }
62 protected void expand(Vector data, Hashtable cache) {
63 for( int i = 0; i < args.length; i++ ) {
64 if ( args[i].getID() == OR )
65 ((OrFn)args[i]).expand(data,cache);
66 else {
67 ValueFunction fn = args[i].simplify();
68 String s = fn.toString();
69 if ( !data.contains(s) ) {
70 data.addElement(s);
71 cache.put(s,fn);
72 }
73 }
74 }
75 }
76 Object getArg(int position) {
77 return args[position];
78 }
79 public boolean references(ValueFunction var) {
80 return args[0].references(var) || args[1].references(var);
81 }
82 public Vector variables() {
83 return Misc.union(args[0].variables(),args[1].variables());
84 }
85 public boolean isDeterminate() {
86 return args[0].isDeterminate() && args[1].isDeterminate();
87 }
88 public ValueFunction duplicate(DuplicationTable table) {
89 return new OrFn(args[0].duplicate(table),args[1].duplicate(table));
90 }
91 ValueFunction normalize() {
92 return new OrFn(args[0].normalize(),args[1].normalize());
93 }
94 public ValueFunction mirror() {
95 return new OrFn(args[0].mirror(),args[1].mirror());
96 }
97 public ValueFunction resolve(ResolutionContext c, Bindings b) {
98 ValueFunction x = args[0].resolve(c,b);
99 ValueFunction y = args[1].resolve(c,b);
100 return (new OrFn(x,y)).evaluationFn();
101 }
102 public boolean equals(Object any) {
103 if ( !(any instanceof OrFn) ) return false;
104 OrFn fn = (OrFn)any;
105 ValueFunction a = this.simplify();
106 ValueFunction b = fn.simplify();
107 return ((ValueFunction)a.getArg(0)).equals((ValueFunction)b.getArg(0)) &&
108 ((ValueFunction)a.getArg(1)).equals((ValueFunction)b.getArg(1));
109 }
110 ValueFunction unify(ValueFunction fn, Bindings b) {
111 ValueFunction x = null, y = null;
112
113 if ( (x = args[0].unifiesWith(fn,b)) != null ) {
114 if ( (y = args[1].unifiesWith(fn,b)) != null ) {
115 if ( x.equals(y) ) return x;
116 else return new OrFn(x,y);
117 }
118 else
119 return x;
120 }
121 else if ( (y = args[1].unifiesWith(fn,b)) != null ) {
122 return y;
123 }
124 return null;
125 }
126 public int baseID() {
127
128 int x = args[0].baseID();
129 int y = args[1].baseID();
130
131 if ( x != y )
132 throw new IllegalArgumentException("Incompatible types in " + this);
133 return x;
134
135 }
136 }