001: /*****************************************************************************
002: * Source code information
003: * -----------------------
004: * Original author Ian Dickinson, HP Labs Bristol
005: * Author email Ian.Dickinson@hp.com
006: * Package Jena 2
007: * Web http://sourceforge.net/projects/jena/
008: * Created July 19th 2003
009: * Filename $RCSfile: DIGInfGraph.java,v $
010: * Revision $Revision: 1.17 $
011: * Release status $State: Exp $
012: *
013: * Last modified on $Date: 2008/01/02 12:07:11 $
014: * by $Author: andy_seaborne $
015: *
016: * (c) Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
017: * [See end of file]
018: *****************************************************************************/package com.hp.hpl.jena.reasoner.dig;
019:
020: // Imports
021: ///////////////
022: import java.util.Iterator;
023:
024: import com.hp.hpl.jena.graph.*;
025: import com.hp.hpl.jena.graph.compose.MultiUnion;
026: import com.hp.hpl.jena.ontology.OntModel;
027: import com.hp.hpl.jena.ontology.Profile;
028: import com.hp.hpl.jena.rdf.model.*;
029: import com.hp.hpl.jena.reasoner.*;
030: import com.hp.hpl.jena.util.iterator.ExtendedIterator;
031: import com.hp.hpl.jena.vocabulary.RDF;
032:
033: /**
034: * <p>
035: * An InfGraph that performs reasoning via a DIG interface to an external reasoner.
036: * </p>
037: *
038: * @author Ian Dickinson, HP Labs
039: * (<a href="mailto:Ian.Dickinson@hp.com" >email</a>)
040: * @version CVS $Id: DIGInfGraph.java,v 1.17 2008/01/02 12:07:11 andy_seaborne Exp $
041: */
042: public class DIGInfGraph extends BaseInfGraph {
043: // Constants
044: //////////////////////////////////
045:
046: // Static variables
047: //////////////////////////////////
048:
049: // Instance variables
050: //////////////////////////////////
051:
052: /** The DIG adapter we will use to communicate with the external reasoner */
053: protected DIGAdapter m_adapter;
054:
055: // Constructors
056: //////////////////////////////////
057:
058: /**
059: * Constructor
060: * @param data the raw data file to be augmented with entailments
061: * @param reasoner the engine, with associated tbox data, whose find interface
062: * can be used to extract all entailments from the data.
063: */
064: public DIGInfGraph(Graph data, DIGReasoner reasoner) {
065: super (data, reasoner);
066:
067: // we want a union of data and tbox
068: if (reasoner.getSchema() != null) {
069: fdata = new FGraph(new MultiUnion(new Graph[] { data,
070: reasoner.getSchema() }));
071: }
072:
073: // create or re-use a free connector
074: DIGConnection conn = DIGConnectionPool.getInstance().allocate(
075: reasoner.getReasonerURL());
076: m_adapter = new DIGAdapter(reasoner.getOntLangModelSpec(),
077: fdata.getGraph(), conn, reasoner.getAxioms());
078: }
079:
080: // External signature methods
081: //////////////////////////////////
082:
083: /**
084: * Perform any initial processing and caching. This call is optional. Most
085: * engines either have negligable set up work or will perform an implicit
086: * "prepare" if necessary. The call is provided for those occasions where
087: * substantial preparation work is possible (e.g. running a forward chaining
088: * rule system) and where an application might wish greater control over when
089: * this prepration is done.
090: */
091: public void prepare() {
092: if (!isPrepared) {
093: m_adapter.resetKB();
094: m_adapter.uploadKB();
095: isPrepared = true;
096: }
097: }
098:
099: /**
100: * <p>Extended find interface used in situations where the implementator
101: * may or may not be able to answer the complete query. It will
102: * attempt to answer the pattern but if its answers are not known
103: * to be complete then it will also pass the request on to the nested
104: * Finder to append more results.</p><p>
105: * <strong>DIG implementation note:</strong> the default call into this
106: * method from the base inference graph makes the continuation a query
107: * of the base graph. Since {@link DIGAdapter} already queries the base
108: * graph, there is no futher need to query it through the continuation.
109: * Consequently, this implementation <em>does not call</em> the continuation.
110: * Client code that wishes to provide a non-default continuation should
111: * sub-class DIGInfGraph and provide a suitable call to the continuation.find().
112: * </p>
113: * @param pattern a TriplePattern to be matched against the data
114: * @param continuation Not used in this implementation
115: */
116: public ExtendedIterator findWithContinuation(TriplePattern pattern,
117: Finder continuation) {
118: prepare();
119: return m_adapter.find(pattern);
120: }
121:
122: /**
123: * <p>An extension of the {@link Graph#find} interface which allows the caller to
124: * encode complex expressions in RDF and then refer to those expressions
125: * within the query triple. For example, one might encode a class expression
126: * and then ask if there are any instances of this class expression in the
127: * InfGraph. In the case of the DIGInfGraph, this is exactly the use case we assume.
128: * In particular, we expect that the <code>object</code> node is the subject of
129: * one or more sentences in <code>param</code> which completely define the class
130: * description.<p>
131: * @param subject the subject Node of the query triple, may be a Node in
132: * the graph or a node in the parameter micro-graph or null
133: * @param property the property to be retrieved or null
134: * @param object the object Node of the query triple, may be a Node in
135: * the graph or a node in the parameter micro-graph.
136: * @param param a small graph encoding an expression which the subject and/or
137: * object nodes refer.
138: */
139: public ExtendedIterator find(Node subject, Node property,
140: Node object, Graph param) {
141: OntModel premises = ModelFactory.createOntologyModel(m_adapter
142: .getSourceSpecification(), ModelFactory
143: .createModelForGraph(param));
144: premises.setStrictMode(false);
145: prepare();
146: return m_adapter.find(new TriplePattern(subject, property,
147: object), premises);
148: }
149:
150: /**
151: * Return the schema graph, if any, bound into this inference graph.
152: */
153: public Graph getSchemaGraph() {
154: return ((DIGReasoner) reasoner).getSchema();
155: }
156:
157: // overriding the BaseInfGraph methods
158:
159: /**
160: * <p>Add one triple to the data graph, mark the graph not-prepared,
161: * but don't run prepare() just yet.</p>
162: * @param t A triple to add to the graph
163: */
164: public synchronized void performAdd(Triple t) {
165: fdata.getGraph().add(t);
166: isPrepared = false;
167: }
168:
169: /**
170: * <p>Delete one triple from the data graph, mark the graph not-prepared,
171: * but don't run prepare() just yet.</p>
172: * @param t A triple to remove from the graph
173: */
174: public void performDelete(Triple t) {
175: fdata.getGraph().delete(t);
176: isPrepared = false;
177: }
178:
179: /**
180: * Replace the underlying data graph for this inference graph and start any
181: * inferences over again. This is primarily using in setting up ontology imports
182: * processing to allow an imports multiunion graph to be inserted between the
183: * inference graph and the raw data, before processing.
184: * @param data the new raw data graph
185: */
186: public void rebind(Graph data) {
187: if (getSchemaGraph() == null) {
188: fdata = new FGraph(data);
189: } else {
190: fdata = new FGraph(new MultiUnion(new Graph[] { data,
191: getSchemaGraph() }));
192: }
193:
194: isPrepared = false;
195: }
196:
197: /**
198: * Switch on/off drivation logging - not supported with DIG reasoner
199: */
200: public void setDerivationLogging(boolean logOn) {
201: throw new UnsupportedOperationException(
202: "Cannot set derivation logging on DIG reasoner");
203: }
204:
205: /**
206: * <p>Test the consistency of the model. This looks for overall inconsistency,
207: * and for any unsatisfiable classes.</p>
208: * @return a ValidityReport structure
209: */
210: public ValidityReport validate() {
211: checkOpen();
212: prepare();
213: StandardValidityReport report = new StandardValidityReport();
214:
215: // look for incoherent KB by listing the individuals
216: try {
217: m_adapter.collectNamedTerms(DIGProfile.ALL_INDIVIDUALS,
218: new String[] { DIGProfile.INDIVIDUAL_SET,
219: DIGProfile.INDIVIDUAL });
220: } catch (DIGInconsistentKBException e) {
221: report.add(true, "DIG KB inconsistent", e.getMessage());
222: // no point continuing further
223: return report;
224: } catch (DIGErrorResponseException e) {
225: report.add(true, "DIG KB incoherent", e.getMessage());
226: }
227:
228: // now look for unsatisfiable classes
229: Profile p = m_adapter.getOntLanguage();
230: Node nothing = p.NOTHING().asNode();
231: Property equivClass = p.EQUIVALENT_CLASS();
232: DIGQueryEquivalentsTranslator q = new DIGQueryEquivalentsTranslator(
233: equivClass.getURI(), true);
234: ExtendedIterator i = q.find(new TriplePattern(null, equivClass
235: .asNode(), p.NOTHING().asNode()), m_adapter);
236:
237: while (i.hasNext()) {
238: Triple t = (Triple) i.next();
239: Node subj = t.getSubject();
240: if (subj != nothing) {
241: report.add(true, "unsatisfiable class",
242: (subj.isBlank() ? subj.getBlankNodeId()
243: .toString() : subj.getURI()), t
244: .getSubject());
245: }
246: }
247:
248: // look for incoherent instances
249: DIGQueryTypesTranslator q1 = new DIGQueryTypesTranslator(
250: RDF.type.getURI());
251: DIGValueToNodeMapper vMap = new DIGValueToNodeMapper();
252: for (Iterator j = m_adapter.getKnownIndividuals().iterator(); j
253: .hasNext();) {
254: String ind = (String) j.next();
255: Node indNode = (Node) vMap.map1(ind);
256: ExtendedIterator i1 = null;
257:
258: try {
259: i1 = q1.find(new TriplePattern(indNode, RDF.type
260: .asNode(), null), m_adapter);
261: } catch (DIGInconsistentKBException e) {
262: report.add(true, "DIG KB inconsistent", e.getMessage());
263: // no point continuing further
264: break;
265: } catch (DIGErrorResponseException e) {
266: // we assume this is an incoherent KB exception - should check
267: report.add(true, "meaningless individual", (indNode
268: .isBlank() ? indNode.getBlankNodeId()
269: .toString() : indNode.getURI()), ind);
270: } finally {
271: if (i1 != null) {
272: i1.close();
273: }
274: }
275: }
276:
277: return report;
278: }
279:
280: // Internal implementation methods
281: //////////////////////////////////
282:
283: //==============================================================================
284: // Inner class definitions
285: //==============================================================================
286:
287: }
288:
289: /*
290: * (c) Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
291: * All rights reserved.
292: *
293: * Redistribution and use in source and binary forms, with or without
294: * modification, are permitted provided that the following conditions
295: * are met:
296: * 1. Redistributions of source code must retain the above copyright
297: * notice, this list of conditions and the following disclaimer.
298: * 2. Redistributions in binary form must reproduce the above copyright
299: * notice, this list of conditions and the following disclaimer in the
300: * documentation and/or other materials provided with the distribution.
301: * 3. The name of the author may not be used to endorse or promote products
302: * derived from this software without specific prior written permission.
303: *
304: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
305: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
306: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
307: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
308: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
309: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
310: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
311: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
312: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
313: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
314: */
|