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  package zeus.concepts.fn;
26  
27  import java.util.*;
28  import zeus.util.*;
29  import zeus.concepts.*;
30  
31  public class MethodCallFn extends ValueFunction {
32     protected Object[] args = new Object[3];
33  
34     public MethodCallFn(String lhs, Vector rhs) {
35        super(METH,3);
36  
37        int index = lhs.lastIndexOf(Fact.A_CHR);
38        String method = lhs.substring(index+1);
39        String object = lhs.substring(0,index);
40  
41        if ( object.indexOf(Fact.A_CHR) != -1 ) 
42           args[0] = new FieldFn(object);
43        else if ( object.charAt(0) == Fact.V_CHR )
44           args[0] = new VarFn(object);
45        else
46           args[0] = new TypeFn(object);
47  
48        args[1] = method;
49        args[2] = rhs;
50     }
51  
52     protected MethodCallFn(ValueFunction arg0, String arg1, Vector arg2) {
53        super(METH,3);
54        args[0] = arg0;
55        args[1] = arg1;
56        args[2] = arg2;
57     }
58  
59     public ValueFunction mirror() {
60        Vector List = (Vector)args[2];
61        Vector otherList = new Vector();
62        ValueFunction fn;
63        for(int i = 0; i < List.size(); i++ ) {
64           fn = (ValueFunction)List.elementAt(i);
65           fn = fn.mirror();
66           otherList.addElement(fn);
67        }
68        return new MethodCallFn(((ValueFunction)args[0]).mirror(),
69                                (String)args[1],otherList);
70     }
71  
72     public String toString() {
73        String s = args[0].toString() + Fact.A_STR + args[1] + "(";
74        Vector List = (Vector)args[2];
75        ValueFunction fn;
76        for(int i = 0; i < List.size(); i++ ) {
77           fn = (ValueFunction)List.elementAt(i);
78           s += fn;
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        return new MethodCallFn(((ValueFunction)args[0]).simplify(),
96                                (String)args[1],otherList);
97     }
98     Object getArg(int position) {
99        return args[position];
100    }
101    public boolean references(ValueFunction var) {
102       if ( ((ValueFunction)args[0]).references(var) ) return true;
103  
104       Vector List = (Vector)args[2];
105       ValueFunction fn;
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       Vector firstList = ((ValueFunction)args[0]).variables();
115 
116       Vector List = (Vector)args[2];
117       Vector otherList = new Vector();
118       ValueFunction fn;
119       for(int i = 0; i < List.size(); i++ ) {
120          fn = (ValueFunction)List.elementAt(i);
121          otherList = Misc.union(otherList,fn.variables());
122       }
123       return Misc.union(firstList,otherList);
124    }
125    public boolean isDeterminate() {
126       if ( !((ValueFunction)args[0]).isDeterminate() ) return false;
127 
128       Vector List = (Vector)args[2];
129       ValueFunction fn;
130       for(int i = 0; i < List.size(); i++ ) {
131          fn = (ValueFunction)List.elementAt(i);
132          if ( !fn.isDeterminate() ) return false;
133       }
134       return true;
135    }
136    ValueFunction normalize() {
137       Vector List = (Vector)args[2];
138       Vector otherList = new Vector();
139       ValueFunction fn;
140       for(int i = 0; i < List.size(); i++ ) {
141          fn = (ValueFunction)List.elementAt(i);
142          fn = fn.normalize();
143          otherList.addElement(fn);
144       }
145       return new MethodCallFn(((ValueFunction)args[0]).normalize(),
146                               (String)args[1],otherList);
147    }
148    public ValueFunction resolve(ResolutionContext c, Bindings b) {
149       Vector List = (Vector)args[2];
150       Vector otherList = new Vector();
151       ValueFunction fn;
152       for(int i = 0; i < List.size(); i++ ) {
153          fn = (ValueFunction)List.elementAt(i);
154          fn = fn.resolve(c,b);
155          otherList.addElement(fn);
156       }
157       MethodCallFn m =  new MethodCallFn(((ValueFunction)args[0]).resolve(c,b),
158                                          (String)args[1],otherList);
159       return m.evaluationFn();
160    }
161 
162    public ValueFunction evaluationFn() {
163       if ( !args[1].equals("isDeterminate") && !isDeterminate() ) return this;
164 
165       return ((ValueFunction)args[0]).invokeMethod(
166                 (String)args[1],(Vector)args[2]);
167    }
168 
169    public ValueFunction duplicate(DuplicationTable table) {
170       Vector List = (Vector)args[2];
171       Vector otherList = new Vector();
172       ValueFunction fn;
173       for(int i = 0; i < List.size(); i++ ) {
174          fn = (ValueFunction)List.elementAt(i);
175          fn = fn.duplicate(table);
176          otherList.addElement(fn);
177       }
178       return new MethodCallFn(((ValueFunction)args[0]).duplicate(table),
179                               (String)args[1],otherList);
180    }
181    public boolean equals(Object any) {
182       if ( !(any instanceof MethodCallFn) ) return false;
183       MethodCallFn fn = (MethodCallFn)any;
184 
185       ValueFunction a = this.simplify();
186       ValueFunction b = fn.simplify();
187       return a.getArg(0).equals(b.getArg(0)) &&
188              a.getArg(1).equals(b.getArg(1)) &&
189              Misc.sameVector((Vector)a.getArg(2),(Vector)b.getArg(2));
190    }
191    ValueFunction unify(ValueFunction fn, Bindings b)  {
192       ValueFunction x = null;
193       if ( (x = evaluationFn()) == this )
194          return new AndFn(this,fn);
195       else
196          return x.unifiesWith(fn,b);
197    }
198 }