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.concepts.fn;
25  
26  import java.util.*;
27  import zeus.util.*;
28  import zeus.concepts.*;
29  
30  public class VectorFn extends ValueFunction {
31     protected Object args = null;
32  
33     public VectorFn(Vector items) {
34        super(VECT,10);
35        args = items;
36     }
37  
38     public ValueFunction mirror() {
39        Vector List = (Vector)args;
40        Vector otherList = new Vector();
41        ValueFunction fn;
42        for(int i = 0; i < List.size(); i++ ) {
43           fn = (ValueFunction)List.elementAt(i);
44           fn = fn.mirror();
45           otherList.addElement(fn);
46        }
47        return new VectorFn(otherList);
48     }
49  
50     public String toString() {
51        String s = "{";
52        Vector List = (Vector)args;
53        ValueFunction fn;
54        for(int i = 0; i < List.size(); i++ ) {
55           fn = (ValueFunction)List.elementAt(i);
56           s += fn;
57           if ( i + 1 < List.size() )
58              s += ",";
59        }
60        s += "}";
61        return s;
62     }
63  
64     ValueFunction simplify() {
65        Vector List = (Vector)args;
66        Vector otherList = new Vector();
67        ValueFunction fn;
68        for(int i = 0; i < List.size(); i++ ) {
69           fn = (ValueFunction)List.elementAt(i);
70           fn = fn.simplify();
71           otherList.addElement(fn);
72        }
73        return new VectorFn(otherList);
74     }
75     Object getArg(int position) {
76        if ( position != 0 ) 
77           throw new ArrayIndexOutOfBoundsException(position);
78        return args;
79     }
80     public boolean references(ValueFunction var) {
81        Vector List = (Vector)args;
82        ValueFunction fn;
83        for(int i = 0; i < List.size(); i++ ) {
84           fn = (ValueFunction)List.elementAt(i);
85           if ( fn.references(var) )
86              return true;
87        }
88        return false;
89     }
90     public Vector variables() {
91        Vector List = (Vector)args;
92        Vector otherList = new Vector();
93        ValueFunction fn;
94        for(int i = 0; i < List.size(); i++ ) {
95           fn = (ValueFunction)List.elementAt(i);
96           otherList = Misc.union(otherList,fn.variables());
97        }
98        return otherList;
99     }
100    public boolean isDeterminate() {
101       Vector List = (Vector)args;
102       ValueFunction fn;
103       for(int i = 0; i < List.size(); i++ ) {
104          fn = (ValueFunction)List.elementAt(i);
105          if ( !fn.isDeterminate() ) return false;
106       }
107       return true;
108    }
109    ValueFunction normalize() {
110       Vector List = (Vector)args;
111       Vector otherList = new Vector();
112       ValueFunction fn;
113       for(int i = 0; i < List.size(); i++ ) {
114          fn = (ValueFunction)List.elementAt(i);
115          fn = fn.normalize();
116          otherList.addElement(fn);
117       }
118       return new VectorFn(otherList);
119    }
120    public ValueFunction resolve(ResolutionContext c, Bindings b) {
121       Vector List = (Vector)args;
122       Vector otherList = new Vector();
123       ValueFunction fn;
124       for(int i = 0; i < List.size(); i++ ) {
125          fn = (ValueFunction)List.elementAt(i);
126          fn = fn.resolve(c,b);
127          otherList.addElement(fn);
128       }
129       VectorFn m =  new VectorFn(otherList);
130       return m.evaluationFn();
131    }
132 
133    public ValueFunction duplicate(DuplicationTable table) {
134       Vector List = (Vector)args;
135       Vector otherList = new Vector();
136       ValueFunction fn;
137       for(int i = 0; i < List.size(); i++ ) {
138          fn = (ValueFunction)List.elementAt(i);
139          fn = fn.duplicate(table);
140          otherList.addElement(fn);
141       }
142       return new VectorFn(otherList);
143    }
144    public boolean equals(Object any) {
145       if ( !(any instanceof VectorFn) ) return false;
146       VectorFn fn = (VectorFn)any;
147 
148       ValueFunction a = this.simplify();
149       ValueFunction b = fn.simplify();
150       return Misc.sameVector((Vector)a.getArg(0),(Vector)b.getArg(0));
151    }
152 
153    ValueFunction unify(ValueFunction fn, Bindings b) {
154       Vector thisVector, otherVector, resultVector;
155       ValueFunction x, y, z;
156 
157       switch( fn.getID() ) {
158          case VECT:
159               thisVector = (Vector)getArg();
160               otherVector = (Vector)fn.getArg();
161               if ( thisVector.size() != otherVector.size() ) return null;
162 
163               Bindings b1 = new Bindings(b);
164               resultVector = new Vector();
165 
166               for(int i = 0; i < thisVector.size(); i++ ) {
167                  x = (ValueFunction)thisVector.elementAt(i);
168                  y = (ValueFunction)otherVector.elementAt(i);
169                  if ( (z = x.unifiesWith(y,b1)) == null )
170                     return null;
171                  resultVector.addElement(z);
172               }
173               b.add(b1);
174               return new VectorFn(resultVector);
175 
176          default:
177               throw new IllegalArgumentException("Unification type clash" +
178                  " between \'" + this + "\' and \'" + fn + "\'");
179       }
180    }
181 
182 
183    /*
184       List of methods associated with this ValueFunction type
185    */
186 
187    static final String[] METHOD_LIST = {
188       /* ValueFunction */ "elementAt",            "1",   /* (int index) */
189       /* BoolFn        */ "setElementAt",         "2",   /* (ValueFunction obj, int index) */
190       /* BoolFn        */ "insertElementAt",      "2",   /* (ValueFunction obj, int index) */
191       /* BoolFn        */ "addElement",           "1",   /* (ValueFunction obj) */
192       /* BoolFn        */ "removeElement",        "1",   /* (ValueFunction obj) */
193       /* BoolFn        */ "removeElementAt",      "1",   /* (int index) */
194       /* BoolFn        */ "removeAllElements",    "0",   /* () */
195       /* BoolFn        */ "containsElement",      "1",   /* (ValueFunction obj) */
196       /* BoolFn        */ "isEmpty",              "0",   /* () */
197       /* IntFn         */ "size",                 "0",   /* () */
198       /* ValueFunction */ "firstElement",         "0",   /* () */
199       /* ValueFunction */ "lastElement",          "0",   /* () */
200       /* VectorFn      */ "union",                "1",   /* (VectorFn obj) */
201       /* VectorFn      */ "intersection",         "1",   /* (VectorFn obj) */
202       /* VectorFn      */ "difference",           "1",   /* (VectorFn obj) */
203    };
204 
205    static final int ELEMENT_AT 		= 0;
206    static final int SET_ELEMENT_AT 	= 2;
207    static final int INSERT_ELEMENT_AT	= 4;
208    static final int ADD_ELEMENT 	= 6;
209    static final int REMOVE_ELEMENT 	= 8;
210    static final int REMOVE_ELEMENT_AT 	= 10;
211    static final int REMOVE_ALL_ELEMENTS = 12;
212    static final int CONTAINS_ELEMENT 	= 14;
213    static final int IS_EMPTY 		= 16;
214    static final int SIZE 		= 18;
215    static final int FIRST_ELEMENT 	= 20;
216    static final int LAST_ELEMENT 	= 22;
217    static final int UNION 		= 24;
218    static final int INTERSECTION 	= 26;
219    static final int DIFFERENCE 		= 28;
220 
221    ValueFunction invokeMethod(String method, Vector arguments) {
222       int position = Misc.whichPosition(method,METHOD_LIST);
223 
224       if ( position == -1 )
225          return super.invokeMethod(method,arguments);
226 
227       StringTokenizer st = new StringTokenizer(METHOD_LIST[position+1],",");
228       boolean num_args_ok = false;
229       int arity = -1;
230       while( !num_args_ok && st.hasMoreTokens() ) {
231          arity = Integer.parseInt(st.nextToken());
232          num_args_ok = (arguments.size() == arity);
233       }
234 
235       if ( !num_args_ok )
236          throw new IllegalArgumentException(
237             "Wrong number of arguments in method VectorFn.\'" + method + "/" +
238              arity + "\' --> " + this);
239 
240        try {
241 
242          IntFn index;
243          ValueFunction value;
244          VectorFn vn;
245          Vector otherData;
246 
247          Vector data = (Vector)args;
248 
249          switch( position ) {
250             case ELEMENT_AT:
251                  index = (IntFn)arguments.elementAt(0);
252                  return (ValueFunction)data.elementAt(index.intValue());
253 
254             case SET_ELEMENT_AT:
255                  value = (ValueFunction)arguments.elementAt(0);
256                  index = (IntFn)arguments.elementAt(1);
257                  data.setElementAt(value,index.intValue());
258                  return BoolFn.trueFn;
259 
260             case INSERT_ELEMENT_AT:
261                  value = (ValueFunction)arguments.elementAt(0);
262                  index = (IntFn)arguments.elementAt(1);
263                  data.insertElementAt(value,index.intValue());
264                  return BoolFn.trueFn;
265 
266             case ADD_ELEMENT:
267                  value = (ValueFunction)arguments.elementAt(0);
268                  data.addElement(value);
269                  return BoolFn.trueFn;
270 
271             case REMOVE_ELEMENT:
272                  value = (ValueFunction)arguments.elementAt(0);
273                  return BoolFn.newBoolFn(data.removeElement(value));
274 
275             case REMOVE_ELEMENT_AT:
276                  index = (IntFn)arguments.elementAt(0);
277                  value = (ValueFunction)data.elementAt(index.intValue());
278                  data.removeElementAt(index.intValue());
279                  return value;
280 
281             case REMOVE_ALL_ELEMENTS:
282                  data.removeAllElements();
283                  return BoolFn.trueFn;
284 
285             case CONTAINS_ELEMENT:
286                  value = (ValueFunction)arguments.elementAt(0);
287                  return BoolFn.newBoolFn(data.contains(value));
288 
289             case IS_EMPTY:
290                  return BoolFn.newBoolFn(data.isEmpty());
291 
292 	    case SIZE:
293                  return new IntFn(data.size());
294 
295             case FIRST_ELEMENT:
296                  return (ValueFunction)data.firstElement();
297 
298             case LAST_ELEMENT:
299                  return (ValueFunction)data.lastElement();
300 
301 	    case UNION:
302                  vn = (VectorFn)arguments.elementAt(0);
303                  otherData = (Vector)vn.getArg();
304                  return new VectorFn(Misc.union(data,otherData));
305 
306 	    case INTERSECTION:
307                  vn = (VectorFn)arguments.elementAt(0);
308                  otherData = (Vector)vn.getArg();
309                  return new VectorFn(Misc.intersection(data,otherData));
310 
311 	    case DIFFERENCE:
312                  vn = (VectorFn)arguments.elementAt(0);
313                  otherData = (Vector)vn.getArg();
314                  return new VectorFn(Misc.difference(data,otherData));
315          }
316       }
317       catch(ClassCastException e) {
318          throw new IllegalArgumentException(
319             "Type mismatch in method \'" + this + Fact.A_CHR + method +
320             "(...)\'");
321 
322       }
323       Core.ERROR(null,1,this); // should never get here
324       return null;
325    }
326 }