001: /******************************************************************
002: * File: ReasonerRegistry.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: ReasonerRegistry.java,v 1.31 2008/01/21 14:54:20 chris-dollin Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner;
010:
011: import com.hp.hpl.jena.rdf.model.*;
012: import com.hp.hpl.jena.vocabulary.*;
013: import com.hp.hpl.jena.graph.*;
014: import com.hp.hpl.jena.reasoner.dig.DIGReasoner;
015: import com.hp.hpl.jena.reasoner.dig.DIGReasonerFactory;
016: import com.hp.hpl.jena.reasoner.rulesys.DAMLMicroReasonerFactory;
017: import com.hp.hpl.jena.reasoner.rulesys.GenericRuleReasonerFactory;
018: import com.hp.hpl.jena.reasoner.rulesys.OWLFBRuleReasonerFactory;
019: import com.hp.hpl.jena.reasoner.rulesys.OWLMicroReasonerFactory;
020: import com.hp.hpl.jena.reasoner.rulesys.OWLMiniReasonerFactory;
021: import com.hp.hpl.jena.reasoner.rulesys.RDFSRuleReasonerFactory;
022: import com.hp.hpl.jena.reasoner.transitiveReasoner.TransitiveReasonerFactory;
023:
024: import java.util.*;
025:
026: /**
027: * A global registry of known reasoner modules. Modules are identified
028: * by a URI and can have associated capability and descriptive
029: * information, in RDF. Currently the schema/ontology for such
030: * descriptions is mostly open. However, we do ensure that each reasoner
031: * URI at least has an associated rdf:type statement to indicate that it
032: * is a reasoner.
033: * <p>
034: * It is up to each reasoner or some associated configuration system
035: * to register it in this registry. </p>
036: *
037: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
038: * @version $Revision: 1.31 $ on $Date: 2008/01/21 14:54:20 $
039: */
040: public class ReasonerRegistry {
041:
042: /** Single glogal instance of the registry */
043: protected static ReasonerRegistry theRegistry;
044:
045: /** Map from reasoner URI to the associated factory */
046: protected Map reasonerFactories = new HashMap();
047:
048: /** Union of the all reasoner capability descriptions */
049: protected Model allDescriptions;
050:
051: /**
052: * Constructor is hidden - go via theRegistry
053: */
054: private ReasonerRegistry() {
055: allDescriptions = ModelFactory.createDefaultModel();
056: // Preload the known Jena reasoers
057: register(TransitiveReasonerFactory.theInstance());
058: register(RDFSRuleReasonerFactory.theInstance());
059: register(OWLFBRuleReasonerFactory.theInstance());
060: register(GenericRuleReasonerFactory.theInstance());
061: register(DAMLMicroReasonerFactory.theInstance());
062: register(DIGReasonerFactory.theInstance());
063: register(OWLMicroReasonerFactory.theInstance());
064: register(OWLMiniReasonerFactory.theInstance());
065: }
066:
067: /**
068: * Return the single global instance of the registry
069: */
070: public static ReasonerRegistry theRegistry() {
071: if (theRegistry == null) {
072: theRegistry = new ReasonerRegistry();
073: }
074: return theRegistry;
075: }
076:
077: /**
078: * Register a Reasoner.
079: * @param factory an factory that can be used to create instances of the reasoner
080: */
081: public void register(ReasonerFactory factory) {
082: reasonerFactories.put(factory.getURI(), factory);
083: Model description = factory.getCapabilities();
084: if (description != null) {
085: allDescriptions.add(description);
086: }
087: allDescriptions.createResource(factory.getURI()).addProperty(
088: RDF.type, ReasonerVocabulary.ReasonerClass);
089: }
090:
091: /**
092: * Register a Reasoner - simple case with no RDF description.
093: * @param factory an factory that can be used to create instances of the reasoner
094: * @param reasonerUri the URI used to label the reasoner, expressed as a
095: * simple string
096: */
097: public void register(String reasonerUri, ReasonerFactory factory) {
098: reasonerFactories.put(reasonerUri, factory);
099: allDescriptions.createResource(reasonerUri).addProperty(
100: RDF.type, ReasonerVocabulary.ReasonerClass);
101: }
102:
103: /**
104: * Return a composite set of RDF capability descriptions for all registered reasoners.
105: * Listing all Resources of type ReasonerClass in the returned model
106: * would enumerate all registered reasoners.
107: */
108: public Model getAllDescriptions() {
109: return allDescriptions;
110: }
111:
112: /**
113: * Return information on a given Reasoner.
114: * @param uri the URI of the reasoner
115: * @return a Resource representing the reasoner whose properties (as obtainable
116: * through listProperties etc) give a capability description of the reasoner;
117: * returns null if no such reasoner is registered.
118: */
119: public Resource getDescription(String uri) {
120: Resource reasonerURI = allDescriptions.getResource(uri);
121: if (allDescriptions.contains(reasonerURI, RDF.type,
122: ReasonerVocabulary.ReasonerClass)) {
123: return reasonerURI;
124: } else {
125: return null;
126: }
127: }
128:
129: /**
130: * Return the factory for the given reasoner.
131: * @param uri the URI of the reasoner
132: * @return the ReasonerFactory instance for this reasoner
133: */
134: public ReasonerFactory getFactory(String uri) {
135: return (ReasonerFactory) reasonerFactories.get(uri);
136: }
137:
138: /**
139: * Create and return a new instance of the reasoner identified by
140: * the given uri.
141: * @param uri the uri of the reasoner to be created, expressed as a simple string
142: * @param configuration an optional set of configuration information encoded in RDF this
143: * parameter can be null if no configuration information is required.
144: * @return a reaoner instance
145: * @throws ReasonerException if there is not such reasoner or if there is
146: * some problem during instantiation
147: */
148: public Reasoner create(String uri, Resource configuration)
149: throws ReasonerException {
150: ReasonerFactory factory = getFactory(uri);
151: if (factory != null) {
152: return factory.create(configuration);
153: } else {
154: throw new ReasonerException(
155: "Attempted to instantiate an unknown reasoner: "
156: + uri);
157: }
158: }
159:
160: /**
161: * Return a property Node which represents the direct version of a
162: * transitively closed property. See <code>makeDirect(String)</code>;
163: * this method makes a new Node with the direct respelling of
164: * <code>node</code>s URI.
165: */
166: public static Node makeDirect(Node node) {
167: return Node.createURI(makeDirect(node.getURI()));
168: }
169:
170: /**
171: * Return a URI string which represents the direct version of a
172: * transitively closed property URI
173: *
174: * <p>Not clear what the right thing to do here is. Should not just invent
175: * a new local name in the same namespace because that might be a controlled
176: * namespace like RDF or RDFS. Can't even just extend the namespace slightly
177: * because that would be violating the web principles of namespace ownership.
178: * On the other hand, this solution results in staggeringly clumsy names.</p>
179: *
180: * @param uri the URI representing the transitive property
181: */
182: public static String makeDirect(String uri) {
183: return "urn:x-hp-direct-predicate:" + uri.replace(':', '_');
184: }
185:
186: /** Prebuilt standard configuration for the default RDFS reasoner. */
187: protected static Reasoner theRDFSReasoner = null;
188:
189: /**
190: * Return a prebuilt standard configuration for the default RDFS reasoner
191: */
192: public static Reasoner getRDFSReasoner() {
193: if (theRDFSReasoner == null)
194: theRDFSReasoner = RDFSRuleReasonerFactory.theInstance()
195: .create(null);
196: return theRDFSReasoner;
197: }
198:
199: /** Prebuilt standard configuration for the default RDFS reasoner. */
200: protected static Reasoner theRDFSSimpleReasoner = null;
201:
202: /**
203: * Return a prebuilt simplified configuration for the default RDFS reasoner
204: */
205: public static Reasoner getRDFSSimpleReasoner() {
206: if (theRDFSSimpleReasoner == null) {
207: theRDFSSimpleReasoner = RDFSRuleReasonerFactory
208: .theInstance().create(null);
209: theRDFSSimpleReasoner.setParameter(
210: ReasonerVocabulary.PROPsetRDFSLevel,
211: ReasonerVocabulary.RDFS_SIMPLE);
212: }
213: return theRDFSSimpleReasoner;
214: }
215:
216: /** Prebuilt standard configuration for the default subclass/subproperty transitive closure reasoner. */
217: protected static Reasoner theTRANSITIVEReasoner;
218:
219: /**
220: * Return a prebuilt standard configuration for the default subclass/subproperty transitive closure reasoner.
221: */
222: public static Reasoner getTransitiveReasoner() {
223: if (theTRANSITIVEReasoner == null)
224: theTRANSITIVEReasoner = TransitiveReasonerFactory
225: .theInstance().create(null);
226: return theTRANSITIVEReasoner;
227: }
228:
229: /** Prebuilt standard configuration OWL reasoner */
230: protected static Reasoner theOWLReasoner;
231:
232: /**
233: * Prebuilt standard configuration for the default OWL reasoner. This configuration is
234: * hybrid forward/backward reasoner.
235: */
236: public static Reasoner getOWLReasoner() {
237: if (theOWLReasoner == null)
238: theOWLReasoner = OWLFBRuleReasonerFactory.theInstance()
239: .create(null);
240: return theOWLReasoner;
241: }
242:
243: /** Prebuilt micro configuration OWL reasoner */
244: protected static Reasoner theOWLMicroReasoner;
245:
246: /**
247: * Prebuilt standard configuration a micro-OWL reasoner. This just supports property axioms,
248: * and class inheritance sufficient to power the OntAPI.
249: */
250: public static Reasoner getOWLMicroReasoner() {
251: if (theOWLMicroReasoner == null)
252: theOWLMicroReasoner = OWLMicroReasonerFactory.theInstance()
253: .create(null);
254: return theOWLMicroReasoner;
255: }
256:
257: /** Prebuilt mini configuration OWL reasoner */
258: protected static Reasoner theOWLMiniReasoner;
259:
260: /**
261: * Prebuilt mini configuration for the default OWL reasoner. This omits bNode
262: * introduction rules which has significant performance gain in some cases and
263: * avoids breaking the find contract.
264: */
265: public static Reasoner getOWLMiniReasoner() {
266: if (theOWLMiniReasoner == null)
267: theOWLMiniReasoner = OWLMiniReasonerFactory.theInstance()
268: .create(null);
269: return theOWLMiniReasoner;
270: }
271:
272: /**
273: * <p>Create a DIG reasoner for the specified language for the OWL
274: * language, with default settings (including the default URL for the
275: * DIG reasoner), and no axioms specified. </p>
276: * @return A new DIG reasoner
277: */
278: public static DIGReasoner getDIGReasoner() {
279: return getDIGReasoner(OWL.NAMESPACE, null);
280: }
281:
282: /**
283: * <p>Create a DIG reasoner for the specified language
284: * ({@linkplain DAML_OIL#NAMESPACE_DAML DAML} or
285: * {@linkplain OWL#NAMESPACE OWL}), without type axioms.</p>
286: * @param lang The ontology language, OWL or DAML, as a resource
287: * @param config Optional configuration root resource, or null
288: * @return A new DIG reasoner
289: */
290: public static DIGReasoner getDIGReasoner(Resource lang,
291: Resource config) {
292: return getDIGReasoner(lang, false, config);
293: }
294:
295: /**
296: * <p>Create a DIG reasoner for the specified language
297: * ({@linkplain DAML_OIL#NAMESPACE_DAML DAML} or
298: * {@linkplain OWL#NAMESPACE OWL}), optionally with axioms that specify
299: * e.g. the types of OWL objects etc.</p>
300: * @param lang The ontology language, OWL or DAML, as a resource
301: * @param withAxioms If true, include the type axioms for the language
302: * @param config Optional configuration root resource, or null
303: * @return A new DIG reasoner
304: */
305: public static DIGReasoner getDIGReasoner(Resource lang,
306: boolean withAxioms, Resource config) {
307: if (!lang.equals(DAML_OIL.NAMESPACE_DAML)
308: && !lang.equals(OWL.NAMESPACE)) {
309: throw new ReasonerException(
310: "Cannot create DIG reasoner for unknown language: "
311: + lang);
312: }
313:
314: boolean owl = lang.equals(OWL.NAMESPACE);
315: String axioms = withAxioms ? (owl ? DIGReasonerFactory.DEFAULT_OWL_AXIOMS
316: : DIGReasonerFactory.DEFAULT_DAML_AXIOMS)
317: : null;
318:
319: return DIGReasonerFactory.theInstance().create(lang, axioms,
320: config);
321: }
322: }
323:
324: /*
325: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
326: All rights reserved.
327:
328: Redistribution and use in source and binary forms, with or without
329: modification, are permitted provided that the following conditions
330: are met:
331:
332: 1. Redistributions of source code must retain the above copyright
333: notice, this list of conditions and the following disclaimer.
334:
335: 2. Redistributions in binary form must reproduce the above copyright
336: notice, this list of conditions and the following disclaimer in the
337: documentation and/or other materials provided with the distribution.
338:
339: 3. The name of the author may not be used to endorse or promote products
340: derived from this software without specific prior written permission.
341:
342: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
343: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
344: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
345: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
346: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
347: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
348: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
349: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
350: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
351: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
352: */
|