001: /******************************************************************
002: * File: TransitiveReasoner.java
003: * Created by: Dave Reynolds
004: * Created on: 16-Jan-03
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: TransitiveReasoner.java,v 1.24 2008/01/02 12:07:50 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.transitiveReasoner;
010:
011: import com.hp.hpl.jena.rdf.model.*;
012: import com.hp.hpl.jena.reasoner.*;
013: import com.hp.hpl.jena.graph.*;
014: import com.hp.hpl.jena.vocabulary.RDFS;
015: import com.hp.hpl.jena.vocabulary.ReasonerVocabulary;
016:
017: /**
018: * A simple "reasoner" used to help with API development.
019: * <p>This reasoner caches a transitive closure of the subClass and
020: * subProperty graphs. The generated infGraph allows both the direct
021: * and closed versions of these properties to be retrieved. The cache is
022: * built when the tbox is bound in but if the final data graph
023: * contains additional subProperty/subClass declarations then the
024: * cache has to be rebuilt.</p>
025: * <p>
026: * The triples in the tbox (if present) will also be included
027: * in any query. Any of tbox or data graph are allowed to be null.</p>
028: *
029: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
030: * @version $Revision: 1.24 $ on $Date: 2008/01/02 12:07:50 $
031: */
032: public class TransitiveReasoner implements Reasoner {
033:
034: /** The precomputed cache of the subClass graph */
035: protected TransitiveGraphCache subClassCache;
036:
037: /** The precomputed cache of the subProperty graph */
038: protected TransitiveGraphCache subPropertyCache;
039:
040: /** The graph registered as the schema, if any */
041: protected Finder tbox = null;
042:
043: /** The direct (minimal) version of the subPropertyOf property */
044: public static final Node directSubPropertyOf = ReasonerRegistry
045: .makeDirect(RDFS.Nodes.subPropertyOf);
046:
047: /** The direct (minimal) version of the subClassOf property */
048: public static final Node directSubClassOf = ReasonerRegistry
049: .makeDirect(RDFS.Nodes.subClassOf);
050:
051: /** The normal subPropertyOf property */
052: public static final Node subPropertyOf = RDFS.Nodes.subPropertyOf;
053:
054: /** The normal subClassOf property */
055: public static final Node subClassOf = RDFS.Nodes.subClassOf;
056:
057: /** The graph capabilities of the infgraphs generated by this reasoner */
058: protected Capabilities capabilities;
059:
060: /** Constructor */
061: public TransitiveReasoner() {
062: subClassCache = new TransitiveGraphCache(directSubClassOf,
063: subClassOf);
064: subPropertyCache = new TransitiveGraphCache(
065: directSubPropertyOf, subPropertyOf);
066: }
067:
068: /**
069: * Private constructor used by bindSchema when
070: * returning a partially bound reasoner instance.
071: */
072: protected TransitiveReasoner(Finder tbox,
073: TransitiveGraphCache subClassCache,
074: TransitiveGraphCache subPropertyCache) {
075: this .tbox = tbox;
076: this .subClassCache = subClassCache;
077: this .subPropertyCache = subPropertyCache;
078: }
079:
080: /**
081: * Return a description of the capabilities of this reasoner encoded in
082: * RDF. These capabilities may be static or may depend on configuration
083: * information supplied at construction time. May be null if there are
084: * no useful capabilities registered.
085: */
086: public Model getReasonerCapabilities() {
087: return TransitiveReasonerFactory.theInstance()
088: .getCapabilities();
089: }
090:
091: /**
092: * Add a configuration description for this reasoner into a partial
093: * configuration specification model.
094: * @param configSpec a Model into which the configuration information should be placed
095: * @param base the Resource to which the configuration parameters should be added.
096: */
097: public void addDescription(Model configSpec, Resource base) {
098: // No configuration
099: }
100:
101: /**
102: * Determine whether the given property is recognized and treated specially
103: * by this reasoner. This is a convenience packaging of a special case of getCapabilities.
104: * @param property the property which we want to ask the reasoner about, given as a Node since
105: * this is part of the SPI rather than API
106: * @return true if the given property is handled specially by the reasoner.
107: */
108: public boolean supportsProperty(Property property) {
109: ReasonerFactory rf = TransitiveReasonerFactory.theInstance();
110: Model caps = rf.getCapabilities();
111: Resource root = caps.getResource(rf.getURI());
112: return caps.contains(root, ReasonerVocabulary.supportsP,
113: property);
114: }
115:
116: /**
117: * Extracts all of the subClass and subProperty declarations from
118: * the given schema/tbox and caches the resultant graphs.
119: * It can only be used once, can't stack up multiple tboxes this way.
120: * This limitation could be lifted - the only difficulty is the need to
121: * reprocess all the earlier tboxes if a new subPropertyOf subPropertyOf
122: * subClassOf is discovered.
123: * @param tbox schema containing the property and class declarations
124: */
125: public Reasoner bindSchema(Graph tbox) throws ReasonerException {
126: return bindSchema(new FGraph(tbox));
127: }
128:
129: /**
130: * Extracts all of the subClass and subProperty declarations from
131: * the given schema/tbox and caches the resultant graphs.
132: * It can only be used once, can't stack up multiple tboxes this way.
133: * This limitation could be lifted - the only difficulty is the need to
134: * reprocess all the earlier tboxes if a new subPropertyOf subPropertyOf
135: * subClassOf is discovered.
136: * @param tbox schema containing the property and class declarations
137: */
138: public Reasoner bindSchema(Model tbox) throws ReasonerException {
139: return bindSchema(new FGraph(tbox.getGraph()));
140: }
141:
142: /**
143: * Extracts all of the subClass and subProperty declarations from
144: * the given schema/tbox and caches the resultant graphs.
145: * It can only be used once, can't stack up multiple tboxes this way.
146: * This limitation could be lifted - the only difficulty is the need to
147: * reprocess all the earlier tboxes if a new subPropertyOf subPropertyOf
148: * subClassOf is discovered.
149: * @param tbox schema containing the property and class declarations
150: */
151: Reasoner bindSchema(Finder tbox) throws ReasonerException {
152: if (this .tbox != null) {
153: throw new ReasonerException(
154: "Attempt to bind multiple rulesets - disallowed for now");
155: }
156: TransitiveGraphCache sCc = new TransitiveGraphCache(
157: directSubClassOf, subClassOf);
158: TransitiveGraphCache sPc = new TransitiveGraphCache(
159: directSubPropertyOf, subPropertyOf);
160: TransitiveEngine.cacheSubPropUtility(tbox, sPc);
161: TransitiveEngine.cacheSubClassUtility(tbox, sPc, sCc);
162:
163: return new TransitiveReasoner(tbox, sCc, sPc);
164: }
165:
166: /**
167: * Attach the reasoner to a set of RDF ddata to process.
168: * The reasoner may already have been bound to specific rules or ontology
169: * axioms (encoded in RDF) through earlier bindRuleset calls.
170: * @param data the RDF data to be processed, some reasoners may restrict
171: * the range of RDF which is legal here (e.g. syntactic restrictions in OWL).
172: * @return an inference graph through which the data+reasoner can be queried.
173: * @throws ReasonerException if the data is ill-formed according to the
174: * constraints imposed by this reasoner.
175: */
176: public InfGraph bind(Graph data) throws ReasonerException {
177: return new TransitiveInfGraph(data, this );
178: }
179:
180: /**
181: * Switch on/off drivation logging.
182: * If set to true then the InfGraph created from the bind operation will start
183: * life with recording of derivations switched on. This is currently only of relevance
184: * to rule-based reasoners.
185: * <p>
186: * Default - false.
187: */
188: public void setDerivationLogging(boolean logOn) {
189: // Irrelevant to this reasoner
190: }
191:
192: /**
193: * Set a configuration paramter for the reasoner. In the case of the this
194: * reasoner there are no configuration parameters and this method is simply
195: * here to meet the interfaces specification
196: *
197: * @param parameter the property identifying the parameter to be changed
198: * @param value the new value for the parameter, typically this is a wrapped
199: * java object like Boolean or Integer.
200: */
201: public void setParameter(Property parameter, Object value) {
202: throw new IllegalParameterException(parameter.toString());
203: }
204:
205: /**
206: * Accessor used during infgraph construction - return the cached
207: * version of the subProperty lattice.
208: */
209: public TransitiveGraphCache getSubPropertyCache() {
210: return subPropertyCache;
211: }
212:
213: /**
214: * Accessor used during infgraph construction - return the cached
215: * version of the subClass lattice.
216: */
217: public TransitiveGraphCache getSubClassCache() {
218: return subClassCache;
219: }
220:
221: /**
222: * Accessor used during infgraph construction - return the partially
223: * bound tbox, if any.
224: */
225: public Finder getTbox() {
226: return tbox;
227: }
228:
229: /**
230: * Return the Jena Graph Capabilties that the inference graphs generated
231: * by this reasoner are expected to conform to.
232: */
233: public Capabilities getGraphCapabilities() {
234: if (capabilities == null) {
235: capabilities = new BaseInfGraph.InfFindSafeCapabilities();
236: }
237: return capabilities;
238: }
239:
240: }
241:
242: /*
243: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
244: All rights reserved.
245:
246: Redistribution and use in source and binary forms, with or without
247: modification, are permitted provided that the following conditions
248: are met:
249:
250: 1. Redistributions of source code must retain the above copyright
251: notice, this list of conditions and the following disclaimer.
252:
253: 2. Redistributions in binary form must reproduce the above copyright
254: notice, this list of conditions and the following disclaimer in the
255: documentation and/or other materials provided with the distribution.
256:
257: 3. The name of the author may not be used to endorse or promote products
258: derived from this software without specific prior written permission.
259:
260: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
261: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
262: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
263: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
264: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
265: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
266: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
267: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
269: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
270: */
|