001: /******************************************************************
002: * File: FBLPRuleReasoner.java
003: * Created by: Dave Reynolds
004: * Created on: 26-Jul-2003
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: FBLPRuleReasoner.java,v 1.11 2008/01/02 12:09:45 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys.impl.oldCode;
010:
011: import com.hp.hpl.jena.rdf.model.*;
012: import com.hp.hpl.jena.reasoner.*;
013: import com.hp.hpl.jena.reasoner.rulesys.ClauseEntry;
014: import com.hp.hpl.jena.reasoner.rulesys.Functor;
015: import com.hp.hpl.jena.reasoner.rulesys.Rule;
016: import com.hp.hpl.jena.reasoner.rulesys.Util;
017: import com.hp.hpl.jena.vocabulary.ReasonerVocabulary;
018: import com.hp.hpl.jena.graph.*;
019:
020: import java.util.*;
021:
022: /**
023: * Rule-based reasoner interface. This is the default rule reasoner to use.
024: * It supports both forward reasoning and backward reasoning, including use
025: * of forward rules to generate and instantiate backward rules.
026: *
027: * This version is purely temporary during development of the LP engine and will get
028: * replaced by the upgraded FBRuleReasoner when the LP section is released.
029: *
030: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
031: * @version $Revision: 1.11 $ on $Date: 2008/01/02 12:09:45 $
032: */
033: public class FBLPRuleReasoner implements Reasoner {
034:
035: /** The parent reasoner factory which is consulted to answer capability questions */
036: protected ReasonerFactory factory;
037:
038: /** The rules to be used by this instance of the forward engine */
039: protected List rules;
040:
041: /** A precomputed set of schema deductions */
042: protected Graph schemaGraph;
043:
044: /** Flag to set whether the inference class should record derivations */
045: protected boolean recordDerivations = false;
046:
047: /** Flag which, if true, enables tracing of rule actions to logger.info */
048: protected boolean traceOn = false;
049:
050: /** Flag, if true we cache the closure of the pure rule set with its axioms */
051: protected static final boolean cachePreload = true;
052:
053: /** The cached empty closure, if wanted */
054: protected InfGraph preload;
055:
056: /** The graph capabilities of the infgraphs generated by this reasoner */
057: protected Capabilities capabilities;
058:
059: /**
060: * Constructor. This is the raw version that does not reference a ReasonerFactory
061: * and so has no capabilities description.
062: * @param rules a list of Rule instances which defines the ruleset to process
063: */
064: public FBLPRuleReasoner(List rules) {
065: this .rules = rules;
066: }
067:
068: /**
069: * Constructor
070: * @param factory the parent reasoner factory which is consulted to answer capability questions
071: */
072: public FBLPRuleReasoner(ReasonerFactory factory) {
073: this (null, factory);
074: }
075:
076: /**
077: * Constructor
078: * @param rules a list of Rule instances which defines the ruleset to process
079: * @param factory the parent reasoner factory which is consulted to answer capability questions
080: */
081: public FBLPRuleReasoner(List rules, ReasonerFactory factory) {
082: this (rules);
083: this .factory = factory;
084: }
085:
086: /**
087: * Internal constructor, used to generated a partial binding of a schema
088: * to a rule reasoner instance.
089: */
090: protected FBLPRuleReasoner(List rules, Graph schemaGraph,
091: ReasonerFactory factory) {
092: this (rules, factory);
093: this .schemaGraph = schemaGraph;
094: }
095:
096: /**
097: * Return a description of the capabilities of this reasoner encoded in
098: * RDF. These capabilities may be static or may depend on configuration
099: * information supplied at construction time. May be null if there are
100: * no useful capabilities registered.
101: */
102: public Model getReasonerCapabilities() {
103: if (factory != null) {
104: return factory.getCapabilities();
105: } else {
106: return null;
107: }
108: }
109:
110: /**
111: * Add a configuration description for this reasoner into a partial
112: * configuration specification model.
113: * @param configSpec a Model into which the configuration information should be placed
114: * @param base the Resource to which the configuration parameters should be added.
115: */
116: public void addDescription(Model configSpec, Resource base) {
117: // No configuration
118: }
119:
120: /**
121: * Determine whether the given property is recognized and treated specially
122: * by this reasoner. This is a convenience packaging of a special case of getCapabilities.
123: * @param property the property which we want to ask the reasoner about, given as a Node since
124: * this is part of the SPI rather than API
125: * @return true if the given property is handled specially by the reasoner.
126: */
127: public boolean supportsProperty(Property property) {
128: if (factory == null)
129: return false;
130: Model caps = factory.getCapabilities();
131: Resource root = caps.getResource(factory.getURI());
132: return caps.contains(root, ReasonerVocabulary.supportsP,
133: property);
134: }
135:
136: /**
137: * Precompute the implications of a schema graph. The statements in the graph
138: * will be combined with the data when the final InfGraph is created.
139: */
140: public Reasoner bindSchema(Graph tbox) throws ReasonerException {
141: if (schemaGraph != null) {
142: throw new ReasonerException(
143: "Can only bind one schema at a time to an OWLRuleReasoner");
144: }
145: FBLPRuleInfGraph graph = new FBLPRuleInfGraph(this , rules,
146: getPreload(), tbox);
147: graph.prepare();
148: FBLPRuleReasoner fbr = new FBLPRuleReasoner(rules, graph,
149: factory);
150: fbr.setDerivationLogging(recordDerivations);
151: fbr.setTraceOn(traceOn);
152: return fbr;
153: }
154:
155: /**
156: * Precompute the implications of a schema Model. The statements in the graph
157: * will be combined with the data when the final InfGraph is created.
158: */
159: public Reasoner bindSchema(Model tbox) throws ReasonerException {
160: return bindSchema(tbox.getGraph());
161: }
162:
163: /**
164: * Attach the reasoner to a set of RDF data to process.
165: * The reasoner may already have been bound to specific rules or ontology
166: * axioms (encoded in RDF) through earlier bindRuleset calls.
167: *
168: * @param data the RDF data to be processed, some reasoners may restrict
169: * the range of RDF which is legal here (e.g. syntactic restrictions in OWL).
170: * @return an inference graph through which the data+reasoner can be queried.
171: * @throws ReasonerException if the data is ill-formed according to the
172: * constraints imposed by this reasoner.
173: */
174: public InfGraph bind(Graph data) throws ReasonerException {
175: Graph schemaArg = schemaGraph == null ? getPreload()
176: : (FBLPRuleInfGraph) schemaGraph;
177: FBLPRuleInfGraph graph = new FBLPRuleInfGraph(this , rules,
178: schemaArg);
179: graph.setDerivationLogging(recordDerivations);
180: graph.setTraceOn(traceOn);
181: graph.rebind(data);
182: return graph;
183: }
184:
185: /**
186: * Set (or change) the rule set that this reasoner should execute.
187: * @param rules a list of Rule objects
188: */
189: public void setRules(List rules) {
190: this .rules = rules;
191: preload = null;
192: }
193:
194: /**
195: * Return the this of Rules used by this reasoner
196: * @return a List of Rule objects
197: */
198: public List getRules() {
199: return rules;
200: }
201:
202: /**
203: * Register an RDF predicate as one whose presence in a goal should force
204: * the goal to be tabled. This is better done directly in the rule set.
205: */
206: public synchronized void tablePredicate(Node predicate) {
207: // Create a dummy rule which tables the predicate ...
208: Rule tablePredicateRule = new Rule("",
209: new ClauseEntry[] { new Functor("table",
210: new Node[] { predicate }) },
211: new ClauseEntry[] {});
212: // ... end append the rule to the ruleset
213: rules.add(tablePredicateRule);
214: }
215:
216: /**
217: * Get the single static precomputed rule closure.
218: */
219: protected synchronized InfGraph getPreload() {
220: if (cachePreload && preload == null) {
221: preload = (new FBLPRuleInfGraph(this , rules, null));
222: preload.prepare();
223: }
224: return preload;
225: }
226:
227: /**
228: * Switch on/off drivation logging.
229: * If set to true then the InfGraph created from the bind operation will start
230: * life with recording of derivations switched on. This is currently only of relevance
231: * to rule-based reasoners.
232: * <p>
233: * Default - false.
234: */
235: public void setDerivationLogging(boolean logOn) {
236: recordDerivations = logOn;
237: }
238:
239: /**
240: * Set the state of the trace flag. If set to true then rule firings
241: * are logged out to the Log at "INFO" level.
242: */
243: public void setTraceOn(boolean state) {
244: traceOn = state;
245: }
246:
247: /**
248: * Set a configuration paramter for the reasoner. The supported parameters
249: * are:
250: * <ul>
251: * <li>PROPderivationLogging - set to true to enable recording all rule derivations</li>
252: * <li>PROPtraceOn - set to true to enable verbose trace information to be sent to the logger INFO channel</li>
253: * </ul>
254: *
255: * @param parameterUri the property identifying the parameter to be changed
256: * @param value the new value for the parameter, typically this is a wrapped
257: * java object like Boolean or Integer.
258: */
259: public void setParameter(Property parameter, Object value) {
260: if (parameter.equals(ReasonerVocabulary.PROPderivationLogging)) {
261: recordDerivations = Util.convertBooleanPredicateArg(
262: parameter, value);
263: } else if (parameter.equals(ReasonerVocabulary.PROPtraceOn)) {
264: traceOn = Util.convertBooleanPredicateArg(parameter, value);
265: } else {
266: throw new IllegalParameterException(
267: "Don't recognize configuration parameter "
268: + parameter + " for rule-based reasoner");
269: }
270: }
271:
272: /**
273: * Return the Jena Graph Capabilties that the inference graphs generated
274: * by this reasoner are expected to conform to.
275: */
276: public Capabilities getGraphCapabilities() {
277: if (capabilities == null) {
278: capabilities = new BaseInfGraph.InfCapabilities();
279: }
280: return capabilities;
281: }
282:
283: }
284:
285: /*
286: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
287: All rights reserved.
288:
289: Redistribution and use in source and binary forms, with or without
290: modification, are permitted provided that the following conditions
291: are met:
292:
293: 1. Redistributions of source code must retain the above copyright
294: notice, this list of conditions and the following disclaimer.
295:
296: 2. Redistributions in binary form must reproduce the above copyright
297: notice, this list of conditions and the following disclaimer in the
298: documentation and/or other materials provided with the distribution.
299:
300: 3. The name of the author may not be used to endorse or promote products
301: derived from this software without specific prior written permission.
302:
303: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
304: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
305: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
306: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
307: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
308: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
309: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
310: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
311: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
312: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
313: */
|