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