KickJava   Java API By Example, From Geeks To Geeks.

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


1 /******************************************************************
2  * File: LPBackwardRuleInfGraph.java
3  * Created by: Dave Reynolds
4  * Created on: 21-Jul-2003
5  *
6  * (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
7  * [See end of file]
8  * $Id: LPBackwardRuleInfGraph.java,v 1.7 2005/02/21 12:17:00 andy_seaborne Exp $
9  *****************************************************************/

10 package com.hp.hpl.jena.reasoner.rulesys;
11
12 import com.hp.hpl.jena.mem.GraphMem;
13 import com.hp.hpl.jena.reasoner.rulesys.impl.*;
14 import com.hp.hpl.jena.reasoner.*;
15 import com.hp.hpl.jena.graph.*;
16 import java.util.*;
17
18 import com.hp.hpl.jena.util.OneToManyMap;
19 import com.hp.hpl.jena.util.iterator.*;
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 /**
24  * Inference graph for accessing the LP version of the backward chaining
25  * rule engine.
26  *
27  * @author <a HREF="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
28  * @version $Revision: 1.7 $ on $Date: 2005/02/21 12:17:00 $
29  */

30 public class LPBackwardRuleInfGraph extends BaseInfGraph implements BackwardRuleInfGraphI {
31
32 // =======================================================================
33
// variables
34

35     /** The LP rule engine controller which handles the processing for this graph */
36     protected LPBRuleEngine engine;
37     
38     /** Table of derivation records, maps from triple to RuleDerivation */
39     protected OneToManyMap derivations;
40     
41     /** An optional graph of separate schema assertions that should also be processed */
42     protected FGraph fschema;
43     
44     /** Cache of deductions made from the rules */
45     protected FGraph fdeductions;
46      
47     /** A finder that searches across the data, schema and axioms */
48     protected Finder dataFind;
49     
50     /** Cache of temporary property values inferred through getTemp calls */
51     protected TempNodeCache tempNodecache;
52         
53     static Log logger = LogFactory.getLog(LPBackwardRuleInfGraph.class);
54     
55 // =======================================================================
56
// Core methods
57

58     /**
59      * Constructor. Create a new backward inference graph to process
60      * the given data. The parent reasoner supplies the ruleset and
61      * any additional schema graph.
62      *
63      * @param reasoner the parent reasoner
64      * @param ruleStore the indexed set of rules to use
65      * @param data the data graph to be processed
66      * @param schema optional precached schema (use null if not required)
67      */

68     public LPBackwardRuleInfGraph(Reasoner reasoner, LPRuleStore ruleStore, Graph data, Graph schema) {
69         super(data, reasoner);
70         if (schema != null) {
71             fschema = new FGraph(schema);
72         }
73         engine = new LPBRuleEngine(this, ruleStore);
74         tempNodecache = new TempNodeCache(this);
75     }
76
77     /**
78      * Return the schema graph, if any, bound into this inference graph.
79      */

80     public Graph getSchemaGraph() {
81         return fschema.getGraph();
82     }
83     
84     /**
85      * Perform any initial processing and caching. This call is optional. Most
86      * engines either have negligable set up work or will perform an implicit
87      * "prepare" if necessary. The call is provided for those occasions where
88      * substantial preparation work is possible (e.g. running a forward chaining
89      * rule system) and where an application might wish greater control over when
90      * this prepration is done.
91      */

92     public void prepare() {
93         if (!isPrepared) {
94             fdeductions = new FGraph( new GraphMem() );
95             extractAxioms();
96             dataFind = fdata;
97             if (fdeductions != null) {
98                 dataFind = FinderUtil.cascade(dataFind, fdeductions);
99             }
100             if (fschema != null) {
101                 dataFind = FinderUtil.cascade(dataFind, fschema);
102             }
103         }
104         
105         isPrepared = true;
106     }
107
108     /**
109      * Replace the underlying data graph for this inference graph and start any
110      * inferences over again. This is primarily using in setting up ontology imports
111      * processing to allow an imports multiunion graph to be inserted between the
112      * inference graph and the raw data, before processing.
113      * @param data the new raw data graph
114      */

115     public synchronized void rebind(Graph data) {
116         engine.checkSafeToUpdate();
117         fdata = new FGraph(data);
118         isPrepared = false;
119     }
120     
121     /**
122      * Cause the inference graph to reconsult the underlying graph to take
123      * into account changes. Normally changes are made through the InfGraph's add and
124      * remove calls are will be handled appropriately. However, in some cases changes
125      * are made "behind the InfGraph's back" and this forces a full reconsult of
126      * the changed data.
127      */

128     public synchronized void rebind() {
129         engine.checkSafeToUpdate();
130         isPrepared = false;
131     }
132
133     /**
134      * Flush out all cached results. Future queries have to start from scratch.
135      */

136     public synchronized void reset() {
137         engine.checkSafeToUpdate();
138         engine.reset();
139     }
140
141     /**
142      * Extended find interface used in situations where the implementator
143      * may or may not be able to answer the complete query. It will
144      * attempt to answer the pattern but if its answers are not known
145      * to be complete then it will also pass the request on to the nested
146      * Finder to append more results.
147      * @param pattern a TriplePattern to be matched against the data
148      * @param continuation either a Finder or a normal Graph which
149      * will be asked for additional match results if the implementor
150      * may not have completely satisfied the query.
151      */

152     public synchronized ExtendedIterator findWithContinuation(TriplePattern pattern, Finder continuation) {
153         checkOpen();
154         if (!isPrepared) prepare();
155         ExtendedIterator result = engine.find(pattern);
156         if (continuation != null) {
157             result = result.andThen(continuation.find(pattern));
158         }
159         return result.filterDrop(Functor.acceptFilter);
160     }
161    
162     /**
163      * Returns an iterator over Triples.
164      * This implementation assumes that the underlying findWithContinuation
165      * will have also consulted the raw data.
166      */

167     public ExtendedIterator graphBaseFind(Node subject, Node property, Node object) {
168         return findWithContinuation(new TriplePattern(subject, property, object), null);
169     }
170
171     /**
172      * Basic pattern lookup interface.
173      * This implementation assumes that the underlying findWithContinuation
174      * will have also consulted the raw data.
175      * @param pattern a TriplePattern to be matched against the data
176      * @return a ExtendedIterator over all Triples in the data set
177      * that match the pattern
178      */

179     public ExtendedIterator find(TriplePattern pattern) {
180         return findWithContinuation(pattern, null);
181     }
182         
183     /**
184      * Add one triple to the data graph, run any rules triggered by
185      * the new data item, recursively adding any generated triples.
186      */

187     public synchronized void performAdd(Triple t) {
188         engine.checkSafeToUpdate();
189         fdata.getGraph().add(t);
190         isPrepared = false;
191     }
192      
193     /**
194      * Removes the triple t (if possible) from the set belonging to this graph.
195      */

196     public synchronized void performDelete(Triple t) {
197         engine.checkSafeToUpdate();
198         fdata.getGraph().delete(t);
199         isPrepared = false;
200     }
201        
202     /**
203      * Set a predicate to be tabled/memoized by the LP engine.
204      */

205     public void setTabled(Node predicate) {
206         engine.tablePredicate(predicate);
207         if (isTraceOn()) {
208             logger.info("LP TABLE " + predicate);
209         }
210     }
211     
212 // =======================================================================
213
// support for proof traces
214

215     /**
216      * Set to true to enable derivation caching
217      */

218     public void setDerivationLogging(boolean recordDerivations) {
219         engine.setDerivationLogging(recordDerivations);
220         if (recordDerivations) {
221             derivations = new OneToManyMap();
222         } else {
223             derivations = null;
224         }
225     }
226     
227     /**
228      * Return the derivation of at triple.
229      * The derivation is a List of DerivationRecords
230      */

231     public Iterator getDerivation(Triple t) {
232         if (derivations == null) {
233             return new NullIterator();
234         } else {
235             return derivations.getAll(t);
236         }
237     }
238        
239     /**
240      * Set the state of the trace flag. If set to true then rule firings
241      * are logged out to the Log at "INFO" level.
242      */

243     public void setTraceOn(boolean state) {
244         engine.setTraceOn(state);
245     }
246     
247     /**
248      * Return true if tracing is switched on
249      */

250     public boolean isTraceOn() {
251         return engine.isTraceOn();
252     }
253         
254 // =======================================================================
255
// Interface between infGraph and the goal processing machinery
256

257     /**
258      * Log a dervivation record against the given triple.
259      */

260     public void logDerivation(Triple t, Object JavaDoc derivation) {
261         derivations.put(t, derivation);
262     }
263
264     /**
265      * Match a pattern just against the stored data (raw data, schema,
266      * axioms) but no derivation.
267      */

268     public ExtendedIterator findDataMatches(TriplePattern pattern) {
269         return dataFind.find(pattern);
270     }
271             
272     /**
273      * Process a call to a builtin predicate
274      * @param clause the Functor representing the call
275      * @param env the BindingEnvironment for this call
276      * @param rule the rule which is invoking this call
277      * @return true if the predicate succeeds
278      */

279     public boolean processBuiltin(ClauseEntry clause, Rule rule, BindingEnvironment env) {
280         throw new ReasonerException("Internal error in FBLP rule engine, incorrect invocation of building in rule " + rule);
281     }
282     
283     /**
284      * Assert a new triple in the deduction graph, bypassing any processing machinery.
285      */

286     public void silentAdd(Triple t) {
287         fdeductions.getGraph().add(t);
288     }
289
290     /**
291      * Retrieve or create a bNode representing an inferred property value.
292      * @param instance the base instance node to which the property applies
293      * @param prop the property node whose value is being inferred
294      * @param pclass the (optional, can be null) class for the inferred value.
295      * @return the bNode representing the property value
296      */

297     public Node getTemp(Node instance, Node prop, Node pclass) {
298         return tempNodecache.getTemp(instance, prop, pclass);
299     }
300     
301 // =======================================================================
302
// Rule engine extras
303

304     /**
305      * Find any axioms (rules with no body) in the rule set and
306      * add those to the auxilliary graph to be included in searches.
307      */

308     protected void extractAxioms() {
309         Graph axioms = fdeductions.getGraph();
310         BBRuleContext contextForBuiltins = null;
311         for (Iterator i = engine.getRuleStore().getAllRules().iterator(); i.hasNext(); ) {
312             Rule rule = (Rule)i.next();
313             if (rule.bodyLength() == 0) {
314                 // An axiom
315
for (int j = 0; j < rule.headLength(); j++) {
316                     ClauseEntry axiom = rule.getHeadElement(j);
317                     if (axiom instanceof TriplePattern) {
318                         axioms.add(((TriplePattern)axiom).asTriple());
319                     } else if (axiom instanceof Functor) {
320                         if (contextForBuiltins == null) {
321                             contextForBuiltins = new BBRuleContext(this);
322                         }
323                         Functor f = (Functor)axiom;
324                         Builtin implementation = f.getImplementor();
325                         if (implementation == null) {
326                             throw new ReasonerException("Attempted to invoke undefined functor: " + f);
327                         }
328                         Node[] args = f.getArgs();
329                         contextForBuiltins.setEnv(new BindingVector(args));
330                         contextForBuiltins.setRule(rule);
331                         implementation.headAction(args, args.length, contextForBuiltins);
332                     }
333                 }
334             }
335         }
336     }
337
338 }
339
340
341
342 /*
343     (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
344     All rights reserved.
345
346     Redistribution and use in source and binary forms, with or without
347     modification, are permitted provided that the following conditions
348     are met:
349
350     1. Redistributions of source code must retain the above copyright
351        notice, this list of conditions and the following disclaimer.
352
353     2. Redistributions in binary form must reproduce the above copyright
354        notice, this list of conditions and the following disclaimer in the
355        documentation and/or other materials provided with the distribution.
356
357     3. The name of the author may not be used to endorse or promote products
358        derived from this software without specific prior written permission.
359
360     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
361     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
362     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
363     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
364     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
365     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
366     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
367     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
368     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
369     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
370 */
Popular Tags