KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > reasoner > BaseInfGraph


1 /******************************************************************
2  * File: BaseInfGraph.java
3  * Created by: Dave Reynolds
4  * Created on: 18-Jan-03
5  *
6  * (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
7  * [See end of file]
8  * $Id: BaseInfGraph.java,v 1.41 2005/03/10 14:35:35 chris-dollin Exp $
9  *****************************************************************/

10 package com.hp.hpl.jena.reasoner;
11
12 import com.hp.hpl.jena.graph.*;
13 import com.hp.hpl.jena.graph.compose.Union;
14 import com.hp.hpl.jena.graph.impl.*;
15 import com.hp.hpl.jena.shared.*;
16 import com.hp.hpl.jena.util.iterator.*;
17 import java.util.Iterator JavaDoc;
18
19 /**
20  * A base level implementation of the InfGraph interface.
21  *
22  * @author <a HREF="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
23  * @version $Revision: 1.41 $ on $Date: 2005/03/10 14:35:35 $
24  */

25 public abstract class BaseInfGraph extends GraphBase implements InfGraph {
26
27     /** The Reasoner instance which performs all inferences and Tbox lookups */
28     protected Reasoner reasoner;
29
30     /** The graph of raw data which is being reasoned over */
31     protected FGraph fdata;
32
33     /** Flag, if set to true then derivations are recorded */
34     protected boolean recordDerivations;
35
36     /** Flag to record if the preparation call has been made and so the graph is ready for queries */
37     protected boolean isPrepared = false;
38
39     /**
40          Inference graphs share the prefix-mapping of their underlying raw graph.
41         @see com.hp.hpl.jena.graph.Graph#getPrefixMapping()
42     */

43     public PrefixMapping getPrefixMapping()
44         { return getRawGraph().getPrefixMapping(); }
45
46     /**
47         Inference graphs share the reifiers of their underlying raw graphs. This may
48         be too simplistic - they won't see quads flying past.
49         TODO write a test case that reveals this.
50         @see com.hp.hpl.jena.graph.Graph#getReifier()
51     */

52     public Reifier getReifier()
53         { return getRawGraph().getReifier(); }
54
55     /**
56      * Constructor
57      * @param data the raw data file to be augmented with entailments
58      * @param reasoner the engine, with associated tbox data, whose find interface
59      * can be used to extract all entailments from the data.
60      */

61     public BaseInfGraph(Graph data, Reasoner reasoner) {
62         this.fdata = new FGraph(data);
63         this.reasoner = reasoner;
64     }
65
66     /**
67         Answer the InfCapabilities of this InfGraph.
68      */

69     public Capabilities getCapabilities() {
70         if (capabilities == null) {
71             return getReasoner().getGraphCapabilities();
72         } else {
73             return capabilities;
74         }
75     }
76
77     /**
78         An InfCapabilities notes that size may not be accurate, and some
79         triples may be irremovable.
80
81         TODO accomodate the properties of the base graph, too.
82
83         @author hedgehog
84     */

85     public static class InfCapabilities extends AllCapabilities
86         {
87         public boolean sizeAccurate() { return false; }
88         public boolean deleteAllowed( boolean every ) { return !every; }
89         public boolean iteratorRemoveAllowed() { return false; }
90         public boolean findContractSafe() { return false; }
91         }
92
93     /**
94         An InfCapabilities notes that size may not be accurate, and some
95         triples may be irremovable.
96
97         TODO accomodate the properties of the base graph, too.
98
99         @author hedgehog
100     */

101     public static class InfFindSafeCapabilities extends InfCapabilities
102         {
103         public boolean findContractSafe() { return true; }
104         }
105
106     public BulkUpdateHandler getBulkUpdateHandler()
107         {
108         if (bulkHandler == null) bulkHandler = new InfBulkUpdateHandler( this );
109         return bulkHandler;
110         }
111
112     /**
113         InfBulkUpdateHandler - a bulk update handler specialised for inference
114         graphs by code for <code>removeAll()</code>.
115
116         @author kers
117     */

118     static class InfBulkUpdateHandler extends SimpleBulkUpdateHandler
119         {
120         public InfBulkUpdateHandler( BaseInfGraph graph )
121             { super(graph); }
122
123         public void remove( Node s, Node p, Node o )
124             {
125             BaseInfGraph g = (BaseInfGraph) graph;
126             g.getRawGraph().getBulkUpdateHandler().remove( s, p, o );
127             g.discardState();
128             g.rebind();
129             manager.notifyEvent( graph, GraphEvents.remove( s, p, o ) );
130             }
131
132         public void removeAll()
133             {
134             BaseInfGraph g = (BaseInfGraph) graph;
135             g.getRawGraph().getBulkUpdateHandler().removeAll();
136             g.discardState();
137             g.rebind();
138             g.getEventManager().notifyEvent( g, GraphEvents.removeAll );
139             }
140         }
141
142     public TransactionHandler getTransactionHandler()
143         { return new InfTransactionHandler( this ); }
144
145     public static class InfTransactionHandler
146         extends TransactionHandlerBase implements TransactionHandler
147         {
148         protected final BaseInfGraph base;
149
150         public InfTransactionHandler( BaseInfGraph base )
151             { this.base = base; }
152
153         public boolean transactionsSupported()
154             { return getBaseHandler().transactionsSupported(); }
155
156         protected TransactionHandler getBaseHandler()
157             { return base.getRawGraph().getTransactionHandler(); }
158
159         public void begin()
160             { getBaseHandler().begin(); }
161
162         public void abort()
163             { getBaseHandler().abort();
164             base.rebind(); }
165
166         public void commit()
167             { getBaseHandler().commit(); }
168         }
169
170     /**
171         discard any state that depends on the content of fdata, because
172         it's just been majorly trashed, solid gone.
173     */

174     protected void discardState()
175         {}
176
177     /**
178      * Return the raw RDF data Graph being processed (i.e. the argument
179      * to the Reasonder.bind call that created this InfGraph).
180      */

181     public Graph getRawGraph() {
182         return fdata.getGraph();
183     }
184
185     /**
186      * Return the Reasoner which is being used to answer queries to this graph.
187      */

188     public Reasoner getReasoner() {
189         return reasoner;
190     }
191
192     /**
193      * Replace the underlying data graph for this inference graph and start any
194      * inferences over again. This is primarily using in setting up ontology imports
195      * processing to allow an imports multiunion graph to be inserted between the
196      * inference graph and the raw data, before processing.
197      * @param data the new raw data graph
198      */

199     public void rebind(Graph data) {
200         fdata = new FGraph(data);
201         isPrepared = false;
202     }
203
204     /**
205      * Cause the inference graph to reconsult the underlying graph to take
206      * into account changes. Normally changes are made through the InfGraph's add and
207      * remove calls are will be handled appropriately. However, in some cases changes
208      * are made "behind the InfGraph's back" and this forces a full reconsult of
209      * the changed data.
210      */

211     public void rebind() {
212         isPrepared = false;
213     }
214
215     /**
216      * Reset any internal caches. Some systems, such as the tabled backchainer,
217      * retain information after each query. A reset will wipe this information preventing
218      * unbounded memory use at the expense of more expensive future queries. A reset
219      * does not cause the raw data to be reconsulted and so is less expensive than a rebind.
220      */

221     public void reset() {
222     }
223
224     /**
225      * Perform any initial processing and caching. This call is optional. Most
226      * engines either have negligable set up work or will perform an implicit
227      * "prepare" if necessary. The call is provided for those occasions where
228      * substantial preparation work is possible (e.g. running a forward chaining
229      * rule system) and where an application might wish greater control over when
230      * this prepration is done.
231      */

232     public void prepare() {
233         // Default is to do no preparation
234
isPrepared = true;
235     }
236
237     /**
238      * Returns a derivations graph. The rule reasoners typically create a
239      * graph containing those triples added to the base graph due to rule firings.
240      * In some applications it can useful to be able to access those deductions
241      * directly, without seeing the raw data which triggered them. In particular,
242      * this allows the forward rules to be used as if they were rewrite transformation
243      * rules.
244      * @return the deductions graph, if relevant for this class of inference
245      * engine or null if not.
246      */

247     public Graph getDeductionsGraph() {
248         return null;
249     }
250
251     /**
252      * Test a global boolean property of the graph. This might included
253      * properties like consistency, OWLSyntacticValidity etc.
254      * It remains to be seen what level of generality is needed here. We could
255      * replace this by a small number of specific tests for common concepts.
256      * @param property the URI of the property to be tested
257      * @return a Node giving the value of the global property, this may
258      * be a boolean literal, some other literal value (e.g. a size).
259      */

260     public Node getGlobalProperty(Node property) {
261         throw new ReasonerException("Global property not implemented: " + property);
262     }
263
264     /**
265      * A convenience version of getGlobalProperty which can only return
266      * a boolean result.
267      */

268     public boolean testGlobalProperty(Node property) {
269         Node resultNode = getGlobalProperty(property);
270         if (resultNode.isLiteral()) {
271             Object JavaDoc result = resultNode.getLiteral().getValue();
272             if (result instanceof Boolean JavaDoc) {
273                 return ((Boolean JavaDoc)result).booleanValue();
274             }
275         }
276         throw new ReasonerException("Global property test returned non-boolean value" +
277                                      "\nTest was: " + property +
278                                      "\nResult was: " + resultNode);
279     }
280
281     /**
282      * Test the consistency of the bound data. This normally tests
283      * the validity of the bound instance data against the bound
284      * schema data.
285      * @return a ValidityReport structure
286      */

287     public ValidityReport validate() {
288         checkOpen();
289         return new StandardValidityReport();
290     }
291
292    /**
293      * An extension of the Graph.find interface which allows the caller to
294      * encode complex expressions in RDF and then refer to those expressions
295      * within the query triple. For example, one might encode a class expression
296      * and then ask if there are any instances of this class expression in the
297      * InfGraph.
298      * @param subject the subject Node of the query triple, may be a Node in
299      * the graph or a node in the parameter micro-graph or null
300      * @param property the property to be retrieved or null
301      * @param object the object Node of the query triple, may be a Node in
302      * the graph or a node in the parameter micro-graph.
303      * @param param a small graph encoding an expression which the subject and/or
304      * object nodes refer.
305      */

306     public ExtendedIterator find(Node subject, Node property, Node object, Graph param) {
307         return cloneWithPremises(param).find(subject, property, object);
308     }
309
310     /**
311      * Returns an iterator over Triples.
312      *
313      * <p>This code used to have the .filterKeep component uncommented. We
314      * think this is because of earlier history, before .matches on a literal node
315      * was implemented as sameValueAs rather than equals. If it turns out that
316      * the filter is needed, it can be commented back in, AND a corresponding
317      * filter added to find(Node x 3) -- and test cases, of course.
318      *
319      * <p>[Chris, after discussion with Dave]
320      */

321     public ExtendedIterator graphBaseFind(TripleMatch m) {
322         return graphBaseFind(m.getMatchSubject(), m.getMatchPredicate(), m.getMatchObject())
323              // .filterKeep(new TripleMatchFilter(m.asTriple()))
324
;
325     }
326
327     /**
328      * Returns an iterator over Triples.
329      * This implementation assumes that the underlying findWithContinuation
330      * will have also consulted the raw data.
331      */

332     public ExtendedIterator graphBaseFind(Node subject, Node property, Node object) {
333         return findWithContinuation(new TriplePattern(subject, property, object), fdata);
334     }
335
336     /**
337      * Extended find interface used in situations where the implementator
338      * may or may not be able to answer the complete query. It will
339      * attempt to answer the pattern but if its answers are not known
340      * to be complete then it will also pass the request on to the nested
341      * Finder to append more results.
342      * @param pattern a TriplePattern to be matched against the data
343      * @param continuation either a Finder or a normal Graph which
344      * will be asked for additional match results if the implementor
345      * may not have completely satisfied the query.
346      */

347     abstract public ExtendedIterator findWithContinuation(TriplePattern pattern, Finder continuation);
348
349
350     /**
351      * Basic pattern lookup interface.
352      * This implementation assumes that the underlying findWithContinuation
353      * will have also consulted the raw data.
354      * @param pattern a TriplePattern to be matched against the data
355      * @return a ExtendedIterator over all Triples in the data set
356      * that match the pattern
357      */

358     public ExtendedIterator find(TriplePattern pattern) {
359         checkOpen();
360         return findWithContinuation(pattern, fdata);
361     }
362
363     /**
364      * Switch on/off drivation logging
365      */

366     public void setDerivationLogging(boolean logOn) {
367         recordDerivations = logOn;
368     }
369
370     /**
371      * Return the derivation of the given triple (which is the result of
372      * some previous find operation).
373      * Not all reasoneers will support derivations.
374      * @return an iterator over Derivation records or null if there is no derivation information
375      * available for this triple.
376      */

377     public Iterator JavaDoc getDerivation(Triple triple) {
378         return null;
379     }
380
381     /**
382      * Return the number of triples in the just the base graph
383      */

384     public int graphBaseSize() {
385         checkOpen();
386         return fdata.getGraph().size();
387     }
388
389     /**
390         Answer true iff this graph is empty. [Used to be in QueryHandler, but moved in
391         here because it's a more primitive operation.]
392     */

393     public boolean isEmpty() {
394         return fdata.getGraph().isEmpty();
395     }
396
397     /**
398      * Free all resources, any further use of this Graph is an error.
399      */

400     public void close() {
401         if (!closed) {
402             fdata.getGraph().close();
403             fdata = null;
404             super.close();
405         }
406     }
407
408     /**
409      * Add one triple to the data graph, run any rules triggered by
410      * the new data item, recursively adding any generated triples.
411      */

412     public synchronized void performAdd(Triple t) {
413         if (!isPrepared) prepare();
414         fdata.getGraph().add(t);
415     }
416
417     /**
418      * Removes the triple t (if possible) from the set belonging to this graph.
419      */

420     public void performDelete(Triple t) {
421         if (!isPrepared) prepare();
422         fdata.getGraph().delete(t);
423     }
424
425     /**
426      * Return the schema graph, if any, bound into this inference graph.
427      */

428     public abstract Graph getSchemaGraph();
429
430     /**
431      * Return a new inference graph which is a clone of the current graph
432      * together with an additional set of data premises. The default
433      * implementation loses ALL partial deductions so far. Some subclasses
434      * may be able to a more efficient job.
435      */

436     public InfGraph cloneWithPremises(Graph premises) {
437         return getReasoner().bindSchema(getSchemaGraph()).bind(new Union(getRawGraph(), premises));
438     }
439
440 }
441
442 /*
443     (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
444     All rights reserved.
445
446     Redistribution and use in source and binary forms, with or without
447     modification, are permitted provided that the following conditions
448     are met:
449
450     1. Redistributions of source code must retain the above copyright
451        notice, this list of conditions and the following disclaimer.
452
453     2. Redistributions in binary form must reproduce the above copyright
454        notice, this list of conditions and the following disclaimer in the
455        documentation and/or other materials provided with the distribution.
456
457     3. The name of the author may not be used to endorse or promote products
458        derived from this software without specific prior written permission.
459
460     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
461     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
462     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
463     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
464     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
465     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
466     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
467     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
468     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
469     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
470 */

471
Popular Tags