1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
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);
162 return -1;
163 }
164
165
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
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]);
187 return;
188 }
189 }
190 Assert.notNull(null);
191 }
192
193
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
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);
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);
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
276 data[i].removeElementAt(j--);
277 required = required - ch.amount;
278
279 }
280 else {
281 ch.amount = ch.amount - required;
282
283 ch = new PreconditionChain( ch );
284 ch.amount = required;
285 required = 0;
286
287 }
288
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);
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 }