Source Code Cross Referenced for FBRuleInfGraph.java in  » RSS-RDF » Jena-2.5.5 » com » hp » hpl » jena » reasoner » rulesys » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » RSS RDF » Jena 2.5.5 » com.hp.hpl.jena.reasoner.rulesys 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /******************************************************************
002:         * File:        FBRuleInfGraph.java
003:         * Created by:  Dave Reynolds
004:         * Created on:  28-May-2003
005:         * 
006:         * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007:         * [See end of file]
008:         * $Id: FBRuleInfGraph.java,v 1.67 2008/01/02 12:07:47 andy_seaborne Exp $
009:         *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys;
010:
011:        import com.hp.hpl.jena.rdf.model.RDFNode;
012:        import com.hp.hpl.jena.rdf.model.ResourceFactory;
013:        import com.hp.hpl.jena.reasoner.rulesys.impl.*;
014:        import com.hp.hpl.jena.reasoner.transitiveReasoner.*;
015:        import com.hp.hpl.jena.reasoner.*;
016:        import com.hp.hpl.jena.shared.ReificationStyle;
017:        import com.hp.hpl.jena.shared.impl.JenaParameters;
018:        import com.hp.hpl.jena.graph.*;
019:
020:        import java.util.*;
021:
022:        //import com.hp.hpl.jena.util.PrintUtil;
023:        import com.hp.hpl.jena.util.OneToManyMap;
024:        import com.hp.hpl.jena.util.PrintUtil;
025:        import com.hp.hpl.jena.util.iterator.*;
026:        import com.hp.hpl.jena.vocabulary.*;
027:
028:        import org.apache.commons.logging.Log;
029:        import org.apache.commons.logging.LogFactory;
030:
031:        /**
032:         * An inference graph that uses a mixture of forward and backward
033:         * chaining rules. The forward rules can create direct deductions from
034:         * the source data and schema and can also create backward rules. A
035:         * query is answered by consulting the union of the raw data, the forward
036:         * derived results and any relevant backward rules (whose answers are tabled
037:         * for future reference).
038:         * 
039:         * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
040:         * @version $Revision: 1.67 $ on $Date: 2008/01/02 12:07:47 $
041:         */
042:        public class FBRuleInfGraph extends BasicForwardRuleInfGraph implements 
043:                BackwardRuleInfGraphI {
044:
045:            /** Single context for the reasoner, used when passing information to builtins */
046:            protected BBRuleContext context;
047:
048:            /** A finder that searches across the data, schema, axioms and forward deductions*/
049:            protected Finder dataFind;
050:
051:            /** The core backward rule engine which includes all the memoized results */
052:            protected LPBRuleEngine bEngine;
053:
054:            /** The original rule set as supplied */
055:            protected List rawRules;
056:
057:            /** The rule list after possible extension by preprocessing hooks */
058:            protected List rules;
059:
060:            /** Static switch from Basic to RETE implementation of the forward component */
061:            public static boolean useRETE = true;
062:
063:            /** Flag, if true then subClass and subProperty lattices will be optimized using TGCs */
064:            protected boolean useTGCCaching = false;
065:
066:            /** Flag, if true then find results will be filtered to remove functors and illegal RDF */
067:            public boolean filterFunctors = true;
068:
069:            /** Optional precomputed cache of the subClass/subproperty lattices */
070:            protected TransitiveEngine transitiveEngine;
071:
072:            /** Optional list of preprocessing hooks  to be run in sequence during preparation time */
073:            protected List preprocessorHooks;
074:
075:            /** Cache of temporary property values inferred through getTemp calls */
076:            protected TempNodeCache tempNodecache;
077:
078:            /** Table of temp nodes which should be hidden from output listings */
079:            protected Set hiddenNodes;
080:
081:            static Log logger = LogFactory.getLog(FBRuleInfGraph.class);
082:
083:            //  =======================================================================
084:            //  Constructors
085:
086:            /**
087:             * Constructor.
088:             * @param reasoner the reasoner which created this inf graph instance
089:             * @param schema the (optional) schema graph to be included
090:             */
091:            public FBRuleInfGraph(Reasoner reasoner, Graph schema) {
092:                super (reasoner, schema);
093:                constructorInit(schema);
094:            }
095:
096:            /**
097:             * Constructor.
098:             * @param reasoner the reasoner which created this inf graph instance
099:             * @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:                this (reasoner, rules, schema, ReificationStyle.Minimal);
104:            }
105:
106:            public FBRuleInfGraph(Reasoner reasoner, List rules, Graph schema,
107:                    ReificationStyle style) {
108:                super (reasoner, rules, schema, style);
109:                this .rawRules = rules;
110:                constructorInit(schema);
111:            }
112:
113:            /**
114:             * Constructor.
115:             * @param reasoner the reasoner which created this inf graph instance
116:             * @param rules the rules to process
117:             * @param schema the (optional) schema graph to be included
118:             * @param data the data graph to be processed
119:             */
120:            public FBRuleInfGraph(Reasoner reasoner, List rules, Graph schema,
121:                    Graph data) {
122:                super (reasoner, rules, schema, data);
123:                this .rawRules = rules;
124:                constructorInit(schema);
125:            }
126:
127:            /**
128:             * Common pieces of initialization code which apply in all constructor cases.
129:             */
130:            private void constructorInit(Graph schema) {
131:                initLP(schema);
132:                tempNodecache = new TempNodeCache(this );
133:                if (JenaParameters.enableFilteringOfHiddenInfNodes) {
134:                    hiddenNodes = new HashSet();
135:                    if (schema != null && schema instanceof  FBRuleInfGraph) {
136:                        hiddenNodes
137:                                .addAll(((FBRuleInfGraph) schema).hiddenNodes);
138:                    }
139:                }
140:            }
141:
142:            /**
143:             * Instantiate the forward rule engine to use.
144:             * Subclasses can override this to switch to, say, a RETE imlementation.
145:             * @param rules the rule set or null if there are not rules bound in yet.
146:             */
147:            protected void instantiateRuleEngine(List rules) {
148:                if (rules != null) {
149:                    if (useRETE) {
150:                        engine = new RETEEngine(this , rules);
151:                    } else {
152:                        engine = new FRuleEngine(this , rules);
153:                    }
154:                } else {
155:                    if (useRETE) {
156:                        engine = new RETEEngine(this );
157:                    } else {
158:                        engine = new FRuleEngine(this );
159:                    }
160:                }
161:            }
162:
163:            /**
164:             * Initialize the LP engine, based on an optional schema graph.
165:             */
166:            private void initLP(Graph schema) {
167:                if (schema != null && schema instanceof  FBRuleInfGraph) {
168:                    LPRuleStore newStore = new LPRuleStore();
169:                    newStore.addAll(((FBRuleInfGraph) schema).bEngine
170:                            .getRuleStore());
171:                    bEngine = new LPBRuleEngine(this , newStore);
172:                } else {
173:                    bEngine = new LPBRuleEngine(this );
174:                }
175:            }
176:
177:            /**
178:             * Instantiate the optional caches for the subclass/suproperty lattices.
179:             * Unless this call is made the TGC caching will not be used.
180:             */
181:            public void setUseTGCCache() {
182:                useTGCCaching = true;
183:                resetTGCCache();
184:            }
185:
186:            /**
187:             * Rest the transitive graph caches
188:             */
189:            private void resetTGCCache() {
190:                if (schemaGraph != null) {
191:                    transitiveEngine = new TransitiveEngine(
192:                            ((FBRuleInfGraph) schemaGraph).transitiveEngine);
193:                } else {
194:                    transitiveEngine = new TransitiveEngine(
195:                            new TransitiveGraphCache(
196:                                    ReasonerVocabulary.directSubClassOf
197:                                            .asNode(), RDFS.subClassOf.asNode()),
198:                            new TransitiveGraphCache(
199:                                    ReasonerVocabulary.directSubPropertyOf
200:                                            .asNode(), RDFS.subPropertyOf
201:                                            .asNode()));
202:                }
203:            }
204:
205:            //  =======================================================================
206:            //   Interface between infGraph and the goal processing machinery
207:
208:            /**
209:             * Search the combination of data and deductions graphs for the given triple pattern.
210:             * This may different from the normal find operation in the base of hybrid reasoners
211:             * where we are side-stepping the backward deduction step.
212:             */
213:            public ExtendedIterator findDataMatches(Node subject,
214:                    Node predicate, Node object) {
215:                return dataFind.find(new TriplePattern(subject, predicate,
216:                        object));
217:            }
218:
219:            /**
220:             * Search the combination of data and deductions graphs for the given triple pattern.
221:             * This may different from the normal find operation in the base of hybrid reasoners
222:             * where we are side-stepping the backward deduction step.
223:             */
224:            public ExtendedIterator findDataMatches(TriplePattern pattern) {
225:                return dataFind.find(pattern);
226:            }
227:
228:            /**
229:             * Process a call to a builtin predicate
230:             * @param clause the Functor representing the call
231:             * @param env the BindingEnvironment for this call
232:             * @param rule the rule which is invoking this call
233:             * @return true if the predicate succeeds
234:             */
235:            public boolean processBuiltin(ClauseEntry clause, Rule rule,
236:                    BindingEnvironment env) {
237:                throw new ReasonerException(
238:                        "Internal error in FBLP rule engine, incorrect invocation of builtin in rule "
239:                                + rule);
240:                // TODO: Remove 
241:                //        if (clause instanceof Functor) {
242:                //            context.setEnv(env);
243:                //            context.setRule(rule);
244:                //            return((Functor)clause).evalAsBodyClause(context);
245:                //        } else {
246:                //            throw new ReasonerException("Illegal builtin predicate: " + clause + " in rule " + rule);
247:                //        }
248:            }
249:
250:            /**
251:             * Adds a new Backward rule as a rusult of a forward rule process. Only some
252:             * infgraphs support this.
253:             */
254:            public void addBRule(Rule brule) {
255:                if (logger.isDebugEnabled()) {
256:                    logger.debug("Adding rule " + brule);
257:                }
258:                bEngine.addRule(brule);
259:                bEngine.reset();
260:            }
261:
262:            /**
263:             * Deletes a new Backward rule as a rules of a forward rule process. Only some
264:             * infgraphs support this.
265:             */
266:            public void deleteBRule(Rule brule) {
267:                if (logger.isDebugEnabled()) {
268:                    logger.debug("Deleting rule " + brule);
269:                }
270:                bEngine.deleteRule(brule);
271:                bEngine.reset();
272:            }
273:
274:            /**
275:             * Adds a set of new Backward rules
276:             */
277:            public void addBRules(List rules) {
278:                for (Iterator i = rules.iterator(); i.hasNext();) {
279:                    Rule rule = (Rule) i.next();
280:                    //            logger.debug("Adding rule " + rule);
281:                    bEngine.addRule(rule);
282:                }
283:                bEngine.reset();
284:            }
285:
286:            /**
287:             * Return an ordered list of all registered backward rules. Includes those
288:             * generated by forward productions.
289:             */
290:            public List getBRules() {
291:                return bEngine.getAllRules();
292:            }
293:
294:            /**
295:             * Return the originally supplied set of rules, may be a mix of forward
296:             * and backward rules.
297:             */
298:            public List getRules() {
299:                return rules;
300:            }
301:
302:            /**
303:             * Set a predicate to be tabled/memoized by the LP engine. 
304:             */
305:            public void setTabled(Node predicate) {
306:                bEngine.tablePredicate(predicate);
307:                if (traceOn) {
308:                    logger.info("LP TABLE " + predicate);
309:                }
310:            }
311:
312:            /**
313:             * Return a compiled representation of all the registered
314:             * forward rules.
315:             */
316:            private Object getForwardRuleStore() {
317:                return engine.getRuleStore();
318:            }
319:
320:            /**
321:             * Add a new deduction to the deductions graph.
322:             */
323:            public void addDeduction(Triple t) {
324:                getCurrentDeductionsGraph().add(t);
325:                if (useTGCCaching) {
326:                    transitiveEngine.add(t);
327:                }
328:            }
329:
330:            /**
331:             * Retrieve or create a bNode representing an inferred property value.
332:             * @param instance the base instance node to which the property applies
333:             * @param prop the property node whose value is being inferred
334:             * @param pclass the (optional, can be null) class for the inferred value.
335:             * @return the bNode representing the property value 
336:             */
337:            public Node getTemp(Node instance, Node prop, Node pclass) {
338:                return tempNodecache.getTemp(instance, prop, pclass);
339:            }
340:
341:            //  =======================================================================
342:            //  Core inf graph methods
343:
344:            /**
345:             * Add a new rule to the rule set. This should only be used by implementations
346:             * of RuleProprocessHook (which are called during rule system preparation phase).
347:             * If called at other times the rule won't be correctly transferred into the
348:             * underlying engines.
349:             */
350:            public void addRuleDuringPrepare(Rule rule) {
351:                if (rules == rawRules) {
352:                    // Ensure the original is preserved in case we need to do a restart
353:                    if (rawRules instanceof  ArrayList) {
354:                        rules = (ArrayList) ((ArrayList) rawRules).clone();
355:                    } else {
356:                        rules = new ArrayList(rawRules);
357:                    }
358:                    // Rebuild the forward engine to use the cloned rules
359:                    instantiateRuleEngine(rules);
360:                }
361:                rules.add(rule);
362:            }
363:
364:            /**
365:             * Add a new preprocessing hook defining an operation that
366:             * should be run when the preparation phase is underway.
367:             */
368:            public void addPreprocessingHook(RulePreprocessHook hook) {
369:                if (preprocessorHooks == null) {
370:                    preprocessorHooks = new ArrayList();
371:                }
372:                preprocessorHooks.add(hook);
373:            }
374:
375:            /**
376:             * Perform any initial processing and caching. This call is optional. Most
377:             * engines either have negligable set up work or will perform an implicit
378:             * "prepare" if necessary. The call is provided for those occasions where
379:             * substantial preparation work is possible (e.g. running a forward chaining
380:             * rule system) and where an application might wish greater control over when
381:             * this prepration is done.
382:             */
383:            public void prepare() {
384:                if (!isPrepared) {
385:                    isPrepared = true;
386:
387:                    // Restore the original pre-hookProcess rules
388:                    rules = rawRules;
389:
390:                    // Is there any data to bind in yet?
391:                    Graph data = null;
392:                    if (fdata != null)
393:                        data = fdata.getGraph();
394:
395:                    // initilize the deductions graph
396:                    if (fdeductions != null && fdeductions instanceof  FGraph) {
397:                        Graph oldDeductions = ((FGraph) fdeductions).getGraph();
398:                        oldDeductions.getBulkUpdateHandler().removeAll();
399:                    } else {
400:                        fdeductions = new FGraph(createDeductionsGraph());
401:                    }
402:                    dataFind = (data == null) ? fdeductions : FinderUtil
403:                            .cascade(fdeductions, fdata);
404:                    Finder dataSource = fdata;
405:
406:                    // Initialize the optional TGC caches
407:                    if (useTGCCaching) {
408:                        resetTGCCache();
409:                        if (schemaGraph != null) {
410:                            // Check if we can just reuse the copy of the raw 
411:                            if ((transitiveEngine.checkOccurance(
412:                                    TransitiveReasoner.subPropertyOf, data)
413:                                    || transitiveEngine
414:                                            .checkOccurance(
415:                                                    TransitiveReasoner.subClassOf,
416:                                                    data)
417:                                    || transitiveEngine.checkOccurance(
418:                                            RDFS.domain.asNode(), data) || transitiveEngine
419:                                    .checkOccurance(RDFS.range.asNode(), data))) {
420:
421:                                // The data graph contains some ontology knowledge so split the caches
422:                                // now and rebuild them using merged data
423:                                transitiveEngine.insert(
424:                                        ((FBRuleInfGraph) schemaGraph).fdata,
425:                                        fdata);
426:                            }
427:                        } else {
428:                            if (data != null) {
429:                                transitiveEngine.insert(null, fdata);
430:                            }
431:                        }
432:                        // Insert any axiomatic statements into the caches
433:                        for (Iterator i = rules.iterator(); i.hasNext();) {
434:                            Rule r = (Rule) i.next();
435:                            if (r.bodyLength() == 0) {
436:                                // An axiom
437:                                for (int j = 0; j < r.headLength(); j++) {
438:                                    Object head = r.getHeadElement(j);
439:                                    if (head instanceof  TriplePattern) {
440:                                        TriplePattern h = (TriplePattern) head;
441:                                        transitiveEngine.add(h.asTriple());
442:                                    }
443:                                }
444:                            }
445:                        }
446:
447:                        transitiveEngine.setCaching(true, true);
448:                        //                dataFind = FinderUtil.cascade(subClassCache, subPropertyCache, dataFind);
449:                        dataFind = FinderUtil.cascade(dataFind,
450:                                transitiveEngine.getSubClassCache(),
451:                                transitiveEngine.getSubPropertyCache());
452:
453:                        // Without the next statement then the transitive closures are not seen by the forward rules
454:                        dataSource = FinderUtil.cascade(dataSource,
455:                                transitiveEngine.getSubClassCache(),
456:                                transitiveEngine.getSubPropertyCache());
457:                    }
458:
459:                    // Make sure there are no Brules left over from pior runs
460:                    bEngine.deleteAllRules();
461:
462:                    // Call any optional preprocessing hook
463:                    if (preprocessorHooks != null
464:                            && preprocessorHooks.size() > 0) {
465:                        Graph inserts = Factory.createGraphMem();
466:                        for (Iterator i = preprocessorHooks.iterator(); i
467:                                .hasNext();) {
468:                            RulePreprocessHook hook = (RulePreprocessHook) i
469:                                    .next();
470:                            hook.run(this , dataFind, inserts);
471:                        }
472:                        if (inserts.size() > 0) {
473:                            FGraph finserts = new FGraph(inserts);
474:                            dataSource = FinderUtil.cascade(fdata, finserts);
475:                            dataFind = FinderUtil.cascade(dataFind, finserts);
476:                        }
477:                    }
478:
479:                    boolean rulesLoaded = false;
480:                    if (schemaGraph != null) {
481:                        Graph rawPreload = ((InfGraph) schemaGraph)
482:                                .getRawGraph();
483:                        if (rawPreload != null) {
484:                            dataFind = FinderUtil.cascade(dataFind, new FGraph(
485:                                    rawPreload));
486:                        }
487:                        rulesLoaded = preloadDeductions(schemaGraph);
488:                    }
489:                    if (rulesLoaded) {
490:                        engine.fastInit(dataSource);
491:                    } else {
492:                        // No preload so do the rule separation
493:                        addBRules(extractPureBackwardRules(rules));
494:                        engine.init(true, dataSource);
495:                    }
496:                    // Prepare the context for builtins run in backwards engine
497:                    context = new BBRuleContext(this );
498:
499:                }
500:            }
501:
502:            /**
503:             * Cause the inference graph to reconsult the underlying graph to take
504:             * into account changes. Normally changes are made through the InfGraph's add and
505:             * remove calls are will be handled appropriately. However, in some cases changes
506:             * are made "behind the InfGraph's back" and this forces a full reconsult of
507:             * the changed data. 
508:             */
509:            public void rebind() {
510:                version++;
511:                if (bEngine != null)
512:                    bEngine.reset();
513:                isPrepared = false;
514:            }
515:
516:            /**
517:             * Cause the inference graph to reconsult both the underlying graph and
518:             * the reasoner ruleset, permits the forward rule set to be dynamically changed.
519:             * Causes the entire rule engine to be rebuilt from the current ruleset and 
520:             * reinitialized against the current data. Not needed for normal cases.
521:             */
522:            public void rebindAll() {
523:                rawRules = ((FBRuleReasoner) reasoner).getRules();
524:                instantiateRuleEngine(rawRules);
525:                rebind();
526:            }
527:
528:            /**
529:             * Set the state of the trace flag. If set to true then rule firings
530:             * are logged out to the Log at "INFO" level.
531:             */
532:            public void setTraceOn(boolean state) {
533:                super .setTraceOn(state);
534:                bEngine.setTraceOn(state);
535:            }
536:
537:            /**
538:             * Set to true to enable derivation caching
539:             */
540:            public void setDerivationLogging(boolean recordDerivations) {
541:                this .recordDerivations = recordDerivations;
542:                engine.setDerivationLogging(recordDerivations);
543:                bEngine.setDerivationLogging(recordDerivations);
544:                if (recordDerivations) {
545:                    derivations = new OneToManyMap();
546:                } else {
547:                    derivations = null;
548:                }
549:            }
550:
551:            /**
552:             * Set to true to cause functor-valued literals to be dropped from rule output.
553:             * Default is true.
554:             */
555:            public void setFunctorFiltering(boolean param) {
556:                filterFunctors = param;
557:            }
558:
559:            /**
560:             * Return the number of rules fired since this rule engine instance
561:             * was created and initialized. The current implementation only counts
562:             * forward rules and does not track dynamic backward rules needed for
563:             * specific queries.
564:             */
565:            public long getNRulesFired() {
566:                return engine.getNRulesFired();
567:            }
568:
569:            /**
570:             * Extended find interface used in situations where the implementator
571:             * may or may not be able to answer the complete query. It will
572:             * attempt to answer the pattern but if its answers are not known
573:             * to be complete then it will also pass the request on to the nested
574:             * Finder to append more results.
575:             * @param pattern a TriplePattern to be matched against the data
576:             * @param continuation either a Finder or a normal Graph which
577:             * will be asked for additional match results if the implementor
578:             * may not have completely satisfied the query.
579:             */
580:            public ExtendedIterator findWithContinuation(TriplePattern pattern,
581:                    Finder continuation) {
582:                checkOpen();
583:                if (!isPrepared)
584:                    prepare();
585:                ExtendedIterator result = new UniqueExtendedIterator(bEngine
586:                        .find(pattern));
587:                if (continuation != null) {
588:                    result = result.andThen(continuation.find(pattern));
589:                }
590:                if (filterFunctors) {
591:                    //            return result.filterDrop(Functor.acceptFilter);
592:                    return result.filterDrop(new Filter() {
593:
594:                        public boolean accept(Object o) {
595:                            return FBRuleInfGraph.this .accept(o);
596:                        }
597:                    });
598:                } else {
599:                    return result;
600:                }
601:            }
602:
603:            /**
604:             * Internal variant of find which omits the filters which block illegal RDF data.
605:             * @param pattern a TriplePattern to be matched against the data
606:             */
607:            public ExtendedIterator findFull(TriplePattern pattern) {
608:                checkOpen();
609:                if (!isPrepared)
610:                    prepare();
611:                return new UniqueExtendedIterator(bEngine.find(pattern));
612:            }
613:
614:            /** 
615:             * Returns an iterator over Triples.
616:             * This implementation assumes that the underlying findWithContinuation 
617:             * will have also consulted the raw data.
618:             */
619:            public ExtendedIterator graphBaseFind(Node subject, Node property,
620:                    Node object) {
621:                return findWithContinuation(new TriplePattern(subject,
622:                        property, object), null);
623:            }
624:
625:            /**
626:             * Basic pattern lookup interface.
627:             * This implementation assumes that the underlying findWithContinuation 
628:             * will have also consulted the raw data.
629:             * @param pattern a TriplePattern to be matched against the data
630:             * @return a ExtendedIterator over all Triples in the data set
631:             *  that match the pattern
632:             */
633:            public ExtendedIterator find(TriplePattern pattern) {
634:                return findWithContinuation(pattern, null);
635:            }
636:
637:            /**
638:             * Flush out all cached results. Future queries have to start from scratch.
639:             */
640:            public void reset() {
641:                version++;
642:                bEngine.reset();
643:                isPrepared = false;
644:            }
645:
646:            /**
647:             * Add one triple to the data graph, run any rules triggered by
648:             * the new data item, recursively adding any generated triples.
649:             */
650:            public synchronized void performAdd(Triple t) {
651:                version++;
652:                fdata.getGraph().add(t);
653:                if (useTGCCaching) {
654:                    if (transitiveEngine.add(t))
655:                        isPrepared = false;
656:                }
657:                if (isPrepared) {
658:                    boolean needReset = false;
659:                    if (preprocessorHooks != null
660:                            && preprocessorHooks.size() > 0) {
661:                        if (preprocessorHooks.size() > 1) {
662:                            for (Iterator i = preprocessorHooks.iterator(); i
663:                                    .hasNext();) {
664:                                if (((RulePreprocessHook) i.next()).needsRerun(
665:                                        this , t)) {
666:                                    needReset = true;
667:                                    break;
668:                                }
669:                            }
670:                        } else {
671:                            needReset = ((RulePreprocessHook) preprocessorHooks
672:                                    .get(0)).needsRerun(this , t);
673:                        }
674:                    }
675:                    if (needReset) {
676:                        isPrepared = false;
677:                    } else {
678:                        engine.add(t);
679:                    }
680:                }
681:                bEngine.reset();
682:            }
683:
684:            /** 
685:             * Removes the triple t (if possible) from the set belonging to this graph. 
686:             */
687:            public void performDelete(Triple t) {
688:                version++;
689:                boolean removeIsFromBase = fdata.getGraph().contains(t);
690:                fdata.getGraph().delete(t);
691:                if (useTGCCaching) {
692:                    if (transitiveEngine.delete(t)) {
693:                        if (isPrepared) {
694:                            bEngine.deleteAllRules();
695:                        }
696:                        isPrepared = false;
697:                    }
698:                }
699:                // Full incremental remove processing requires reference counting
700:                // of all deductions. It's not clear the cost of maintaining the
701:                // reference counts is worth it so the current implementation
702:                // forces a recompute if any external deletes are performed.
703:                if (isPrepared) {
704:                    bEngine.deleteAllRules();
705:                    isPrepared = false;
706:                    // Re-enable the code below when/if ref counting is added and remove above
707:                    // if (removeIsFromBase) engine.delete(t);
708:                }
709:                bEngine.reset();
710:            }
711:
712:            /**
713:             * Return a new inference graph which is a clone of the current graph
714:             * together with an additional set of data premises. Attempts to the replace
715:             * the default brute force implementation by one that can reuse some of the
716:             * existing deductions.
717:             */
718:            // This implementatin was incomplete. By commenting it out we revert to
719:            // the global brute force solution of cloning the full graph
720:            //    public InfGraph cloneWithPremises(Graph premises) {
721:            //        prepare();
722:            //        FBRuleInfGraph graph = new FBRuleInfGraph(getReasoner(), rawRules, this);
723:            //        if (useTGCCaching) graph.setUseTGCCache();
724:            //        graph.setDerivationLogging(recordDerivations);
725:            //        graph.setTraceOn(traceOn);
726:            //        // Implementation note:  whilst current tests pass its not clear that 
727:            //        // the nested passing of FBRuleInfGraph's will correctly handle all
728:            //        // cases of indirectly bound schema data. If we do uncover a problem here
729:            //        // then either include the raw schema in a Union with the premises or
730:            //        // revert of a more brute force version. 
731:            //        graph.rebind(premises);
732:            //        return graph;
733:            //    }
734:            /** 
735:             * Free all resources, any further use of this Graph is an error.
736:             */
737:            public void close() {
738:                if (!closed) {
739:                    bEngine.halt();
740:                    bEngine = null;
741:                    transitiveEngine = null;
742:                    super .close();
743:                }
744:            }
745:
746:            //  =======================================================================
747:            //  Generalized validation machinery. Assumes rule set has special validation
748:            //  rules that can be turned on.
749:
750:            /**
751:             * Test the consistency of the bound data. This normally tests
752:             * the validity of the bound instance data against the bound
753:             * schema data. 
754:             * @return a ValidityReport structure
755:             */
756:            public ValidityReport validate() {
757:                checkOpen();
758:                StandardValidityReport report = new StandardValidityReport();
759:                // Switch on validation
760:                Triple validateOn = new Triple(Node.createAnon(),
761:                        ReasonerVocabulary.RB_VALIDATION.asNode(), Functor
762:                                .makeFunctorNode("on", new Node[] {}));
763:                // We sneak this switch directly into the engine to avoid contaminating the
764:                // real data - this is only possible only the forward engine has been prepared
765:                //      add(validateOn);
766:                if (!isPrepared) {
767:                    prepare();
768:                }
769:                engine.add(validateOn);
770:                // Look for all reports
771:                TriplePattern pattern = new TriplePattern(null,
772:                        ReasonerVocabulary.RB_VALIDATION_REPORT.asNode(), null);
773:                for (Iterator i = findFull(pattern); i.hasNext();) {
774:                    Triple t = (Triple) i.next();
775:                    Node rNode = t.getObject();
776:                    boolean foundReport = false;
777:                    if (rNode.isLiteral()) {
778:                        Object rVal = rNode.getLiteralValue();
779:                        if (rVal instanceof  Functor) {
780:                            Functor rFunc = (Functor) rVal;
781:                            foundReport = true;
782:                            StringBuffer description = new StringBuffer();
783:                            String nature = rFunc.getName();
784:                            String type = rFunc.getArgs()[0].toString();
785:                            String text = rFunc.getArgs()[1].toString();
786:                            description.append(text + "\n");
787:                            description.append("Culprit = "
788:                                    + PrintUtil.print(t.getSubject()) + "\n");
789:                            for (int j = 2; j < rFunc.getArgLength(); j++) {
790:                                description.append("Implicated node: "
791:                                        + PrintUtil.print(rFunc.getArgs()[j])
792:                                        + "\n");
793:                            }
794:                            Node culpritN = t.getSubject();
795:                            RDFNode culprit = null;
796:                            if (culpritN.isURI()) {
797:                                culprit = ResourceFactory
798:                                        .createResource(culpritN.getURI());
799:                            }
800:                            report.add(nature.equalsIgnoreCase("error"), type,
801:                                    description.toString(), culprit);
802:                        }
803:                    }
804:                }
805:                //        // Debug
806:                //        Node ia = Node.createURI("http://jena.hpl.hp.com/testing/reasoners/owl#ia");
807:                //        System.out.println("Types of ia");
808:                //        PrintUtil.printOut(findFull(new TriplePattern(ia, RDF.Nodes.type, null)));
809:                //        System.out.println("different froms");
810:                //        PrintUtil.printOut(findFull(new TriplePattern(null, OWL.differentFrom.asNode(), null)));
811:                //        System.out.println("ia same as");
812:                //        PrintUtil.printOut(findFull(new TriplePattern(ia, OWL.sameIndividualAs.asNode(), null)));
813:                //        // end
814:                return report;
815:            }
816:
817:            //  =======================================================================
818:            //  Helper methods
819:
820:            /**
821:             * Scan the initial rule set and pick out all the backward-only rules with non-null bodies,
822:             * and transfer these rules to the backward engine. 
823:             */
824:            private static List extractPureBackwardRules(List rules) {
825:                List bRules = new ArrayList();
826:                for (Iterator i = rules.iterator(); i.hasNext();) {
827:                    Rule r = (Rule) i.next();
828:                    if (r.isBackward() && r.bodyLength() > 0) {
829:                        bRules.add(r);
830:                    }
831:                }
832:                return bRules;
833:            }
834:
835:            /**
836:             * Adds a set of precomputed triples to the deductions store. These do not, themselves,
837:             * fire any rules but provide additional axioms that might enable future rule
838:             * firing when real data is added. Used to implement bindSchema processing
839:             * in the parent Reasoner.
840:             * @return true if the preload was able to load rules as well
841:             */
842:            protected boolean preloadDeductions(Graph preloadIn) {
843:                Graph d = fdeductions.getGraph();
844:                FBRuleInfGraph preload = (FBRuleInfGraph) preloadIn;
845:                // If the rule set is the same we can reuse those as well
846:                if (preload.rules == rules) {
847:                    // Load raw deductions
848:                    for (Iterator i = preload.getDeductionsGraph().find(null,
849:                            null, null); i.hasNext();) {
850:                        d.add((Triple) i.next());
851:                    }
852:                    // Load backward rules
853:                    addBRules(preload.getBRules());
854:                    // Load forward rules
855:                    engine.setRuleStore(preload.getForwardRuleStore());
856:                    // Add access to raw data
857:                    return true;
858:                } else {
859:                    return false;
860:                }
861:            }
862:
863:            /**
864:             * Called to flag that a node should be hidden from external queries.
865:             */
866:            public void hideNode(Node n) {
867:                if (!JenaParameters.enableFilteringOfHiddenInfNodes)
868:                    return;
869:                if (hiddenNodes == null) {
870:                    hiddenNodes = new HashSet();
871:                }
872:                synchronized (hiddenNodes) {
873:                    hiddenNodes.add(n);
874:                }
875:            }
876:
877:            //  =======================================================================
878:            //  Support for LP engine profiling
879:
880:            /**
881:             * Reset the LP engine profile.
882:             * @param enable it true then profiling will continue with a new empty profile table,
883:             * if false profiling will stop all current data lost.
884:             */
885:            public void resetLPProfile(boolean enable) {
886:                bEngine.resetProfile(enable);
887:            }
888:
889:            /**
890:             * Print a profile of LP rules used since the last reset.
891:             */
892:            public void printLPProfile() {
893:                bEngine.printProfile();
894:            }
895:
896:            //  =======================================================================
897:            //  Implement Filter signature
898:
899:            /**
900:             * Post-filter query results to hide unwanted
901:             * triples from the glare of publicity. Unwanted triples
902:             * are triples with Functor literals and triples with hidden nodes
903:             * as subject or object.
904:             */
905:            public boolean accept(Object tin) {
906:                Triple t = (Triple) tin;
907:
908:                if (((Triple) t).getSubject().isLiteral())
909:                    return true;
910:
911:                if (JenaParameters.enableFilteringOfHiddenInfNodes
912:                        && hiddenNodes != null) {
913:                    if (hiddenNodes.contains(t.getSubject())
914:                            || hiddenNodes.contains(t.getObject())
915:                            || hiddenNodes.contains(t.getPredicate())) {
916:                        return true;
917:                    }
918:                }
919:
920:                if (filterFunctors) {
921:                    if (Functor.isFunctor(t.getObject())) {
922:                        return true;
923:                    }
924:                }
925:
926:                return false;
927:
928:            }
929:
930:            //  =======================================================================
931:            //   Inner classes
932:
933:            /**
934:             * Structure used to wrap up pre-processed/compiled rule sets.
935:             */
936:            public static class RuleStore {
937:
938:                /** The raw rules */
939:                protected List rawRules;
940:
941:                /** The indexed store used by the forward chainer */
942:                protected Object fRuleStore;
943:
944:                /** The separated backward rules */
945:                protected List bRules;
946:
947:                /** 
948:                 * Constructor.
949:                 */
950:                public RuleStore(List rawRules, Object fRuleStore, List bRules) {
951:                    this .rawRules = rawRules;
952:                    this .fRuleStore = fRuleStore;
953:                    this .bRules = bRules;
954:                }
955:
956:            }
957:
958:        }
959:
960:        /*
961:         (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
962:         All rights reserved.
963:
964:         Redistribution and use in source and binary forms, with or without
965:         modification, are permitted provided that the following conditions
966:         are met:
967:
968:         1. Redistributions of source code must retain the above copyright
969:         notice, this list of conditions and the following disclaimer.
970:
971:         2. Redistributions in binary form must reproduce the above copyright
972:         notice, this list of conditions and the following disclaimer in the
973:         documentation and/or other materials provided with the distribution.
974:
975:         3. The name of the author may not be used to endorse or promote products
976:         derived from this software without specific prior written permission.
977:
978:         THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
979:         IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
980:         OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
981:         IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
982:         INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
983:         NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
984:         DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
985:         THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
986:         (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
987:         THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
988:         */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.