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.fn;
25  
26  import java.util.*;
27  import zeus.util.*;
28  import zeus.concepts.*;
29  
30  public class ConstraintBFn extends ValueFunction {
31     static final int NONVAR = 0;
32     static final int VAR    = 3;
33  
34     static final String[] FUNCTIONS = {
35        "nonvar", "0", "false",
36        "var"   , "0", "false"
37     };
38  
39     protected Object[] args = new Object[3];
40     protected int position = -1;
41  
42     public ConstraintBFn(ValueFunction fn, String lhs, Vector rhs) {
43        super(CONSB,0);
44        args[0] = fn;
45        args[1] = lhs;
46        args[2] = rhs;
47  
48        if ( (position = Misc.whichPosition(lhs,FUNCTIONS)) == -1 ||
49             ((position % 3) != 0) ) {
50           throw new IllegalArgumentException("Unknown operator " + lhs +
51              " in constraint expression.");
52        }
53  
54        int arity = Integer.parseInt(FUNCTIONS[position+1]);
55        if ( rhs == null || rhs.size() != arity ) {
56           throw new IllegalArgumentException(
57              "Wrong number of arguments used in constraint expression " +
58              lhs + "/" + arity + ".");
59        }
60     }
61     public ValueFunction mirror() {
62        Vector List = (Vector)args[2];
63        Vector otherList = new Vector();
64        ValueFunction fn;
65        for(int i = 0; i < List.size(); i++ ) {
66           fn = (ValueFunction)List.elementAt(i);
67           fn = fn.mirror();
68           otherList.addElement(fn);
69        }
70        fn = ((ValueFunction)args[0]).mirror();
71        return new ConstraintBFn(fn,(String)args[1],otherList);
72     }
73  
74     public String toString() {
75        String s = args[0].toString() + "::" + (String)args[1] + "(";
76        Vector List = (Vector)args[2];
77        for(int i = 0; i < List.size(); i++ ) {
78           s += List.elementAt(i);
79           if ( i + 1 < List.size() )
80              s += ",";
81        }
82        s += ")";
83        return s;
84     }
85  
86     ValueFunction simplify() {
87        Vector List = (Vector)args[2];
88        Vector otherList = new Vector();
89        ValueFunction fn;
90        for(int i = 0; i < List.size(); i++ ) {
91           fn = (ValueFunction)List.elementAt(i);
92           fn = fn.simplify();
93           otherList.addElement(fn);
94        }
95        fn = ((ValueFunction)args[0]).simplify();
96        return new ConstraintBFn(fn,(String)args[1],otherList);
97     }
98     Object getArg(int position) {
99        return args[position];
100    }
101    public boolean references(ValueFunction var) {
102       ValueFunction fn = (ValueFunction)args[0];
103       if ( fn.references(var) ) return true;
104 
105       Vector List = (Vector)args[2];
106       for(int i = 0; i < List.size(); i++ ) {
107          fn = (ValueFunction)List.elementAt(i);
108          if ( fn.references(var) )
109             return true;
110       }
111       return false;
112    }
113    public Vector variables() {
114       ValueFunction fn = (ValueFunction)args[0];
115       Vector otherList = fn.variables();
116 
117       Vector List = (Vector)args[2];
118       for(int i = 0; i < List.size(); i++ ) {
119          fn = (ValueFunction)List.elementAt(i);
120          otherList = Misc.union(otherList,fn.variables());
121       }
122       return otherList;
123    }
124    public boolean isDeterminate() {
125       ValueFunction fn = (ValueFunction)args[0];
126       if ( !fn.isDeterminate() ) return false;
127 
128       Vector List = (Vector)args[2];
129       for(int i = 0; i < List.size(); i++ ) {
130          fn = (ValueFunction)List.elementAt(i);
131          if ( !fn.isDeterminate() ) return false;
132       }
133       return true;
134    }
135    ValueFunction normalize() {
136       Vector List = (Vector)args[2];
137       Vector otherList = new Vector();
138       ValueFunction fn;
139       for(int i = 0; i < List.size(); i++ ) {
140          fn = (ValueFunction)List.elementAt(i);
141          fn = fn.normalize();
142          otherList.addElement(fn);
143       }
144       fn = ((ValueFunction)args[0]).normalize();
145       return new ConstraintBFn(fn,(String)args[1],otherList);
146    }
147    public ValueFunction resolve(ResolutionContext c, Bindings b) {
148       ValueFunction a = ((ValueFunction)args[0]).resolve(c,b);
149 
150       Vector List = (Vector)args[2];
151       Vector otherList = new Vector();
152       ValueFunction fn;
153       for(int i = 0; i < List.size(); i++ ) {
154          fn = (ValueFunction)List.elementAt(i);
155          fn = fn.resolve(c,b);
156          otherList.addElement(fn);
157       }
158       return (new ConstraintBFn(a,(String)args[1],otherList)).evaluationFn();
159    }
160 
161    protected final boolean onlyEvaluateIfDeterminate() {
162       return (Boolean.valueOf(FUNCTIONS[position+2])).booleanValue();
163    }
164 
165    ValueFunction unify(ValueFunction fn, Bindings b) {
166       if ( onlyEvaluateIfDeterminate() &&
167            (!isDeterminate() || !fn.isDeterminate()) )
168          return new AndFn(this,fn);
169 
170       switch(position) {
171          case NONVAR:
172               if ( !fn.isDeterminate() ) return null;
173               break;
174 
175          case VAR:
176               if ( fn.isDeterminate() ) return null;
177               break;
178 
179          default:
180               throw new IllegalArgumentException(
181                  "Unknown operator in: \'" + this + "\'");
182       }
183 
184       ValueFunction x = (ValueFunction)args[0];
185       return x.unifiesWith(fn,b);
186    }
187    public ValueFunction duplicate(DuplicationTable table) {
188       ValueFunction a = ((ValueFunction)args[0]).duplicate(table);
189 
190       Vector List = (Vector)args[2];
191       Vector otherList = new Vector();
192       ValueFunction fn;
193       for(int i = 0; i < List.size(); i++ ) {
194          fn = (ValueFunction)List.elementAt(i);
195          fn = fn.duplicate(table);
196          otherList.addElement(fn);
197       }
198       return new ConstraintBFn(a,(String)args[1],otherList);
199    }
200    public boolean equals(Object any) {
201       if ( !(any instanceof ConstraintBFn) ) return false;
202       ConstraintBFn fn = (ConstraintBFn)any;
203 
204       ValueFunction a = this.simplify();
205       ValueFunction b = fn.simplify();
206       return a.getArg(0).equals(b.getArg(0)) &&
207              a.getArg(1).equals(b.getArg(1)) &&
208              Misc.sameVector((Vector)a.getArg(2),(Vector)b.getArg(2));
209 
210    }
211 }