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