001: /******************************************************************
002: * File: RDFSReasoner.java
003: * Created by: Dave Reynolds
004: * Created on: 21-Jan-03
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: RDFSReasoner.java,v 1.25 2008/01/02 12:06:44 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.rdfsReasoner1;
010:
011: import com.hp.hpl.jena.reasoner.*;
012: import com.hp.hpl.jena.reasoner.rulesys.Util;
013: import com.hp.hpl.jena.reasoner.transitiveReasoner.*;
014: import com.hp.hpl.jena.rdf.model.*;
015: import com.hp.hpl.jena.graph.*;
016: import com.hp.hpl.jena.vocabulary.RDFS;
017: import com.hp.hpl.jena.vocabulary.ReasonerVocabulary;
018:
019: /**
020: * @deprecated Obsoleted at jena2p4, replaced by
021: * {@link com.hp.hpl.jena.reasoner.rulesys.RDFSRuleReasoner}.
022: *
023: * An RDFS reasoner suited to modest vocabularies but large instance
024: * data. It does eager processing on the class and property declarations
025: * and caches the results. This means that the initial creation can
026: * be slow. However, if the vocabulary and instance data can be
027: * separated then at least the class lattice results can be reused.
028: * <p>
029: * Instance related rules are implemented using a very simple rewrite
030: * system. Triple queries that match a rule are rewritten and reapplied
031: * as queries. This is reasonably efficient for fairly ground queries,
032: * especially where the predicate is ground. It performs redundant
033: * passes over the data for unground queries, especially any that
034: * need that might match (*, type, Resource) or (*, type, Property)!</p>
035: *
036: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
037: * @version $Revision: 1.25 $ on $Date: 2008/01/02 12:06:44 $
038: */
039: public class RDFSReasoner extends TransitiveReasoner implements
040: Reasoner {
041: /** The domain property */
042: public static final Node domainP = RDFS.Nodes.domain;
043:
044: /** The range property */
045: public static final Node rangeP = RDFS.Nodes.range;
046:
047: /** Note if the reasoner is configured to scan for member properties */
048: protected boolean scanProperties = true;
049:
050: /** Constructor */
051: public RDFSReasoner() {
052: super ();
053: }
054:
055: /**
056: * Constructor
057: * @param configuration a set of arbitrary configuration information to be
058: * passed the reasoner, encoded as RDF properties of a base configuration resource,
059: * can be null in no custom configuration is required. The
060: * only meaningful configuration property at present is scanProperties.
061: */
062: public RDFSReasoner(Resource configuration) {
063: super ();
064: if (configuration != null) {
065: Boolean flag = checkBinaryPredicate(
066: RDFSReasonerFactory.scanProperties, configuration);
067: if (flag != null)
068: scanProperties = flag.booleanValue();
069: }
070: }
071:
072: /**
073: * Private constructor used by bindSchema when
074: * returning a partially bound reasoner instance.
075: */
076: protected RDFSReasoner(Finder tbox,
077: TransitiveGraphCache subClassCache,
078: TransitiveGraphCache subPropertyCache,
079: boolean scanProperties) {
080: super (tbox, subClassCache, subPropertyCache);
081: this .scanProperties = scanProperties;
082: }
083:
084: /**
085: * Determine whether the given property is recognized and treated specially
086: * by this reasoner. This is a convenience packaging of a special case of getCapabilities.
087: * @param property the property which we want to ask the reasoner about, given as a Node since
088: * this is part of the SPI rather than API
089: * @return true if the given property is handled specially by the reasoner.
090: */
091: public boolean supportsProperty(Property property) {
092: ReasonerFactory rf = RDFSReasonerFactory.theInstance();
093: Model caps = rf.getCapabilities();
094: Resource root = caps.getResource(rf.getURI());
095: return caps.contains(root, ReasonerVocabulary.supportsP,
096: property);
097: }
098:
099: /**
100: * Helper method - extracts the truth of a boolean configuration
101: * predicate.
102: * @param pred the predicate to be tested
103: * @param configuration the configuration node
104: * @return null if there is no setting otherwise a Boolean giving the setting value
105: */
106: private Boolean checkBinaryPredicate(Property predicate,
107: Resource configuration) {
108: StmtIterator i = configuration.listProperties(predicate);
109: if (i.hasNext()) {
110: return new Boolean(i.nextStatement().getObject().toString()
111: .equalsIgnoreCase("true"));
112: } else {
113: return null;
114: }
115: }
116:
117: /**
118: * Extracts all of the subClass and subProperty declarations from
119: * the given schema/tbox and caches the resultant graphs.
120: * It can only be used once, can't stack up multiple tboxes this way.
121: * This limitation could be lifted - the only difficulty is the need to
122: * reprocess all the earlier tboxes if a new subPropertyOf subPropertyOf
123: * subClassOf is discovered.
124: * @param tbox schema containing the property and class declarations
125: */
126: public Reasoner bindSchema(Graph tbox) throws ReasonerException {
127: if (this .tbox != null) {
128: throw new ReasonerException(
129: "Attempt to bind multiple rulesets - disallowed for now");
130: }
131: FGraph ftbox = new FGraph(tbox);
132: TransitiveGraphCache sCc = new TransitiveGraphCache(
133: directSubClassOf, subClassOf);
134: TransitiveGraphCache sPc = new TransitiveGraphCache(
135: directSubPropertyOf, subPropertyOf);
136: TransitiveEngine.cacheSubPropUtility(ftbox, sPc);
137: TransitiveEngine.cacheSubClassUtility(ftbox, sPc, sCc);
138: sPc.setCaching(true);
139: return new RDFSReasoner(ftbox, sCc, sPc, scanProperties);
140: }
141:
142: /**
143: * Attach the reasoner to a set of RDF ddata to process.
144: * The reasoner may already have been bound to specific rules or ontology
145: * axioms (encoded in RDF) through earlier bindRuleset calls.
146: * @param data the RDF data to be processed, some reasoners may restrict
147: * the range of RDF which is legal here (e.g. syntactic restrictions in OWL).
148: * @return an inference graph through which the data+reasoner can be queried.
149: * @throws ReasonerException if the data is ill-formed according to the
150: * constraints imposed by this reasoner.
151: */
152: public InfGraph bind(Graph data) throws ReasonerException {
153: return new RDFSInfGraph(this , data);
154: }
155:
156: /**
157: * Switch on/off drivation logging.
158: * If set to true then the InfGraph created from the bind operation will start
159: * life with recording of derivations switched on. This is currently only of relevance
160: * to rule-based reasoners.
161: * <p>
162: * Default - false.
163: */
164: public void setDerivationLogging(boolean logOn) {
165: // Irrelevant to this reasoner
166: }
167:
168: /**
169: * Set a configuration parameter for the reasoner. The only supported parameter at present is:
170: * are:
171: * <ul>
172: * <li>RDFSReasonerFactory.scanProperties - set this to Boolean true to
173: * enable scanning of all properties looking for container membership properties, default on. </li>
174: * </ul>
175: *
176: * @param parameter the property identifying the parameter to be changed
177: * @param value the new value for the parameter, typically this is a wrapped
178: * java object like Boolean or Integer.
179: */
180: public void setParameter(Property parameter, Object value) {
181: if (parameter.equals(RDFSReasonerFactory.scanProperties)) {
182: scanProperties = Util.convertBooleanPredicateArg(parameter,
183: value);
184: } else {
185: throw new IllegalParameterException(parameter.toString());
186: }
187: }
188:
189: }
190:
191: /*
192: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
193: All rights reserved.
194:
195: Redistribution and use in source and binary forms, with or without
196: modification, are permitted provided that the following conditions
197: are met:
198:
199: 1. Redistributions of source code must retain the above copyright
200: notice, this list of conditions and the following disclaimer.
201:
202: 2. Redistributions in binary form must reproduce the above copyright
203: notice, this list of conditions and the following disclaimer in the
204: documentation and/or other materials provided with the distribution.
205:
206: 3. The name of the author may not be used to endorse or promote products
207: derived from this software without specific prior written permission.
208:
209: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
210: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
211: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
212: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
213: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
214: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
215: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
216: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
217: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
218: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
219: */
|