Introduction
AllegroGraph has two different inference engines: one supports a superset of RDFS inference rules and the other supports OWL 2 RL. The first is called the dynamic RDFS++ reasoner because it generates inferred triples on-the-fly and does not save them in the triple-store. The second is an OWL 2 RL materializer: it uses a set of inference rules to generate new triples and adds them to the triple-store.
If the triple store is changed via additions or deletions then materialization may have to be run again so that the triple store contains the correct set of materialized triples.
The dynamic reasoner is best when:
- you do not need OWL 2 RL inference rules and
- the store you are using is changing.
The materializer is best when:
- OWL 2 RL inference is required or
- the store is relatively static.
OWL 2 RL is the subset of OWL 2 that is designed to support rule based reasoners. OWL 2 RL contains a large number of rules for generating triples and some rules for verifying that the triple store is consistent with respect to the OWL 2 RL ontology.
The materializer implements a subset of the OWL 2 RL rules and we plan to add more rules in future versions. The complete rule set is described on the OWL 2 RL reference page.
APIs
There is an AGWebView interface (see WebView, particularly the Repository Overview Page section), a Java interface (see AGMaterializer#newInstance()
and AGRepositoryConnection#materialize
), a Python interface, as well as the Lisp interface described below. There is also a command-line interface described next.
Command Line Interface
The program agmaterialize is the command-line version of the materializer. agmaterialize must be run on the same machine where the AllegroGraph server is running. Here is an overview of its options:
Usage:
agmaterialize [OPTIONS] DBNAME
The options are identified with a double dash when the full option name is used (--verbose
) and a single dash when a single letter abbreviation is used (-v
).
Materialization options:
- --delete
- Delete existing materialized triples and exit. No materialization is performed.
- --display-ontology
- Read and display the store's ontology and exit. No materialization is performed.
- -g GRAPH, --inferred-graph GRAPH
- The graph into which inferred triples will be placed
- --rule NAME
- Specify materialization rule; can be used multiple times. Rules are: all, class, property, restriction, same-as, values-from.
- --bulk
- If specified, then materialization will be run in bulk mode. This mode provides approximately 30% faster materialization. Note that bulk mode is global to the store and means that transactions will not be durable (in particular, will not be logged). Therefore, the switch should generally be used only when the store is not being used for other operations and the store should be backed up when the materialization is complete.
Other options:
-v, --verbose : Include more output (this option may be repeated, the more times it appears, the more output will be provided).
Triple-store options:
- -c CATALOG, --catalog CATALOG
- CATALOG name on server; use "" for the root catalog. The default is the root catalog.
- -p PORT, --port PORT
- Server port (default 10035, which is the usual port default).
Example:
The database is lubm-50. The --catalog
, --rule
, and --verbose
options are specified (--verbose
twice which means more information will be provided than if --verbose
was just specified once):
./agmaterialize -c stores --rule all --verbose -verbose lubm-50
Lisp API
materialize-entailed-triples
The main function is
Materialize inferred triples based on a rule set.
where
db: specifies the triple store to materialize (defaults to
*db*
)commit: should be
nil
or a number. Ifnil
then the materializer will never commit (which is not a good idea if the database is large and there are many materialized triples). If commit is a number then after this many triples are added to the triple store a commit will be done, and a commit will be done when the materializer is finished.materialized-graph: the graph into which inferred triples will be added.
print-ontology: will print the classes and properties found in the triple store.
use-type-subproperty: change the implied predicate for subproperty reasoning
verbose: Either true or a number. If true, then all materializer logging is sent to the log. Using a number can limit the amount of logging information generated with higher numbers indicating more logging. A level of 4 tends to present a reasonable amount of detail without being too overwhelming.
with: either "all" or a list of the sets of rules to run (details below).
without: a list of sets of rules to not run.
The symbolic names for the rulesets (which are written as string) are as follows. These are described in detail in the materializer documentation.
- "all"
- "same-as"
- "restriction"
- "values-from"
- "class"
- "property"
Note that "values-from" is a special subset of "restriction" rules. If "restriction" is specified then you can also specify "values-from" to enable that set of restriction rules
Examples
Examples of how to specify rulesets
(materialize-entailed-triples)
will add the RDFS++ entailed triples.
(materialize-entailed-triples :with "all")
will run all rules. Note that the result of this call may differ between versions of the materializer.
(materialize-entailed-triples :with '("same-as" "restriction"))
run the RDFS++ reasoning as well as "same-as" and "restriction".
(materialize-entailed-triples :with '("values-from"))
this is just basic RDFS++ reasoning as "restriction" was not specified as well so "values-from" is ignored.
(materialize-entailed-triples :without '("property" "values-from"))
run all rules except "property" and the "values-from" part of "restriction" reasoning.
The use-type-subproperty
argument changes the triple which is generated in the following way:
Given:
classA rdfs:subClassOf classB
mytype rdfs:subPropertyOf rdf:type
objX mytype classA
then:
we would normally generate this triple::
objX rdf:type classB
but if use-type-subproperty
is true then we will instead generate this triple:
objX mytype classB
delete-materialized-triples
The second function in the API is:
Remove any previously materialized triples.
db: specifies the triple store to materialize (defaults to
*db*
)commit: If true, then the a commit-triple-store will run after inferred triples are deleted.
- materialized-graph: the graph from which inferred triples will be removed.
Note: materialize-entailed-triples will call delete-materialized-triples before starting to add triples.
Rule Sets
The table below is from the OWL 2 RL definition. We’ve added a second column where we describe how this rule is treated by the materializer.
Rules which are not implemented are numbered 1, 2, or 3 or have no number at all. The numbers indicate why they aren’t done. The rules with no number have not been considered yet for inclusion in the materializer and may appear in a future version.
Rules numbered 10 or 11 have been included in the materializer. Rules numbered 10 are part of the basic RDFS++ materializer and always run. Rules numbered 11 are implemented by another part of the materializer where they are run as independent rules. If the number 11 is followed by one or more ruleset names then those rulesets must be enabled for these rules to run.
notes | If | then | ||
---|---|---|---|---|
eq-ref | 1 | T(?s, ?p, ?o) | T(?s, owl:sameAs, ?s) T(?p, owl:sameAs, ?p) T(?o, owl:sameAs, ?o) | |
eq-sym | 11 same-as | T(?x, owl:sameAs, ?y) | T(?y, owl:sameAs, ?x) | |
eq-trans | 11 same-as | T(?x, owl:sameAs, ?y) T(?y, owl:sameAs, ?z) | T(?x, owl:sameAs, ?z) | |
eq-rep-s | 11 same-as | T(?s, owl:sameAs, ?s') T(?s, ?p, ?o) | T(?s', ?p, ?o) | |
eq-rep-p | 11 same-as | T(?p, owl:sameAs, ?p') T(?s, ?p, ?o) | T(?s, ?p', ?o) | |
eq-rep-o | 11 same-as | T(?o, owl:sameAs, ?o') T(?s, ?p, ?o) | T(?s, ?p, ?o') | |
eq-diff1 | 2 | T(?x, owl:sameAs, ?y) T(?x, owl:differentFrom, ?y) | inconsistent | |
eq-diff2 | 2 | T(?x, rdf:type, owl:AllDifferent) T(?x, owl:members, ?y) LIST[?y, ?z1, ..., ?zn] T(?zi, owl:sameAs, ?zj) | inconsistent | for each 1 ≤ i < j ≤ n |
eq-diff3 | 2 | T(?x, rdf:type, owl:AllDifferent) T(?x, owl:distinctMembers, ?y) LIST[?y, ?z1, ..., ?zn] T(?zi, owl:sameAs, ?zj) | inconsistent | for each 1 ≤ i < j ≤ n |
prp-ap | T(ap, rdf:type, owl:AnnotationProperty) | for each built-in annotation property of OWL 2 RL | ||
prp-dom | 10 | T(?p, rdfs:domain, ?c) T(?x, ?p, ?y) | T(?x, rdf:type, ?c) | |
prp-rng | 10 | T(?p, rdfs:range, ?c) T(?x, ?p, ?y) | T(?y, rdf:type, ?c) | |
prp-fp | 10 | T(?p, rdf:type, owl:FunctionalProperty) T(?x, ?p, ?y1) T(?x, ?p, ?y2) | T(?y1, owl:sameAs, ?y2) | |
prp-ifp | 10 | T(?p, rdf:type, owl:InverseFunctionalProperty) T(?x1, ?p, ?y) T(?x2, ?p, ?y) | T(?x1, owl:sameAs, ?x2) | |
prp-irp | 2 | T(?p, rdf:type, owl:IrreflexiveProperty) T(?x, ?p, ?x) | inconsistent | |
prp-symp | T(?p, rdf:type, owl:SymmetricProperty) T(?x, ?p, ?y) | T(?y, ?p, ?x) | ||
prp-asyp | 2 | T(?p, rdf:type, owl:AsymmetricProperty) T(?x, ?p, ?y) T(?y, ?p, ?x) | inconsistent | |
prp-trp | 11 | T(?p, rdf:type, owl:TransitiveProperty) T(?x, ?p, ?y) T(?y, ?p, ?z) | T(?x, ?p, ?z) | |
prp-spo1 | 10 | T(?p1, rdfs:subPropertyOf, ?p2) T(?x, ?p1, ?y) | T(?x, ?p2, ?y) | |
prp-spo2 | T(?p, owl:propertyChainAxiom, ?x) LIST[?x, ?p1, ..., ?pn] T(?u1, ?p1, ?u2) T(?u2, ?p2, ?u3) ... T(?un, ?pn, ?un+1) | T(?u1, ?p, ?un+1) | ||
prp-eqp1 | 10 | T(?p1, owl:equivalentProperty, ?p2) T(?x, ?p1, ?y) | T(?x, ?p2, ?y) | |
prp-eqp2 | 10 | T(?p1, owl:equivalentProperty, ?p2) T(?x, ?p2, ?y) | T(?x, ?p1, ?y) | |
prp-pdw | 2 | T(?p1, owl:propertyDisjointWith, ?p2) T(?x, ?p1, ?y) T(?x, ?p2, ?y) | inconsistent | |
prp-adp | 2 | T(?x, rdf:type, owl:AllDisjointProperties) T(?x, owl:members, ?y) LIST[?y, ?p1, ..., ?pn] T(?u, ?pi, ?v) T(?u, ?pj, ?v) | inconsistent | for each 1 ≤ i < j ≤ n |
prp-inv1 | 10 | T(?p1, owl:inverseOf, ?p2) T(?x, ?p1, ?y) | T(?y, ?p2, ?x) | |
prp-inv2 | 10 | T(?p1, owl:inverseOf, ?p2) T(?x, ?p2, ?y) | T(?y, ?p1, ?x) | |
prp-key | T(?c, owl:hasKey, ?u) LIST[?u, ?p1, ..., ?pn] T(?x, rdf:type, ?c) T(?x, ?p1, ?z1) ... T(?x, ?pn, ?zn) T(?y, rdf:type, ?c) T(?y, ?p1, ?z1) ... T(?y, ?pn, ?zn) | T(?x, owl:sameAs, ?y) | ||
prp-npa1 | 2 | T(?x, owl:sourceIndividual, ?i1) T(?x, owl:assertionProperty, ?p) T(?x, owl:targetIndividual, ?i2) T(?i1, ?p, ?i2) | inconsistent | |
prp-npa2 | 2 | T(?x, owl:sourceIndividual, ?i) T(?x, owl:assertionProperty, ?p) T(?x, owl:targetValue, ?lt) T(?i, ?p, ?lt) | inconsistent | |
cls-thing | 10 | T(owl:Thing, rdf:type, owl:Class) | ||
cls-nothing1 | 10 | T(owl:Nothing, rdf:type, owl:Class) | ||
cls-nothing2 | 2 | T(?x, rdf:type, owl:Nothing) | inconsistent | |
cls-int1 | 11 class | T(?c, owl:intersectionOf, ?x) LIST[?x, ?c1, ..., ?cn] T(?y, rdf:type, ?c1) T(?y, rdf:type, ?c2) ... T(?y, rdf:type, ?cn) | T(?y, rdf:type, ?c) | |
cls-int2 | 11 class | T(?c, owl:intersectionOf, ?x) LIST[?x, ?c1, ..., ?cn] T(?y, rdf:type, ?c) | T(?y, rdf:type, ?c1) T(?y, rdf:type, ?c2) ... T(?y, rdf:type, ?cn) | |
cls-uni | 11 class | T(?c, owl:unionOf, ?x) LIST[?x, ?c1, ..., ?cn] T(?y, rdf:type, ?ci) | T(?y, rdf:type, ?c) | for each 1 ≤ i ≤ n |
cls-com | 2 | T(?c1, owl:complementOf, ?c2) T(?x, rdf:type, ?c1) T(?x, rdf:type, ?c2) | inconsistent | |
cls-svf1 | 11 restriction & values-from | T(?x, owl:someValuesFrom, ?y) T(?x, owl:onProperty, ?p) T(?u, ?p, ?v) T(?v, rdf:type, ?y) | T(?u, rdf:type, ?x) | |
cls-svf2 | 11 restriction & values-from | T(?x, owl:someValuesFrom, owl:Thing) T(?x, owl:onProperty, ?p) T(?u, ?p, ?v) | T(?u, rdf:type, ?x) | |
cls-avf | 11 restriction & values-from | T(?x, owl:allValuesFrom, ?y) T(?x, owl:onProperty, ?p) T(?u, rdf:type, ?x) T(?u, ?p, ?v) | T(?v, rdf:type, ?y) | |
cls-hv1 | 11 restriction & values-from | T(?x, owl:hasValue, ?y) T(?x, owl:onProperty, ?p) T(?u, rdf:type, ?x) | T(?u, ?p, ?y) | |
cls-hv2 | 11 restriction & values-from | T(?x, owl:hasValue, ?y) T(?x, owl:onProperty, ?p) T(?u, ?p, ?y) | T(?u, rdf:type, ?x) | |
cls-maxc1 | 2 | T(?x, owl:maxCardinality, "0"^^xsd:nonNegativeInteger) T(?x, owl:onProperty, ?p) T(?u, rdf:type, ?x) T(?u, ?p, ?y) | inconsistent | |
cls-maxc2 | 11 restriction | T(?x, owl:maxCardinality, "1"^^xsd:nonNegativeInteger) T(?x, owl:onProperty, ?p) T(?u, rdf:type, ?x) T(?u, ?p, ?y1) T(?u, ?p, ?y2) | T(?y1, owl:sameAs, ?y2) | |
cls-maxqc1 | 2 | T(?x, owl:maxQualifiedCardinality, "0"^^xsd:nonNegativeInteger) T(?x, owl:onProperty, ?p) T(?x, owl:onClass, ?c) T(?u, rdf:type, ?x) T(?u, ?p, ?y) T(?y, rdf:type, ?c) | inconsistent | |
cls-maxqc2 | 2 | T(?x, owl:maxQualifiedCardinality, "0"^^xsd:nonNegativeInteger) T(?x, owl:onProperty, ?p) T(?x, owl:onClass, owl:Thing) T(?u, rdf:type, ?x) T(?u, ?p, ?y) | inconsistent | |
cls-maxqc3 | 11 restriction | T(?x, owl:maxQualifiedCardinality, "1"^^xsd:nonNegativeInteger) T(?x, owl:onProperty, ?p) T(?x, owl:onClass, ?c) T(?u, rdf:type, ?x) T(?u, ?p, ?y1) T(?y1, rdf:type, ?c) T(?u, ?p, ?y2) T(?y2, rdf:type, ?c) | T(?y1, owl:sameAs, ?y2) | |
cls-maxqc4 | 11 restriction | T(?x, owl:maxQualifiedCardinality, "1"^^xsd:nonNegativeInteger) T(?x, owl:onProperty, ?p) T(?x, owl:onClass, owl:Thing) T(?u, rdf:type, ?x) T(?u, ?p, ?y1) T(?u, ?p, ?y2) | T(?y1, owl:sameAs, ?y2) | |
cls-oo | T(?c, owl:oneOf, ?x) LIST[?x, ?y1, ..., ?yn] | T(?y1, rdf:type, ?c) ... T(?yn, rdf:type, ?c) | ||
cax-sco | 10 | T(?c1, rdfs:subClassOf, ?c2) T(?x, rdf:type, ?c1) | T(?x, rdf:type, ?c2) | |
cax-eqc1 | 11 class | T(?c1, owl:equivalentClass, ?c2) T(?x, rdf:type, ?c1) | T(?x, rdf:type, ?c2) | |
cax-eqc2 | 11 class | T(?c1, owl:equivalentClass, ?c2) T(?x, rdf:type, ?c2) | T(?x, rdf:type, ?c1) | |
cax-dw | 2 | T(?c1, owl:disjointWith, ?c2) T(?x, rdf:type, ?c1) T(?x, rdf:type, ?c2) | inconsistent | |
cax-adc | 2 | T(?x, rdf:type, owl:AllDisjointClasses) T(?x, owl:members, ?y) LIST[?y, ?c1, ..., ?cn] T(?z, rdf:type, ?ci) T(?z, rdf:type, ?cj) | inconsistent | for each 1 ≤ i < j ≤ n |
dt-type1 | T(dt, rdf:type, rdfs:Datatype) | for each datatype dt supported in OWL 2 RL | ||
dt-type2 | 3 | T(lt, rdf:type, dt) | for each literal lt and each datatype dt supported in OWL 2 RL such that the data value of lt is contained in the value space of dt | |
dt-eq | 3 | T(lt1, owl:sameAs, lt2) | for all literals lt1 and lt2 with the same data value | |
dt-diff | 3 | T(lt1, owl:differentFrom, lt2) | for all literals lt1 and lt2 with different data values | |
dt-not-type | 3 | T(lt, rdf:type, dt) | inconsistent | for each literal lt and each datatype dt supported in OWL 2 RL such that t |
scm-cls | 11 class | T(?c, rdf:type, owl:Class) | T(?c, rdfs:subClassOf, ?c) T(?c, owl:equivalentClass, ?c) T(?c, rdfs:subClassOf, owl:Thing) T(owl:Nothing, rdfs:subClassOf, ?c) | |
scm-sco | 11 always | T(?c1, rdfs:subClassOf, ?c2) T(?c2, rdfs:subClassOf, ?c3) | T(?c1, rdfs:subClassOf, ?c3) | |
scm-eqc1 | 11 | T(?c1, owl:equivalentClass, ?c2) | T(?c1, rdfs:subClassOf, ?c2) T(?c2, rdfs:subClassOf, ?c1) | |
scm-eqc2 | 11 | T(?c1, rdfs:subClassOf, ?c2) T(?c2, rdfs:subClassOf, ?c1) | T(?c1, owl:equivalentClass, ?c2) | |
scm-op | T(?p, rdf:type, owl:ObjectProperty) | T(?p, rdfs:subPropertyOf, ?p) T(?p, owl:equivalentProperty, ?p) | ||
scm-dp | T(?p, rdf:type, owl:DatatypeProperty) | T(?p, rdfs:subPropertyOf, ?p) T(?p, owl:equivalentProperty, ?p) | ||
scm-spo | 10 | T(?p1, rdfs:subPropertyOf, ?p2) T(?p2, rdfs:subPropertyOf, ?p3) | T(?p1, rdfs:subPropertyOf, ?p3) | |
scm-eqp1 | T(?p1, owl:equivalentProperty, ?p2) | T(?p1, rdfs:subPropertyOf, ?p2) T(?p2, rdfs:subPropertyOf, ?p1) | ||
scm-eqp2 | T(?p1, rdfs:subPropertyOf, ?p2) T(?p2, rdfs:subPropertyOf, ?p1) | T(?p1, owl:equivalentProperty, ?p2) | ||
scm-dom1 | 11 | T(?p, rdfs:domain, ?c1) T(?c1, rdfs:subClassOf, ?c2) | T(?p, rdfs:domain, ?c2) | |
scm-dom2 | 11 | T(?p2, rdfs:domain, ?c) T(?p1, rdfs:subPropertyOf, ?p2) | T(?p1, rdfs:domain, ?c) | |
scm-rng1 | 11 | T(?p, rdfs:range, ?c1) T(?c1, rdfs:subClassOf, ?c2) | T(?p, rdfs:range, ?c2) | |
scm-rng2 | 11 | T(?p2, rdfs:range, ?c) T(?p1, rdfs:subPropertyOf, ?p2) | T(?p1, rdfs:range, ?c) | |
scm-hv | 11 | T(?c1, owl:hasValue, ?i) T(?c1, owl:onProperty, ?p1) T(?c2, owl:hasValue, ?i) T(?c2, owl:onProperty, ?p2) T(?p1, rdfs:subPropertyOf, ?p2) | T(?c1, rdfs:subClassOf, ?c2) | |
scm-svf1 | 11 | T(?c1, owl:someValuesFrom, ?y1) T(?c1, owl:onProperty, ?p) T(?c2, owl:someValuesFrom, ?y2) T(?c2, owl:onProperty, ?p) T(?y1, rdfs:subClassOf, ?y2) | T(?c1, rdfs:subClassOf, ?c2) | |
scm-svf2 | 11 | T(?c1, owl:someValuesFrom, ?y) T(?c1, owl:onProperty, ?p1) T(?c2, owl:someValuesFrom, ?y) T(?c2, owl:onProperty, ?p2) T(?p1, rdfs:subPropertyOf, ?p2) | T(?c1, rdfs:subClassOf, ?c2) | |
scm-avf1 | 11 | T(?c1, owl:allValuesFrom, ?y1) T(?c1, owl:onProperty, ?p) T(?c2, owl:allValuesFrom, ?y2) T(?c2, owl:onProperty, ?p) T(?y1, rdfs:subClassOf, ?y2) | T(?c1, rdfs:subClassOf, ?c2) | |
scm-avf2 | 11 | T(?c1, owl:allValuesFrom, ?y) T(?c1, owl:onProperty, ?p1) T(?c2, owl:allValuesFrom, ?y) T(?c2, owl:onProperty, ?p2) T(?p1, rdfs:subPropertyOf, ?p2) | T(?c2, rdfs:subClassOf, ?c1) | |
scm-int | T(?c, owl:intersectionOf, ?x) LIST[?x, ?c1, ..., ?cn] | T(?c, rdfs:subClassOf, ?c1) T(?c, rdfs:subClassOf, ?c2) ... T(?c, rdfs:subClassOf, ?cn) | ||
scm-uni | T(?c, owl:unionOf, ?x) LIST[?x, ?c1, ..., ?cn] | T(?c1, rdfs:subClassOf, ?c) T(?c2, rdfs:subClassOf, ?c) ... T(?cn, rdfs:subClassOf, ?c) |
Code | Explanation |
---|---|
1 | Not done due to the database clutter that would result. May be an option in the future. |
2 | Not done because rule is a consistency check and does not materializes triples |
3 | Not done because it is too expensive to calculate a canonical value for each literal and compare that to the canonical value of every other literal to find those that are identical. Also this would add triples with a literal as the subject which is not valid RDF. |
2 | Not done but may appear in a future version of the materializer. |
10 | Done using initial RDFS++ code |
11 | Done via materialization rules |