View Javadoc

1   /*
2   * The contents of this file are subject to the BT "ZEUS" Open Source 
3   * Licence (L77741), Version 1.0 (the "Licence"); you may not use this file 
4   * except in compliance with the Licence. You may obtain a copy of the Licence
5   * from $ZEUS_INSTALL/licence.html or alternatively from
6   * http://www.labs.bt.com/projects/agents/zeus/licence.htm
7   * 
8   * Except as stated in Clause 7 of the Licence, software distributed under the
9   * Licence is distributed WITHOUT WARRANTY OF ANY KIND, either express or 
10  * implied. See the Licence for the specific language governing rights and 
11  * limitations under the Licence.
12  * 
13  * The Original Code is within the package zeus.*.
14  * The Initial Developer of the Original Code is British Telecommunications
15  * public limited company, whose registered office is at 81 Newgate Street, 
16  * London, EC1A 7AJ, England. Portions created by British Telecommunications 
17  * public limited company are Copyright 1996-9. All Rights Reserved.
18  * 
19  * THIS NOTICE MUST BE INCLUDED ON ANY COPY OF THIS FILE
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       // System.out.println("evaluating joinNode " + toString()); 
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 }