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.rete;
25
26 import java.util.*;
27 import zeus.util.*;
28 import zeus.concepts.*;
29 import zeus.concepts.fn.*;
30
31
32 class JoinNode extends Node {
33 static final int PLAIN = 0;
34 static final int NOT = 1;
35
36 Vector constraints = new Vector();
37 Hashtable db = new Hashtable();
38 Hashtable pathDb1 = new Hashtable();
39 Hashtable pathDb2 = new Hashtable();
40 Hashtable bindingsDb = new Hashtable();
41 int type = PLAIN;
42
43 JoinNode(ReteEngine engine) {
44 super(engine);
45 }
46 void add(int l_position, String l_attribute, ValueFunction l_value,
47 int r_position, String r_attribute, ValueFunction r_value) {
48
49 JoinEntry e = new JoinEntry(l_position,l_attribute,l_value,
50 r_position,r_attribute,r_value);
51 constraints.addElement(e);
52 }
53 void addPath(String l_path, String r_path, String d_path) {
54 Assert.notFalse(pathDb1.put(l_path,r_path) == null);
55 Assert.notFalse(pathDb1.put(r_path,l_path) == null);
56 Assert.notFalse(pathDb2.put(l_path,d_path) == null);
57 }
58 void reset() {
59 db.clear();
60 bindingsDb.clear();
61 }
62
63
64 void evaluate(String path, int tag, int type, Vector input, Bindings b) {
65
66 Vector store;
67 boolean found;
68 Fact f1, f2;
69 String l_path, r_path;
70 Vector l_memory, r_memory;
71 Vector l_bindings, r_bindings;
72 Bindings b1, b2;
73
74 switch(type) {
75 case LEFT:
76 l_path = path;
77 r_path = (String)pathDb1.get(path);
78 l_memory = (Vector)db.get(l_path);
79 l_bindings = (Vector)bindingsDb.get(l_path);
80 if ( l_memory == null ) {
81 l_memory = new Vector();
82 l_bindings = new Vector();
83 db.put(l_path,l_memory);
84 bindingsDb.put(l_path,l_bindings);
85 }
86 r_memory = (Vector)db.get(r_path);
87 r_bindings = (Vector)bindingsDb.get(r_path);
88 if ( r_memory == null ) {
89 r_memory = new Vector();
90 r_bindings = new Vector();
91 db.put(r_path,r_memory);
92 bindingsDb.put(r_path,r_bindings);
93 }
94
95 if ( tag == ADD ) {
96 l_memory.addElement(input);
97 l_bindings.addElement(new Bindings(b));
98 }
99 else {
100 found = false;
101 for(int i = 0; !found && i < l_memory.size(); i++ ) {
102 store = (Vector)l_memory.elementAt(i);
103 found = true;
104 for(int j = 0; found && j < input.size(); j++ ) {
105 f1 = (Fact)input.elementAt(j);
106 f2 = (Fact)store.elementAt(j);
107 found &= f1.equals(f2);
108 }
109 if ( found ) {
110 l_memory.removeElementAt(i);
111 l_bindings.removeElementAt(i--);
112 }
113 }
114 if ( !found ) return;
115 }
116 for(int i = 0; i < r_memory.size(); i++ ) {
117 store = (Vector)r_memory.elementAt(i);
118 b2 = (Bindings)r_bindings.elementAt(i);
119 b1 = new Bindings(b);
120 if ( b1.add(b2) )
121 evaluate(l_path,tag,input,store,b1);
122 }
123 break;
124
125 case RIGHT:
126 r_path = path;
127 l_path = (String)pathDb1.get(path);
128 l_memory = (Vector)db.get(l_path);
129 l_bindings = (Vector)bindingsDb.get(l_path);
130 if ( l_memory == null ) {
131 l_memory = new Vector();
132 l_bindings = new Vector();
133 db.put(l_path,l_memory);
134 bindingsDb.put(l_path,l_bindings);
135 }
136 r_memory = (Vector)db.get(r_path);
137 r_bindings = (Vector)bindingsDb.get(r_path);
138 if ( r_memory == null ) {
139 r_memory = new Vector();
140 r_bindings = new Vector();
141 db.put(r_path,r_memory);
142 bindingsDb.put(r_path,r_bindings);
143 }
144
145 if ( tag == ADD ) {
146 r_memory.addElement(input);
147 r_bindings.addElement(new Bindings(b));
148 }
149 else {
150 found = false;
151 for(int i = 0; !found && i < r_memory.size(); i++ ) {
152 store = (Vector)r_memory.elementAt(i);
153 found = true;
154 for(int j = 0; found && j < input.size(); j++ ) {
155 f1 = (Fact)input.elementAt(j);
156 f2 = (Fact)store.elementAt(j);
157 found &= f1.equals(f2);
158 }
159 if ( found ) {
160 r_memory.removeElementAt(i);
161 r_bindings.removeElementAt(i--);
162 }
163 }
164 if ( !found ) return;
165 }
166 for(int i = 0; i < l_memory.size(); i++ ) {
167 store = (Vector)l_memory.elementAt(i);
168 b1 = (Bindings)l_bindings.elementAt(i);
169 b2 = new Bindings(b);
170 if ( b2.add(b1) )
171 evaluate(l_path,tag,store,input,b2);
172 }
173 break;
174
175 default:
176 Assert.notNull(null);
177 }
178 }
179
180
181 protected void evaluate(String path, int tag, Vector left,
182 Vector right, Bindings b) {
183 boolean status = true;
184 JoinEntry e;
185 Fact f1, f2;
186
187 for(int i = 0; status && i < constraints.size(); i++ ) {
188 e = (JoinEntry)constraints.elementAt(i);
189 f1 = (Fact)left.elementAt(e.l_position);
190 f2 = (Fact)right.elementAt(e.r_position);
191 ValueFunction lv = f1.getFn(e.l_attribute);
192 ValueFunction rv = f2.getFn(e.r_attribute);
193 status &= lv != null && rv != null &&
194 e.l_value.unifiesWith(lv,b) != null &&
195 e.r_value.unifiesWith(rv,b) != null;
196 }
197 if ( status ) {
198 Vector result = new Vector();
199 for(int i = 0; i < left.size(); i++ )
200 result.addElement(left.elementAt(i));
201 for(int i = 0; i < right.size(); i++ )
202 result.addElement(right.elementAt(i));
203
204 path = (String)pathDb2.get(path);
205 propagate(path,tag,result,b);
206 }
207 }
208 public boolean equals(Object any) {
209 if ( !(any instanceof JoinNode) ) return false;
210 JoinNode node = (JoinNode)any;
211 if ( node.type != PLAIN ) return false;
212 if ( node.constraints.size() != constraints.size() ) return false;
213 boolean result = true;
214 JoinEntry e1, e2;
215 for(int i = 0; result && i < constraints.size(); i++ ) {
216 e1 = (JoinEntry)constraints.elementAt(i);
217 e2 = (JoinEntry)node.constraints.elementAt(i);
218 result &= e1.equals(e2);
219 }
220 return result;
221 }
222 public String toString() {
223 return "JoinNode(" + constraints + ")";
224 }
225 }