KickJava   Java API By Example, From Geeks To Geeks.

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


1 /******************************************************************
2  * File: FBRuleInfGraph.java
3  * Created by: Dave Reynolds
4  * Created on: 28-May-2003
5  *
6  * (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
7  * [See end of file]
8  * $Id: FBRuleInfGraph.java,v 1.52 2005/04/08 14:20:49 der 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.rdf.model.RDFNode;
14 import com.hp.hpl.jena.rdf.model.ResourceFactory;
15 import com.hp.hpl.jena.reasoner.rulesys.impl.*;
16 import com.hp.hpl.jena.reasoner.transitiveReasoner.*;
17 import com.hp.hpl.jena.reasoner.*;
18 import com.hp.hpl.jena.shared.impl.JenaParameters;
19 import com.hp.hpl.jena.graph.*;
20
21 import java.util.*;
22
23 //import com.hp.hpl.jena.util.PrintUtil;
24
import com.hp.hpl.jena.util.OneToManyMap;
25 import com.hp.hpl.jena.util.PrintUtil;
26 import com.hp.hpl.jena.util.iterator.*;
27 import com.hp.hpl.jena.vocabulary.*;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 /**
33  * An inference graph that uses a mixture of forward and backward
34  * chaining rules. The forward rules can create direct deductions from
35  * the source data and schema and can also create backward rules. A
36  * query is answered by consulting the union of the raw data, the forward
37  * derived results and any relevant backward rules (whose answers are tabled
38  * for future reference).
39  *
40  * @author <a HREF="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
41  * @version $Revision: 1.52 $ on $Date: 2005/04/08 14:20:49 $
42  */

