jena-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject svn commit: r1165922 [2/3] - in /incubator/jena/site/trunk: content/jena/documentation/inference/ content/jena/documentation/inference/data/ content/jena/documentation/ontology/ content/jena/documentation/tools/ templates/
Date Tue, 06 Sep 2011 23:07:18 GMT
Modified: incubator/jena/site/trunk/content/jena/documentation/inference/index.mdtext
--- incubator/jena/site/trunk/content/jena/documentation/inference/index.mdtext (original)
+++ incubator/jena/site/trunk/content/jena/documentation/inference/index.mdtext Tue Sep  6 23:07:18 2011
@@ -1 +1,2095 @@
-Title: Reasoners and rule engines
+Title: Reasoners and rule engines: Jena inference support
+<p>This section of the documentation describes the current support for inference
+  available within Jena. It includes an outline of the general inference API,
+  together with details of the specific rule engines and configurations for RDFS
+  and OWL inference supplied with Jena.</p>
+<p> Not all of the fine details of the API are covered here: refer to the Jena
+  <a href="../javadoc/index.html">Javadoc</a> to get the full details of the capabilities
+  of the API. </p>
+<p> Note that this is a preliminary version of this document, some errors or inconsistencies
+  are possible, and feedback to the author (via the <a href="">jena-dev</a>
+  support list) is welcomed. </p>
+##<a name="index"></a>Index
+  <li><a href="#overview">Overview of inference support</a> </li>
+  <li><a href="#api">The inference API</a></li>
+  <li><a href="#rdfs">The RDFS reasoner</a></li>
+  <li><a href="#owl">The OWL reasoner</a></li>
+  <li><a href="#daml">DAML support</a></li>
+  <li><a href="#transitive">The transitive reasoner</a></li>
+  <li><a href="#rules">The general purpose rule engine</a></li>
+  <li><a href="#extensions">Extending the inference support</a></li>
+  <li><a href="#futures">Futures</a></li>
+##<a name="overview"></a>Overview of inference support
+<p>The Jena inference subsystem is designed to allow a range of inference engines
+  or reasoners to be plugged into Jena. Such engines are used to derive additional
+  RDF assertions which are entailed from some base RDF together with any optional
+  ontology information and the axioms and rules associated with the reasoner.
+  The primary use of this mechanism is to support the use of languages such as
+  RDFS and OWL which allow additional facts to be inferred from instance data
+  and class descriptions. However, the machinery is designed to be quite general
+  and, in particular, it includes a generic rule engine that can be used for many
+  RDF processing or transformation tasks.</p>
+<p>We will try to use the term <em>inference</em> to refer to the abstract process
+  of deriving additional information and the term <em>reasoner</em> to refer to
+  a specific code object that performs this task. Such usage is arbitrary and
+  if we slip into using equivalent terms like <em>reasoning</em> and <em>inference
+  engine</em> please forgive us. </p>
+<p>The overall structure of the inference machinery is illustrated below. </p>
+<p class="centered"><img src="../images/reasoner-overview.png" width="544" height="305" alt="Overall structure of inference machinery"></p>
+<p>Applications normally access the inference machinery by using the <a href="../javadoc/com/hp/hpl/jena/rdf/model/ModelFactory.html"><code>ModelFactory</code></a>
+  to associate a data set with some reasoner to create a new Model. Queries to
+  the created model will return not only those statements that were present in
+  the original data but also additional statements than can be derived from the
+  data using the rules or other inference mechanisms implemented by the reasoner.</p>
+<p>As illustrated the inference machinery is actually implemented at the level
+  of the Graph SPI, so that any of the different Model interfaces can be constructed
+  around an inference Graph. In particular, the <a href="../ontology/index.html">Ontology
+  API</a> provides convenient ways to link appropriate reasoners into the <code>OntModel</code>s
+  that it constructs. As part of the general RDF API we also provide an <a href="../javadoc/com/hp/hpl/jena/rdf/model/InfModel.html"><code>InfModel</code></a>,
+  this is an extension to the normal <code>Model</code> interface that provides
+  additional control and access to an underlying inference graph. </p>
+<p>The reasoner API supports the notion of specializing a reasoner by binding
+  it to a set of schema or ontology data using the <code>bindSchema</code> call.
+  The specialized reasoner can then be attached to different sets of instance
+  data using <code>bind</code> calls. In situations where the same schema information
+  is to be used multiple times with different sets of instance data then this
+  technique allows for some reuse of inferences across the different uses of the
+  schema. In RDF there is no strong separation between schema (aka Ontology AKA
+  tbox) data and instance (AKA abox) data and so any data, whether class or instance
+  related, can be included in either the <code>bind</code> or <code>bindSchema</code>
+  calls - the names are suggestive rather than restrictive.</p>
+<p>To keep the design as open ended as possible Jena also includes a <code>ReasonerRegistry</code>.
+  This is a static class though which the set of reasoners currently available
+  can be examined. It is possible to register new reasoner types and to dynamically
+  search for reasoners of a given type. The <code>ReasonerRegistry</code> also
+  provides convenient access to prebuilt instances of the main supplied reasoners.</p>
+###Available reasoners
+<p>Included in the Jena distribution are a number of predefined reasoners:</p>
+  <dt>Transitive reasoner</dt>
+  <dd>Provides support for storing and traversing class and property lattices.
+    This implements just the <i>transitive</i> and <i>reflexive</i> properties
+    of <code>rdfs:subPropertyOf</code> and <code>rdfs:subClassOf</code>.</dd>
+  <dt>RDFS rule reasoner</dt>
+  <dd>Implements a configurable subset of the RDFS entailments.</dd>
+  <dt>OWL, OWL Mini, OWL Micro Reasoners</dt>
+  <dd>A set of useful but incomplete implementation of the OWL/Lite subset of the OWL/Full
+    language. </dd>
+  <dt>DAML micro reasoner</dt>
+  <dd>Used internally to enable the legacy DAML API to provide minimal (RDFS scale) inferencing.</dd>
+  <dt>Generic rule reasoner</dt>
+  <dd>A rule based reasoner that supports user defined rules. Forward chaining,
+    tabled backward chaining and hybrid execution strategies are supported.</dd>
+<p>[<a href="#index">index</a>]</p>
+##<a name="api"></a>The Inference API
+  <li><a href="#reasonerAPI">Generic reasoner API</a></li>
+  <li><a href="#generalExamples">Small examples</a></li>
+  <li><a href="#operationsOnInferenceModels">Operations on inference models</a><br>
+    - <a href="#validation">Validation</a><br>
+    - <a href="#extendedListStatements">Extended list statements</a><br>
+    - <a href="#directRelations">Direct and indirect relations</a><br>
+    - <a href="#derivations">Derivations</a><br>
+    - <a href="#rawAccess">Accessing raw data and deductions</a><br>
+    - <a href="#processingControl">Processing control</a><br>
+    - <a href="#tracing">Tracing</a> <br>
+  </li>
+###<a name="reasonerAPI"></a>Generic reasoner API
+####Finding a reasoner
+<p>For each type of reasoner there is a factory class (which conforms to the interface
+  <code><a href="../javadoc/com/hp/hpl/jena/reasoner/ReasonerFactory.html">ReasonerFactory</a></code>)
+  an instance of which can be used to create instances of the <code>associated
+  <a href="../javadoc/com/hp/hpl/jena/reasoner/Reasoner.html">Reasoner</a></code>.
+  The factory instances can be located by going directly to a known factory class
+  and using the static <code>theInstance</code>() method or by retrieval from
+  a global <code><a href="../javadoc/com/hp/hpl/jena/reasoner/ReasonerRegistry.html">ReasonerRegistry</a></code>
+  which stores factory instances indexed by URI assigned to the reasoner. </p>
+<p>In addition, there are convenience methods on the <code>ReasonerRegistry</code>
+  for locating a prebuilt instance of each of the main reasoners (<code>getTransitiveReasoner</code>,
+  <code>getRDFSReasoner</code>, <code>getRDFSSimpleReasoner</code>, <code>getOWLReasoner</code>, <code>getOWLMiniReasoner</code>, <code>getOWLMicroReasoner</code>).</p>
+<p>Note that the factory objects for constructing reasoners are just there to
+  simplify the design and extension of the registry service. Once you have a reasoner
+  instance, the same instance can reused multiple times by binding it to different
+  datasets, without risk of interference - there is no need to create a new reasoner
+  instance each time.</p>
+<p>If working with the <a href="../ontology/index.html">Ontology API</a> it is
+  not always necessary to explicitly locate a reasoner. The prebuilt instances
+  of OntModelSpec provide easy access to the appropriate reasoners to use for
+  different Ontology configurations.</p>
+<p>Similarly, if all you want is a plain RDF Model with RDFS inference included
+  then the convenience methods <code>ModelFactory.createRDFSModel</code> can be
+  used. </p>
+####Configuring a reasoner
+<p>The behaviour of many of the reasoners can be configured. To allow arbitrary
+  configuration information to be passed to reasoners we use RDF to encode the
+  configuration details. The <code>ReasonerFactory.create</code> method can be
+  passed a Jena <code>Resource</code> object, the properties of that object will
+  be used to configure the created reasoner.</p>
+<p>To simplify the code required for simple cases we also provide a direct Java
+  method to set a single configuration parameter, <code>Reasoner.setParameter</code>.
+  The parameter being set is identified by the corresponding configuration property.</p>
+<p>For the built in reasoners the available configuration parameters are described
+  below and are predefined in the <code><a href="../javadoc/com/hp/hpl/jena/vocabulary/ReasonerVocabulary.html">ReasonerVocabulary</a></code>
+  class.</p>
+<p>The parameter value can normally be a String or a structured value. For example,
+  to set a boolean value one can use the strings &quot;true&quot; or &quot;false&quot;,
+  or in Java use a Boolean object or in RDF use an instance of xsd:Boolean</p>
+####Applying a reasoner to data
+<p>Once you have an instance of a reasoner it can then be attached to a set of
+  RDF data to create an inference model. This can either be done by putting all
+  the RDF data into one Model or by separating into two components - schema and
+  instance data. For some external reasoners a hard separation may be required.
+  For all of the built in reasoners the separation is arbitrary. The prime value
+  of this separation is to allow some deductions from one set of data (typically
+  some schema definitions) to be efficiently applied to several subsidiary sets
+  of data (typically sets of instance data).</p>
+<p>If you want to specialize the reasoner this way, by partially-applying it to
+  a set schema data, use the <code>Reasoner.bindSchema</code> method which returns
+  a new, specialized, reasoner.</p>
+<p>To bind the reasoner to the final data set to create an inference model see
+  the <a href="../javadoc/com/hp/hpl/jena/rdf/model/ModelFactory.html"><code>ModelFactory</code></a>
+  methods, particularly <code>ModelFactory.createInfModel</code>. </p>
+####Accessing inferences
+<p>Finally, having created a inference model then any API operations which access
+  RDF statements will be able to access additional statements which are entailed
+  from the bound data by means of the reasoner. Depending on the reasoner these
+  additional <i>virtual</i> statements may all be precomputed the first time the
+  model is touched, may be dynamically recomputed each time or may be computed
+  on-demand but cached.</p>
+####Reasoner description
+<p>The reasoners can be described using RDF metadata which can be searched to
+  locate reasoners with appropriate properties. The calls <code>Reasoner.getCapabilities</code>
+  and <code>Reasoner.supportsProperty</code> are used to access this descriptive
+  metadata.</p>
+<p>[<a href="#api">API index</a>] [<a href="#index">main index</a>]</p>
+###<a name="generalExamples"></a>Some small examples
+<p>These initial examples are not designed to illustrate the power of the reasoners
+  but to illustrate the code required to set one up.</p>
+<p>Let us first create a Jena model containing the statements that some property
+  &quot;p&quot; is a subproperty of another property &quot;q&quot; and that we
+  have a resource &quot;a&quot; with value &quot;foo&quot; for &quot;p&quot;.
+  This could be done by writing an RDF/XML or N3 file and reading that in but
+  we have chosen to use the RDF API:</p>
+<pre>    String NS = "urn:x-hp-jena:eg/";
+    // Build a trivial example data set
+    Model rdfsExample = ModelFactory.createDefaultModel();
+    Property p = rdfsExample.createProperty(NS, "p");
+    Property q = rdfsExample.createProperty(NS, "q");
+    rdfsExample.add(p, RDFS.subPropertyOf, q);
+    rdfsExample.createResource(NS+"a").addProperty(p, "foo");
+<p>Now we can create an inference model which performs RDFS inference over this
+  data by using:</p>
+<pre>    InfModel inf = ModelFactory.createRDFSModel(rdfsExample);  // [1]
+<p>We can then check that resulting model shows that &quot;a&quot; also has property
+  &quot;q&quot; of value &quot;foo&quot; by virtue of the subPropertyOf entailment:</p>
+<pre>    Resource a = inf.getResource(NS+"a");
+    System.out.println("Statement: " + a.getProperty(q));
+<p>Which prints the output:</p>
+<pre>   <i> Statement: [urn:x-hp-jena:eg/a, urn:x-hp-jena:eg/q, Literal&lt;foo&gt;]</i>
+<p>Alternatively we could have created an empty inference model and then added
+  in the statements directly to that model.</p>
+<p>If we wanted to use a different reasoner which is not available as a convenience
+  method or wanted to configure one we would change line [1]. For example, to
+  create the same set up manually we could replace [1] by:</p>
+<pre>    Reasoner reasoner = ReasonerRegistry.getRDFSReasoner();
+    InfModel inf = ModelFactory.createInfModel(reasoner, rdfsExample);</pre>
+<p>or even more manually by<br>
+<pre>    Reasoner reasoner = RDFSRuleReasonerFactory.theInstance().create(null);
+    InfModel inf = ModelFactory.createInfModel(reasoner, rdfsExample);
+<p>The purpose of creating a new reasoner instance like this variant would be
+  to enable configuration parameters to be set. For example, if we were to listStatements
+  on inf Model we would see that it also &quot;includes&quot; all the RDFS axioms,
+  of which there are quite a lot. It is sometimes useful to suppress these and
+  only see the &quot;interesting&quot; entailments. This can be done by setting
+  the processing level parameter by creating a description of a new reasoner configuration
+  and passing that to the factory method:</p>
+<pre>    Resource config = ModelFactory.createDefaultModel()
+                      .createResource()
+                      .addProperty(ReasonerVocabulary.PROPsetRDFSLevel, "simple");
+    Reasoner reasoner = RDFSRuleReasonerFactory.theInstance().create(config);
+    InfModel inf = ModelFactory.createInfModel(reasoner, rdfsExample);
+<p>This is a rather long winded way of setting a single parameter, though it can
+  be useful in the cases where you want to store this sort of configuration information
+  in a separate (RDF) configuration file. For hardwired cases the following alternative
+  is often simpler:</p>
+<pre>    Reasoner reasoner = RDFSRuleReasonerFactory.theInstance()Create(null);
+    reasoner.setParameter(ReasonerVocabulary.PROPsetRDFSLevel,
+                          ReasonerVocabulary.RDFS_SIMPLE);
+    InfModel inf = ModelFactory.createInfModel(reasoner, rdfsExample);
+<p>Finally, supposing you have a more complex set of schema information, defined
+  in a Model called <i>schema,</i> and you want to apply this schema to several
+  sets of instance data without redoing too many of the same intermediate deductions.
+  This can be done by using the SPI level methods: </p>
+<pre>    Reasoner boundReasoner = reasoner.bindSchema(schema);
+    InfModel inf = ModelFactory.createInfModel(boundReasoner, data);
+<p>This creates a new reasoner, independent from the original, which contains
+  the schema data. Any queries to an InfModel created using the boundReasoner
+  will see the schema statements, the data statements and any statements entailed
+  from the combination of the two. Any updates to the InfModel will be reflected
+  in updates to the underlying data model - the schema model will not be affected.</p>
+<p>[<a href="#api">API index</a>] [<a href="#index">main index</a>]</p>
+###<a name="operationsOnInferenceModels"></a>Operations on inference models
+<p>For many applications one simply creates a model incorporating some inference
+  step, using the <code>ModelFactory</code> methods, and then just works within
+  the standard Jena Model API to access the entailed statements. However, sometimes
+  it is necessary to gain more control over the processing or to access additional
+  reasoner features not available as <i>virtual</i> triples.</p>
+####<a name="validation"></a>Validation
+<p>The most common reasoner operation which can't be exposed through additional
+  triples in the inference model is that of validation. Typically the ontology
+  languages used with the semantic web allow constraints to be expressed, the
+  validation interface is used to detect when such constraints are violated by
+  some data set. </p>
+<p>A simple but typical example is that of datatype ranges in RDFS. RDFS allows
+  us to specify the range of a property as lying within the value space of some
+  datatype. If an RDF statement asserts an object value for that property which
+  lies outside the given value space there is an inconsistency.</p>
+<p>To test for inconsistencies with a data set using a reasoner we use the <code>InfModel.validate()</code>
+  interface. This performs a global check across the schema and instance data
+  looking for inconsistencies. The result is a <code>ValidityReport</code> object
+  which comprises a simple pass/fail flag (<code>ValidityReport.isValid()</code>)
+  together with a list of specific reports (instances of the <code>ValidityReport.Report</code>
+  interface) which detail any detected inconsistencies. At a minimum the individual
+  reports should be printable descriptions of the problem but they can also contain
+  an arbitrary reasoner-specific object which can be used to pass additional information
+  which can be used for programmatic handling of the violations.</p>
+<p>For example, to check a data set and list any problems one could do something
+  like:</p>
+<pre>    Model data = FileManager.get().loadModel(fname);
+    InfModel infmodel = ModelFactory.createRDFSModel(data);
+    ValidityReport validity = infmodel.validate();
+    if (validity.isValid()) {
+        System.out.println("OK");
+    } else {
+        System.out.println("Conflicts");
+        for (Iterator i = validity.getReports(); i.hasNext(); ) {
+            System.out.println(" - " +;
+        }
+    }
+<p>The file <code>testing/reasoners/rdfs/dttest2.nt</code> declares a property
+  <code>bar</code> with range <code>xsd:integer</code> and attaches a <code>bar</code>
+  value to some resource with the value <code>&quot;25.5&quot;^^xsd:decimal</code>.
+  If we run the above sample code on this file we see:</p>
+  <p><i>Conflicts <br>
+    - Error (dtRange): Property has a
+    typed range Datatype[ -&gt; class java.math.BigInteger]that
+    is not compatible with 25.5: </i></p>
+<p>Whereas the file <code>testing/reasoners/rdfs/dttest3.nt</code> uses the value
+  &quot;25&quot;^^xsd:decimal instead, which is a valid integer and so passes.
+<p>Note that the individual validation records can include warnings as well as
+  errors. A warning does not affect the overall <code>isValid()</code> status
+  but may indicate some issue the application may wish to be aware of. For example,
+  it would be possible to develop a modification to the RDFS reasoner which warned
+  about use of a property on a resource that is not explicitly declared to have
+  the type of the domain of the property. </p>
+<p>A particular case of this arises in the case of OWL. In the Description Logic
+  community a class which cannot have an instance is regarded as &quot;inconsistent&quot;.
+  That term is used because it generally arises from an error in the ontology.
+  However, it is not a logical inconsistency - i.e. something giving rise to a
+  contradiction. Having an instance of such a class is, clearly a logical error.
+  In the Jena 2.2 release we clarified the semantics of <code>isValid()</code>.
+  An ontology which is logically consistent but contains empty classes is regarded
+  as valid (that is <code>isValid()</code> is false only if there is a logical
+  inconsistency). Class expressions which cannot be instantiated are treated as
+  warnings rather than errors. To make it easier to test for this case there is
+  an additional method <code>Report.isClean()</code> which returns true if the
+  ontology is both valid (logically consistent) and generated no warnings (such
+  as inconsistent classes).</p>
+####<a name="extendedListStatements"></a>Extended list statements
+<p>The default API supports accessing all entailed information at the level of
+  individual triples. This is surprisingly flexible but there are queries which
+  cannot be easily supported this way. The first such is when the query needs
+  to make reference to an expression which is not already present in the data.
+  For example, in description logic systems it is often possible to ask if there
+  are any instances of some class expression. Whereas using the triple-based approach
+  we can only ask if there are any instances of some class already defined (though
+  it could be defined by a bNode rather than be explicitly named).</p>
+<p>To overcome this limitation the <code>InfModel</code> API supports a notion
+  of &quot;posit&quot;, that is a set of assertions which can be used to temporarily
+  declare new information such as the definition of some class expression. These
+  temporary assertions can then be referenced by the other arguments to the <code>listStatements</code>
+  command. With the current reasoners this is an expensive operation, involving
+  the temporary creation of an entire new model with the additional posits added
+  and all inference has to start again from scratch. Thus it is worth considering
+  preloading your data with expressions you might need to query over. However,
+  for some external reasoners, especially description logic reasoners, we anticipate
+  restricted uses of this form of listStatement will be important.</p>
+####<a name="directRelations"></a>Direct and indirect relationships
+<p>The second type of operation that is not obviously convenient at the triple
+  level involves distinguishing between direct and indirect relationships. If
+  a relation is transitive, for example rdfs:subClassOf, then we can define the
+  notion of the <i>minimal</i> or <i>direct</i> form of the relationship from
+  which all other values of the relation can be derived by transitive closure.
+<p align="center"><img src="../images/direct-relations.PNG" width="473" height="204">
+<p>Normally, when an InfGraph is queried for a transitive relation the results
+  returned show the inferred relations, i.e. the full transitive closure (all
+  the links (ii) in the illustration). However, in some cases, such when as building
+  a hierarchical UI widget to represent the graph, it is more convenient to only
+  see the direct relations (iii). This is achieved by defining special <i>direct</i>
+  aliases for those relations which can be queried this way. For the built in
+  reasoners this functionality is available for <code>rdfs:subClassOf</code> and
+  <code>rdfs:subPropertyOf</code> and the direct aliases for these are defined
+  in <a href="../javadoc/com/hp/hpl/jena/vocabulary/ReasonerVocabulary.html"><code>ReasonerVocabulary</code></a>.</p>
+<p>Typically the easiest way to work with such indirect and direct relations is
+  to use the <a href="../ontology/index.html">Ontology API</a> which hides the
+  grubby details of these property aliases.</p>
+####<a name="derivations"></a>Derivations
+<p>It is sometimes useful to be able to trace where an inferred statement was
+  generated from. This is achieved using the <code>InfModel.getDerivation(Statement)</code>
+  method. This returns a iterator over a set <a href="../javadoc/com/hp/hpl/jena/reasoner/Derivation.html"><code>Derviation</code></a>
+  objects through which a brief description of the source of the derivation can
+  be obtained. Typically understanding this involves tracing the sources for other
+  statements which were used in this derivation and the <code>Derivation.PrintTrace</code>
+  method is used to do this recursively.</p>
+<p>The general form of the Derivation objects is quite abstract but in the case
+  of the rule-based reasoners they have a more detailed internal structure that
+  can be accessed - see <code><a href="../javadoc/com/hp/hpl/jena/reasoner/rulesys/RuleDerivation.html">RuleDerivation</a></code>.</p>
+<p>Derviation information is rather expensive to compute and store. For this reason,
+  it is not recorded by default and <code>InfModel.serDerivationLogging(true)</code>
+  must be used to enable derivations to be recorded. This should be called before
+  any queries are made to the inference model.</p>
+<p>As an illustration suppose that we have a raw data model which asserts three
+  triples:</p>
+<pre>eg:A eg:p eg:B .
+eg:B eg:p eg:C .
+eg:C eg:p eg:D .</pre>
+<p>and suppose that we have a trivial rule set which computes the transitive closure
+  over relation eg:p</p>
+<pre>    String rules = "[rule1: (?a eg:p ?b) (?b eg:p ?c) -&gt; (?a eg:p ?c)]";
+    Reasoner reasoner = new GenericRuleReasoner(Rule.parseRules(rules));
+    reasoner.setDerivationLogging(true);
+    InfModel inf = ModelFactory.createInfModel(reasoner, rawData);</pre>
+<p>Then we can query whether eg:A is related through eg:p to eg:D and list the
+  derivation route using the following code fragment: </p>
+<pre>    PrintWriter out = new PrintWriter(System.out);
+    for (StmtIterator i = inf.listStatements(A, p, D); i.hasNext(); ) {
+        Statement s = i.nextStatement();
+        System.out.println("Statement is " + s);
+        for (Iterator id = inf.getDerivation(s); id.hasNext(); ) {
+            Derivation deriv = (Derivation);
+            deriv.printTrace(out, true);
+        }
+    }
+    out.flush();
+<p>Which generates the output:</p>
+<pre><i>Statement is [urn:x-hp:eg/A, urn:x-hp:eg/p, urn:x-hp:eg/D]
+Rule rule1 concluded (eg:A eg:p eg:D) &lt;-
+    Fact (eg:A eg:p eg:B)
+    Rule rule1 concluded (eg:B eg:p eg:D) &lt;-
+        Fact (eg:B eg:p eg:C)
+        Fact (eg:C eg:p eg:D)</i></pre>
+####<a name="rawAccess"></a>Accessing raw data and deductions
+<p>From an <code>InfModel</code> it is easy to retrieve the original, unchanged,
+  data over which the model has been computed using the <code>getRawModel()</code>
+  call. This returns a model equivalent to the one used in the initial <code>bind</code>
+  call. It might not be the same Java object but it uses the same Java object
+  to hold the underlying data graph. </p>
+<p>Some reasoners, notably the forward chaining rule engine, store the deduced
+  statements in a concrete form and this set of deductions can be obtained separately
+  by using the <code>getDeductionsModel()</code> call. </p>
+####<a name="processingControl"></a>Processing control
+<p>Having bound a <code>Model</code> into an <code>InfModel</code> by using a
+  <code>Reasoner</code> its content can still be changed by the normal <code>add</code>
+  and <code>remove</code> calls to the <code>InfModel</code>. Any such change
+  the model will usually cause all current deductions and temporary rules to be
+  discarded and inference will start again from scratch at the next query. Some
+  reasoners, such as the RETE-based forward rule engine, can work incrementally.
+<p>In the non-incremental case then the processing will not be started until a
+  query is made. In that way a sequence of add and removes can be undertaken without
+  redundant work being performed at each change. In some applications it can be
+  convenient to trigger the initial processing ahead of time to reduce the latency
+  of the first query. This can be achieved using the<code> InfModel.prepare()</code>
+  call. This call is not necessary in other cases, any query will automatically
+  trigger an internal prepare phase if one is required.</p>
+<p>There are times when the data in a model bound into an InfModel can is changed
+  &quot;behind the scenes&quot; instead of through calls to the InfModel. If this
+  occurs the result of future queries to the InfModel are unpredictable. To overcome
+  this and force the InfModel to reconsult the raw data use the <code>InfModel.rebind()</code>
+  call.</p>
+<p>Finally, some reasoners can store both intermediate and final query results
+  between calls. This can substantially reduce the cost of working with the inference
+  services but at the expense of memory usage. It is possible to force an InfModel
+  to discard all such cached state by using the <code>InfModel.reset()</code>
+  call. It there are any outstanding queries (i.e. StmtIterators which have not
+  been read to the end yet) then those will be aborted (the next hasNext() call
+  will return false).</p>
+####<a name="tracing"></a>Tracing
+<p>When developing new reasoner configurations, especially new rule sets for the
+  rule engines, it is sometimes useful to be able to trace the operations of the
+  associated inference engine. Though, often this generates too much information
+  to be of use and selective use of the <code>print</code> builtin can be more
+  effective. </p>
+<p>Tracing is not supported by a convenience API call but, for those reasoners
+  that support it, it can be enabled using:</p>
+<pre>   reasoner.setParameter(ReasonerVocabulary.PROPtraceOn, Boolean.TRUE);
+<p>Dynamic tracing control is sometimes possible on the InfModel itself by retrieving
+  its underlying InfGraph and calling <code>setTraceOn()</code> call. If you need
+  to make use of this see the full javadoc for the relevant InfGraph implementation.</p>
+<p>[<a href="#api">API index</a>] [<a href="#index">main index</a>]</p>
+##<a name="rdfs"></a>The RDFS reasoner
+  <li><a href="#RDFSintro">RDFS reasoner - introduction and coverage</a></li>
+  <li><a href="#RDFSconfiguration">RDFS Configuration</a></li>
+  <li><a href="#RDFSexamples">RDFS Example</a></li>
+  <li><a href="#RDFSnotes">RDFS implementation and performance notes</a></li>
+###<a name="RDFSintro"></a>RDFS reasoner - intro and coverage
+<p>Jena includes an RDFS reasoner (<code>RDFSRuleReasoner</code>) which supports
+  almost all of the RDFS entailments described by the RDF Core working group [<a href="">RDF
+  Semantics</a>]. The only omissions are deliberate and are described below.</p>
+<p>This reasoner is accessed using <code>ModelFactory.createRDFSModel</code> or
+  manually via <code>ReasonerRegistery.getRDFSReasoner()</code>.</p>
+<p>During the preview phases of Jena experimental RDFS reasoners were released,
+  some of which are still included in the code base for now but applications should
+  not rely on their stability or continued existence.</p>
+<p>When configured in <i>full</i> mode (see below for configuration information)
+  then the RDFS reasoner implements all RDFS entailments except for the bNode
+  closure rules. These closure rules imply, for example, that for all triples
+  of the form:</p>
+<pre>eg:a eg:p nnn^^datatype .</pre>
+<p>we should introduce the corresponding blank nodes:</p>
+<pre>eg:a eg:p _:anon1 .
+_:anon1 rdf:type datatype .</pre>
+<p>Whilst such rules are both correct and necessary to reduce RDF datatype entailment
+  down to simple entailment they are not useful in implementation terms. In Jena
+  simple entailment can be implemented by translating a graph containing bNodes
+  to an equivalent query containing variables in place of the bNodes. Such a query
+  is can directly match the literal node and the RDF API can be used to extract
+  the datatype of the literal. The value to applications of directly seeing the
+  additional bNode triples, even in <i>virtual</i> triple form, is negligible
+  and so this has been deliberately omitted from the reasoner. </p>
+<p>[<a href="#rdfs">RDFS index</a>] [<a href="#index">main index</a>]</p>
+###<a name="RDFSconfiguration"></a>RDFS configuration
+<p>The RDFSRuleReasoner can be configured to work at three different compliance
+  levels: </p>
+  <dt>Full</dt>
+  <dd>This implements all of the RDFS axioms and closure rules with the exception
+    of bNode entailments and datatypes (rdfD 1). See above for comments on these.
+    This is an expensive mode because all statements in the data graph need to
+    be checked for possible use of container membership properties. It also generates
+    type assertions for all resources and properties mentioned in the data (rdf1,
+    rdfs4a, rdfs4b).</dd>
+  <dt>Default</dt>
+  <dd>This omits the expensive checks for container membership properties and
+    the &quot;everything is a resource&quot; and &quot;everything used as a property
+    is one&quot; rules (rdf1, rdfs4a, rdfs4b). The latter information is available
+    through the Jena API and creating virtual triples to this effect has little
+    practical value.<br>
+    This mode does include all the axiomatic rules. Thus, for example, even querying
+    an &quot;empty&quot; RDFS InfModel will return triples such as <code>[rdf:type
+    rdfs:range rdfs:Class]</code>.</dd>
+  <dt>Simple</dt>
+  <dd>This implements just the transitive closure of subPropertyOf and subClassOf
+    relations, the domain and range entailments and the implications of subPropertyOf
+    and subClassOf. It omits all of the axioms. This is probably the most useful
+    mode but is not the default because it is a less complete implementation of
+    the standard. </dd>
+<p>The level can be set using the <code>setParameter</code> call, e.g.</p>
+<pre>    reasoner.setParameter(ReasonerVocabulary.PROPsetRDFSLevel,
+                          ReasonerVocabulary.RDFS_SIMPLE);
+<p>or by constructing an RDF configuration description and passing that to the
+  RDFSRuleReasonerFactory e.g.</p>
+<pre>    Resource config = ModelFactory.createDefaultModel()
+                      .createResource()
+                      .addProperty(ReasonerVocabulary.PROPsetRDFSLevel, "simple");
+    Reasoner reasoner = RDFSRuleReasonerFactory.theInstance()Create(config);
+####Summary of parameters
+<table width="90%" border="1" cellspacing="0" cellpadding="0">
+  <tr>
+    <td width="22%"><b>Parameter</b></td>
+    <td width="16%"><b>Values</b></td>
+    <td width="62%"><b>Description</b></td>
+  </tr>
+  <tr>
+    <td width="22%">
+      <div align="left">PROPsetRDFSLevel</div>
+    </td>
+    <td width="16%">&quot;full&quot;, &quot;default&quot;, &quot;simple&quot;</td>
+    <td width="62%">
+      <div align="left">Sets the RDFS processing level as described above.</div>
+    </td>
+  </tr>
+  <tr>
+    <td width="22%">
+      <div align="left">PROPenableCMPScan</div>
+    </td>
+    <td width="16%">Boolean</td>
+    <td width="62%">
+      <div align="left">If true forces a preprocessing pass which finds all usages
+        of rdf:_n properties and declares them as ContainerMembershipProperties.
+        This is implied by setting the level parameter to &quot;full&quot; and
+        is not normally used directly.</div>
+    </td>
+  </tr>
+  <tr>
+    <td width="22%">
+      <div align="left">PROPtraceOn</div>
+    </td>
+    <td width="16%">Boolean</td>
+    <td width="62%">
+      <div align="left">If true switches on exhaustive tracing of rule executions
+        to the log4j <i>info</i> appender.</div>
+    </td>
+  </tr>
+  <tr>
+    <td width="22%">
+      <div align="left">PROPderivationLogging</div>
+    </td>
+    <td width="16%">Boolean</td>
+    <td width="62%">
+      <div align="left">If true causes derivation routes to be recorded internally
+        so that future getDerivation calls can return useful information.</div>
+    </td>
+  </tr>
+<p>[<a href="#rdfs">RDFS index</a>] [<a href="#index">main index</a>]</p>
+###<a name="RDFSexamples"></a>RDFS Example
+<p>As a complete worked example let us create a simple RDFS schema, some instance
+  data and use an instance of the RDFS reasoner to query the two.</p>
+<p>We shall use a trivial schema:</p>
+ &nbsp;&lt;rdf:Description rdf:about="&amp;eg;mum"&gt;
+ &nbsp;&nbsp;&nbsp;&lt;rdfs:subPropertyOf rdf:resource="&amp;eg;parent"/&gt;
+ &nbsp;&lt;/rdf:Description&gt;
+ &nbsp;&lt;rdf:Description rdf:about="&amp;eg;parent"&gt;
+ &nbsp;&nbsp;&nbsp;&lt;rdfs:range &nbsp;rdf:resource="&amp;eg;Person"/&gt;
+ &nbsp;&nbsp;&nbsp;&lt;rdfs:domain rdf:resource="&amp;eg;Person"/&gt;
+ &nbsp;&lt;/rdf:Description&gt;
+ &nbsp;&lt;rdf:Description rdf:about="&amp;eg;age"&gt;
+ &nbsp;&nbsp;&nbsp;&lt;rdfs:range rdf:resource="&amp;xsd;integer" /&gt;
+ &nbsp;&lt;/rdf:Description&gt;
+<p>This defines a property <code>parent</code> from <code>Person</code> to <code>Person</code>,
+  a sub-property <code>mum</code> of <code>parent</code> and an integer-valued
+  property <code>age</code>.</p>
+<p>We shall also use the even simpler instance file:</p>
+ &nbsp;&lt;Teenager rdf:about="&amp;eg;colin"&gt;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;mum rdf:resource="&amp;eg;rosy" /&gt;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;age&gt;13&lt;/age&gt;
+ &nbsp;&lt;/Teenager&gt;
+  Which defines a <code>Teenager</code> called <code>colin</code> who has a <code>mum</code>
+  <code>rosy</code> and an <code>age</code> of 13.</p>
+<p>Then the following code fragment can be used to read files containing these
+  definitions, create an inference model and query it for information on the <code>rdf:type</code>
+  of <code>colin</code> and the <code>rdf:type</code> of <code>Person</code>:</p>
+<pre>Model schema = FileManager.get().loadModel("file:data/rdfsDemoSchema.rdf");
+Model data = FileManager.get().loadModel("file:data/rdfsDemoData.rdf");
+InfModel infmodel = ModelFactory.createRDFSModel(schema, data);
+Resource colin = infmodel.getResource("urn:x-hp:eg/colin");
+System.out.println("colin has types:");
+printStatements(infmodel, colin, RDF.type, null);
+Resource Person = infmodel.getResource("urn:x-hp:eg/Person");
+System.out.println("\nPerson has types:");
+printStatements(infmodel, Person, RDF.type, null);</pre>
+<p>This produces the output:</p>
+<pre><i>colin has types:
+ - (eg:colin rdf:type eg:Teenager)
+ - (eg:colin rdf:type rdfs:Resource)
+ - (eg:colin rdf:type eg:Person)
+Person has types:
+ - (eg:Person rdf:type rdfs:Class)
+ - (eg:Person rdf:type rdfs:Resource)</i></pre>
+<p>This says that <code>colin</code> is both a <code>Teenager</code> (by direct
+  definition), a <code>Person</code> (because he has a <code>mum</code> which
+  means he has a <code>parent</code> and the domain of <code>parent</code> is
+  <code>Person</code>) and an <code>rdfs:Resource</code>. It also says that <code>Person</code>
+  is an <code>rdfs:Class</code>, even though that wasn't explicitly in the schema,
+  because it is used as object of range and domain statements.</p>
+<p>If we add the additional code:</p>
+<pre>ValidityReport validity = infmodel.validate();
+if (validity.isValid()) {
+    System.out.println("\nOK");
+} else {
+    System.out.println("\nConflicts");
+    for (Iterator i = validity.getReports(); i.hasNext(); ) {
+        ValidityReport.Report report = (ValidityReport.Report);
+        System.out.println(" - " + report);
+    }
+  Then we get the additional output:</p>
+ - Error (dtRange): Property urn:x-hp:eg/age has a typed range
+Datatype[ -&gt; class java.math.BigInteger]
+that is not compatible with 13</i></pre>
+<p>because the age was given using an RDF plain litera where as the schema requires
+  it to be a datatyped literal which is compatible with xsd:integer.</p>
+<p>[<a href="#rdfs">RDFS index</a>] [<a href="#index">main index</a>]</p>
+###<a name="RDFSnotes"></a>RDFS implementation and performance notes
+<p>The RDFSRuleReasoner is a hybrid implementation. The subproperty and subclass
+  lattices are eagerly computed and stored in a compact in-memory form using the
+  TransitiveReasoner (see below). The identification of which container membership
+  properties (properties like rdf:_1) are present is implemented using a preprocessing
+  hook. The rest of the RDFS operations are implemented by explicit rule sets
+  executed by the general hybrid rule reasoner. The three different processing
+  levels correspond to different rule sets. These rule sets are located by looking
+  for files &quot;`etc/*.rules`&quot; on the classpath and so could,
+  in principle, be overridden by applications wishing to modify the rules. </p>
+<p>Performance for in-memory queries appears to be good. Using a synthetic dataset
+  we obtain the following times to determine the extension of a class from a class
+  hierarchy:</p>
+<table width="77%" border="1" cellspacing="0" cellpadding="0">
+  <tr>
+    <td width="6%"><b>Set</b></td>
+    <td width="14%"><b>#concepts</b></td>
+    <td width="18%"><b>total instances</b></td>
+    <td width="25%"><b>#instances of concept</b></td>
+    <td width="17%"><b>JenaRDFS</b></td>
+    <td width="20%"><b>XSB*</b></td>
+  </tr>
+  <tr>
+    <td width="6%">1</td>
+    <td width="14%">155</td>
+    <td width="18%">1550</td>
+    <td width="25%">310</td>
+    <td width="17%">0.07</td>
+    <td width="20%">0.16</td>
+  </tr>
+  <tr>
+    <td width="6%">2</td>
+    <td width="14%">780</td>
+    <td width="18%">7800</td>
+    <td width="25%">1560</td>
+    <td width="17%">0.25</td>
+    <td width="20%">0.47</td>
+  </tr>
+  <tr>
+    <td width="6%">3</td>
+    <td width="14%">3905</td>
+    <td width="18%">39050</td>
+    <td width="25%">7810</td>
+    <td width="17%">1.16</td>
+    <td width="20%">2.11</td>
+  </tr>
+<p>The times are in seconds, normalized to a 1.1GHz Pentium processor. The XSB*
+  figures are taken from a pre-published paper and may not be directly comparable
+  (for example they do not include any rule compilation time) - they are just
+  offered to illustrate that the RDFSRuleReasoner has broadly similar scaling
+  and performance to other rule-based implementations.</p>
+<p>The Jena RDFS implementation has not been tested and evaluated over database
+  models. The Jena architecture makes it easy to construct such models but in
+  the absence of caching we would expect the performance to be poor. Future work
+  on adapting the rule engines to exploit the capabilities of the more sophisticated
+  database backends will be considered.</p>
+<p>[<a href="#rdfs">RDFS index</a>] [<a href="#index">main index</a>]</p>
+##<a name="owl"></a>The OWL reasoner
+  <li><a href="#OWLintro">OWL reasoner introduction</a></li>
+  <li><a href="#OWLcoverage">OWL coverage</a></li>
+  <li><a href="#OWLconfiguration">OWL configuration</a></li>
+  <li><a href="#OWLexamples">OWL example</a></li>
+  <li><a href="#OWLnotes">OWL notes and limitations</a></li>
+<p><a name="OWLintro"></a>The second major set of reasoners supplied with Jena is a rule-based
+  implementation of the OWL/lite subset of OWL/full.</p>
+<p>The current release includes a default OWL reasoner and two small/faster configurations.
+Each of the configurations is intended to be a sound implementation of a subset of OWL/full semantics
+but none of them is complete (in the technical sense). For complete OWL DL reasoning use
+an external DL reasoner such as Pellet, Racer or FaCT. The <a href="../how-to/dig-reasoner.html">jena DIG interface</a> makes it
+easy to connect to any reasoner that supports the DIG standard. Performance (especially memory use) of the fuller reasoner
+configuration still leaves something to be desired and will the subject of future work - time permitting.</p>
+<p>See also <a href="#OWLnotes">subsection 5</a> for notes on more specific limitations
+  of the current implementation. </p>
+###<a name="OWLcoverage"></a>OWL coverage
+<p>The Jena OWL reasoners could be described as instance-based reasoners. That
+  is, they work by using rules to propagate the if- and only-if- implications of
+  the OWL constructs on instance data. Reasoning about classes is done indirectly
+  - for each declared class a prototypical instance is created and elaborated.
+  If the prototype for a class A can be deduced as being a member of class B then
+  we conclude that A is a subClassOf B. This approach is in contrast to more sophisticated
+  Description Logic reasoners which work with class expressions and can be less
+  efficient when handling instance data but more efficient with complex class expressions
+  and able to provide complete reasoning. </p>
+<p>We thus anticipate that the OWL rule reasoner will be most suited to applications
+  involving primarily instance reasoning with relatively simple, regular ontologies
+  and least suited to applications involving large rich ontologies. A better characterisation
+  of the tradeoffs involved would be useful and will be sought.</p>
+<p>We intend that the OWL reasoners should be smooth extensions of the RDFS reasoner
+  described above. That is all RDFS entailments found by the RDFS reasoner will
+  also be found by the OWL reasoners and scaling on RDFS schemas should be similar
+  (though there are some costs, see later). The instance-based implementation
+  technique is in keeping with this &quot;RDFS plus a bit&quot; approach.</p>
+<p>Another reason for choosing this inference approach is that it makes it possible
+  to experiment with support for different constructs, including constructs that
+  go beyond OWL, by modification of the rule set. In particular, some applications
+  of interest to ourselves involve ontology transformation which very often implies
+  the need to support property composition. This is something straightforward
+  to express in rule-based form and harder to express in standard Description
+  Logics.</p>
+<p>Since RDFS is not a subset of the OWL/Lite or OWL/DL languages the Jena implementation
+  is an incomplete implementation of OWL/full. We provide three implementations
+  a default (&quot;full&quot; one), a slightly cut down &quot;mini&quot; and a
+  rather smaller/faster &quot;micro&quot;. The default OWL rule reasoner (<code>ReasonerRegistry.getOWLReasoner()</code>)
+  supports the constructs as listed below. The OWLMini reasoner is nearly the
+  same but omits the forward entailments from minCardinality/someValuesFrom restrictions
+  - that is it avoids introducing bNodes which avoids some infinite expansions
+  and enables it to meet the Jena API contract more precisely. The OWLMicro reasoner
+  just supports RDFS plus the various property axioms, intersectionOf, unionOf
+  (partial) and hasValue. It omits the cardinality restrictions and equality axioms,
+  which enables it to achieve much higher performance. </p>
+<table width="90%" border="1" cellspacing="0" cellpadding="0">
+  <tr>
+    <td width="36%"><b>Constructs</b></td>
+    <td width="16%"><b>Supported by</b></td>
+    <td width="48%"><b>Notes</b></td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">rdfs:subClassOf, rdfs:subPropertyOf, rdf:type</div>
+    </td>
+    <td width="16%">all</td>
+    <td width="48%">
+      <div align="left">Normal RDFS semantics supported including meta use (e.g.
+        taking the subPropertyOf subClassOf).</div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">rdfs:domain, rdfs:range</div>
+    </td>
+    <td width="16%">all</td>
+    <td width="48%">
+      <div align="left">Stronger if-and-only-if semantics supported</div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:intersectionOf</div>
+    </td>
+    <td width="16%">all</td>
+    <td width="48%">&nbsp;</td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:unionOf</div>
+    </td>
+    <td width="16%">all</td>
+    <td width="48%">
+      <div align="left">Partial support. If C=unionOf(A,B) then will infer that
+        A,B are subclasses of C, and thus that instances of A or B are instances
+        of C. Does not handle the reverse (that an instance of C must be either
+        an instance of A or an instance of B).</div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:equivalentClass</div>
+    </td>
+    <td width="16%">all</td>
+    <td width="48%">
+      <div align="left"></div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:disjointWith</div>
+    </td>
+    <td width="16%">full, mini</td>
+    <td width="48%">
+      <div align="left"></div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:sameAs, owl:differentFrom, owl:distinctMembers</div>
+    </td>
+    <td width="16%">full, mini</td>
+    <td width="48%">
+      <div align="left">owl:distinctMembers is currently translated into a quadratic
+        set of owl:differentFrom assertions.</div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">Owl:Thing</div>
+    </td>
+    <td width="16%">all</td>
+    <td width="48%">&nbsp;</td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:equivalentProperty, owl:inverseOf </div>
+    </td>
+    <td width="16%">all</td>
+    <td width="48%">
+      <div align="left"></div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:FunctionalProperty, owl:InverseFunctionalProperty</div>
+    </td>
+    <td width="16%">all</td>
+    <td width="48%">
+      <div align="left"></div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:SymmeticProperty, owl:TransitiveProperty</div>
+    </td>
+    <td width="16%">all</td>
+    <td width="48%">
+      <div align="left"></div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:someValuesFrom</div>
+    </td>
+    <td width="16%">full, (mini)</td>
+    <td width="48%">
+      <div align="left">
+        <p>Full supports both directions (existence of a value implies membership
+          of someValuesFrom restriction, membership of someValuesFrom implies
+          the existence of a bNode representing the value).<br>
+          Mini omits the latter &quot;bNode introduction&quot; which avoids some
+          infinite closures.</p>
+      </div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:allValuesFrom</div>
+    </td>
+    <td width="16%">full, mini</td>
+    <td width="48%">
+      <div align="left">Partial support, forward direction only (member of a allValuesFrom(p,
+        C) implies that all p values are of type C). Does handle cases where the
+        reverse direction is trivially true (e.g. by virtue of a global rdfs:range
+        axiom). </div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:minCardinality, owl:maxCardinality, owl:cardinality</div>
+    </td>
+    <td width="16%">full, (mini)</td>
+    <td width="48%">
+      <div align="left">
+        <p>Restricted to cardinalities of 0 or 1, though higher cardinalities
+          are partially supported in validation for the case of literal-valued
+          properties.<br>
+          Mini omits the bNodes introduction in the minCardinality(1) case, see
+          someValuesFrom above.</p>
+      </div>
+    </td>
+  </tr>
+  <tr>
+    <td width="36%">
+      <div align="left">owl:hasValue</div>
+    </td>
+    <td width="16%">all</td>
+    <td width="48%">
+      <div align="left"></div>
+    </td>
+  </tr>
+<p>The critical constructs which go beyond OWL/lite and are not supported in the
+  Jena OWL reasoner are complementOf and oneOf. As noted above the support for
+  unionOf is partial (due to limitations of the rule based approach) but is useful
+  for traversing class hierarchies.</p>
+<p>Even within these constructs rule based implementations are limited in the
+  extent to which they can handle equality reasoning - propositions provable by
+  reasoning over concrete and introduced instances are covered but reasoning by
+  cases is not supported.</p>
+<p>Nevertheless, the full reasoner passes the normative OWL working group positive
+  and negative entailment tests for the supported constructs, though some tests
+  need modification for the comprehension axioms (see below).</p>
+<p>The OWL rule set does include incomplete support for validation of datasets
+  using the above constructs. Specifically, it tests for:</p>
+  <li>Illegal existence of a property restricted by a maxCardinality(0) restriction.</li>
+  <li>Two individuals both sameAs and differentFrom each other.</li>
+  <li>Two classes declared as disjoint but where one subsumes the other (currently
+    reported as a violation concerning the class prototypes, error message to
+    be improved).</li>
+  <li>Range or a allValuesFrom violations for DatatypeProperties.</li>
+  <li>Too many literal-values for a DatatypeProperty restricted by a maxCardinality(N)
+    restriction.</li>
+<p>[<a href="#owl">OWL index</a>] [<a href="#index">main index</a>]</p>
+###<a name="OWLconfiguration"></a>OWL Configuration
+<p>This reasoner is accessed using <code>ModelFactory.createOntologyModel</code>
+  with the prebuilt <a href="../javadoc/com/hp/hpl/jena/ontology/OntModelSpec.html"><code>OntModelSpec</code></a>
+  <code>OWL_MEM_RULE_INF</code> or manually via <code>ReasonerRegistery.getOWLReasoner()</code>.</p>
+<p>There are no OWL-specific configuration parameters though the reasoner supports
+  the standard control parameters:</p>
+<table width="90%" border="1" cellspacing="0" cellpadding="0">
+  <tr>
+    <td width="22%"><b>Parameter</b></td>
+    <td width="16%"><b>Values</b></td>
+    <td width="62%"><b>Description</b></td>
+  </tr>
+  <tr>
+    <td width="22%">
+      <div align="left">PROPtraceOn</div>
+    </td>
+    <td width="16%">boolean</td>
+    <td width="62%">
+      <div align="left">If true switches on exhaustive tracing of rule executions
+        to the log4j <i>info</i> appender.</div>
+    </td>
+  </tr>
+  <tr>
+    <td width="22%">
+      <div align="left">PROPderivationLogging</div>
+    </td>
+    <td width="16%">Boolean</td>
+    <td width="62%">
+      <div align="left">If true causes derivation routes to be recorded internally
+        so that future getDerivation calls can return useful information.</div>
+    </td>
+  </tr>
+<p>As we gain experience with the ways in which OWL is used and the capabilities
+  of the rule-based approach we imagine useful subsets of functionality emerging
+  - like that that supported by the RDFS reasoner in the form of the level settings.</p>
+<p>[<a href="#owl">OWL index</a>] [<a href="#index">main index</a>]</p>
+###<a name="OWLexamples"></a>OWL Example
+<p>As an example of using the OWL inference support, consider the sample schema
+  and data file in the data directory - <a href="data/owlDemoSchema.xml">owlDemoSchema.xml</a>
+  and <a href="data/owlDemoData.xml">owlDemoData.xml</a>. </p>
+<p>The schema file shows a simple, artificial ontology concerning computers which
+  defines a GamingComputer as a Computer which includes at least one bundle of
+  type GameBundle and a component with the value gamingGraphics. </p>
+<p>The data file shows information on serveral hypothetical computer configurations
+  including two different descriptions of the configurations &quot;whiteBoxZX&quot;
+  and &quot;<code>bigName42</code>&quot;.</p>
+<p>We can create an instance of the OWL reasoner, specialized to the demo schema
+  and then apply that to the demo data to obtain an inference model, as follows:</p>
+<pre>    Model schema = FileManager.get().loadModel("file:data/owlDemoSchema.owl");
+    Model data = FileManager.get().loadModel("file:data/owlDemoData.rdf");
+    Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
+    reasoner = reasoner.bindSchema(schema);
+    InfModel infmodel = ModelFactory.createInfModel(reasoner, data);</pre>
+<p>A typical example operation on such a model would be to find out all we know
+  about a specific instance, for example the <code>nForce</code> mother board.
+  This can be done using:</p>
+<pre>    Resource nForce = infmodel.getResource("urn:x-hp:eg/nForce");
+    System.out.println("nForce *:");
+    printStatements(infmodel, nForce, null, null);<br></pre>
+<p> where <code>printStatements</code> is defined by: </p>
+<pre>    public void printStatements(Model m, Resource s, Property p, Resource o) {
+        for (StmtIterator i = m.listStatements(s,p,o); i.hasNext(); ) {
+            Statement stmt = i.nextStatement();
+            System.out.println(" - " + PrintUtil.print(stmt));
+        }
+    }</pre>
+<p>This produces the output:</p>
+<pre><i>nForce *:
+ - (eg:nForce rdf:type owl:Thing)
+ - (eg:nForce owl:sameAs eg:unknownMB)
+ - (eg:nForce owl:sameAs eg:nForce)
+ - (eg:nForce rdf:type eg:MotherBoard)
+ - (eg:nForce rdf:type rdfs:Resource)
+ - (eg:nForce rdf:type a3b24:f7822755ad:-7ffd)
+ - (eg:nForce eg:hasGraphics eg:gamingGraphics)
+ - (eg:nForce eg:hasComponent eg:gamingGraphics)</i></pre>
+<p>Note that this includes inferences based on subClass inheritance (being an
+  <code>eg:MotherBoard</code> implies it is an <code>owl:Thing</code> and an <code>rdfs:Resource</code>),
+  property inheritance (<code>eg:hasComponent eg:gameGraphics</code> derives from
+  <code>hasGraphics</code> being a subProperty of <code>hasComponent</code>) and
+  cardinality reasoning (it is the sameAs <code>eg:unknownMB</code> because computers
+  are defined to have only one motherboard and the two diffferent descriptions
+  of <code>whileBoxZX</code> use these two different terms for the mother board).<i>
+  </i>The anonymous rdf:type statement referencesthe <code>&quot;hasValue(eg:hasComponent,
+  eg:gamingGraphics)&quot; </code>restriction mentioned in the definition of GamingComputer.</p>
+<p>A second, typical operation is instance recognition. Testing if an individual
+  is an instance of a class expression. In this case the <code>whileBoxZX</code>
+  is identifiable as a <code>GamingComputer</code> because it is a <code>Computer</code>,
+  is explicitly declared as having an appropriate bundle and can be inferred to
+  have a <code>gamingGraphics</code> component from the combination of the <code>nForce</code>
+  inferences we've already seen and the transitivity of <code>hasComponent</code>.
+  We can test this using:</p>
+<pre>    Resource gamingComputer = infmodel.getResource("urn:x-hp:eg/GamingComputer");
+    Resource whiteBox = infmodel.getResource("urn:x-hp:eg/whiteBoxZX");
+    if (infmodel.contains(whiteBox, RDF.type, gamingComputer)) {
+        System.out.println("White box recognized as gaming computer");
+    } else {
+        System.out.println("Failed to recognize white box correctly");
+    }</pre>
+<p> Which gnerates the output:</p>
+<pre><i>White box recognized as gaming computer</i></pre>
+<p>Finally, we can check for inconsistencies within the data by using the validation
+  interface:</p>
+<pre>    ValidityReport validity = infmodel.validate();
+    if (validity.isValid()) {
+        System.out.println("OK");
+    } else {
+        System.out.println("Conflicts");
+        for (Iterator i = validity.getReports(); i.hasNext(); ) {
+            ValidityReport.Report report = (ValidityReport.Report);
+            System.out.println(" - " + report);
+        }
+    }</pre>
+<p>Which generates the output:</p>
+ - Error (conflict): Two individuals both same and different, may be
+   due to disjoint classes or functional properties
+Culprit = eg:nForce2
+Implicated node: eg:bigNameSpecialMB</i>
+... + 3 other similar reports
+<p>This is due to the two records for the <code>bigName42</code> configuration
+  referencing two motherboards which are explicitly defined to be different resources
+  and thus violate the FunctionProperty nature of <code>hasMotherBoard</code>.</p>
+<p>[<a href="#owl">OWL index</a>] [<a href="#index">main index</a>]</p>
+###<a name="OWLnotes"></a>OWL notes and limitations
+####Comprehension axioms
+<p>A critical implication of our variant of the instance-based approach is that
+  the reasoner does not directly answer queries relating to dynamically introduced
+  class expressions.</p>
+<p>For example, given a model containing the RDF assertions corresponding to the
+  two OWL axioms:</p>
+<pre>class A = intersectionOf (minCardinality(P, 1), maxCardinality(P,1))
+class B = cardinality(P,1)</pre>
+<p>Then the reasoner can demonstrate that classes A and B are equivalent, in particular
+  that any instance of A is an instance of B and vice versa. However, given a
+  model just containing the first set of assertions you cannot directly query
+  the inference model for the individual triples that make up <i>cardinality(P,1)</i>.
+  If the relevant class expressions are not already present in your model then
+  you need to use the list-with-posits mechanism described <a href="#extendedListStatements">above</a>,
+  though be warned that such posits start inference afresh each time and can be
+  expensive. </p>
+<p>Actually, it would be possible to introduce comprehension axioms for simple
+  cases like this example. We have, so far, chosen not to do so. First, since
+  the OWL/full closure is generally infiite, some limitation on comprehension
+  inferences seems to be useful. Secondly, the typical queries that Jena applications
+  expect to be able to issue would suddenly jump in size and cost - causing a
+  support nightmare. For example, queries such as (a, rdf:type, *) would become
+  near-unusable.</p>
+<p>Approximately, 10 of the OWL working group tests for the supported OWL subset
+  currently rely on such comprehension inferences. The shipping version of the
+  Jena rule reasoner passes these tests only after they have been rewritten to
+  avoid the comprehension requirements.<br>
+<p>As noted above the current OWL rule set introduces prototypical instances for
+  each defined class. These prototypical instances used to be visible to queries.
+  From release 2.1 they are used internally but should not longer be visible.
+<p>We noted <a href="#directRelations">above</a> that the Jena reasoners support
+  a separation of direct and indirect relations for transitive properties such
+  as subClassOf. The current implementation of the full and mini OWL reasoner
+  fails to do this and the direct forms of the queries will fail. The OWL Micro
+  reasoner, which is but a small extension of RDFS, does suppor the direct queries.</p>
+<p>This does not affect querying though the Ontology API, which works around this
+  limitation. It only affects direct RDF accesses to the inference model.</p>
+<p>The OWL reasoners use the rule engines for all inference. The full and mini
+  configurations omit some of the performance tricks employed by the RDFS reasoner
+  (notably the use of the custom transitive reasoner) making those OWL reasoner
+  configurations slower than the RDFS reasoner on pure RDFS data (typically around
+  x3-4 slow down). The OWL Micro reasoner is intended to be as close to RDFS performance
+  while also supporting the core OWL constructs as described earlier.</p>
+<p>Once the owl constructs are used then substantial reasoning can be required.
+  The most expensive aspect of the supported constructs is the equality reasoning
+  implied by use of cardinality restrictions and FunctionalProperties. The current
+  rule set implements equality reasoning by identifying all sameAs deductions
+  during the initial forward &quot;prepare&quot; phase. This may require the entire
+  instance dataset to be touched several times searching for occurrences of FunctionalProperties.</p>
+<p>Beyond this the rules implementing the OWL constructs can interact in complex
+  ways leading to serious performance overheads for complex ontologies. Characterising
+  the sorts of ontologies and inference problems that are well tackled by this
+  sort of implementation and those best handled by plugging a Description Logic
+  engine, or a saturation theorem prover, into Jena is a topic for future work.</p>
+<p>One random hint: explicitly importing the owl.owl definitions causes much duplication
+  of rule use and a substantial slow down - the OWL axioms that the reasoner can
+  handle are already built in and don't need to be redeclared.</p>
+<p>The rule based approach cannot offer a complete solution for OWL/Lite, let
+  alone the OWL/Full fragment corresponding to the OWL/Lite constructs. In addition
+  the current implementation is still under development and may well have ommisions
+  and oversights. We intend that the reasoner should be sound (all inferred triples
+  should be valid) but not complete. </p>
+<p>[<a href="#owl">OWL index</a>] [<a href="#index">main index</a>]</p>
+##<a name="daml"></a>DAML support
+<p>This is minimal legacy support. The DAMLMicroReasoner is
+  essentially the RDFS reasoner augmented by axioms declaring the equivalence
+  between the DAML constructs and their RDFS aliases. It is invoked using the
+  prebuilt <a href="../javadoc/com/hp/hpl/jena/ontology/OntModelSpec.html"><code>OntModelSpec</code></a>
+  <code>DAML_MEM_RULE_INF.</code></p>
+<p>There are <u><b>no</b></u> plans to go beyond this and offer more complete
+  DAML inference support.</p>
+<p>[<a href="#index">index</a>]</p>
+##<a name="transitive"></a>The transitive reasoner
+<p>The TransitiveReasoner provides support for storing and traversing class and
+  property lattices. This implements just the <i>transitive</i> and <i>symmetric</i>
+  properties of <code>rdfs:subPropertyOf</code> and <code>rdfs:subClassOf</code>.
+  It is not all that exciting on its own but is one of the building blocks used
+  for the more complex reasoners. It is a hardwired Java implementation that stores
+  the class and property lattices as graph structures. It is slightly higher performance,
+  and somewhat more space efficient, than the alternative of using the pure rule
+  engines to performance transitive closure but its main advantage is that it
+  implements the direct/minimal version of those relations as well as the transitively
+  closed version.</p>
+<p>The <code>GenericRuleReasoner</code> (see below) can optionally use an instance
+  of the transitive reasoner for handling these two properties. This is the approach
+  used in the default RDFS reasoner.</p>
+<p>It has no configuration options.</p>
+<p>[<a href="#index">Index</a>]</p>
+##<a name="rules"></a>The general purpose rule engine
+  <li><a href="#RULEoverview">Overview of the rule engine(s)</a></li>
+  <li><a href="#RULEsyntax">Rule syntax and structure</a></li>
+  <li><a href="#RULEforward">Forward chaining engine</a></li>
+  <li><a href="#RULEbackward">Backward chaining engine</a></li>
+  <li><a href="#RULEhybrid">Hybrid engine</a></li>
+  <li><a href="#RULEconfiguration">GenericRuleReasoner configuration</a></li>
+  <li><a href="#RULEbuiltins">Builtin primitives</a></li>
+  <li><a href="#RULEexamples">Example</a></li>
+  <li><a href="#RDFSPlusRules">Combining RDFS/OWL with custom rules</a></li>
+  <li><a href="#RULEnotes">Notes</a></li>
+  <li><a href="#RULEextensions">Extensions</a></li>
+###<a name="RULEoverview"></a>Overview of the rule engine(s)
+<p>Jena includes a general purpose rule-based reasoner which is used to implement
+  both the RDFS and OWL reasoners but is also available for general use. This
+  reasoner supports rule-based inference over RDF graphs and provides forward
+  chaining, backward chaining and a hybrid execution model. To be more exact,
+  there are two internal rule engines one forward chaining RETE engine and one
+  tabled datalog engine - they can be run separately or the forward engine can
+  be used to prime the backward engine which in turn will be used to answer queries.</p>
+<p>The various engine configurations are all accessible through a single parameterized
+  reasoner <code><a href="../javadoc/com/hp/hpl/jena/reasoner/rulesys/GenericRuleReasoner.html">GenericRuleReasoner</a></code>.
+  At a minimum a <code>GenericRuleReasoner</code> requires a ruleset to define
+  its behaviour. A <code>GenericRuleReasoner</code> instance with a ruleset can
+  be used like any of the other reasoners described above - that is it can be
+  bound to a data model and used to answer queries to the resulting inference
+  model. </p>
+<p>The rule reasoner can also be extended by registering new procedural primitives.
+  The current release includes a starting set of primitives which are sufficient
+  for the RDFS and OWL implementations but is easily extensible.</p>
+<p>[<a href="#rules">rule index</a>] [<a href="#index">main index</a>]</p>
+### <a name="RULEsyntax"></a>Rule syntax and structure
+<p>A rule for the rule-based reasoner is defined by a Java <code><a href="../javadoc/com/hp/hpl/jena/reasoner/rulesys/Rule.html">Rule</a></code>
+  object with a list of body terms (premises), a list of head terms (conclusions)
+  and an optional name and optional direction. Each term or <a href="../javadoc/com/hp/hpl/jena/reasoner/rulesys/ClauseEntry.html"><code>ClauseEntry</code></a>
+  is either a triple pattern, an extended triple pattern or a call to a builtin
+  primitive. A rule set is simply a List of Rules.</p>
+<p>For convenience a rather simple parser is included with Rule which allows rules
+  to be specified in reasonably compact form in text source files. However, it
+  would be perfectly possible to define alternative parsers which handle rules
+  encoded using, say, XML or RDF and generate Rule objects as output. It would
+  also be possible to build a real parser for the current text file syntax which
+  offered better error recovery and diagnostics.</p>
+<p>An informal description of the simplified text rule syntax is:</p>
+<pre><i>Rule</i>      :=   <i>bare-rule</i> .
+          or   [ <i>bare-rule</i> ]<br>       or   [ ruleName : <i>bare-rule</i> ]
+<i>bare-rule</i> :=   <i>term</i>, ... <i>term</i> -&gt; <i>hterm</i>, ... <i>hterm</i>    // forward rule
+          or   <i>bhterm</i> &lt;- <i>term</i>, ... <i>term   </i> // backward rule<i>
+hterm     :=   term
+          </i>or   [<i> bare-rule </i>]<i>
+term</i>      :=   (<i>node</i>, <i>node</i>, <i>node</i>)           // triple pattern
+          or   (<i>node</i>, <i>node</i>, <i>functor</i>)        // extended triple pattern
+          or   builtin(<i>node</i>, ... <i>node</i>)      // invoke procedural primitive
+<i>bhterm</i>      :=   (<i>node</i>, <i>node</i>, <i>node</i>)           // triple pattern
+<i>functor</i>   :=   functorName(<i>node</i>, ... <i>node</i>)  // structured literal
+<i>node</i>      :=   <i>uri-ref</i>                   // e.g.
+          or   prefix:localname          // e.g. rdf:type
+          or   &lt;<i>uri-ref</i>&gt;          // e.g. &lt;myscheme:myuri&gt;
+          or   ?<i>varname                    </i>// variable
+          or   'a literal'                 // a plain string literal
+          or   'lex'^^typeURI              // a typed literal, xsd:* type names supported
+          or   number                      // e.g. 42 or 25.5</pre>
+<p>The &quot;,&quot; separators are optional.</p>
+<p>The difference between the forward and backward rule syntax is only relevant
+  for the hybrid execution strategy, see below.</p>
+<p>The <i>functor</i> in an extended triple pattern is used to create and access
+  structured literal values. The functorName can be any simple identifier and
+  is not related to the execution of builtin procedural primitives, it is just
+  a datastructure. It is useful when a single semantic structure is defined across
+  multiple triples and allows a rule to collect those triples together in one
+  place.</p>
+<p>To keep rules readable qname syntax is supported for URI refs. The set of known
+  prefixes is those registered with the <code><a href="../javadoc/com/hp/hpl/jena/util/PrintUtil.html">PrintUtil</a></code>
+  object. This initially knows about rdf, rdfs, owl, daml, xsd and a test namespace
+  eg, but more mappings can be registered in java code. In addition it is possible to
+  define additional prefix mappings in the rule file, see below. </p>
+<p>Here are some example rules which illustrate most of these constructs:</p>
+<pre>[allID: (?C rdf:type owl:Restriction), (?C owl:onProperty ?P),
+     (?C owl:allValuesFrom ?D)  -&gt; (?C owl:equivalentClass all(?P, ?D)) ]
+[all2: (?C rdfs:subClassOf all(?P, ?D)) -&gt; print('Rule for ', ?C)
+    [all1b: (?Y rdf:type ?D) &lt;- (?X ?P ?Y), (?X rdf:type ?C) ] ]
+[max1: (?A rdf:type max(?P, 1)), (?A ?P ?B), (?A ?P ?C)
+      -&gt; (?B owl:sameAs ?C) ]
+<p>Rule <code>allID</code> illustrates the functor use for collecting the components
+  of an OWL restriction into a single datastructure which can then fire further
+  rules. Rule <code>all2</code> illustrates a forward rule which creates a new
+  backward rule and also calls the <code>print</code> procedural primitive. Rule
+  <code>max1</code> illustrates use of numeric literals.<br>
+Rule files may be loaded and parsed using:
+List rules = Rule.rulesFromURL("file:myfile.rules");
+BufferedReader br = /* open reader */ ;
+List rules = Rule.parseRules( Rule.rulesParserFromReader(br) );
+String ruleSrc = /* list of rules in line */
+List rules = Rule.parseRules( rulesSrc );
+In the first two cases (reading from a URL or a BufferedReader) the rule file is
+preprocessed by a simple processor which strips comments and supports some additional
+macro commands:
+<dt><code># ...</code></dt>
+<dd>A comment line.</dd>
+<dt><code>// ...</code></dt>
+<dd>A comment line.<br /><br /></dd>
+<dt><code>@prefix pre: &lt;http://domain/url#&gt;.</code></dt>
+<dd>Defines a prefix <code>pre</code> which can be used in the rules.
+The prefix is local to the rule file.<br /><br /></dd>
+<dt><code>@include &lt;urlToRuleFile&gt;.</code></dt>
+<dd>Includes the rules defined in the given file in this file. The included rules
+will appear before the user defined rules, irrespective of where in the file
+the @include directive appears. A set of special cases is supported to allow
+a rule file to include the predefined rules for RDFS and OWL - in place of a real
+URL for a rule file use one of the keywords
+<code>OWLMini</code> (case insensitive).
+So an example complete rule file which includes the RDFS rules and defines
+a single extra rule is:
+    # Example rule file
+    @prefix pre: &lt;;.
+    @include &lt;RDFS&gt;.
+    [rule1: (?f pre:father ?a) (?u pre:brother ?f) -&gt; (?u pre:uncle ?a)]
+<p>[<a href="#rules">Rule index</a>] [<a href="#index">main index</a>]</p>
+### <a name="RULEforward"></a>Forward chaining engine
+<p>If the rule reasoner is configured to run in forward mode then only the forward
+  chaining engine will be used. The first time the inference Model is queried
+  (or when an explicit <code>prepare()</code> call is made, see <a href="#processingControl">above</a>)
+  then all of the relevant data in the model will be submitted to the rule engine.
+  Any rules which fire that create additional triples do so in an internal <i>deductions</i>
+  graph and can in turn trigger additional rules. There is a <i>remove</i> primitive
+  that can be used to remove triples and such removals can also trigger rules
+  to fire in removal mode. This cascade of rule firings continues until no more
+  rules can fire. It is perfectly possible, though not a good idea, to write rules
+  that will loop infinitely at this point.</p>
+<p>Once the preparation phase is complete the inference graph will act as if it
+  were the union of all the statements in the original model together with all
+  the statements in the internal deductions graph generated by the rule firings.
+  All queries will see all of these statements and will be of similar speed to
+  normal model accesses. It is possible to separately access the original raw
+  data and the set of deduced statements if required, see <a href="#rawAccess">above</a>.</p>
+<p>If the inference model is changed by adding or removing statements through
+  the normal API then this will trigger further rule firings. The forward rules
+  work incrementally and only the consequences of the added or removed triples
+  will be explored. The default rule engine is based on the standard RETE algorithm
+  (C.L Forgy, <i>RETE: A fast algorithm for the many pattern/many object pattern
+  match problem, </i>Artificial Intelligence 1982) which is optimized for such
+  incremental changes. </p>
+<p>When run in forward mode all rules are treated as forward even if they were
+  written in backward (&quot;&lt;-&quot;) syntax. This allows the same rule set
+  to be used in different modes to explore the performance tradeoffs.</p>
+<p>There is no guarantee of the order in which matching rules will fire or the
+  order in which body terms will be tested, however once a rule fires its head-terms
+  will be executed in left-to-right sequence.</p>
+<p>In forward mode then head-terms which assert backward rules (such as <code>all1b</code>
+  above) are ignored.</p>
+<p>There are in fact two forward engines included within the Jena code base,
+  an earlier non-RETE implementation is retained for now because it can be more
+  efficient in some circumstances but has identical external semantics. This alternative
+  engine is likely to be eliminated in a future release once more tuning has been
+  done to the default RETE engine.</p>
+<p>[<a href="#rules">Rule index</a>] [<a href="#index">main index</a>]</p>
+###<a name="RULEbackward"></a>Backward chaining engine
+<p>If the rule reasoner is run in backward chaining mode it uses a logic programming
+  (LP) engine with a similar execution strategy to Prolog engines. When the inference
+  Model is queried then the query is translated into a goal and the engine attempts
+  to satisfy that goal by matching to any stored triples and by goal resolution
+  against the backward chaining rules.</p>
+<p>Except as noted below rules will be executed in top-to-bottom, left-to-right
+  order with backtracking, as in SLD resolution. In fact, the rule language is
+  essentially datalog rather than full prolog, whilst the functor syntax within
+  rules does allow some creation of nested data structures they are flat (not
+  recursive) and so can be regarded a syntactic sugar for datalog.</p>
+<p>As a datalog language the rule syntax is a little surprising because it restricts
+  all properties to be binary (as in RDF) and allows variables in any position
+  including the property position. In effect, rules of the form:</p>
+<pre>(s, p, o), (s1, p1, o1) ... &lt;- (sb1, pb1, ob1), .... </pre>
+<p>Can be thought of as being translated to datalog rules of the form:</p>
+<pre>triple(s, p, o)    :- triple(sb1, pb1, ob1), ...
+triple(s1, p1, o1) :- triple(sb1, pb1, ob1), ...
+<p>where &quot;triple/3&quot; is a hidden implicit predicate. Internally, this
+  transformation is not actually used, instead the rules are implemented directly.</p>
+<p>In addition, all the data in the raw model supplied to the engine is treated
+  as if it were a set of <code>triple(s,p,o)</code> facts which are prepended to
+  the front of the rule set. Again, the implementation does not actually work
+  that way but consults the source graph, with all its storage and indexing capabilities,
+  directly.</p>
+<p>Because the order of triples in a Model is not defined then this is one violation
+  to strict top-to-bottom execution. Essentially all ground facts are consulted
+  before all rule clauses but the ordering of ground facts is arbitrary.</p>
+<p>The LP engine supports tabling. When a goal is tabled then all previously computed
+  matches to that goal are recorded (memoized) and used when satisfying future
+  similar goals. When such a tabled goal is called and all known answers have
+  been consumed then the goal will suspend until some other execution branch has
+  generated new results and then be resumed. This allows one to successfully run
+  recursive rules such as transitive closure which would be infinite loops in
+  normal SLD prolog. This execution strategy, SLG, is essentially the same as
+  that used in the well known <a href="">XSB</a> system.</p>
+<p>In the Jena rule engine the goals to be tabled are identified by the property
+  field of the triple. One can request that all goals be tabled by calling the
+  <code>tableAll()</code> primitive or that all goals involving a given property
+  <code>P</code> be tabled by calling <code>table(P)</code>. Note that if any
+  property is tabled then goals such as <code>(A, ?P, ?X)</code> will all be tabled
+  because the property variable might match one of the tabled properties.</p>
+<p>Thus the rule set:</p>
+-&gt; table(rdfs:subClassOf).
+[r1: (?A rdfs:subClassOf ?C) &lt;- (?A rdfs:subClassOf ?B) (?B rdfs:subClassOf ?C)]</pre>
+<p>will successfully compute the transitive closure of the subClassOf relation.
+  Any query of the form (*, rdfs:subClassOf, *) will be satisfied by a mixture
+  of ground facts and resolution of rule r1. Without the first line this rule
+  would be an infinite loop. </p>
+<p>The tabled results of each query are kept indefinitely. This means that queries
+  can exploit all of the results of the subgoals involved in previous queries.
+  In essence we build up a closure of the data set in response to successive queries.
+  The <code>reset()</code> operation on the inference model will force these tabled
+  results to be discarded, thus saving memory and the expense of response time
+  for future queries.</p>
+<p>When the inference Model is updated by adding or removing statements all tabled
+  results are discarded by an internal <code>reset()</code> and the next query
+  will rebuild the tabled results from scratch. <br>
+<p>Note that backward rules can only have one consequent so that if writing rules that
+might be run in either backward or forward mode then they should be limited to a single consequent each.
+<p>[<a href="#rules">Rule index</a>] [<a href="#index">main index</a>]</p>
+###<a name="RULEhybrid"></a>Hybrid rule engine
+<p>The rule reasoner has the option of employing both of the individual rule engines
+  in conjunction. When run in this <i>hybrid</i> mode the data flows look something
+  like this: </p>
+<p align="center"><img src="../images/jena-inf-figure2.png"></p>
+<p align="left">The forward engine runs, as described above, and maintains a set
+  of inferred statements in the <i>deductions</i> store. Any forward rules which
+  assert new backward rules will instantiate those rules according to the forward
+  variable bindings and pass the instantiated rules on to the backward engine.</p>
+<p align="left">Queries are answered by using the backward chaining LP engine,
+  employing the merge of the supplied and generated rules applied to the merge
+  of the raw and deduced data.</p>
+<p align="left">This split allows the ruleset developer to achieve greater performance
+  by only including backward rules which are relevant to the dataset at hand.
+  In particular, we can use the forward rules to compile a set of backward rules
+  from the ontology information in the dataset. As a simple example consider trying
+  to implement the RDFS subPropertyOf entailments using a rule engine. A simple
+  approach would involve rules like:</p>
+<pre> (?a ?q ?b) &lt;- (?p rdfs:subPropertyOf ?q), (?a ?p ?b) .
+<p align="left">Such a rule would work but every goal would match the head of
+  this rule and so every query would invoke a dynamic test for whether there was
+  a subProperty of the property being queried for. Instead the hybrid rule:</p>
+<pre>(?p rdfs:subPropertyOf ?q), notEqual(?p,?q) -&gt; [ (?a ?q ?b) &lt;- (?a ?p ?b) ] .</pre>
+<p align="left">would precompile all the declared subPropertyOf relationships
+  into simple chain rules which would only fire if the query goal references a
+  property which actually has a sub property. If there are no subPropertyOf relationships
+  then there will be no overhead at query time for such a rule.</p>
+<p align="left">Note that there are no loops in the above data flows. The backward
+  rules are not employed when searching for matches to forward rule terms. This
+  two-phase execution is simple to understand and keeps the semantics of the rule
+  engines straightforward. However, it does mean that care needs to be take when
+  formulating rules. If in the above example there were ways that the subPropertyOf
+  relation could be derived from some other relations then that derivation would
+  have to be accessible to the forward rules for the above to be complete.</p>
+<p align="left">Updates to an inference Model working in hybrid mode will discard
+  all the tabled LP results, as they do in the pure backward case. However, the
+  forward rules still work incrementally, including incrementally asserting or
+  removing backward rules in response to the data changes.</p>
+<p>[<a href="#rules">Rule index</a>] [<a href="#index">main index</a>]</p>
+###<a name="RULEconfiguration"></a>GenericRuleReasoner configuration
+<p>As with the other reasoners there are a set of parameters, identified by RDF
+  properties, to control behaviour of the <code>GenericRuleReasoner</code>. These
+  parameters can be set using the <code>Reasoner.setParameter</code> call or passed
+  into the Reasoner factory in an RDF Model.</p>
+<p>The primary parameter required to instantiate a useful <code>GenericRuleReasoner</code>
+  is a rule set which can be passed into the constructor, for example:</p>
+<pre>String ruleSrc = "[rule1: (?a eg:p ?b) (?b eg:p ?c) -&gt; (?a eg:p ?c)]";
+List rules = Rule.parseRules(ruleSrc);
+Reasoner reasoner = new GenericRuleReasoner(rules);</pre>
+<p>A short cut, useful when the rules are defined in local text files using the
+  syntax described earlier, is the <code>ruleSet</code> parameter which gives
+  a file name which should be loadable from either the classpath or relative to
+  the current working directory.<br>
+####Summary of parameters
+<table width="90%" border="1" cellspacing="0" cellpadding="0">
+  <tr>
+    <td width="26%"><b>Parameter</b></td>
+    <td width="23%"><b>Values</b></td>
+    <td width="51%"><b>Description</b></td>
+  </tr>
+  <tr>
+    <td width="26%">
+      <div align="left">PROPruleMode</div>
+    </td>
+    <td width="23%">&quot;forward&quot;, &quot;forwardRETE&quot;, &quot;backward&quot;,
+      &quot;hybrid&quot; </td>
+    <td width="51%">
+      <div align="left">Sets the rule direction mode as discussed above. Default
+        is &quot;hybrid&quot;.</div>
+    </td>
+  </tr>
+  <tr>
+    <td width="26%">
+      <div align="left">PROPruleSet</div>
+    </td>
+    <td width="23%">filename-string</td>
+    <td width="51%">
+      <div align="left">The name of a rule text file which can be found on the
+        classpath or from the current directory. </div>
+    </td>
+  </tr>
+  <tr>
+    <td width="26%">
+      <div align="left">PROPenableTGCCaching</div>
+    </td>
+    <td width="23%">Boolean</td>
+    <td width="51%">
+      <div align="left">If true, causes an instance of the TransitiveReasoner
+        to be inserted in the forward dataflow to cache the transitive closure
+        of the subProperty and subClass lattices.</div>
+    </td>
+  </tr>
+  <tr>
+    <td width="26%">
+      <div align="left">PROPenableFunctorFiltering</div>
+    </td>
+    <td width="23%">Boolean</td>
+    <td width="51%">
+      <div align="left">If set to true, this causes the structured literals (functors)
+        generated by rules to be filtered out of any final queries. This allows
+        them to be used for storing intermediate results hidden from the view
+        of the InfModel's clients.</div>
+    </td>
+  </tr>
+  <tr>
+    <td width="26%">
+      <div align="left">PROPenableOWLTranslation</div>
+    </td>
+    <td width="23%">Boolean</td>
+    <td width="51%">

[... 505 lines stripped ...]

View raw message