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  /*
25   * @(#)ConsumedDb.java 1.00
26   */
27  
28  package zeus.actors;
29  
30  import java.util.*;
31  import zeus.util.*;
32  import zeus.concepts.*;
33  import zeus.actors.rtn.*;
34  
35  /***
36   * The Consumed Resources Database is an internal storage component used by
37   * the {@link Planner} in the course of its activities. It is unlikely
38   * that developers will need to call these methods directly.
39   */
40  
41  public class ConsumedDb 
42  {
43     protected Vector[]   data = null;
44     protected int[]      consumed = null;
45     protected DataRec[]  records = null;
46     protected PlanRecord owner = null;
47  
48     protected boolean resources_consumed = false;
49     protected boolean resources_released = false;
50     protected Vector  all_subgoals = new Vector();
51  
52     // meaningless init  to allow rearch
53     public ConsumedDb () {
54      ;
55      }
56  
57     public ConsumedDb(PlanRecord owner, PrimitiveTask task) {
58        consumed = task.numPreconditions();
59        Assert.notNull(owner);
60        this.owner = owner;
61        data = new Vector[consumed.length];
62        records = new DataRec[consumed.length];
63  
64        for(int i = 0; i < records.length; i++)
65           records[i] = new DataRec(task.getPrecondition(i),owner,i);
66     }
67     
68     
69     public DataRec getDatarec(int precond_position) {
70        Core.DEBUG(2,"Getting datarec for " + owner + " at position " +
71                     precond_position);
72        return records[precond_position];
73     }
74     
75     
76     public int amountUsed(int precond_position) {
77        return consumed[precond_position];
78     }
79  
80  
81     public synchronized void add(int precond_position, PlanRecord child,
82                                  int effect_position, int amount) {
83        PreconditionChain ch;
84        Assert.notFalse(requiredItems(precond_position) >= amount);
85        if ( data[precond_position] == null)
86             data[precond_position] = new Vector();
87  
88        ch = new PreconditionChain(child,effect_position,amount);
89        data[precond_position].addElement(ch);
90     }
91     
92     
93     public synchronized void add(int precond_position, String goal_id,
94                                  int amount) {
95  
96        Assert.notFalse(requiredItems(precond_position) >= amount);
97        if ( data[precond_position] == null)
98             data[precond_position] = new Vector();
99  
100       PreconditionChain ch = new PreconditionChain(goal_id,amount);
101       data[precond_position].addElement(ch);
102    }
103 
104 
105    public synchronized void add(int precond_position, PreconditionChain ch) {
106       Assert.notFalse(requiredItems(precond_position) >= ch.amount);
107       if ( data[precond_position] == null)
108            data[precond_position] = new Vector();
109       data[precond_position].addElement(ch);
110    }
111 
112 
113    public int requiredItems(int position) {
114       PreconditionChain ch;
115       if ( records[position] == null ) return consumed[position];
116       int available = records[position].nAvailable();
117       if ( data[position] != null ) {
118          for(int i = 0; i < data[position].size(); i++ ) {
119             ch = (PreconditionChain)data[position].elementAt(i);
120             available += ch.amount;
121          }
122       }
123       return consumed[position] - available;
124    }
125    
126    
127    public boolean hasEnoughResources() {
128       boolean has_enough = true;
129       ResourceDb db = owner.getAgentContext().ResourceDb();
130       int now = (int)owner.getAgentContext().now();
131       for(int i = 0; has_enough && i < records.length; i++ )
132          has_enough &= records[i].nAvailable() == consumed[i] &&
133                        records[i].executeNow(db,now);
134       return has_enough;
135    }
136    
137    
138    public void newStartTime(int start) {
139       for(int i = 0; i < records.length; i++ )
140          records[i].newStartTime(start);
141    }
142    
143    
144    public void consumeResources() {
145       ResourceDb db = owner.getAgentContext().ResourceDb();
146       for(int i = 0; i < records.length; i++ )
147          db.consume(records[i]);
148       resources_consumed = true;
149    }
150    
151    
152    public int getPosition(String goal_id) {
153       PreconditionChain ch;
154       for(int i = 0; i < data.length; i++ ) {
155          for(int j = 0; data[i] != null && j < data[i].size(); j++ ) {
156             ch = (PreconditionChain)data[i].elementAt(j);
157             if ( ch.isExternal() && goal_id.equals(ch.key) )
158                return i;
159          }
160       }
161       Assert.notNull(null); // sh. never get here
162       return -1;
163    }
164    
165     // sync
166    public void factExists(int precond_position, PlanRecord child,
167                                        int effect_position, int amount) {
168       ResourceDb db = owner.getAgentContext().ResourceDb();
169       Vector List = data[precond_position];
170       for(int j = 0; j < List.size(); j++ ) {
171          PreconditionChain ch = (PreconditionChain)List.elementAt(j);
172          if ( ch.record == child && ch.position == effect_position &&
173               ch.amount == amount ) {
174             List.removeElementAt(j--);
175             Goal g = db.allocateResource(owner,precond_position,amount);
176 //            Assert.notFalse( g == null ); // FOR NOW
177             if ( g != null ) {
178                System.err.println("Resource Taken by someone?:\n" + g);
179                try {
180                    throw new Exception (); 
181                }
182                catch (Exception e) { 
183                 e.printStackTrace(); }
184             }
185             Core.DEBUG(2,"Calling Constrain: " + records[precond_position]);
186             constrain(records[precond_position]); //PROBLEM? 
187             return;
188          }
189       }
190       Assert.notNull(null); // sh. never get here
191    }
192    
193    // sync
194    public void factExists(String goal_id) {
195       ResourceDb db = owner.getAgentContext().ResourceDb();
196       int precond_position = getPosition(goal_id);
197       Vector List = data[precond_position];
198       for(int j = 0; j < List.size(); j++ ) {
199          PreconditionChain ch = (PreconditionChain)List.elementAt(j);
200          if ( ch.isExternal() && ch.key.equals(goal_id) ) {
201             List.removeElementAt(j--);
202             Goal g = db.allocateResource(owner,precond_position,ch.amount);
203 //            Assert.notFalse( g == null ); // FOR NOW
204             if ( g != null ) {
205                System.err.println("Resource Taken by someone?:\n" + g);
206             }
207             constrain(records[precond_position]);
208             Core.DEBUG(2,"Calling Constrain: " + records[precond_position]);
209             return;
210          }
211       }
212       Assert.notNull(null); // sh. never get here
213    }
214    
215    
216    public synchronized void replace(String goal_id, PlanRecord child,
217                                     int effect_position, int amount) {
218 
219       int precond_position = getPosition(goal_id);
220       Vector List = data[precond_position];
221       for(int j = 0; j < List.size(); j++ ) {
222          PreconditionChain ch = (PreconditionChain)List.elementAt(j);
223          if (ch.isExternal() && ch.key.equals(goal_id) ) {
224             if ( ch.amount == amount )
225                List.removeElementAt(j--);
226             else
227                ch.amount -= amount;
228             ch = new PreconditionChain(child,effect_position,amount);
229             List.addElement(ch);
230             return;
231          }
232       }
233       Assert.notNull(null); // sh. never get here
234    }
235 
236 
237    protected boolean constrain(DataRec datarec) {
238       Core.DEBUG(2,"Constrain: " + datarec);
239       Fact f1 = datarec.mostGeneralDescriptor();
240       Core.DEBUG(2,"Constrain: mgd " + f1);
241       Bindings b = new Bindings(owner.getAgentContext().whoami());
242       Fact f2 = datarec.getFact();
243       Core.DEBUG(2,"Constrain: getFact " + f2);
244       Assert.notFalse( f1.unifiesWith(f2,b) );
245       return  owner.applyConstraints(b);
246    }
247    
248    
249    
250    public Fact[][] getInputData() {
251       Fact[][] data = new Fact[consumed.length][];
252       for( int i = 0; i < data.length; i++ ) 
253          data[i] = records[i].getData();
254       return data;
255    }
256    
257    
258    public PlanRecord getOwner() { return owner; }
259    
260    
261    public synchronized void share(ConsumedDb db) {
262       DataRec datarec;
263       int required;
264       PreconditionChain ch;
265       for(int i = 0; i < consumed.length; i++) {
266          required = db.requiredItems(i);
267          datarec = records[i].subtract(db.getOwner(),i,required);
268          Assert.notNull(datarec);
269          required = required - datarec.nAvailable();
270          Core.DEBUG(2,"Share consumedb of " + owner + " at " + i +
271                                " require " + required);
272          for(int j = 0; required > 0 && j < data[i].size(); j++ ) {
273             ch = (PreconditionChain)data[i].elementAt(j);
274             if ( ch.amount <= required ) {
275                // remove ch from data[i]
276                data[i].removeElementAt(j--);
277                required = required - ch.amount;
278                // now add ch to db at position i
279             }
280             else {
281                ch.amount = ch.amount - required;
282                // create new ch for db at position i
283                ch = new PreconditionChain( ch );
284                ch.amount = required;
285                required = 0;
286                // now add ch to db at position i
287             }
288             // now adding ch to db at position i
289             db.add(i,ch);
290          }
291       }
292    }
293    
294    
295    public synchronized Hashtable getAllChildren() {
296     System.out.println("getAllChildren is called"); 
297       Hashtable output = new Hashtable();
298       PreconditionChain ch;
299       Fact f1;
300       for(int i = 0; i < data.length; i++ ) {
301          for(int j = 0; data[i] != null && j < data[i].size(); j++ ) {
302             ch = (PreconditionChain)data[i].elementAt(j);
303             f1 = new Fact(records[i].getFact());
304             f1.setNumber(ch.amount);
305             if ( ch.isExternal() ) 
306                output.put(f1,ch.key);
307             else
308                output.put(f1,ch.record);
309          }
310       }
311       return output;
312    }
313    
314    
315    public synchronized Vector currentSubgoals() {
316       Vector output = new Vector();
317       PreconditionChain ch;
318       StringTokenizer st;
319       for(int i = 0; i < data.length; i++ ) {
320          for(int j = 0; data[i] != null && j < data[i].size(); j++ ) {
321             ch = (PreconditionChain)data[i].elementAt(j);
322             if ( ch.isExternal() ) {
323                st = new StringTokenizer(ch.key,"/");
324                output.addElement(st.nextToken());
325             }
326             else
327                output.addElement(ch.record.getGoal().getId());
328          }
329       }
330       return output;
331    }
332    
333    
334    public synchronized Vector allSubgoals() {
335       Vector output = currentSubgoals();
336       all_subgoals = Misc.union(all_subgoals,output);
337       return all_subgoals;
338    }
339    
340    
341    public synchronized PlanRecord[] getChildren() {
342       Vector output = new Vector();
343       PreconditionChain ch;
344       for(int i = 0; i < data.length; i++ ) {
345          for(int j = 0; data[i] != null && j < data[i].size(); j++ ) {
346             ch = (PreconditionChain)data[i].elementAt(j);
347             if ( !ch.isExternal() && !output.contains(ch.record) )
348                output.addElement(ch.record);
349          }
350       }
351       PlanRecord[] result = new PlanRecord[output.size()];
352       for(int i = 0; i < result.length; i++)
353          result[i] = (PlanRecord)output.elementAt(i);
354       output = null;
355       return result;
356    }
357    
358    
359    public synchronized boolean update(PlanRecord image, PlanRecord record) {
360       PreconditionChain ch;
361       for(int i = 0; i < data.length; i++ ) {
362          for(int j = 0; data[i] != null && j < data[i].size(); j++ ) {
363             ch = (PreconditionChain)data[i].elementAt(j);
364             if ( !ch.isExternal() && ch.record == record ) {
365                ch.record = image;
366                return true;
367             }
368          }
369       }
370       return false;
371    }
372    
373    
374    public synchronized boolean update(String image, String key) {
375       PreconditionChain ch;
376       for(int i = 0; i < data.length; i++ ) {
377          for(int j = 0; data[i] != null && j < data[i].size(); j++ ) {
378             ch = (PreconditionChain)data[i].elementAt(j);
379             if ( ch.isExternal() && ch.key.equals(key) ) {
380                ch.key = image;
381                return true;
382             }
383          }
384       }
385       return false;
386    }
387    
388    
389    public synchronized void releaseResources(SuppliedDb given) {
390       if ( resources_consumed ) return;
391       if ( resources_released ) return;
392 
393       ResourceDb db = owner.getAgentContext().ResourceDb();
394       for(int i = 0; i < records.length; i++ )
395          db.free(records[i]);
396 
397       PreconditionChain ch;
398       Engine engine = owner.getAgentContext().Engine();
399       for(int i = 0; i < data.length; i++ ) {
400          for(int j = 0; data[i] != null && j < data[i].size(); j++ ) {
401             ch = (PreconditionChain)data[i].elementAt(j);
402             if ( ch.isExternal() ) {
403                if ( given == null || !given.cancelReservation(ch.key) )
404                   engine.getAuditTable().cancel(ch.key);
405             }
406             else
407                ch.record.breakEffectChain(ch.position,owner,i,ch.amount);
408          }
409       }
410 
411       resources_released = true;
412    }
413    
414    
415    public synchronized Fact remove(String goal_id) {
416       for(int i = 0; i < data.length; i++ ) {
417          for(int j = 0; data[i] != null && j < data[i].size(); j++ ) {
418             PreconditionChain ch = (PreconditionChain)data[i].elementAt(j);
419             if ( ch.isExternal() && goal_id.equals(ch.key) ) {
420                data[i].removeElementAt(j--);
421                Fact f1 = new Fact(records[i].getFact());
422                f1.setNumber(ch.amount);
423                return f1;
424             }
425          }
426       }
427       Assert.notNull(null); // sh. never get here
428       return null;
429    }
430    
431    
432    public synchronized Fact remove(int precond_position, PlanRecord child,
433                                    int effect_position, int amount) {
434       PreconditionChain ch;
435       for(int j = 0; j < data[precond_position].size(); j++ ) {
436          ch = (PreconditionChain)data[precond_position].elementAt(j);
437          if ( ch.record == child && ch.position == effect_position
438               && ch.amount == amount ) {
439             data[precond_position].removeElementAt(j--);
440             Fact f1 = new Fact(records[precond_position].getFact());
441             f1.setNumber(ch.amount);
442             return f1;
443          }
444       }
445       Assert.notNull(null);
446       return null;
447    }
448    
449    
450    public String toString() {
451       String out = "ConsumedDb(" + "\n" + owner + "\n";
452       for(int i = 0; i < data.length; i++ ) {
453          if ( data[i] != null )
454             out += "data[" + i + "]: " + data[i] + "\n";
455       }
456       out += ")";
457       return out;
458    }
459 }