43 public class FBRuleInfGraph extends BasicForwardRuleInfGraph implements BackwardRuleInfGraphI, Filter {
44     
45     /** Single context for the reasoner, used when passing information to builtins */
46     protected BBRuleContext context;
47      
48     /** A finder that searches across the data, schema, axioms and forward deductions*/
49     protected Finder dataFind;
50     
51     /** The core backward rule engine which includes all the memoized results */
52     protected LPBRuleEngine bEngine;
53     
54     /** The original rule set as supplied */
55     protected List rawRules;
56     
57     /** The rule list after possible extension by preprocessing hooks */
58     protected List rules;
59     
60     /** Static switch from Basic to RETE implementation of the forward component */
61     public static boolean useRETE = true;
62
63     /** Flag, if true then subClass and subProperty lattices will be optimized using TGCs */
64     protected boolean useTGCCaching = false;
65     
66     /** Flag, if true then find results will be filtered to remove functors and illegal RDF */
67     public boolean filterFunctors = true;
68     
69     /** Optional precomputed cache of the subClass/subproperty lattices */
70     protected TransitiveEngine transitiveEngine;
71     
72     /** Optional list of preprocessing hooks to be run in sequence during preparation time */
73     protected List preprocessorHooks;
74     
75     /** Cache of temporary property values inferred through getTemp calls */
76     protected TempNodeCache tempNodecache;
77     
78     /** Table of temp nodes which should be hidden from output listings */
79     protected Set hiddenNodes;
80     
81     static Log logger = LogFactory.getLog(FBRuleInfGraph.class);
82
83 // =======================================================================
84
// Constructors
85

86     /**
87      * Constructor.
88      * @param reasoner the reasoner which created this inf graph instance
89      * @param schema the (optional) schema graph to be included
90      */

91     public FBRuleInfGraph(Reasoner reasoner, Graph schema) {
92         super(reasoner, schema);
93         constructorInit(schema);
94     }
95
96     /**
97      * Constructor.
98      * @param reasoner the reasoner which created this inf graph instance
99      * @param rules the rules to process
100      * @param schema the (optional) schema graph to be included
101      */

102     public FBRuleInfGraph(Reasoner reasoner, List rules, Graph schema) {
103         super(reasoner, rules, schema);
104         this.rawRules = rules;
105         constructorInit(schema);
106     }
107
108     /**
109      * Constructor.
110      * @param reasoner the reasoner which created this inf graph instance
111      * @param rules the rules to process
112      * @param schema the (optional) schema graph to be included
113      * @param data the data graph to be processed
114      */

115     public FBRuleInfGraph(Reasoner reasoner, List rules, Graph schema, Graph data) {
116         super(reasoner, rules, schema, data);
117         this.rawRules = rules;
118         constructorInit(schema);
119     }
120
121     /**
122      * Common pieces of initialization code which apply in all constructor cases.
123      */

124     private void constructorInit(Graph schema) {
125         initLP(schema);
126         tempNodecache = new TempNodeCache(this);
127         if (JenaParameters.enableFilteringOfHiddenInfNodes) {
128             hiddenNodes = new HashSet();
129             if (schema != null && schema instanceof FBRuleInfGraph) {
130                 hiddenNodes.addAll(((FBRuleInfGraph)schema).hiddenNodes);
131             }
132         }
133     }
134     
135     /**
136      * Instantiate the forward rule engine to use.
137      * Subclasses can override this to switch to, say, a RETE imlementation.
138      * @param rules the rule set or null if there are not rules bound in yet.
139      */

140     protected void instantiateRuleEngine(List rules) {
141         if (rules != null) {
142             if (useRETE) {
143                 engine = new RETEEngine(this, rules);
144             } else {
145                 engine = new FRuleEngine(this, rules);
146             }
147         } else {
148             if (useRETE) {
149                 engine = new RETEEngine(this);
150             } else {
151                 engine = new FRuleEngine(this);
152             }
153         }
154     }
155
156     /**
157      * Initialize the LP engine, based on an optional schema graph.
158      */

159     private void initLP(Graph schema) {
160         if (schema != null && schema instanceof FBRuleInfGraph) {
161             LPRuleStore newStore = new LPRuleStore();
162             newStore.addAll(((FBRuleInfGraph)schema).bEngine.getRuleStore());
163             bEngine = new LPBRuleEngine(this, newStore);
164         } else {
165             bEngine = new LPBRuleEngine(this);
166         }
167     }
168     
169     /**
170      * Instantiate the optional caches for the subclass/suproperty lattices.
171      * Unless this call is made the TGC caching will not be used.
172      */

173     public void setUseTGCCache() {
174         useTGCCaching = true;
175         if (schemaGraph != null) {
176             transitiveEngine = new TransitiveEngine(((FBRuleInfGraph)schemaGraph).transitiveEngine);
177         } else {
178             transitiveEngine = new TransitiveEngine(
179                 new TransitiveGraphCache(ReasonerVocabulary.directSubClassOf.asNode(), RDFS.subClassOf.asNode()),
180                 new TransitiveGraphCache(ReasonerVocabulary.directSubPropertyOf.asNode(), RDFS.subPropertyOf.asNode()));
181         }
182     }
183     
184 // =======================================================================
185
// Interface between infGraph and the goal processing machinery
186

187     
188     /**
189      * Search the combination of data and deductions graphs for the given triple pattern.
190      * This may different from the normal find operation in the base of hybrid reasoners
191      * where we are side-stepping the backward deduction step.
192      */

193     public ExtendedIterator findDataMatches(Node subject, Node predicate, Node object) {
194         return dataFind.find(new TriplePattern(subject, predicate, object));
195     }
196     
197     /**
198      * Search the combination of data and deductions graphs for the given triple pattern.
199      * This may different from the normal find operation in the base of hybrid reasoners
200      * where we are side-stepping the backward deduction step.
201      */

202     public ExtendedIterator findDataMatches(TriplePattern pattern) {
203         return dataFind.find(pattern);
204     }
205             
206     /**
207      * Process a call to a builtin predicate
208      * @param clause the Functor representing the call
209      * @param env the BindingEnvironment for this call
210      * @param rule the rule which is invoking this call
211      * @return true if the predicate succeeds
212      */

213     public boolean processBuiltin(ClauseEntry clause, Rule rule, BindingEnvironment env) {
214         throw new ReasonerException("Internal error in FBLP rule engine, incorrect invocation of building in rule " + rule);
215         // TODO: Remove
216
// if (clause instanceof Functor) {
217
// context.setEnv(env);
218
// context.setRule(rule);
219
// return((Functor)clause).evalAsBodyClause(context);
220
// } else {
221
// throw new ReasonerException("Illegal builtin predicate: " + clause + " in rule " + rule);
222
// }
223
}
224     
225     /**
226      * Adds a new Backward rule as a rusult of a forward rule process. Only some
227      * infgraphs support this.
228      */

229     public void addBRule(Rule brule) {
230         if (logger.isDebugEnabled()) {
231             logger.debug("Adding rule " + brule);
232         }
233         bEngine.addRule(brule);
234         bEngine.reset();
235     }
236        
237     /**
238      * Deletes a new Backward rule as a rules of a forward rule process. Only some
239      * infgraphs support this.
240      */

241     public void deleteBRule(Rule brule) {
242         if (logger.isDebugEnabled()) {
243             logger.debug("Deleting rule " + brule);
244         }
245         bEngine.deleteRule(brule);
246         bEngine.reset();
247     }
248     
249     /**
250      * Adds a set of new Backward rules
251      */

252     public void addBRules(List rules) {
253         for (Iterator i = rules.iterator(); i.hasNext(); ) {
254             Rule rule = (Rule)i.next();
255 // logger.debug("Adding rule " + rule);
256
bEngine.addRule(rule);
257         }
258         bEngine.reset();
259     }
260     
261     /**
262      * Return an ordered list of all registered backward rules. Includes those
263      * generated by forward productions.
264      */

265     public List getBRules() {
266         return bEngine.getAllRules();
267     }
268     
269     /**
270      * Return the originally supplied set of rules, may be a mix of forward
271      * and backward rules.
272      */

273     public List getRules() {
274         return rules;
275     }
276       
277     /**
278      * Set a predicate to be tabled/memoized by the LP engine.
279      */

280     public void setTabled(Node predicate) {
281         bEngine.tablePredicate(predicate);
282         if (traceOn) {
283             logger.info("LP TABLE " + predicate);
284         }
285     }
286     
287     /**
288      * Return a compiled representation of all the registered
289      * forward rules.
290      */

291     private Object JavaDoc getForwardRuleStore() {
292         return engine.getRuleStore();
293     }
294     
295     /**
296      * Add a new deduction to the deductions graph.
297      */

298     public void addDeduction(Triple t) {
299         getCurrentDeductionsGraph().add(t);
300         if (useTGCCaching) {
301             transitiveEngine.add(t);
302         }
303     }
304
305     /**
306      * Retrieve or create a bNode representing an inferred property value.
307      * @param instance the base instance node to which the property applies
308      * @param prop the property node whose value is being inferred
309      * @param pclass the (optional, can be null) class for the inferred value.
310      * @return the bNode representing the property value
311      */

312     public Node getTemp(Node instance, Node prop, Node pclass) {
313         return tempNodecache.getTemp(instance, prop, pclass);
314     }
315    
316 // =======================================================================
317
// Core inf graph methods
318

319     /**
320      * Add a new rule to the rule set. This should only be used by implementations
321      * of RuleProprocessHook (which are called during rule system preparation phase).
322      * If called at other times the rule won't be correctly transferred into the
323      * underlying engines.
324      */

325     public void addRuleDuringPrepare(Rule rule) {
326         if (rules == rawRules) {
327             // Ensure the original is preserved in case we need to do a restart
328
if (rawRules instanceof ArrayList) {
329                 rules = (ArrayList) ((ArrayList)rawRules).clone();
330             } else {
331                 rules = new ArrayList(rawRules);
332             }
333             // Rebuild the forward engine to use the cloned rules
334
instantiateRuleEngine(rules);
335         }
336         rules.add(rule);
337     }
338     
339     /**
340      * Add a new preprocessing hook defining an operation that
341      * should be run when the preparation phase is underway.
342      */

343     public void addPreprocessingHook(RulePreprocessHook hook) {
344         if (preprocessorHooks == null) {
345             preprocessorHooks = new ArrayList();
346         }
347         preprocessorHooks.add(hook);
348     }
349     
350     /**
351      * Perform any initial processing and caching. This call is optional. Most
352      * engines either have negligable set up work or will perform an implicit
353      * "prepare" if necessary. The call is provided for those occasions where
354      * substantial preparation work is possible (e.g. running a forward chaining
355      * rule system) and where an application might wish greater control over when
356      * this prepration is done.
357      */

358     public void prepare() {
359         if (!isPrepared) {
360             isPrepared = true;
361             
362             // Restore the original pre-hookProcess rules
363
rules = rawRules;
364             
365             // Is there any data to bind in yet?
366
Graph data = null;
367             if (fdata != null) data = fdata.getGraph();
368             
369             // initilize the deductions graph
370
fdeductions = new FGraph( new GraphMem() );
371             dataFind = (data == null) ? fdeductions : FinderUtil.cascade(fdeductions, fdata);
372             Finder dataSource = fdata;
373             
374             // Initialize the optional TGC caches
375
if (useTGCCaching) {
376                 if (schemaGraph != null) {
377                     // Check if we can just reuse the copy of the raw
378
if (
379                         (transitiveEngine.checkOccurance(TransitiveReasoner.subPropertyOf, data) ||
380                          transitiveEngine.checkOccurance(TransitiveReasoner.subClassOf, data) ||
381                          transitiveEngine.checkOccurance(RDFS.domain.asNode(), data) ||
382                          transitiveEngine.checkOccurance(RDFS.range.asNode(), data) )) {
383                 
384                         // The data graph contains some ontology knowledge so split the caches
385
// now and rebuild them using merged data
386
transitiveEngine.insert(((FBRuleInfGraph)schemaGraph).fdata, fdata);
387                     }
388                 } else {
389                     if (data != null) {
390                         transitiveEngine.insert(null, fdata);
391                     }
392                 }
393                 // Insert any axiomatic statements into the caches
394
for (Iterator i = rules.iterator(); i.hasNext(); ) {
395                     Rule r = (Rule)i.next();
396                     if (r.bodyLength() == 0) {
397                         // An axiom
398
for (int j = 0; j < r.headLength(); j++) {
399                             Object JavaDoc head = r.getHeadElement(j);
400                             if (head instanceof TriplePattern) {
401                                 TriplePattern h = (TriplePattern) head;
402                                 transitiveEngine.add(h.asTriple());
403                             }
404                         }
405                     }
406                 }
407
408                 transitiveEngine.setCaching(true, true);
409 // dataFind = FinderUtil.cascade(subClassCache, subPropertyCache, dataFind);
410
dataFind = FinderUtil.cascade(dataFind, transitiveEngine.getSubClassCache(), transitiveEngine.getSubPropertyCache());
411                 
412                 // Without the next statement then the transitive closures are not seen by the forward rules
413
dataSource = FinderUtil.cascade(dataSource, transitiveEngine.getSubClassCache(), transitiveEngine.getSubPropertyCache());
414             }
415             
416             // Make sure there are no Brules left over from pior runs
417
bEngine.deleteAllRules();
418
419             // Call any optional preprocessing hook
420
if (preprocessorHooks != null && preprocessorHooks.size() > 0) {
421                 Graph inserts = new GraphMem();
422                 for (Iterator i = preprocessorHooks.iterator(); i.hasNext(); ) {
423                     RulePreprocessHook hook = (RulePreprocessHook)i.next();
424                     hook.run(this, dataFind, inserts);
425                 }
426                 if (inserts.size() > 0) {
427                     FGraph finserts = new FGraph(inserts);
428                     dataSource = FinderUtil.cascade(fdata, finserts);
429                     dataFind = FinderUtil.cascade(dataFind, finserts);
430                 }
431             }
432             
433             boolean rulesLoaded = false;
434             if (schemaGraph != null) {
435                 Graph rawPreload = ((InfGraph)schemaGraph).getRawGraph();
436                 if (rawPreload != null) {
437                     dataFind = FinderUtil.cascade(dataFind, new FGraph(rawPreload));
438                 }
439                 rulesLoaded = preloadDeductions(schemaGraph);
440             }
441             if (rulesLoaded) {
442                 engine.fastInit(dataSource);
443             } else {
444                 // No preload so do the rule separation
445
addBRules(extractPureBackwardRules(rules));
446                 engine.init(true, dataSource);
447             }
448             // Prepare the context for builtins run in backwards engine
449
context = new BBRuleContext(this);
450             
451         }
452     }
453     
454     /**
455      * Cause the inference graph to reconsult the underlying graph to take
456      * into account changes. Normally changes are made through the InfGraph's add and
457      * remove calls are will be handled appropriately. However, in some cases changes
458      * are made "behind the InfGraph's back" and this forces a full reconsult of
459      * the changed data.
460      */

461     public void rebind() {
462         if (bEngine != null) bEngine.reset();
463         isPrepared = false;
464     }
465     
466     /**
467      * Set the state of the trace flag. If set to true then rule firings
468      * are logged out to the Log at "INFO" level.
469      */

470     public void setTraceOn(boolean state) {
471         super.setTraceOn(state);
472         bEngine.setTraceOn(state);
473     }
474
475     /**
476      * Set to true to enable derivation caching
477      */

478     public void setDerivationLogging(boolean recordDerivations) {
479         this.recordDerivations = recordDerivations;
480         engine.setDerivationLogging(recordDerivations);
481         bEngine.setDerivationLogging(recordDerivations);
482         if (recordDerivations) {
483             derivations = new OneToManyMap();
484         } else {
485             derivations = null;
486         }
487     }
488    
489     /**
490      * Set to true to cause functor-valued literals to be dropped from rule output.
491      * Default is true.
492      */

493     public void setFunctorFiltering(boolean param) {
494         filterFunctors = param;
495     }
496     
497     /**
498      * Return the number of rules fired since this rule engine instance
499      * was created and initialized. The current implementation only counts
500      * forward rules and does not track dynamic backward rules needed for
501      * specific queries.
502      */

503     public long getNRulesFired() {
504         return engine.getNRulesFired();
505     }
506     
507     /**
508      * Extended find interface used in situations where the implementator
509      * may or may not be able to answer the complete query. It will
510      * attempt to answer the pattern but if its answers are not known
511      * to be complete then it will also pass the request on to the nested
512      * Finder to append more results.
513      * @param pattern a TriplePattern to be matched against the data
514      * @param continuation either a Finder or a normal Graph which
515      * will be asked for additional match results if the implementor
516      * may not have completely satisfied the query.
517      */

518     public ExtendedIterator findWithContinuation(TriplePattern pattern, Finder continuation) {
519         checkOpen();
520         if (!isPrepared) prepare();
521         ExtendedIterator result = new UniqueExtendedIterator(bEngine.find(pattern));
522         if (continuation != null) {
523             result = result.andThen(continuation.find(pattern));
524         }
525         if (filterFunctors) {
526 // return result.filterDrop(Functor.acceptFilter);
527
return result.filterDrop(this);
528         } else {
529             return result;
530         }
531     }
532     
533     /**
534      * Internal variant of find which omits the filters which block illegal RDF data.
535      * @param pattern a TriplePattern to be matched against the data
536      */

537     public ExtendedIterator findFull(TriplePattern pattern) {
538         checkOpen();
539         if (!isPrepared) prepare();
540         return new UniqueExtendedIterator(bEngine.find(pattern));
541     }
542    
543     /**
544      * Returns an iterator over Triples.
545      * This implementation assumes that the underlying findWithContinuation
546      * will have also consulted the raw data.
547      */

548     public ExtendedIterator graphBaseFind(Node subject, Node property, Node object) {
549         return findWithContinuation(new TriplePattern(subject, property, object), null);
550     }
551
552     /**
553      * Basic pattern lookup interface.
554      * This implementation assumes that the underlying findWithContinuation
555      * will have also consulted the raw data.
556      * @param pattern a TriplePattern to be matched against the data
557      * @return a ExtendedIterator over all Triples in the data set
558      * that match the pattern
559      */

560     public ExtendedIterator find(TriplePattern pattern) {
561         return findWithContinuation(pattern, null);
562     }
563
564     /**
565      * Flush out all cached results. Future queries have to start from scratch.
566      */

567     public void reset() {
568         bEngine.reset();
569         isPrepared = false;
570     }
571
572     /**
573      * Add one triple to the data graph, run any rules triggered by
574      * the new data item, recursively adding any generated triples.
575      */

576     public synchronized void performAdd(Triple t) {
577         fdata.getGraph().add(t);
578         if (useTGCCaching) {
579             if (transitiveEngine.add(t)) isPrepared = false;
580         }
581         if (isPrepared) {
582             engine.add(t);
583         }
584         bEngine.reset();
585     }
586
587     /**
588      * Removes the triple t (if possible) from the set belonging to this graph.
589      */

590     public void performDelete(Triple t) {
591         boolean removeIsFromBase = fdata.getGraph().contains(t);
592         fdata.getGraph().delete(t);
593         if (useTGCCaching) {
594             if (transitiveEngine.delete(t)) {
595                 if (isPrepared) {
596                     bEngine.deleteAllRules();
597                 }
598                 isPrepared = false;
599             }
600         }
601         // Full incremental remove processing requires reference counting
602
// of all deductions. It's not clear the cost of maintaining the
603
// reference counts is worth it so the current implementation
604
// forces a recompute if any external deletes are performed.
605
if (isPrepared) {
606             bEngine.deleteAllRules();
607             isPrepared = false;
608             // Re-enable the code below when/if ref counting is added and remove above
609
// if (removeIsFromBase) engine.delete(t);
610
}
611         bEngine.reset();
612     }
613     
614     /**
615      * Return a new inference graph which is a clone of the current graph
616      * together with an additional set of data premises. Attempts to the replace
617      * the default brute force implementation by one that can reuse some of the
618      * existing deductions.
619      */

620     public InfGraph cloneWithPremises(Graph premises) {
621         prepare();
622         FBRuleInfGraph graph = new FBRuleInfGraph(getReasoner(), rawRules, this);
623         if (useTGCCaching) graph.setUseTGCCache();
624         graph.setDerivationLogging(recordDerivations);
625         graph.setTraceOn(traceOn);
626         // Implementation note: whilst current tests pass its not clear that
627
// the nested passing of FBRuleInfGraph's will correctly handle all
628
// cases of indirectly bound schema data. If we do uncover a problem here
629
// then either include the raw schema in a Union with the premises or
630
// revert of a more brute force version.
631
graph.rebind(premises);
632         return graph;
633     }
634     
635     /**
636      * Free all resources, any further use of this Graph is an error.
637      */

638     public void close() {
639         if (!closed) {
640             bEngine.halt();
641             bEngine = null;
642             transitiveEngine = null;
643             super.close();
644         }
645     }
646     
647 // =======================================================================
648
// Generalized validation machinery. Assumes rule set has special validation
649
// rules that can be turned on.
650

651     /**
652      * Test the consistency of the bound data. This normally tests
653      * the validity of the bound instance data against the bound
654      * schema data.
655      * @return a ValidityReport structure
656      */

657     public ValidityReport validate() {
658         checkOpen();
659         StandardValidityReport report = new StandardValidityReport();
660         // Switch on validation
661
Triple validateOn = new Triple(Node.createAnon(),
662                                 ReasonerVocabulary.RB_VALIDATION.asNode(),
663                                 Functor.makeFunctorNode("on", new Node[] {}));
664         // We sneak this switch directly into the engine to avoid contaminating the
665
// real data - this is only possible only the forward engine has been prepared
666
// add(validateOn);
667
if (!isPrepared) {
668             prepare();
669         }
670         engine.add(validateOn);
671         // Look for all reports
672
TriplePattern pattern = new TriplePattern(null, ReasonerVocabulary.RB_VALIDATION_REPORT.asNode(), null);
673         for (Iterator i = findFull(pattern); i.hasNext(); ) {
674             Triple t = (Triple)i.next();
675             Node rNode = t.getObject();
676             boolean foundReport = false;
677             if (rNode.isLiteral()) {
678                 Object JavaDoc rVal = rNode.getLiteral().getValue();
679                 if (rVal instanceof Functor) {
680                     Functor rFunc = (Functor)rVal;
681                     foundReport = true;
682                     StringBuffer JavaDoc description = new StringBuffer JavaDoc();
683                     String JavaDoc nature = rFunc.getName();
684                     String JavaDoc type = rFunc.getArgs()[0].toString();
685                     String JavaDoc text = rFunc.getArgs()[1].toString();
686                     description.append( text + "\n");
687                     description.append( "Culprit = " + PrintUtil.print(t.getSubject()) +"\n");
688                     for (int j = 2; j < rFunc.getArgLength(); j++) {
689                         description.append( "Implicated node: " + PrintUtil.print(rFunc.getArgs()[j]) + "\n");
690                     }
691                     Node culpritN = t.getSubject();
692                     RDFNode culprit = null;
693                     if (culpritN.isURI()) {
694                         culprit = ResourceFactory.createResource(culpritN.getURI());
695                     }
696                     report.add(nature.equalsIgnoreCase("error"), type, description.toString(), culprit);
697                 }
698             }
699         }
700 // // Debug
701
// Node ia = Node.createURI("http://jena.hpl.hp.com/testing/reasoners/owl#ia");
702
// System.out.println("Types of ia");
703
// PrintUtil.printOut(findFull(new TriplePattern(ia, RDF.Nodes.type, null)));
704
// System.out.println("different froms");
705
// PrintUtil.printOut(findFull(new TriplePattern(null, OWL.differentFrom.asNode(), null)));
706
// System.out.println("ia same as");
707
// PrintUtil.printOut(findFull(new TriplePattern(ia, OWL.sameIndividualAs.asNode(), null)));
708
// // end
709
return report;
710     }
711
712 // =======================================================================
713
// Helper methods
714

715     /**
716      * Scan the initial rule set and pick out all the backward-only rules with non-null bodies,
717      * and transfer these rules to the backward engine.
718      */

719     private static List extractPureBackwardRules(List rules) {
720         List bRules = new ArrayList();
721         for (Iterator i = rules.iterator(); i.hasNext(); ) {
722             Rule r = (Rule)i.next();
723             if (r.isBackward() && r.bodyLength() > 0) {
724                 bRules.add(r);
725             }
726         }
727         return bRules;
728     }
729
730     /**
731      * Adds a set of precomputed triples to the deductions store. These do not, themselves,
732      * fire any rules but provide additional axioms that might enable future rule
733      * firing when real data is added. Used to implement bindSchema processing
734      * in the parent Reasoner.
735      * @return true if the preload was able to load rules as well
736      */

737     protected boolean preloadDeductions(Graph preloadIn) {
738         Graph d = fdeductions.getGraph();
739         FBRuleInfGraph preload = (FBRuleInfGraph)preloadIn;
740         // If the rule set is the same we can reuse those as well
741
if (preload.rules == rules) {
742             // Load raw deductions
743
for (Iterator i = preload.getDeductionsGraph().find(null, null, null); i.hasNext(); ) {
744                 d.add((Triple)i.next());
745             }
746             // Load backward rules
747
addBRules(preload.getBRules());
748             // Load forward rules
749
engine.setRuleStore(preload.getForwardRuleStore());
750             // Add access to raw data
751
return true;
752         } else {
753             return false;
754         }
755     }
756    
757     /**
758      * Called to flag that a node should be hidden from external queries.
759      */

760     public void hideNode(Node n) {
761         if (! JenaParameters.enableFilteringOfHiddenInfNodes) return;
762         if (hiddenNodes == null) {
763             hiddenNodes = new HashSet();
764         }
765         synchronized (hiddenNodes) {
766             hiddenNodes.add(n);
767         }
768     }
769     
770 // =======================================================================
771
// Support for LP engine profiling
772

773     /**
774      * Reset the LP engine profile.
775      * @param enable it true then profiling will continue with a new empty profile table,
776      * if false profiling will stop all current data lost.
777      */

778     public void resetLPProfile(boolean enable) {
779         bEngine.resetProfile(enable);
780     }
781     
782     /**
783      * Print a profile of LP rules used since the last reset.
784      */

785     public void printLPProfile() {
786         bEngine.printProfile();
787     }
788     
789 // =======================================================================
790
// Implement Filter signature
791

792     /**
793      * Post-filter query results to hide unwanted
794      * triples from the glare of publicity. Unwanted triples
795      * are triples with Functor literals and triples with hidden nodes
796      * as subject or object.
797      */

798     public boolean accept(Object JavaDoc tin) {
799         Triple t = (Triple)tin;
800         
801         if (((Triple)t).getSubject().isLiteral()) return true;
802         
803         if (JenaParameters.enableFilteringOfHiddenInfNodes && hiddenNodes != null) {
804             if (hiddenNodes.contains(t.getSubject()) || hiddenNodes.contains(t.getObject()) || hiddenNodes.contains(t.getPredicate())) {
805                 return true;
806             }
807         }
808         
809         if (filterFunctors) {
810             if (Functor.isFunctor(t.getObject())) {
811                 return true;
812             }
813         }
814         
815         return false;
816
817      }
818      
819 // =======================================================================
820
// Inner classes
821

822     /**
823      * Structure used to wrap up pre-processed/compiled rule sets.
824      */

825     public static class RuleStore {
826         
827         /** The raw rules */
828         protected List rawRules;
829         
830         /** The indexed store used by the forward chainer */
831         protected Object JavaDoc fRuleStore;
832         
833         /** The separated backward rules */
834         protected List bRules;
835         
836         /**
837          * Constructor.
838          */

839         public RuleStore(List rawRules, Object JavaDoc fRuleStore, List bRules) {
840             this.rawRules = rawRules;
841             this.fRuleStore = fRuleStore;
842             this.bRules = bRules;
843         }
844         
845     }
846    
847     
848 }
849
850
851 /*
852     (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
853     All rights reserved.
854
855     Redistribution and use in source and binary forms, with or without
856     modification, are permitted provided that the following conditions
857     are met:
858
859     1. Redistributions of source code must retain the above copyright
860        notice, this list of conditions and the following disclaimer.
861
862     2. Redistributions in binary form must reproduce the above copyright
863        notice, this list of conditions and the following disclaimer in the
864        documentation and/or other materials provided with the distribution.
865
866     3. The name of the author may not be used to endorse or promote products
867        derived from this software without specific prior written permission.
868
869     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
870     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
871     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
872     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
873     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
874     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
875     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
876     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
877     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
878     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
879 */
Popular Tags