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;
25  
26  import java.util.*;
27  import zeus.util.*;
28  import zeus.concepts.fn.*;
29  
30  
31  public class TaskNode {
32     public static final String  BEGIN = "begin";
33     public static final String  END = "end";
34     public static final String  DEFAULT_GROUP = "default";
35  
36     protected boolean   isConditionalNode = false;
37     protected String    name;
38     protected Hashtable consumed = new Hashtable();
39     protected Hashtable produced = new Hashtable();
40  
41     public TaskNode(String name) {
42        setName(name);
43        consumed.put(DEFAULT_GROUP, new Vector());
44        produced.put(DEFAULT_GROUP, new Vector());
45     }
46  
47     public TaskNode(String name, Fact[] consumed, Fact[] produced) {
48        setName(name);
49        setPostconditions(produced);
50        setPreconditions(consumed);
51     }
52     public TaskNode(String name, Vector consumed, Vector produced) {
53        setName(name);
54        setPostconditions(produced);
55        setPreconditions(consumed);
56     }
57  
58     public TaskNode(TaskNode node) {
59        name = node.getName();
60        setPostconditions(node.getPostconditions());
61        setPreconditions(node.getPreconditions());
62     }
63  
64     public final boolean isConditionalNode() { return isConditionalNode; }
65     public final boolean isBeginNode()       { return name.equals(BEGIN); }
66     public final boolean isEndNode()         { return name.equals(END); }
67     public final String  getName()           { return name;   }
68  
69     public final void setName(String name)  {
70        Assert.notNull(name);
71        Assert.notFalse( !name.equals("") );
72        this.name = name;
73     }
74  
75     public String[] getPreconditionGroups() {
76        String[] output = new String[consumed.size()];
77        Enumeration enum = consumed.keys();
78        for(int i = 0; enum.hasMoreElements(); i++ )
79           output[i] = (String)enum.nextElement();
80        return output;
81     }
82  
83     public String[] getPostconditionGroups() {
84        String[] output = new String[produced.size()];
85        Enumeration enum = produced.keys();
86        for(int i = 0; enum.hasMoreElements(); i++ )
87           output[i] = (String)enum.nextElement();
88        return output;
89     }
90  
91     public void setPostconditions(Hashtable input) {
92        produced.clear();
93        String group;
94        Vector data, List;
95        Enumeration enum = input.keys();
96        while( enum.hasMoreElements() ) {
97           group = (String)enum.nextElement();
98           List = (Vector)input.get(group);
99           data = new Vector();
100          for(int i = 0; i < List.size(); i++ )
101             data.addElement(new Fact((Fact)List.elementAt(i)));
102          produced.put(group,data);
103       }
104    }
105 
106    public void setPreconditions(Hashtable input) {
107       consumed.clear();
108       String group;
109       Vector data, List;
110       Enumeration enum = input.keys();
111       while( enum.hasMoreElements() ) {
112          group = (String)enum.nextElement();
113          List = (Vector)input.get(group);
114          data = new Vector();
115          for(int i = 0; i < List.size(); i++ )
116             data.addElement(new Fact((Fact)List.elementAt(i)));
117          consumed.put(group,data);
118       }
119    }
120 
121    public Hashtable getAllPostconditions() {
122       Hashtable output = new Hashtable();
123       String group;
124       Vector data, List;
125       Enumeration enum = produced.keys();
126       while( enum.hasMoreElements() ) {
127          group = (String)enum.nextElement();
128          List = (Vector)produced.get(group);
129          data = new Vector();
130          for(int i = 0; i < List.size(); i++ )
131             data.addElement(new Fact((Fact)List.elementAt(i)));
132          output.put(group,data);
133       }
134       return output;
135    }
136 
137    public Hashtable getAllPreconditions() {
138       Hashtable output = new Hashtable();
139       String group;
140       Vector data, List;
141       Enumeration enum = consumed.keys();
142       while( enum.hasMoreElements() ) {
143          group = (String)enum.nextElement();
144          List = (Vector)consumed.get(group);
145          data = new Vector();
146          for(int i = 0; i < List.size(); i++ )
147             data.addElement(new Fact((Fact)List.elementAt(i)));
148          output.put(group,data);
149       }
150       return output;
151    }
152 
153    public Vector produced() { return getGroup(produced,DEFAULT_GROUP); }
154    public Vector consumed() { return getGroup(consumed,DEFAULT_GROUP); }
155 
156    public Vector produced(String group) { return getGroup(produced,group); }
157    public Vector consumed(String group) { return getGroup(consumed,group); }
158 
159    public void setPostconditions(Vector List) {
160       setPostconditions(DEFAULT_GROUP,List);
161    }
162    public void setPostconditions(Fact[] List) {
163       setPostconditions(DEFAULT_GROUP,List);
164    }
165    public void setPreconditions(Vector List) {
166       setPreconditions(DEFAULT_GROUP,List);
167    }
168    public void setPreconditions(Fact[] List) {
169       setPreconditions(DEFAULT_GROUP,List);
170    }
171 
172    protected Vector getGroup(Hashtable table, String group) {
173       Vector data = (Vector)table.get(group);
174       if ( data == null ) {
175          data = new Vector();
176          table.put(group,data);
177       }
178       return data;
179    }
180 
181    public void setPostconditions(String group, Vector List) {
182       Vector data = getGroup(produced,group);
183       data.removeAllElements();
184       for(int i = 0; i < List.size(); i++ )
185          data.addElement(new Fact((Fact)List.elementAt(i)));
186    }
187 
188    public void setPostconditions(String group, Fact[] List) {
189       Vector data = getGroup(produced,group);
190       data.removeAllElements();
191       for(int i = 0; i < List.length; i++ )
192          data.addElement(new Fact(List[i]));
193    }
194 
195    public void setPreconditions(String group, Vector List) {
196       Vector data = getGroup(consumed,group);
197       data.removeAllElements();
198       for(int i = 0; i < List.size(); i++ )
199          data.addElement(new Fact((Fact)List.elementAt(i)));
200    }
201 
202    public void setPreconditions(String group, Fact[] List) {
203       Vector data = getGroup(consumed,group);
204       data.removeAllElements();
205       for(int i = 0; i < List.length; i++ )
206          data.addElement(new Fact(List[i]));
207    }
208 
209    public Fact[] getPostconditions() {
210       return getPostconditions(DEFAULT_GROUP);
211    }
212    public Fact[] getPreconditions() {
213       return getPreconditions(DEFAULT_GROUP);
214    }
215 
216    public Fact[] getPostconditions(String group) {
217       Vector data = getGroup(produced,group);
218       Fact[] out = new Fact[data.size()];
219       for(int i = 0; i < data.size(); i++)
220          out[i] = new Fact((Fact)data.elementAt(i));
221       return out;
222    }
223 
224    public Fact[] getPreconditions(String group) {
225       Vector data = getGroup(consumed,group);
226       Fact[] out = new Fact[data.size()];
227       for(int i = 0; i < data.size(); i++)
228          out[i] = new Fact((Fact)data.elementAt(i));
229       return out;
230    }
231 
232    public int countPreconditions() {
233       return countPreconditions(DEFAULT_GROUP);
234    }
235    public int countPostconditions() {
236       return countPostconditions(DEFAULT_GROUP);
237    }
238    public int[] numPreconditions() {
239       return numPreconditions(DEFAULT_GROUP);
240    }
241    public int[] numPostconditions() {
242       return numPostconditions(DEFAULT_GROUP);
243    }
244 
245    public int countPreconditions(String group) {
246       return getGroup(consumed,group).size();
247    }
248    public int countPostconditions(String group) {
249       return getGroup(produced,group).size();
250    }
251 
252    public int[] numPreconditions(String group) {
253       Vector data = getGroup(consumed,group);
254       int[] array = new int[data.size()];
255       for(int i = 0; i < data.size(); i++)
256          array[i] = ((Fact)data.elementAt(i)).getNumber();
257       return array;
258    }
259    public int[] numPostconditions(String group) {
260       Vector data = getGroup(produced,group);
261       int[] array = new int[data.size()];
262       for(int i = 0; i < data.size(); i++)
263          array[i] = ((Fact)data.elementAt(i)).getNumber();
264       return array;
265    }
266 
267    public Fact getPrecondition(String fid) {
268       return getPrecondition(DEFAULT_GROUP,fid);
269    }
270    public Fact getPostcondition(String fid) {
271       return getPostcondition(DEFAULT_GROUP,fid);
272    }
273    public Fact getPrecondition(int pos) {
274       return getPrecondition(DEFAULT_GROUP,pos);
275    }
276    public Fact getPostcondition(int pos) {
277       return getPostcondition(DEFAULT_GROUP,pos);
278    }
279    public int getConsumedPos(Fact fact) {
280       return getConsumedPos(DEFAULT_GROUP,fact);
281    }
282    public int getProducedPos(Fact fact) {
283       return getProducedPos(DEFAULT_GROUP,fact);
284    }
285 
286    public Fact getPrecondition(String group, String fid) {
287       Vector data = getGroup(consumed,group);
288       Fact f;
289       for(int i = 0; i < data.size(); i++) {
290         f = (Fact)data.elementAt(i);
291         if ( fid.equals(f.getId()))
292            return f;
293       }
294       return null;
295    }
296    public Fact getPostcondition(String group, String fid) {
297       Vector data = getGroup(produced,group);
298       Fact f;
299       for(int i = 0; i < data.size(); i++) {
300         f = (Fact)data.elementAt(i);
301         if ( fid.equals(f.getId()))
302            return f;
303       }
304       return null;
305    }
306    public Fact getPrecondition(String group, int pos) {
307       Vector data = getGroup(consumed,group);
308       return (Fact)data.elementAt(pos);
309    }
310    public Fact getPostcondition(String group, int pos) {
311       Vector data = getGroup(produced,group);
312       return (Fact)data.elementAt(pos);
313    }
314 
315    public int getConsumedPos(String group, Fact fact) {
316       Vector data = getGroup(consumed,group);
317       String fid = fact.getId();
318       Fact f;
319       for(int i = 0; i < data.size(); i++) {
320         f = (Fact)data.elementAt(i);
321         if ( fid.equals(f.getId()))
322            return i;
323       }
324       Assert.notNull(null);
325       return -1;
326    }
327    public int getProducedPos(String group, Fact fact) {
328       Vector data = getGroup(produced,group);
329       String fid = fact.getId();
330       Fact f;
331       for(int i = 0; i < data.size(); i++) {
332         f = (Fact)data.elementAt(i);
333          if ( fid.equals(f.getId()))
334            return i;
335       }
336       Assert.notNull(null);
337       return -1;
338    }
339 
340    public void relaxNumberFields() {
341       Fact f1;
342       ValueFunction fn;
343       Vector data;
344       Enumeration enum = consumed.elements();
345       while( enum.hasMoreElements() ) {
346          data = (Vector)enum.nextElement();
347          for(int i = 0; i < data.size(); i++ ) {
348             f1 = (Fact)data.elementAt(i);
349             if ( f1.isa(OntologyDb.ENTITY) ) {
350                fn = f1.getFn(OntologyDb.NUMBER);
351                if ( fn.getID() == ValueFunction.INT )
352                   f1.setValue(OntologyDb.NUMBER,f1.newVar());
353             }
354          }
355       }
356       enum = produced.elements();
357       while( enum.hasMoreElements() ) {
358          data = (Vector)enum.nextElement();
359          for(int i = 0; i < data.size(); i++ ) {
360             f1 = (Fact)data.elementAt(i);
361             if ( f1.isa(OntologyDb.ENTITY) ) {
362                fn = f1.getFn(OntologyDb.NUMBER);
363                if ( fn.getID() == ValueFunction.INT )
364                   f1.setValue(OntologyDb.NUMBER,f1.newVar());
365             }
366          }
367       }
368    }
369 
370    public boolean resolve(Bindings bindings) {
371       Core.DEBUG(3,"TaskNode resolve: b = " + bindings);
372       return resolve(new ResolutionContext(),bindings);
373    }
374    public boolean resolve(ResolutionContext context, Bindings bindings) {
375    /***
376       Note: All precondition groups (actually there is only one -- the
377       default group) must be successfully resolved. However, for postcondition
378       groups, any group that does not successfully resolve is removed. If all
379       postcondition groups are eventually removed, then the resolution is
380       deemed to have failed.
381    */
382       boolean status = true;
383       Vector data;
384       Enumeration enum = consumed.elements();
385       while( enum.hasMoreElements() ) {
386          data = (Vector)enum.nextElement();
387          for(int i = 0; status && i < data.size(); i++ )
388             status &= ((Fact)data.elementAt(i)).resolve(context,bindings);
389       }
390 
391       if ( !status ) return status;
392 
393       String group;
394       Bindings b;
395       enum = produced.keys();
396       while( enum.hasMoreElements() ) {
397          group = (String)enum.nextElement();
398          data = (Vector)produced.get(group);
399 
400          boolean local_status = true;
401          b = new Bindings(bindings);
402          for(int i = 0; local_status && i < data.size(); i++ )
403             local_status &= ((Fact)data.elementAt(i)).resolve(context,b);
404 
405          if ( local_status )
406 	    bindings.add(b);
407          else
408             produced.remove(group);
409       }
410 
411       if ( produced.isEmpty() ) return false;
412       return status;
413    }
414 
415    public String toString() {
416       String s = new String("(");
417 
418       s += ":name " + name + " ";
419       s += ":is_conditional " + isConditionalNode + " ";
420 
421       Enumeration enum;
422       String group;
423       Vector data;
424 
425       if ( !consumed.isEmpty() ) {
426          s += ":consumed_facts (";
427          enum = consumed.keys();
428          while( enum.hasMoreElements() ) {
429             group = (String)enum.nextElement();
430             data = (Vector)consumed.get(group);
431             s += "(:group " + group + " (";
432             for(int i = 0; i < data.size(); i++ )
433                s += data.elementAt(i);
434             s += "))";
435          }
436          s += ") ";
437       }
438       if ( !produced.isEmpty() ) {
439          s += ":produced_facts (";
440          enum = produced.keys();
441          while( enum.hasMoreElements() ) {
442             group = (String)enum.nextElement();
443             data = (Vector)produced.get(group);
444             s += "(:group " + group + " (";
445             for(int i = 0; i < data.size(); i++ )
446                s += data.elementAt(i);
447             s += "))";
448          }
449          s += ") ";
450       }
451       return s.trim() + ")";
452    }
453 
454    public String pprint() {
455       return pprint(0);
456    }
457    public String pprint(int sp) {
458       String suffix, prefix;
459       String tabs = Misc.spaces(sp);
460       String eol  = "\n" + tabs + " ";
461 
462       String s = new String("(");
463 
464       s += ":name " + name + eol;
465       s += ":is_conditional " + isConditionalNode + eol;
466 
467       Enumeration enum;
468       String group;
469       Vector data;
470 
471       if ( !consumed.isEmpty() ) {
472          prefix = ":consumed_facts ";
473          suffix = Misc.spaces(1 + sp + prefix.length());
474          s += prefix + "(";
475 	 enum = consumed.keys();
476          while( enum.hasMoreElements() ) {
477             group = (String)enum.nextElement();
478             data = (Vector)consumed.get(group);
479             s += "(:group " + group + " (";
480             for(int i = 0; i < data.size(); i++ )
481                s += ((Fact)data.elementAt(i)).pprint(1+suffix.length()) +
482                     "\n" + suffix + " ";
483             s = s.trim() + "\n" + suffix + "))" + eol;
484          }
485          s = s.trim() + "\n" + suffix + ")" + eol;
486       }
487       if ( !produced.isEmpty() ) {
488          prefix = ":produced_facts ";
489          suffix = Misc.spaces(1 + sp + prefix.length());
490          s += prefix + "(";
491 	 enum = produced.keys();
492          while( enum.hasMoreElements() ) {
493             group = (String)enum.nextElement();
494             data = (Vector)produced.get(group);
495             s += "(:group " + group + " (";
496             for(int i = 0; i < data.size(); i++ )
497                s += ((Fact)data.elementAt(i)).pprint(1+suffix.length()) +
498                     "\n" + suffix + " ";
499             s = s.trim() + "\n" + suffix + "))" + eol;
500          }
501          s = s.trim() + "\n" + suffix + ")" + eol;
502       }
503       return s.trim() + "\n" + tabs + ")";
504    }
505 
506    public TaskNode duplicate(String name, GenSym genSym) {
507       DuplicationTable table = new DuplicationTable(name,genSym);
508       return duplicate(table);
509    }
510    public TaskNode duplicate(DuplicationTable table) {
511       Enumeration enum;
512       String group;
513       Vector data;
514       Fact[] xdata;
515 
516       TaskNode xnode = new TaskNode(name);
517 
518       enum = consumed.keys();
519       while( enum.hasMoreElements() ) {
520          group = (String)enum.nextElement();
521          data = (Vector)consumed.get(group);
522          xdata = new Fact[data.size()];
523          for(int i = 0; i < data.size(); i++ )
524             xdata[i] = ((Fact)data.elementAt(i)).duplicate(table);
525          xnode.setPreconditions(group,xdata);
526       }
527 
528       enum = produced.keys();
529       while( enum.hasMoreElements() ) {
530          group = (String)enum.nextElement();
531          data = (Vector)produced.get(group);
532          xdata = new Fact[data.size()];
533          for(int i = 0; i < data.size(); i++ )
534             xdata[i] = ((Fact)data.elementAt(i)).duplicate(table);
535          xnode.setPostconditions(group,xdata);
536       }
537       return xnode;
538    }
539 }