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  public class Action {
32     public static final int ASSERT    = 0;
33     public static final int RETRACT   = 1;
34     public static final int MODIFY    = 2;
35     public static final int PRINT     = 3;
36     public static final int MESSAGE   = 4;
37     public static final int ACHIEVE   = 5;
38     public static final int BUY       = 6;
39     public static final int SELL      = 7;
40     public static final int EXECUTE   = 8;
41  
42     public static final int BIND      = 9;
43     public static final int IF        = 10;
44     public static final int WHILE     = 11;
45     public static final int OPEN      = 12;
46     public static final int CLOSE     = 13;
47     public static final int READ      = 14;
48     public static final int READLN    = 15;
49     public static final int SYSTEM    = 16;
50     public static final int CALL      = 17;
51     public static final int PRINTLN   = 18;
52  
53     public static final String[] types = {
54        "assert",
55        "retract",
56        "modify",
57        "print",
58        "send_message",
59        "achieve",
60        "buy",
61        "sell",
62        "execute",
63        "bind",
64        "if",
65        "while",
66        "open",
67        "close",
68        "read",
69        "readln",
70        "system",
71        "call",
72        "println"
73     };
74  
75     public int       type         = -1;
76     public Vector    items        = null;
77     public Hashtable table        = null;
78     public Object    head         = null;
79     public Object    sub_head     = null;
80     public Object    sub_sub_head = null;
81     public Vector    sub_items    = null;
82  
83     public Action(String type) {
84        this(Misc.whichPosition(type,types));
85     }
86  
87     public Action(int type) {
88        this.type = type;
89  
90        switch(type) {
91           case ASSERT:
92           case EXECUTE:
93                break;
94  
95           case RETRACT:
96                items = new Vector(10);
97                break;
98  
99           case MODIFY:
100          case MESSAGE:
101          case ACHIEVE:
102          case BUY:
103          case SELL:
104               table = new Hashtable();
105               break;
106 
107 
108          case IF:
109               items = new Vector(10);
110               sub_items = new Vector(10);
111               break;
112 
113          case WHILE:
114               items = new Vector(10);
115               break;
116 
117          case PRINT:
118          case PRINTLN:
119 	 case OPEN:
120          case CLOSE:
121          case SYSTEM:
122               items = new Vector(10);
123               break;
124 
125          case BIND:
126 	 case READ:
127          case READLN:
128               break;
129          default:
130               Core.USER_ERROR("Unknown action type " + type);
131       }
132    }
133    
134    public Action(Action a) {
135       type = a.type;
136 
137       ValueFunction var;
138       Action b;
139       switch(type) {
140          case ASSERT:
141               head = new ReteFact((ReteFact)a.head);
142               break;
143 
144          case CLOSE:
145 	 case EXECUTE:
146               head = ((ValueFunction)a.head).mirror();
147               break;
148 
149          case SYSTEM:
150          case RETRACT:
151               items = new Vector(10);
152               for(int i = 0; i < a.items.size(); i++ ) {
153                  var = (ValueFunction)a.items.elementAt(i);
154                  items.addElement(var.mirror());
155               }
156               break;
157 
158          case MODIFY:
159          case MESSAGE:
160          case ACHIEVE:
161          case BUY:
162          case SELL:
163  	      table = new Hashtable();
164               Enumeration enum = a.table.keys();
165               Object key;
166               while( enum.hasMoreElements() ) {
167                  key = enum.nextElement();
168                  var = (ValueFunction)a.table.get(key);
169                  table.put(key,var.mirror());
170               }
171               switch(type) {
172                  case MODIFY:
173                       head = ((ValueFunction)a.head).mirror();
174                       break;
175                  case ACHIEVE:
176                  case BUY:
177                  case SELL:
178                       head = new ReteFact((ReteFact)a.head);
179                       break;
180               }
181               break;
182 
183          case PRINTLN:
184          case PRINT:
185               head = ((ValueFunction)a.head).mirror();
186               items = new Vector(10);
187               for(int i = 0; i < a.items.size(); i++ ) {
188                  var = (ValueFunction)a.items.elementAt(i);
189                  items.addElement(var.mirror());
190               }
191               break;
192 
193          case IF:
194       	      head = ((ValueFunction)a.head).mirror();
195               items = new Vector(10);
196               for(int i = 0; i < a.items.size(); i++ ) {
197                  b = (Action)a.items.elementAt(i);
198                  items.addElement(new Action(b));
199               }
200               sub_items = new Vector(10);
201               for(int i = 0; i < a.sub_items.size(); i++ ) {
202                  b = (Action)a.sub_items.elementAt(i);
203                  sub_items.addElement(new Action(b));
204               }
205               break;
206 
207          case WHILE:
208       	      head = ((ValueFunction)a.head).mirror();
209               items = new Vector(10);
210               for(int i = 0; i < a.items.size(); i++ ) {
211                  b = (Action)a.items.elementAt(i);
212                  items.addElement(new Action(b));
213               }
214               break;
215 
216 	 case OPEN:
217               head = ((ValueFunction)a.head).mirror();
218               sub_head = ((ValueFunction)a.sub_head).mirror();
219               sub_sub_head = ((ValueFunction)a.sub_sub_head).mirror();
220               break;
221 
222          case BIND:
223 	 case READ:
224 	 case READLN:
225               head = ((ValueFunction)a.head).mirror();
226               sub_head = ((ValueFunction)a.sub_head).mirror();
227               break;
228       }
229    }
230 
231    public Action duplicate(String name, GenSym genSym) {
232       DuplicationTable table = new DuplicationTable(name,genSym);
233       return duplicate(table);
234    }
235    public Action duplicate(DuplicationTable table) {
236       Action a = new Action(type);
237 
238       ValueFunction var;
239       Action b;
240       switch(type) {
241          case ASSERT:
242               a.head = ((ReteFact)this.head).duplicate(table);
243               break;
244 
245          case CLOSE:
246          case EXECUTE:
247               a.head = ((ValueFunction)this.head).duplicate(table);
248               break;
249 
250          case SYSTEM:
251 	 case RETRACT:
252               for(int i = 0; i < this.items.size(); i++ ) {
253                  var = (ValueFunction)this.items.elementAt(i);
254                  var = var.duplicate(table);
255                  a.items.addElement(var);
256               }
257               break;
258 
259          case MODIFY:
260          case MESSAGE:
261          case ACHIEVE:
262          case BUY:
263          case SELL:
264               Enumeration enum = this.table.keys();
265               Object key;
266               while( enum.hasMoreElements() ) {
267                  key = enum.nextElement();
268                  var = (ValueFunction)this.table.get(key);
269                  var = var.duplicate(table);
270                  a.table.put(key,var);
271               }
272               switch(type) {
273                  case MODIFY:
274                       a.head = ((ValueFunction)this.head).duplicate(table);
275                       break;
276                  case ACHIEVE:
277                  case BUY:
278                  case SELL:
279                       a.head = ((ReteFact)this.head).duplicate(table);
280                       break;
281               }
282               break;
283 
284          case PRINTLN:
285          case PRINT:
286               a.head = ((ValueFunction)this.head).duplicate(table);
287               for(int i = 0; i < this.items.size(); i++ ) {
288                  var = (ValueFunction)this.items.elementAt(i);
289                  var = var.duplicate(table);
290                  a.items.addElement(var);
291               }
292               break;
293 
294          case IF:
295       	      a.head = ((ValueFunction)this.head).duplicate(table);
296               a.items = new Vector(10);
297               for(int i = 0; i < this.items.size(); i++ ) {
298                  b = (Action)this.items.elementAt(i);
299                  a.items.addElement(b.duplicate(table));
300               }
301               a.sub_items = new Vector(10);
302               for(int i = 0; i < this.sub_items.size(); i++ ) {
303                  b = (Action)this.sub_items.elementAt(i);
304                  a.sub_items.addElement(b.duplicate(table));
305               }
306               break;
307 
308          case WHILE:
309       	      a.head = ((ValueFunction)this.head).duplicate(table);
310               a.items = new Vector(10);
311               for(int i = 0; i < this.items.size(); i++ ) {
312                  b = (Action)this.items.elementAt(i);
313                  a.items.addElement(b.duplicate(table));
314               }
315               break;
316 
317 	 case OPEN:
318               a.head = ((ValueFunction)this.head).duplicate(table);
319               a.sub_head = ((ValueFunction)this.sub_head).duplicate(table);
320               a.sub_sub_head = ((ValueFunction)this.sub_sub_head).duplicate(table);
321               break;
322 
323          case BIND:
324 	 case READ:
325 	 case READLN:
326 // System.err.println("Action dup-before: table = " + table);
327               a.head = ((ValueFunction)this.head).duplicate(table);
328               a.sub_head = ((ValueFunction)this.sub_head).duplicate(table);
329 // System.err.println("Action dup-after: table = " + table);
330               break;
331 
332       }
333       return a;
334    }
335 
336    public boolean resolve(Bindings b) {
337       ValueFunction var;
338       Action a;
339 
340       switch(type) {
341          case ASSERT:
342               return ((ReteFact)head).resolve(b);
343 
344          case EXECUTE:
345               head = ((ValueFunction)head).resolve(b);
346               return head != null;
347 
348          case SYSTEM:
349          case RETRACT:
350               for(int i = 0; i < items.size(); i++ ) {
351                  var = (ValueFunction)items.elementAt(i);
352                  var = var.resolve(b);
353                  if ( var == null ) return false;
354                  items.setElementAt(var,i);
355               }
356               break;
357 
358          case MODIFY:
359          case MESSAGE:
360          case ACHIEVE:
361          case BUY:
362          case SELL:
363               Enumeration enum = table.keys();
364               Object key;
365               while( enum.hasMoreElements() ) {
366                  key = enum.nextElement();
367                  var = (ValueFunction)table.get(key);
368                  var = var.resolve(b);
369                  if ( var == null ) return false;
370                  table.put(key,var);
371               }
372               switch(type) {
373                  case MODIFY:
374                       head = ((ValueFunction)head).resolve(b);
375                       if ( head == null ) return false;
376                       break;
377                  case ACHIEVE:
378                  case BUY:
379                  case SELL:
380                       return ((ReteFact)head).resolve(b);
381               }
382               break;
383 
384          case PRINTLN:
385          case PRINT:
386               head = ((ValueFunction)head).resolve(b);
387               if ( head == null ) return false;
388 
389               for(int i = 0; i < items.size(); i++ ) {
390                  var = (ValueFunction)items.elementAt(i);
391                  var = var.resolve(b);
392                  if ( var == null ) return false;
393                  items.setElementAt(var,i);
394               }
395               break;
396 
397          case IF:
398       	      head = ((ValueFunction)head).resolve(b);
399               if ( head == null ) return false;
400 
401               for(int i = 0; i < items.size(); i++ ) {
402                  a = (Action)items.elementAt(i);
403                  if ( !a.resolve(b) ) return false;
404               }
405               for(int i = 0; i < sub_items.size(); i++ ) {
406                  a = (Action)sub_items.elementAt(i);
407                  if ( !a.resolve(b) ) return false;
408               }
409               break;
410 
411          case WHILE:
412       	      head = ((ValueFunction)head).resolve(b);
413               if ( head == null ) return false;
414 
415               for(int i = 0; i < items.size(); i++ ) {
416                  a = (Action)items.elementAt(i);
417                  if ( !a.resolve(b) ) return false;
418               }
419               break;
420 
421 	 case OPEN:
422               head = ((ValueFunction)head).resolve(b);
423               sub_head = ((ValueFunction)sub_head).resolve(b);
424               sub_sub_head = ((ValueFunction)sub_sub_head).resolve(b);
425               return head != null && sub_head != null && sub_sub_head != null;
426 
427          case BIND:
428 	 case READ:
429 	 case READLN:
430               head = ((ValueFunction)head).resolve(b);
431               sub_head = ((ValueFunction)sub_head).resolve(b);
432               return head != null && sub_head != null;
433       }
434       return true;
435    }
436    
437    public String toString() {
438       ValueFunction var;
439       Enumeration enum;
440       String s = "(" + types[type] + " ";
441       switch(type) {
442          case ASSERT:
443               s += head;
444               break;
445 
446          case CLOSE:
447 	 case EXECUTE:
448               s += head;
449               break;
450 
451          case SYSTEM:
452          case RETRACT:
453               s += Misc.concat(items);
454               break;
455 
456          case MODIFY:
457 	 case MESSAGE:
458          case ACHIEVE:
459          case BUY:
460          case SELL:
461               switch(type) {
462                  case MODIFY:
463                       s += head + " ";
464                       break;
465                  case ACHIEVE:
466                  case BUY:
467                  case SELL:
468                       s += "(" + OntologyDb.GOAL_FACT + " " + head + ") ";
469                       break;
470               }
471               enum = table.keys();
472               Object key;
473               while( enum.hasMoreElements() ) {
474                  key = enum.nextElement();
475                  var = (ValueFunction)table.get(key);
476                  s += "(" + key + " " + var + ") ";
477               }
478               break;
479 
480          case PRINTLN:
481          case PRINT:
482               s += head + " " + Misc.concat(items);
483               break;
484 
485          case IF:
486       	      s += head + " then\n " + Misc.concat(items);
487               if ( !sub_items.isEmpty() )
488 	         s += "\n else\n " + Misc.concat(sub_items);
489               break;
490 
491          case WHILE:
492       	      s += head + " do\n " + Misc.concat(items);
493               break;
494 
495 	 case OPEN:
496               s += head + " " + sub_head + " " + sub_sub_head;
497               break;
498 
499          case BIND:
500 	 case READ:
501 	 case READLN:
502               s += head + " " + sub_head;
503               break;
504 
505       }
506       return s.trim() + ")";
507    }
508    
509    public String pprint() {
510       return pprint(0);
511    }
512    public String pprint(int sp) {
513       return Misc.spaces(sp) + toString();
514    }
515 }