📄 rdfsinfgraph.java
字号:
/******************************************************************
* File: RDFSInfGraph.java
* Created by: Dave Reynolds
* Created on: 21-Jan-03
*
* (c) Copyright 2003, 2004, 2005, 2006, 2007 Hewlett-Packard Development Company, LP
* [See end of file]
* $Id: RDFSInfGraph.java,v 1.24 2007/01/02 11:48:52 andy_seaborne Exp $
*****************************************************************/
package com.hp.hpl.jena.reasoner.rdfsReasoner1;
import com.hp.hpl.jena.reasoner.*;
import com.hp.hpl.jena.reasoner.transitiveReasoner.*;
import com.hp.hpl.jena.datatypes.*;
import com.hp.hpl.jena.graph.*;
import com.hp.hpl.jena.graph.impl.*;
import com.hp.hpl.jena.vocabulary.*;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.util.iterator.UniqueExtendedIterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.*;
/**
* An RDFS reasoner that has been bound to both a TBox and an ABox.
* It cannot be bound any futher. Once this Bound reasoner has been
* created all the class, property and associated declarations have
* been extracted and cached and all queries are answerable directly
* from the cached results or from query rewrites.
*
* <p>Initially the subClass/subProperty caches are shared with
* the parent RDFSReasoner so they can be shared across instance data.
* However, if any update includes any such declarations then the caches
* have to be cloned and separated.</p>
*
* @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
* @version $Revision: 1.24 $ on $Date: 2007/01/02 11:48:52 $
*/
public class RDFSInfGraph extends BaseInfGraph {
//=======================================================================
// variables
/** The precomputed cache of the subClass graph */
protected TransitiveGraphCache subClassCache;
/** Flag to indicate that this cache has already been split off from
* the parent reasoner */
protected boolean haveSplitSubClassCache = false;
/** The precomputed cache of the subProperty graph */
protected TransitiveGraphCache subPropertyCache;
/** Router which maps queries onto different cache components that can answer then */
protected PatternRouter router;
/** Cache of axiomatci triples to be included in the tripleCache */
protected FGraph axioms = new FGraph(Factory.createGraphMem());
/** The data supplied as a tbox, may be null, will be included as part of tripleCache if not null */
protected Finder tbox;
/** Cache of precomputed triples which are added to data - this includes
* the tbox, axioms and forward deductions */
protected Finder tripleCache;
/** Optional map of property node to datatype ranges */
protected HashMap dtRange = null;
/** Flag to control whether properties are eagerly scanned */
protected boolean scanProperties = true;
//=======================================================================
// static rules and axioms
protected static Log logger = LogFactory.getLog(RDFSInfGraph.class);
/** The RDFS forward rule set */
protected static BaseFRule[] rules = new BaseFRule[] {
new AssertFRule("?x rdf:type rdfs:Class -> ?x rdfs:subClassOf rdfs:Resource"),
new AssertFRule("?x rdf:type rdfs:Class -> ?x rdfs:subClassOf ?x"),
new AssertFRule("?x rdf:type rdf:Property -> ?x rdfs:subPropertyOf ?x"),
new BackchainFRule("?p rdfs:subPropertyOf ?q -> ?s ?q ?o <- ?s ?p ?o"),
new BackchainFRule("?c rdfs:subClassOf ?d -> ?s rdf:type ?d <- ?s rdf:type ?c"),
new BackchainFRule("?p rdfs:domain ?z -> ?s rdf:type ?z <- ?s ?p _"),
new BackchainFRule("?p rdfs:range ?z -> ?o rdf:type ?z <- _ ?p ?s")
}; // end of RDFS rule set definitions
/** The RDFS special case backward rule set */
protected static BRWRule[] brules = new BRWRule[] {
new ResourceBRWRule(),
new PropertyBRWRule()
};
/** The RDFS built in axioms */
protected static Triple[] baseAxioms = new Triple[] {
BaseFRule.parseTriple("rdf:type rdfs:range rdfs:Class"),
BaseFRule.parseTriple("rdfs:Resource rdf:type rdfs:Class"),
BaseFRule.parseTriple("rdfs:Literal rdf:type rdfs:Class"),
BaseFRule.parseTriple("rdf:Statement rdf:type rdfs:Class"),
BaseFRule.parseTriple("rdf:nil rdf:type rdf:List"),
BaseFRule.parseTriple("rdf:XMLLiteral rdf:type rdfs:Datatype"),
BaseFRule.parseTriple("rdf:Alt rdf:type rdfs:Class"),
BaseFRule.parseTriple("rdf:Seq rdf:type rdfs:Class"),
BaseFRule.parseTriple("rdf:Bag rdf:type rdfs:Class"),
BaseFRule.parseTriple("rdf:XMLLiteral rdf:type rdfs:Class"),
BaseFRule.parseTriple("rdfs:Container rdf:type rdfs:Class"),
BaseFRule.parseTriple("rdfs:ContainerMembershipProperty rdf:type rdfs:Class"),
BaseFRule.parseTriple("rdfs:isDefinedBy rdf:type rdf:Property"),
BaseFRule.parseTriple("rdfs:seeAlso rdf:type rdf:Property"),
BaseFRule.parseTriple("rdfs:comment rdf:type rdf:Property"),
BaseFRule.parseTriple("rdfs:label rdf:type rdf:Property"),
BaseFRule.parseTriple("rdf:subject rdf:type rdf:Property"),
BaseFRule.parseTriple("rdf:predicate rdf:type rdf:Property"),
BaseFRule.parseTriple("rdf:object rdf:type rdf:Property"),
BaseFRule.parseTriple("rdf:first rdf:type rdf:Property"),
BaseFRule.parseTriple("rdf:rest rdf:type rdf:Property"),
BaseFRule.parseTriple("rdf:type rdf:type rdf:Property"),
BaseFRule.parseTriple("rdfs:range rdf:type rdf:Property"),
BaseFRule.parseTriple("rdfs:domain rdf:type rdf:Property"),
BaseFRule.parseTriple("rdfs:subPropertyOf rdfs:domain rdf:Property"),
BaseFRule.parseTriple("rdfs:subPropertyOf rdfs:range rdf:Property"),
BaseFRule.parseTriple("rdfs:subClassOf rdfs:domain rdfs:Class"),
BaseFRule.parseTriple("rdfs:subClassOf rdfs:range rdfs:Class"),
// These may be redundant
BaseFRule.parseTriple("rdfs:subPropertyOf rdfs:subPropertyOf rdfs:subPropertyOf"),
BaseFRule.parseTriple("rdfs:subClassOf rdfs:subPropertyOf rdfs:subClassOf"),
BaseFRule.parseTriple("rdf:subject rdfs:subPropertyOf rdf:subject"),
BaseFRule.parseTriple("rdf:predicate rdfs:subPropertyOf rdf:predicate"),
BaseFRule.parseTriple("rdf:object rdfs:subPropertyOf rdf:object"),
BaseFRule.parseTriple("rdf:first rdfs:subPropertyOf rdf:first"),
BaseFRule.parseTriple("rdf:rest rdfs:subPropertyOf rdf:rest"),
BaseFRule.parseTriple("rdf:type rdfs:subPropertyOf rdf:type"),
BaseFRule.parseTriple("rdfs:range rdfs:subPropertyOf rdfs:range"),
BaseFRule.parseTriple("rdfs:domain rdfs:subPropertyOf rdfs:domain")
};
//=======================================================================
// constructors
/**
* Constructor
* @param data the raw data graph being bound to the reasoner
* @param reasoner the RDFSReasoner which spawned this InfGraph
*/
public RDFSInfGraph( RDFSReasoner reasoner, Graph data) {
super(data, reasoner);
this.scanProperties = reasoner.scanProperties;
}
//=======================================================================
// global methods
/**
* Returns the scanProperties flag.
*
* <p>If this is set to true then when a reasoner instance is constructed
* the whole data graph is scanned to detect all properties and the
* results are cached. This is expensive but without this
* some cases of rdf:_n properties will not be handled.</p>
*
* <p>This method is just here for development purposes and will
* be replaced by the configuration machinery</p>
* @return boolean
*/
public boolean getScanProperties() {
return scanProperties;
}
/**
* Sets the scanProperties flag
*
* <p>If this is set to true then when a reasoner instance is constructed
* the whole data graph is scanned to detect all properties and the
* results are cached. This is expensive but without this
* some cases of rdf:_n properties will not be handled.</p>
*
* <p>This method is just here for development purposes and will
* be replaced by the configuration machinery</p>
* @param scanProperties The scanProperties to set
*/
public void setScanProperties(boolean scanProperties) {
this.scanProperties = scanProperties;
}
//=======================================================================
// methods
/**
* Return the schema graph, if any, bound into this inference graph.
*/
public Graph getSchemaGraph() {
if (tbox == null) return null;
if (tbox instanceof FGraph) {
return ((FGraph)tbox).getGraph();
} else {
throw new ReasonerException("RDFS1 reasoner got into an illegal state");
}
}
/**
* Perform any initial processing and caching. This call is optional. Most
* engines either have negligable set up work or will perform an implicit
* "prepare" if necessary. The call is provided for those occasions where
* substantial preparation work is possible (e.g. running a forward chaining
* rule system) and where an application might wish greater control over when
* this prepration is done.
*/
public void prepare() {
this.subClassCache = ((TransitiveReasoner)reasoner).getSubClassCache();
this.subPropertyCache = ((TransitiveReasoner)reasoner).getSubPropertyCache().deepCopy();
this.tbox = ((TransitiveReasoner)reasoner).getTbox();
haveSplitSubClassCache = false;
// Combine a place to hold axioms and local deductions and the tbox into single cache
if (tbox == null) {
tripleCache = axioms;
} else {
tripleCache = FinderUtil.cascade(axioms, tbox);
}
// Check for vocabulary definitions in the data graph
Graph data = fdata.getGraph();
if (
(TransitiveEngine.checkOccuranceUtility(RDFSReasoner.subPropertyOf, data, subPropertyCache) ||
TransitiveEngine.checkOccuranceUtility(RDFSReasoner.subClassOf, data, subPropertyCache) ||
TransitiveEngine.checkOccuranceUtility(RDFSReasoner.domainP, data, subPropertyCache) ||
TransitiveEngine.checkOccuranceUtility(RDFSReasoner.rangeP, data, subPropertyCache) )) {
// The data graph contains some ontology knowledge so split the caches
// now and rebuild them using merged data
Finder tempTbox = tbox == null ? fdata : FinderUtil.cascade(tbox, fdata);
splitSubClassCache();
TransitiveEngine.cacheSubPropUtility(tempTbox, subPropertyCache);
TransitiveEngine.cacheSubClassUtility(tempTbox, subPropertyCache, subClassCache);
// Cache the closures of subPropertyOf because these are likely to be
// small and accessed a lot
subPropertyCache.setCaching(true);
}
// add axioms
for (int i = 0; i < baseAxioms.length; i++) {
axioms.getGraph().add(baseAxioms[i]);
}
TransitiveEngine.cacheSubPropUtility(axioms, subPropertyCache);
// identify all properties and collection properties
// This can be disabled in which case queries of the form (*,type,Property) will be
// slower and no ContainerMembershipProperty assertions will be detected
if (scanProperties) {
ExtendedIterator it = tripleCache.findWithContinuation(new TriplePattern(null, null, null), fdata);
HashSet properties = new HashSet();
String memberPrefix = RDF.getURI() + "_";
Node sP = RDF.Property.asNode();
while (it.hasNext()) {
Triple triple = (Triple)it.next();
Node prop = triple.getPredicate();
if (prop.equals(RDF.type.asNode()) && prop.equals(RDF.Property.asNode()) ) {
prop = triple.getSubject();
}
if (properties.add(prop)) {
// Unseen property - add the subPropertyOf statement
subPropertyCache.addRelation(new Triple(prop, sP, prop));
if (prop.getURI().startsWith(memberPrefix)) {
// A container property
axioms.getGraph().add(new Triple(prop, RDF.type.asNode(), RDFS.ContainerMembershipProperty.asNode()));
subPropertyCache.addRelation( new Triple(prop, sP, RDFS.member.asNode()));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -