1 10 package com.hp.hpl.jena.reasoner.rdfsReasoner1; 11 12 import com.hp.hpl.jena.reasoner.*; 13 import com.hp.hpl.jena.reasoner.transitiveReasoner.*; 14 import com.hp.hpl.jena.datatypes.*; 15 import com.hp.hpl.jena.graph.*; 16 import com.hp.hpl.jena.graph.impl.*; 17 import com.hp.hpl.jena.mem.GraphMem; 18 import com.hp.hpl.jena.vocabulary.*; 19 import com.hp.hpl.jena.util.iterator.ExtendedIterator; 20 import com.hp.hpl.jena.util.iterator.UniqueExtendedIterator; 21 22 import org.apache.commons.logging.Log; 23 import org.apache.commons.logging.LogFactory; 24 25 import java.util.*; 26 27 42 public class RDFSInfGraph extends BaseInfGraph { 43 44 47 48 protected TransitiveGraphCache subClassCache; 49 50 52 protected boolean haveSplitSubClassCache = false; 53 54 55 protected TransitiveGraphCache subPropertyCache; 56 57 58 protected PatternRouter router; 59 60 61 protected FGraph axioms = new FGraph(new GraphMem()); 62 63 64 protected Finder tbox; 65 66 68 protected Finder tripleCache; 69 70 71 protected HashMap dtRange = null; 72 73 74 protected boolean scanProperties = true; 75 76 79 protected static Log logger = LogFactory.getLog(RDFSInfGraph.class); 80 81 82 protected static BaseFRule[] rules = new BaseFRule[] { 83 new AssertFRule("?x rdf:type rdfs:Class -> ?x rdfs:subClassOf rdfs:Resource"), 84 new AssertFRule("?x rdf:type rdfs:Class -> ?x rdfs:subClassOf ?x"), 85 new AssertFRule("?x rdf:type rdf:Property -> ?x rdfs:subPropertyOf ?x"), 86 new BackchainFRule("?p rdfs:subPropertyOf ?q -> ?s ?q ?o <- ?s ?p ?o"), 87 new BackchainFRule("?c rdfs:subClassOf ?d -> ?s rdf:type ?d <- ?s rdf:type ?c"), 88 new BackchainFRule("?p rdfs:domain ?z -> ?s rdf:type ?z <- ?s ?p _"), 89 new BackchainFRule("?p rdfs:range ?z -> ?o rdf:type ?z <- _ ?p ?s") 90 }; 92 93 protected static BRWRule[] brules = new BRWRule[] { 94 new ResourceBRWRule(), 95 new PropertyBRWRule() 96 }; 97 98 99 protected static Triple[] baseAxioms = new Triple[] { 100 BaseFRule.parseTriple("rdf:type rdfs:range rdfs:Class"), 101 102 BaseFRule.parseTriple("rdfs:Resource rdf:type rdfs:Class"), 103 BaseFRule.parseTriple("rdfs:Literal rdf:type rdfs:Class"), 104 BaseFRule.parseTriple("rdf:Statement rdf:type rdfs:Class"), 105 BaseFRule.parseTriple("rdf:nil rdf:type rdf:List"), 106 BaseFRule.parseTriple("rdf:XMLLiteral rdf:type rdfs:Datatype"), 107 108 BaseFRule.parseTriple("rdf:Alt rdf:type rdfs:Class"), 109 BaseFRule.parseTriple("rdf:Seq rdf:type rdfs:Class"), 110 BaseFRule.parseTriple("rdf:Bag rdf:type rdfs:Class"), 111 BaseFRule.parseTriple("rdf:XMLLiteral rdf:type rdfs:Class"), 112 BaseFRule.parseTriple("rdfs:Container rdf:type rdfs:Class"), 113 BaseFRule.parseTriple("rdfs:ContainerMembershipProperty rdf:type rdfs:Class"), 114 115 BaseFRule.parseTriple("rdfs:isDefinedBy rdf:type rdf:Property"), 116 BaseFRule.parseTriple("rdfs:seeAlso rdf:type rdf:Property"), 117 BaseFRule.parseTriple("rdfs:comment rdf:type rdf:Property"), 118 BaseFRule.parseTriple("rdfs:label rdf:type rdf:Property"), 119 120 BaseFRule.parseTriple("rdf:subject rdf:type rdf:Property"), 121 BaseFRule.parseTriple("rdf:predicate rdf:type rdf:Property"), 122 BaseFRule.parseTriple("rdf:object rdf:type rdf:Property"), 123 BaseFRule.parseTriple("rdf:first rdf:type rdf:Property"), 124 BaseFRule.parseTriple("rdf:rest rdf:type rdf:Property"), 125 BaseFRule.parseTriple("rdf:type rdf:type rdf:Property"), 126 BaseFRule.parseTriple("rdfs:range rdf:type rdf:Property"), 127 BaseFRule.parseTriple("rdfs:domain rdf:type rdf:Property"), 128 129 BaseFRule.parseTriple("rdfs:subPropertyOf rdfs:domain rdf:Property"), 130 BaseFRule.parseTriple("rdfs:subPropertyOf rdfs:range rdf:Property"), 131 BaseFRule.parseTriple("rdfs:subClassOf rdfs:domain rdfs:Class"), 132 BaseFRule.parseTriple("rdfs:subClassOf rdfs:range rdfs:Class"), 133 134 BaseFRule.parseTriple("rdfs:subPropertyOf rdfs:subPropertyOf rdfs:subPropertyOf"), 136 BaseFRule.parseTriple("rdfs:subClassOf rdfs:subPropertyOf rdfs:subClassOf"), 137 BaseFRule.parseTriple("rdf:subject rdfs:subPropertyOf rdf:subject"), 138 BaseFRule.parseTriple("rdf:predicate rdfs:subPropertyOf rdf:predicate"), 139 BaseFRule.parseTriple("rdf:object rdfs:subPropertyOf rdf:object"), 140 BaseFRule.parseTriple("rdf:first rdfs:subPropertyOf rdf:first"), 141 BaseFRule.parseTriple("rdf:rest rdfs:subPropertyOf rdf:rest"), 142 BaseFRule.parseTriple("rdf:type rdfs:subPropertyOf rdf:type"), 143 BaseFRule.parseTriple("rdfs:range rdfs:subPropertyOf rdfs:range"), 144 BaseFRule.parseTriple("rdfs:domain rdfs:subPropertyOf rdfs:domain") 145 }; 146 147 150 155 public RDFSInfGraph( RDFSReasoner reasoner, Graph data) { 156 super(data, reasoner); 157 this.scanProperties = reasoner.scanProperties; 158 } 159 160 163 175 public boolean getScanProperties() { 176 return scanProperties; 177 } 178 179 191 public void setScanProperties(boolean scanProperties) { 192 this.scanProperties = scanProperties; 193 } 194 195 198 201 public Graph getSchemaGraph() { 202 if (tbox == null) return null; 203 if (tbox instanceof FGraph) { 204 return ((FGraph)tbox).getGraph(); 205 } else { 206 throw new ReasonerException("RDFS1 reasoner got into an illegal state"); 207 } 208 } 209 210 218 public void prepare() { 219 this.subClassCache = ((TransitiveReasoner)reasoner).getSubClassCache(); 220 this.subPropertyCache = ((TransitiveReasoner)reasoner).getSubPropertyCache().deepCopy(); 221 this.tbox = ((TransitiveReasoner)reasoner).getTbox(); 222 haveSplitSubClassCache = false; 223 224 if (tbox == null) { 226 tripleCache = axioms; 227 } else { 228 tripleCache = FinderUtil.cascade(axioms, tbox); 229 } 230 231 Graph data = fdata.getGraph(); 233 if ( 234 (TransitiveEngine.checkOccuranceUtility(RDFSReasoner.subPropertyOf, data, subPropertyCache) || 235 TransitiveEngine.checkOccuranceUtility(RDFSReasoner.subClassOf, data, subPropertyCache) || 236 TransitiveEngine.checkOccuranceUtility(RDFSReasoner.domainP, data, subPropertyCache) || 237 TransitiveEngine.checkOccuranceUtility(RDFSReasoner.rangeP, data, subPropertyCache) )) { 238 239 Finder tempTbox = tbox == null ? fdata : FinderUtil.cascade(tbox, fdata); 242 243 splitSubClassCache(); 244 TransitiveEngine.cacheSubPropUtility(tempTbox, subPropertyCache); 245 TransitiveEngine.cacheSubClassUtility(tempTbox, subPropertyCache, subClassCache); 246 subPropertyCache.setCaching(true); 249 } 250 251 for (int i = 0; i < baseAxioms.length; i++) { 253 axioms.getGraph().add(baseAxioms[i]); 254 } 255 TransitiveEngine.cacheSubPropUtility(axioms, subPropertyCache); 256 257 if (scanProperties) { 261 ExtendedIterator it = tripleCache.findWithContinuation(new TriplePattern(null, null, null), fdata); 262 HashSet properties = new HashSet(); 263 String memberPrefix = RDF.getURI() + "_"; 264 Node sP = RDF.Property.getNode(); 265 while (it.hasNext()) { 266 Triple triple = (Triple)it.next(); 267 Node prop = triple.getPredicate(); 268 if (prop.equals(RDF.type.getNode()) && prop.equals(RDF.Property.getNode()) ) { 269 prop = triple.getSubject(); 270 } 271 if (properties.add(prop)) { 272 subPropertyCache.addRelation(new Triple(prop, sP, prop)); 274 if (prop.getURI().startsWith(memberPrefix)) { 275 axioms.getGraph().add(new Triple(prop, RDF.type.getNode(), RDFS.ContainerMembershipProperty.getNode())); 277 subPropertyCache.addRelation( new Triple(prop, sP, RDFS.member.getNode())); 278 } 279 } 280 } 281 } 282 283 router = new PatternRouter(); 285 router.register(subPropertyCache); 286 router.register(subClassCache); 287 288 checkAllForwardRules(); 290 291 for (int i = 0; i < brules.length; i++) { 293 addBRule(brules[i]); 294 } 295 296 isPrepared = true; 297 } 298 299 310 public ExtendedIterator findWithContinuation(TriplePattern pattern, Finder continuation) { 311 checkOpen(); 312 if (!isPrepared) prepare(); 313 return new UniqueExtendedIterator(router.find(pattern, tripleCache, continuation,this)); 314 } 315 316 321 public ExtendedIterator findNested(TriplePattern pattern, Finder continuation, HashSet firedRules) { 322 return router.find(pattern, tripleCache, continuation,this, firedRules); 323 } 324 325 329 public ExtendedIterator findRawWithContinuation(TriplePattern pattern, Finder continuation) { 330 return tripleCache.findWithContinuation(pattern, continuation); 331 } 332 333 338 public ExtendedIterator findProperties() { 339 return subPropertyCache.listAllSubjects(); 340 } 341 342 346 public boolean isProperty(Node prop) { 347 return subPropertyCache.isSubject(prop); 348 } 349 350 356 public ValidityReport validate() { 357 StandardValidityReport report = new StandardValidityReport(); 358 HashMap dtRange = getDTRange(); 359 for (Iterator props = dtRange.keySet().iterator(); props.hasNext(); ) { 360 Node prop = (Node)props.next(); 361 for (Iterator i = find(null, prop, null); i.hasNext(); ) { 362 Triple triple = (Triple)i.next(); 363 report.add(checkLiteral(prop, triple.getObject())); 364 } 365 } 366 return report; 367 } 368 369 372 376 private HashMap getDTRange() { 377 if (dtRange == null) { 378 dtRange = new HashMap(); 379 for (Iterator i = find(null, RDFS.range.asNode(), null); i.hasNext(); ) { 380 Triple triple = (Triple)i.next(); 381 Node prop = triple.getSubject(); 382 Node rangeValue = triple.getObject(); 383 if (rangeValue.isURI()) { 384 RDFDatatype dt = TypeMapper.getInstance().getTypeByName(rangeValue.getURI()); 385 if (dt != null) { 386 List range = (ArrayList) dtRange.get(prop); 387 if (range == null) { 388 range = new ArrayList(); 389 dtRange.put(prop, range); 390 } 391 range.add(dt); 392 } 393 } 394 } 395 } 396 return dtRange; 397 } 398 399 407 private ValidityReport.Report checkLiteral(Node prop, Node value) { 408 List range = (List) getDTRange().get(prop); 409 if (range != null) { 410 if (!value.isLiteral()) { 411 return new ValidityReport.Report(true, "dtRange", 412 "Property " + prop + " has a typed range but was given a non literal value " + value); 413 } 414 LiteralLabel ll = value.getLiteral(); 415 for (Iterator i = range.iterator(); i.hasNext(); ) { 416 RDFDatatype dt = (RDFDatatype)i.next(); 417 if (!dt.isValidLiteral(ll)) { 418 return new ValidityReport.Report(true, "dtRange", 419 "Property " + prop + " has a typed range " + dt + 420 "that is not compatible with " + value); 421 } 422 } 423 } 424 return null; 425 } 426 427 432 private void checkAllForwardRules() { 433 Finder caches = FinderUtil.cascade(subPropertyCache, subClassCache, tripleCache); 435 for (int i = 0; i < rules.length; i++) { 437 BaseFRule rule = rules[i]; 438 TriplePattern head = rule.getHead(); 439 Node pPattern = head.getPredicate(); 440 if (pPattern.isVariable()) { 441 checkRule(head, rule, caches); 442 } else { 443 TriplePattern spPatt = new TriplePattern(null, TransitiveReasoner.subPropertyOf, pPattern); 445 ExtendedIterator sps = subPropertyCache.find(spPatt); 446 while (sps.hasNext()) { 447 TriplePattern altHead = new TriplePattern( 448 head.getSubject(), 449 ((Triple)sps.next()).getSubject(), 450 head.getObject()); 451 checkRule(altHead, rule, caches); 452 } 453 } 454 } 455 } 456 457 460 private void checkRule(TriplePattern altHead, BaseFRule rule, Finder caches) { 461 Iterator it = caches.findWithContinuation(altHead, fdata); 462 while (it.hasNext()) { 463 Triple t = (Triple)it.next(); 464 rule.bindAndFire(t, this); 465 } 466 } 467 468 469 473 public void assertTriple(Triple t) { 474 axioms.getGraph().add(t); 475 } 476 477 481 public void addBRule(BRWRule rule) { 482 router.register(rule); 483 } 484 485 489 private void splitSubClassCache() { 490 if (!haveSplitSubClassCache) { 491 subClassCache = subClassCache.deepCopy(); 492 haveSplitSubClassCache = true; 493 } 494 } 495 496 500 public String toString() { 501 StringBuffer state = new StringBuffer (); 502 TriplePattern all = new TriplePattern(null, null, null); 503 if (tripleCache != null) { 504 state.append("axioms + tbox\n"); 505 for (Iterator i = tripleCache.find(all); i.hasNext(); ) { 506 state.append(TriplePattern.simplePrintString((Triple)i.next())); 507 state.append("\n"); 508 } 509 } 510 if (fdata != null) { 511 state.append("Bound raw data\n"); 512 for (Iterator i = fdata.find(all); i.hasNext(); ) { 513 state.append(TriplePattern.simplePrintString((Triple)i.next())); 514 state.append("\n"); 515 } 516 } 517 if (router != null) { 518 state.append("Rule set\n"); 519 state.append(router.toString()); 520 } 521 return state.toString(); 522 } 523 524 } 525 526 555 | Popular Tags |