KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > reasoner > rulesys > Functor


1 /******************************************************************
2  * File: Functor.java
3  * Created by: Dave Reynolds
4  * Created on: 29-Mar-03
5  *
6  * (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
7  * [See end of file]
8  * $Id: Functor.java,v 1.20 2005/02/27 14:08:53 der Exp $
9  *****************************************************************/

10 package com.hp.hpl.jena.reasoner.rulesys;
11
12 import com.hp.hpl.jena.graph.*;
13 import com.hp.hpl.jena.util.PrintUtil;
14 import com.hp.hpl.jena.util.iterator.Filter;
15 import com.hp.hpl.jena.datatypes.*;
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18
19 import java.util.*;
20
21 /**
22  * A functor comprises a functor name and a list of
23  * arguments. The arguments are Nodes of any type except functor nodes
24  * (there is no functor nesting). Functors play three roles in rules -
25  * in heads they represent actions (procedural attachement); in bodies they
26  * represent builtin predicates; in TriplePatterns they represent embedded
27  * structured literals that are used to cache matched subgraphs such as
28  * restriction specifications.
29  *
30  * @author <a HREF="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
31  * @version $Revision: 1.20 $ on $Date: 2005/02/27 14:08:53 $
32  */

33 public class Functor implements ClauseEntry {
34     /** Functor's name */
35     protected String JavaDoc name;
36     
37     /** Argument list - an array of nodes */
38     protected Node[] args;
39     
40     /** A built in that implements the functor */
41     protected Builtin implementor;
42     
43     /** A static Filter instance that detects triples with Functor objects */
44     public static final Filter acceptFilter = new Filter() {
45                 public boolean accept(Object JavaDoc t) {
46                     if (((Triple)t).getSubject().isLiteral()) return true;
47                     Node n = ((Triple)t).getObject();
48                     return n.isLiteral() && n.getLiteral().getDatatype() == FunctorDatatype.theFunctorDatatype;
49                 }
50             };
51     
52     protected static Log logger = LogFactory.getLog(Functor.class);
53     
54     /**
55      * Constructor.
56      * @param name the name of the functor
57      * @param args a list of nodes defining the arguments
58      */

59     public Functor(String JavaDoc name, List args) {
60         this.name = name;
61         this.args = (Node[]) args.toArray(new Node[]{});
62     }
63     
64     /**
65      * Constructor.
66      * @param name the name of the functor
67      * @param args an array of nodes defining the arguments, this will not be copied so beware of
68      * accidental structure sharing
69      */

70     public Functor(String JavaDoc name, Node[] args) {
71         this.name = name;
72         this.args = args;
73     }
74     
75     /**
76      * Constructor
77      * @param name the name of the functor
78      * @param args a list of nodes defining the arguments
79      * @param registry a table of builtins to consult to check for
80      * implementations of this functor when used as a rule clause
81      */

82     public Functor(String JavaDoc name, List args, BuiltinRegistry registry) {
83         this.name = name;
84         this.args = (Node[]) args.toArray(new Node[]{});
85         this.implementor = registry.getImplementation(name);
86     }
87     
88     /**
89      * Return the functor name
90      */

91     public String JavaDoc getName() {
92         return name;
93     }
94     
95     /**
96      * Return the functor aguments as an array of nodes
97      */

98     public Node[] getArgs() {
99         return args;
100     }
101     
102     /**
103      * Return the length of the functor argument array.
104      */

105     public int getArgLength() {
106         return args.length;
107     }
108     
109     /**
110      * Returns true if the functor is fully ground, no variables
111      */

112     public boolean isGround() {
113         for (int i = 0; i < args.length; i++) {
114             Node n = args[i];
115             if (n instanceof Node_RuleVariable || n instanceof Node_ANY) {
116                 return false;
117             }
118         }
119         return true;
120     }
121     
122     /**
123      * Returns true if the functor is fully ground in the given environment
124      */

125     public boolean isGround(BindingEnvironment env) {
126         for (int i = 0; i < args.length; i++) {
127             Node n = args[i];
128             if (env.getGroundVersion(args[i]).isVariable()) return false;
129         }
130         return true;
131     }
132     
133     /**
134      * Execute the given built in as a body clause.
135      * @param context an execution context giving access to other relevant data
136      * @return true if the functor has an implementation and that implementation returns true when evaluated
137      */

138     public boolean evalAsBodyClause(RuleContext context) {
139         if (getImplementor() == null) {
140             logger.warn("Invoking undefined functor " + getName() + " in " + context.getRule().toShortString());
141             return false;
142         }
143         return implementor.bodyCall(getBoundArgs(context.getEnv()), args.length, context);
144     }
145     
146     /**
147      * Execute the given built in as a body clause, only if it is side-effect-free.
148      * @param context an execution context giving access to other relevant data
149      * @return true if the functor has an implementation and that implementation returns true when evaluated
150      */

151     public boolean safeEvalAsBodyClause(RuleContext context) {
152         if (getImplementor() == null) {
153             logger.warn("Invoking undefined functor " + getName() + " in " + context.getRule().toShortString());
154             return false;
155         }
156         if (implementor.isSafe()) {
157             return implementor.bodyCall(getBoundArgs(context.getEnv()), args.length, context);
158         } else {
159             return false;
160         }
161     }
162     
163     /**
164      * Return a new Node array containing the bound versions of this Functor's arguments
165      */

166     public Node[] getBoundArgs(BindingEnvironment env) {
167         Node[] boundargs = new Node[args.length];
168         for (int i = 0; i < args.length; i++) {
169             boundargs[i] = env.getGroundVersion(args[i]);
170         }
171         return boundargs;
172     }
173     
174     /**
175      * Return the Builtin that implements this functor
176      * @return the Builtin or null if there isn't one
177      */

178     public Builtin getImplementor() {
179         if (implementor == null) {
180             implementor = BuiltinRegistry.theRegistry.getImplementation(name);
181         }
182         return implementor;
183     }
184     
185     /**
186      * Set the Builtin that implements this functor.
187      */

188     public void setImplementor(Builtin implementor) {
189         this.implementor = implementor;
190     }
191     
192     /**
193      * Printable string describing the functor
194      */

195     public String JavaDoc toString() {
196         StringBuffer JavaDoc buff = new StringBuffer JavaDoc(name);
197         buff.append("(");
198         for (int i = 0; i < args.length; i++) {
199             buff.append(PrintUtil.print(args[i]));
200             if (i < args.length - 1) {
201                 buff.append(" ");
202             }
203         }
204         buff.append(")");
205         return buff.toString();
206     }
207
208     /**
209      * tests that a given Node represents a functor
210      */

211     public static boolean isFunctor(Node n) {
212         if (n == null) return false;
213         return n.isLiteral() && n.getLiteral().getDatatype() == FunctorDatatype.theFunctorDatatype;
214     }
215     
216     /**
217      * Equality is based on structural comparison
218      */

219     public boolean equals(Object JavaDoc obj) {
220         if (obj instanceof Functor) {
221             Functor f2 = (Functor)obj;
222             if (name.equals(f2.name) && args.length == f2.args.length) {
223                 for (int i = 0; i < args.length; i++) {
224                     if (!args[i].sameValueAs(f2.args[i])) return false;
225                 }
226                 return true;
227             }
228         }
229         return false;
230     }
231     
232     /** hash function override */
233     public int hashCode() {
234         return (name.hashCode()) ^ (args.length << 2);
235     }
236     
237     /**
238      * Compare Functors, taking into account variable indices.
239      * The equality function ignores differences between variables.
240      */

241     public boolean sameAs(Object JavaDoc o) {
242         if (o instanceof Functor) {
243             Functor f2 = (Functor)o;
244             if (name.equals(f2.name) && args.length == f2.args.length) {
245                 for (int i = 0; i < args.length; i++) {
246                     if (! Node_RuleVariable.sameNodeAs(args[i], f2.args[i])) return false;
247                 }
248                 return true;
249             }
250         }
251         return false;
252     }
253     
254     /**
255      * Create a functor and wrap it up as a Literal node
256      * @param name the name of the functor
257      * @param args an array of nodes defining the arguments, this will not be copied so beware of
258      * accidental structure sharing
259      */

260     public static Node makeFunctorNode(String JavaDoc name, Node[] args) {
261         return makeFunctorNode( new Functor( name, args ) );
262     }
263     
264     /**
265      * Wrap a functor as a Literal node
266      * @param f the functor data structure to be wrapped in a node.
267      */

268     public static Node makeFunctorNode(Functor f) {
269         return Node.createUncachedLiteral(f, null, FunctorDatatype.theFunctorDatatype);
270     }
271     
272    /**
273     * Inner class. Dummy datatype definition for
274     * functor-valued literals.
275     */

276    public static class FunctorDatatype extends BaseDatatype {
277     
278         public FunctorDatatype() {
279             super("urn:x-hp-jena:Functor");
280         }
281         
282         public static final RDFDatatype theFunctorDatatype = new FunctorDatatype();
283    }
284
285 }
286
287 /*
288     (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
289     All rights reserved.
290
291     Redistribution and use in source and binary forms, with or without
292     modification, are permitted provided that the following conditions
293     are met:
294
295     1. Redistributions of source code must retain the above copyright
296        notice, this list of conditions and the following disclaimer.
297
298     2. Redistributions in binary form must reproduce the above copyright
299        notice, this list of conditions and the following disclaimer in the
300        documentation and/or other materials provided with the distribution.
301
302     3. The name of the author may not be used to endorse or promote products
303        derived from this software without specific prior written permission.
304
305     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
306     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
307     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
308     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
309     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
310     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
311     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
312     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
313     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
314     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
315 */

316
Popular Tags