001: /******************************************************************
002: * File: RDFSRuleReasoner.java
003: * Created by: Dave Reynolds
004: * Created on: 16-Jun-2003
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: RDFSRuleReasoner.java,v 1.20 2008/01/02 12:07:47 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys;
010:
011: import java.util.*;
012:
013: import com.hp.hpl.jena.graph.*;
014: import com.hp.hpl.jena.rdf.model.*;
015: import com.hp.hpl.jena.reasoner.*;
016: import com.hp.hpl.jena.reasoner.rulesys.impl.RDFSCMPPreprocessHook;
017: import com.hp.hpl.jena.vocabulary.ReasonerVocabulary;
018:
019: /**
020: * A full implemention of RDFS reasoning using a hybrid rule system, together
021: * with optimized subclass/subproperty closure using the transitive graph caches.
022: * Implements the container membership property rules using an optional
023: * data scanning hook. Implements datatype range validation.
024: *
025: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
026: * @version $Revision: 1.20 $ on $Date: 2008/01/02 12:07:47 $
027: */
028: public class RDFSRuleReasoner extends GenericRuleReasoner {
029:
030: /** Constant: used to indicate default RDFS processing level */
031: public static final String DEFAULT_RULES = "default";
032:
033: /** Constant: used to indicate full RDFS processing level */
034: public static final String FULL_RULES = "full";
035:
036: /** Constant: used to indicate minimal RDFS processing level */
037: public static final String SIMPLE_RULES = "simple";
038:
039: /** The location of the default RDFS rule definitions on the class path */
040: protected static final String RULE_FILE = "etc/rdfs-fb-tgc-noresource.rules";
041:
042: /** The location of the full RDFS rule definitions on the class path */
043: protected static final String FULL_RULE_FILE = "etc/rdfs-fb-tgc.rules";
044:
045: /** The location of the simple RDFS rule definitions on the class path */
046: protected static final String SIMPLE_RULE_FILE = "etc/rdfs-fb-tgc-simple.rules";
047:
048: /** The cached rule sets, indexed by processing level */
049: protected static HashMap ruleSets = new HashMap();
050:
051: /** The rule file names, indexed by processing level */
052: protected static HashMap ruleFiles;
053:
054: /** The (stateless) preprocessor for container membership properties */
055: protected static RulePreprocessHook cmpProcessor = new RDFSCMPPreprocessHook();
056:
057: static {
058: ruleFiles = new HashMap();
059: ruleFiles.put(DEFAULT_RULES, RULE_FILE);
060: ruleFiles.put(FULL_RULES, FULL_RULE_FILE);
061: ruleFiles.put(SIMPLE_RULES, SIMPLE_RULE_FILE);
062: }
063:
064: /**
065: * Constructor
066: */
067: public RDFSRuleReasoner(ReasonerFactory parent) {
068: super (loadRulesLevel(DEFAULT_RULES), parent);
069: setMode(HYBRID);
070: setTransitiveClosureCaching(true);
071: //addPreprocessingHook(new RDFSCMPPreprocessHook());
072: }
073:
074: /**
075: * Constructor
076: * @param factory the parent reasoner factory which is consulted to answer capability questions
077: * @param configuration RDF information to configure the rule set and mode, can be null
078: */
079: public RDFSRuleReasoner(ReasonerFactory factory,
080: Resource configuration) {
081: this (factory);
082: if (configuration != null) {
083: StmtIterator i = configuration.listProperties();
084: while (i.hasNext()) {
085: Statement st = i.nextStatement();
086: doSetParameter(st.getPredicate(), st.getObject()
087: .toString());
088: }
089: }
090: }
091:
092: /**
093: * Internal constructor, used to generated a partial binding of a schema
094: * to a rule reasoner instance.
095: */
096: protected RDFSRuleReasoner(FBRuleInfGraph schemaGraph,
097: ReasonerFactory factory) {
098: super (schemaGraph.getRules(), factory);
099: this .schemaGraph = schemaGraph;
100: }
101:
102: /**
103: * Internal version of setParameter that does not directly raise an
104: * exception on parameters it does not reconize.
105: * @return false if the parameter was not recognized
106: */
107: protected boolean doSetParameter(Property parameter, Object value) {
108: if (parameter.equals(ReasonerVocabulary.PROPenableCMPScan)) {
109: boolean scanProperties = Util.convertBooleanPredicateArg(
110: parameter, value);
111: if (scanProperties) {
112: addPreprocessingHook(cmpProcessor);
113: } else {
114: removePreprocessingHook(cmpProcessor);
115: }
116: return true;
117: } else if (parameter
118: .equals(ReasonerVocabulary.PROPsetRDFSLevel)) {
119: String level = ((String) value).toLowerCase();
120: setRules(loadRulesLevel(level));
121: if (level.equals(FULL_RULES)) {
122: addPreprocessingHook(cmpProcessor);
123: } else {
124: removePreprocessingHook(cmpProcessor);
125: }
126: return true;
127: } else {
128: return super .doSetParameter(parameter, value);
129: }
130: }
131:
132: /**
133: * Attach the reasoner to a set of RDF data to process.
134: * The reasoner may already have been bound to specific rules or ontology
135: * axioms (encoded in RDF) through earlier bindRuleset calls.
136: *
137: * @param data the RDF data to be processed, some reasoners may restrict
138: * the range of RDF which is legal here (e.g. syntactic restrictions in OWL).
139: * @return an inference graph through which the data+reasoner can be queried.
140: * @throws ReasonerException if the data is ill-formed according to the
141: * constraints imposed by this reasoner.
142: */
143: public InfGraph bind(Graph data) throws ReasonerException {
144: Graph schemaArg = schemaGraph == null ? getPreload()
145: : schemaGraph;
146: InfGraph graph = null;
147: List ruleSet = ((FBRuleInfGraph) schemaArg).getRules();
148: FBRuleInfGraph fbgraph = new RDFSRuleInfGraph(this , ruleSet,
149: schemaArg);
150: graph = fbgraph;
151: if (enableTGCCaching)
152: fbgraph.setUseTGCCache();
153: fbgraph.setTraceOn(traceOn);
154: if (preprocessorHooks != null) {
155: for (Iterator i = preprocessorHooks.iterator(); i.hasNext();) {
156: fbgraph.addPreprocessingHook((RulePreprocessHook) i
157: .next());
158: }
159: }
160: graph.setDerivationLogging(recordDerivations);
161: graph.rebind(data);
162: return graph;
163: }
164:
165: /**
166: * Precompute the implications of a schema graph. The statements in the graph
167: * will be combined with the data when the final InfGraph is created.
168: */
169: public Reasoner bindSchema(Graph tbox) throws ReasonerException {
170: if (schemaGraph != null) {
171: throw new ReasonerException(
172: "Can only bind one schema at a time to an RDFSRuleReasoner");
173: }
174: FBRuleInfGraph graph = new FBRuleInfGraph(this , rules,
175: getPreload(), tbox);
176: if (enableTGCCaching)
177: ((FBRuleInfGraph) graph).setUseTGCCache();
178: graph.prepare();
179: RDFSRuleReasoner grr = new RDFSRuleReasoner(graph, factory);
180: grr.setDerivationLogging(recordDerivations);
181: grr.setTraceOn(traceOn);
182: grr.setTransitiveClosureCaching(enableTGCCaching);
183: grr.setFunctorFiltering(filterFunctors);
184: if (preprocessorHooks != null) {
185: for (Iterator i = preprocessorHooks.iterator(); i.hasNext();) {
186: grr.addPreprocessingHook((RulePreprocessHook) i.next());
187: }
188: }
189: return grr;
190: }
191:
192: /**
193: * Return the RDFS rule set, loading it in if necessary.
194: * @param level a string defining the processing level required
195: */
196: public static List loadRulesLevel(String level) {
197: List ruleSet = (List) ruleSets.get(level);
198: if (ruleSet == null) {
199: String file = (String) ruleFiles.get(level);
200: if (file == null) {
201: throw new ReasonerException(
202: "Illegal RDFS conformance level: " + level);
203: }
204: ruleSet = loadRules(file);
205: ruleSets.put(level, ruleSet);
206: }
207: return ruleSet;
208: }
209:
210: /**
211: * Return the Jena Graph Capabilties that the inference graphs generated
212: * by this reasoner are expected to conform to.
213: */
214: public Capabilities getGraphCapabilities() {
215: if (capabilities == null) {
216: capabilities = new BaseInfGraph.InfFindSafeCapabilities();
217: }
218: return capabilities;
219: }
220:
221: }
222:
223: /*
224: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
225: All rights reserved.
226:
227: Redistribution and use in source and binary forms, with or without
228: modification, are permitted provided that the following conditions
229: are met:
230:
231: 1. Redistributions of source code must retain the above copyright
232: notice, this list of conditions and the following disclaimer.
233:
234: 2. Redistributions in binary form must reproduce the above copyright
235: notice, this list of conditions and the following disclaimer in the
236: documentation and/or other materials provided with the distribution.
237:
238: 3. The name of the author may not be used to endorse or promote products
239: derived from this software without specific prior written permission.
240:
241: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
242: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
243: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
244: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
245: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
246: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
247: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
249: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
250: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
251: */
|