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.actors;
25  
26  import java.util.*;
27  import zeus.util.*;
28  import zeus.concepts.*;
29  
30  public class DataRec implements Observer {
31     protected int              nAvailable = 0;
32     protected Fact             fact = null;
33     protected PlanRecord       record = null;
34     protected int              position = -1;
35     protected Vector           available = new Vector();
36     protected boolean          isNegative;
37  
38  
39     // meaningless init  to allow rearch
40     public DataRec() {
41     ;
42     }
43  
44     public DataRec(Fact fact, PlanRecord record, int precond_position) {
45        Assert.notNull(fact);
46        Assert.notNull(record);
47        Assert.notFalse(precond_position >= 0);
48  
49        this.fact = fact;
50        this.record = record;
51        this.position = precond_position;
52        this.isNegative = fact.isNegative();
53     }
54  
55     public DataRec(Fact fact) {
56        Core.ERROR(fact,1,this);
57  
58        this.fact = fact;
59        this.isNegative = fact.isNegative();
60        Core.ERROR(!isNegative,2,this);
61     }
62  
63     public boolean add(ResourceItem item, int start, int num) {
64        Core.ERROR(!isNegative,3,this);
65        if ( item.reserve(this,start,!fact.isReadOnly(),num) ) {
66           available.addElement(item);
67           nAvailable += num;
68           return true;
69        }
70        return false;
71     }
72  
73     public void free() {
74        nAvailable = 0;
75        available.removeAllElements();
76     }
77  
78     public void update(Observable o, Object arg) {
79        Core.ERROR(!isNegative,4,this);
80        ResourceItem item = (ResourceItem)o;
81        String operation = (String)arg;
82        Fact f1 = item.getFact();
83        Core.DEBUG(3,"Notification in datarec from " + f1.pprint() +
84           " of " + operation);
85  
86        if ( operation.equals("deleted") ) {
87           // item has been deleted: remove item & alert
88           // record to try to reallocate for item.fact
89           int num = remove(item);
90           if ( record != null )  {
91              if ( !fact.isReadOnly() )
92                 record.updateCost(-1.0*num*f1.getUnitCost());
93              record.reallocateResource(position,num);
94           }
95           else {
96              System.err.println("Reserved item deleted - what do we do??");
97           }
98        }
99     }
100 
101    public boolean executeNow(ResourceDb db, int now) {
102       if ( isNegative ) {
103          // make sure db does not contain fact
104          return db.evalNegative(fact);
105       }
106       else {
107          ResourceItem item;
108          boolean execute_now = true;
109          for(int i = 0; execute_now && i < available.size(); i++ ) {
110             item = (ResourceItem) available.elementAt(i);
111             execute_now &= item.executeNow(this,now);
112          }
113          return execute_now;
114       }
115    }
116    public void newStartTime(int start) {
117       if ( isNegative ) {
118          return;
119       }
120       else {
121          ResourceItem item;
122          for(int i = 0; i < available.size(); i++ ) {
123             item = (ResourceItem) available.elementAt(i);
124             Assert.notFalse(item.newStartTime(this,start));
125          }
126       }
127    }
128 
129    public DataRec subtract(PlanRecord rec, int position, int required) {
130       Core.ERROR(!isNegative,5,this);
131       Core.ERROR(record,6,this);
132       DataRec datarec = rec.getDatarec(position);
133       ResourceItem item;
134       int start = rec.getStartTime();
135       int no;
136       for(int i = 0; required > 0 && i < available.size(); i++ ) {
137          item = (ResourceItem) available.elementAt(i);
138          no = item.getReservedAmount(this);
139          if ( no > required ) {
140             item.changeReservedAmount(this,no-required);
141             datarec.add(item,start,required);
142          }
143          else { // no <= required
144             item.cancelReservation(this);
145             datarec.add(item,start,no);
146             available.removeElementAt(i--);
147          }
148          nAvailable -= Math.min(no,required);
149          required -= Math.min(no,required);
150       }
151       return datarec;
152    }
153 
154    public boolean contains(ResourceItem item) {
155       Core.ERROR(!isNegative,7,this);
156       return available.contains(item);
157    }
158 
159    protected int remove(ResourceItem item) {
160       available.removeElement(item);
161       int no = item.getReservedAmount(this);
162       item.cancelReservation(this);
163       nAvailable = nAvailable - no;
164       return no;
165    }
166 
167    public int getPosition() {
168       Core.ERROR(record,8,this);
169       return position;
170    }
171    public PlanRecord getRecord() {
172       Core.ERROR(record,9,this);
173       return record;
174    }
175    public String getId() {
176       return fact.getId();
177    }
178    public Vector available() {
179       return available;
180    }
181    public int nAvailable() {
182       return isNegative ? fact.getNumber() : nAvailable;
183    }
184    public Fact getFact() {
185       return fact;
186    }
187    public double getCost() {
188       if ( isNegative )
189          return fact.getNetCost();
190       else {
191          double cost = 0;
192          ResourceItem item;
193          Fact f;
194          for(int i = 0; i < available.size(); i++ ) {
195             item = (ResourceItem)available.elementAt(i);
196             f = item.getFact();
197             cost += f.getUnitCost() * item.getReservedAmount(this);
198          }
199          return cost;
200       }
201    }
202 
203    public Fact[] getData() {
204       Fact[] out;
205       if ( isNegative ) {
206          out = new Fact[1];
207          out[0] = fact;
208       }
209       else {
210          Assert.notFalse(nAvailable > 0);
211          ResourceItem item;
212          out = new Fact[available.size()];
213          for(int i = 0; i < available.size(); i++ ) {
214            item = (ResourceItem)available.elementAt(i);
215            out[i] = new Fact( item.getFact() );
216            out[i].setNumber(item.getReservedAmount(this));
217          }
218       }
219       return out;
220    }
221 
222    public Fact mostGeneralDescriptor() {
223       if ( isNegative ) return fact;
224 
225       if ( available.isEmpty() ) return fact;
226       Fact f2;
227       Fact f1 = new Fact( ((ResourceItem)available.elementAt(0)).getFact() );
228       for(int i = 1; i < available.size(); i++) {
229          f2 = ((ResourceItem)available.elementAt(i)).getFact();
230          Assert.notFalse( f1.disjoin(f2) );
231       }
232       if ( f1.isa(OntologyDb.ENTITY) ) f1.setNumber(f1.newVar());
233       return f1;
234    }
235 }