1 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.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 43 public class FBRuleInfGraph extends BasicForwardRuleInfGraph implements BackwardRuleInfGraphI, Filter { 44 45 46 protected BBRuleContext context; 47 48 49 protected Finder dataFind; 50 51 52 protected LPBRuleEngine bEngine; 53 54 55 protected List rawRules; 56 57 58 protected List rules; 59 60 61 public static boolean useRETE = true; 62 63 64 protected boolean useTGCCaching = false; 65 66 67 public boolean filterFunctors = true; 68 69 70 protected TransitiveEngine transitiveEngine; 71 72 73 protected List preprocessorHooks; 74 75 76 protected TempNodeCache tempNodecache; 77 78 79 protected Set hiddenNodes; 80 81 static Log logger = LogFactory.getLog(FBRuleInfGraph.class); 82 83 86 91 public FBRuleInfGraph(Reasoner reasoner, Graph schema) { 92 super(reasoner, schema); 93 constructorInit(schema); 94 } 95 96 102 public FBRuleInfGraph(Reasoner reasoner, List rules, Graph schema) { 103 super(reasoner, rules, schema); 104 this.rawRules = rules; 105 constructorInit(schema); 106 } 107 108 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 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 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 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 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 187 188 193 public ExtendedIterator findDataMatches(Node subject, Node predicate, Node object) { 194 return dataFind.find(new TriplePattern(subject, predicate, object)); 195 } 196 197 202 public ExtendedIterator findDataMatches(TriplePattern pattern) { 203 return dataFind.find(pattern); 204 } 205 206 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 } 224 225 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 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 252 public void addBRules(List rules) { 253 for (Iterator i = rules.iterator(); i.hasNext(); ) { 254 Rule rule = (Rule)i.next(); 255 bEngine.addRule(rule); 257 } 258 bEngine.reset(); 259 } 260 261 265 public List getBRules() { 266 return bEngine.getAllRules(); 267 } 268 269 273 public List getRules() { 274 return rules; 275 } 276 277 280 public void setTabled(Node predicate) { 281 bEngine.tablePredicate(predicate); 282 if (traceOn) { 283 logger.info("LP TABLE " + predicate); 284 } 285 } 286 287 291 private Object getForwardRuleStore() { 292 return engine.getRuleStore(); 293 } 294 295 298 public void addDeduction(Triple t) { 299 getCurrentDeductionsGraph().add(t); 300 if (useTGCCaching) { 301 transitiveEngine.add(t); 302 } 303 } 304 305 312 public Node getTemp(Node instance, Node prop, Node pclass) { 313 return tempNodecache.getTemp(instance, prop, pclass); 314 } 315 316 319 325 public void addRuleDuringPrepare(Rule rule) { 326 if (rules == rawRules) { 327 if (rawRules instanceof ArrayList) { 329 rules = (ArrayList) ((ArrayList)rawRules).clone(); 330 } else { 331 rules = new ArrayList(rawRules); 332 } 333 instantiateRuleEngine(rules); 335 } 336 rules.add(rule); 337 } 338 339 343 public void addPreprocessingHook(RulePreprocessHook hook) { 344 if (preprocessorHooks == null) { 345 preprocessorHooks = new ArrayList(); 346 } 347 preprocessorHooks.add(hook); 348 } 349 350 358 public void prepare() { 359 if (!isPrepared) { 360 isPrepared = true; 361 362 rules = rawRules; 364 365 Graph data = null; 367 if (fdata != null) data = fdata.getGraph(); 368 369 fdeductions = new FGraph( new GraphMem() ); 371 dataFind = (data == null) ? fdeductions : FinderUtil.cascade(fdeductions, fdata); 372 Finder dataSource = fdata; 373 374 if (useTGCCaching) { 376 if (schemaGraph != null) { 377 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 transitiveEngine.insert(((FBRuleInfGraph)schemaGraph).fdata, fdata); 387 } 388 } else { 389 if (data != null) { 390 transitiveEngine.insert(null, fdata); 391 } 392 } 393 for (Iterator i = rules.iterator(); i.hasNext(); ) { 395 Rule r = (Rule)i.next(); 396 if (r.bodyLength() == 0) { 397 for (int j = 0; j < r.headLength(); j++) { 399 Object 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(dataFind, transitiveEngine.getSubClassCache(), transitiveEngine.getSubPropertyCache()); 411 412 dataSource = FinderUtil.cascade(dataSource, transitiveEngine.getSubClassCache(), transitiveEngine.getSubPropertyCache()); 414 } 415 416 bEngine.deleteAllRules(); 418 419 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 addBRules(extractPureBackwardRules(rules)); 446 engine.init(true, dataSource); 447 } 448 context = new BBRuleContext(this); 450 451 } 452 } 453 454 461 public void rebind() { 462 if (bEngine != null) bEngine.reset(); 463 isPrepared = false; 464 } 465 466 470 public void setTraceOn(boolean state) { 471 super.setTraceOn(state); 472 bEngine.setTraceOn(state); 473 } 474 475 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 493 public void setFunctorFiltering(boolean param) { 494 filterFunctors = param; 495 } 496 497 503 public long getNRulesFired() { 504 return engine.getNRulesFired(); 505 } 506 507 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(this); 528 } else { 529 return result; 530 } 531 } 532 533 537 public ExtendedIterator findFull(TriplePattern pattern) { 538 checkOpen(); 539 if (!isPrepared) prepare(); 540 return new UniqueExtendedIterator(bEngine.find(pattern)); 541 } 542 543 548 public ExtendedIterator graphBaseFind(Node subject, Node property, Node object) { 549 return findWithContinuation(new TriplePattern(subject, property, object), null); 550 } 551 552 560 public ExtendedIterator find(TriplePattern pattern) { 561 return findWithContinuation(pattern, null); 562 } 563 564 567 public void reset() { 568 bEngine.reset(); 569 isPrepared = false; 570 } 571 572 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 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 if (isPrepared) { 606 bEngine.deleteAllRules(); 607 isPrepared = false; 608 } 611 bEngine.reset(); 612 } 613 614 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 graph.rebind(premises); 632 return graph; 633 } 634 635 638 public void close() { 639 if (!closed) { 640 bEngine.halt(); 641 bEngine = null; 642 transitiveEngine = null; 643 super.close(); 644 } 645 } 646 647 651 657 public ValidityReport validate() { 658 checkOpen(); 659 StandardValidityReport report = new StandardValidityReport(); 660 Triple validateOn = new Triple(Node.createAnon(), 662 ReasonerVocabulary.RB_VALIDATION.asNode(), 663 Functor.makeFunctorNode("on", new Node[] {})); 664 if (!isPrepared) { 668 prepare(); 669 } 670 engine.add(validateOn); 671 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 rVal = rNode.getLiteral().getValue(); 679 if (rVal instanceof Functor) { 680 Functor rFunc = (Functor)rVal; 681 foundReport = true; 682 StringBuffer description = new StringBuffer (); 683 String nature = rFunc.getName(); 684 String type = rFunc.getArgs()[0].toString(); 685 String 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 return report; 710 } 711 712 715 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 737 protected boolean preloadDeductions(Graph preloadIn) { 738 Graph d = fdeductions.getGraph(); 739 FBRuleInfGraph preload = (FBRuleInfGraph)preloadIn; 740 if (preload.rules == rules) { 742 for (Iterator i = preload.getDeductionsGraph().find(null, null, null); i.hasNext(); ) { 744 d.add((Triple)i.next()); 745 } 746 addBRules(preload.getBRules()); 748 engine.setRuleStore(preload.getForwardRuleStore()); 750 return true; 752 } else { 753 return false; 754 } 755 } 756 757 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 773 778 public void resetLPProfile(boolean enable) { 779 bEngine.resetProfile(enable); 780 } 781 782 785 public void printLPProfile() { 786 bEngine.printProfile(); 787 } 788 789 792 798 public boolean accept(Object 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 822 825 public static class RuleStore { 826 827 828 protected List rawRules; 829 830 831 protected Object fRuleStore; 832 833 834 protected List bRules; 835 836 839 public RuleStore(List rawRules, Object fRuleStore, List bRules) { 840 this.rawRules = rawRules; 841 this.fRuleStore = fRuleStore; 842 this.bRules = bRules; 843 } 844 845 } 846 847 848 } 849 850 851 | Popular Tags |