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 AndFn extends ValueFunction {
31     protected ValueFunction[] args = new ValueFunction[2];
32  
33     public AndFn(ValueFunction lhsArg, ValueFunction rhsArg) {
34        super(AND,5);
35        args[0] = lhsArg;
36        args[1] = rhsArg;
37     }
38     public String toString() {
39        String out = "(" + args[0] + "&" + args[1] + ")";
40        return out;
41     }
42     ValueFunction simplify() {
43        Hashtable cache = new Hashtable();
44        Vector data = new Vector();
45        this.expand(data,cache);
46        Misc.sort(data);
47        return concatenate(data,cache);
48     }
49     protected ValueFunction concatenate(Vector data, Hashtable cache) {
50        return concatenate(data,0,cache);
51     }
52     protected ValueFunction concatenate(Vector data, int i, Hashtable cache) {
53        if ( i + 1 == data.size() )
54           return (ValueFunction)cache.get(data.elementAt(i));
55        else if ( i + 2 == data.size() )
56           return new AndFn((ValueFunction)cache.get(data.elementAt(i)),
57                            (ValueFunction)cache.get(data.elementAt(i+1)));
58        else
59           return new AndFn((ValueFunction)cache.get(data.elementAt(i)),
60                            concatenate(data,i+1,cache));
61     }
62     void expand(Vector data) {
63        Hashtable cache = new Hashtable();
64        expand(data,cache);
65     }
66     protected void expand(Vector data, Hashtable cache) {
67        for( int i = 0; i < args.length; i++ ) {
68           if ( args[i].getID() == AND )
69              ((AndFn)args[i]).expand(data,cache);
70           else {
71              ValueFunction fn = args[i].simplify();
72              String s = fn.toString();
73              if ( !data.contains(s) ) {
74                 data.addElement(s);
75                 cache.put(s,fn);
76              }
77           }
78        }
79     }
80     boolean subsumes(AndFn fn) {
81        Vector superset = new Vector();
82        Vector subset = new Vector();
83        this.expand(superset);
84        fn.expand(subset);
85        return Misc.isSubset(subset,superset);
86     }
87     Object getArg(int position) {
88        return args[position];
89     }
90     public boolean isDeterminate() {
91        return args[0].isDeterminate() && args[1].isDeterminate();
92     }
93     ValueFunction normalize() {
94        return new AndFn(args[0].normalize(),args[1].normalize());
95     }
96     public boolean references(ValueFunction var) {
97        return args[0].references(var) || args[1].references(var);
98     }
99     public Vector variables() {
100       return Misc.union(args[0].variables(),args[1].variables());
101    }
102    public ValueFunction mirror() {
103       return new AndFn(args[0].mirror(),args[1].mirror());
104    }
105    public ValueFunction resolve(ResolutionContext c, Bindings b) {
106       ValueFunction x = args[0].resolve(c,b);
107       ValueFunction y = args[1].resolve(c,b);
108       return x.equals(y) ? x : new AndFn(x,y);
109    }
110    public ValueFunction duplicate(DuplicationTable table) {
111       return new AndFn(args[0].duplicate(table),args[1].duplicate(table));
112    }
113    public boolean equals(Object any) {
114       if ( !(any instanceof AndFn) ) return false;
115       AndFn fn = (AndFn)any;
116 
117       ValueFunction a = this.simplify();
118       ValueFunction b = fn.simplify();
119       return ((ValueFunction)a.getArg(0)).equals((ValueFunction)b.getArg(0)) &&
120              ((ValueFunction)a.getArg(1)).equals((ValueFunction)b.getArg(1));
121    }
122    ValueFunction unify(ValueFunction fn, Bindings b) {
123       ValueFunction x = null, y = null;
124 
125       if ( fn instanceof AndFn &&
126            ((AndFn)fn).subsumes(this) ) return fn;
127 
128       if ( (x = args[0].unifiesWith(fn,b)) != null &&
129            (y = args[1].unifiesWith(fn,b)) != null ) {
130          if ( x.equals(y) ) return x;
131          else               return new AndFn(x,y);
132       }
133       return null;
134    }
135 
136    public int baseID() {
137       // must be called when Fn is known to be determinate
138       int x = args[0].baseID();
139       int y = args[1].baseID();
140       // perform type checking
141       if ( x != y )
142          throw new IllegalArgumentException("Incompatible types in " + this);
143       return x;
144    }
145 }