Table of Contents

Introduction

Limitations

API

materialize-entailed-triples

delete-materialized-triples

Materialization rule sets

Introduction

The materializer generates triples by applying a set of rules to the current triples in the triple store and then places the resulting triples back in the triple store.

The materializer differs from the RDFS++ reasoner in that the materializer computes all inferred triples at once and stores them whereas the RDFS++ reasoner computes inferred triples dynamically and does not store them in the triple store.

If the triple store is changed via additions or deletions then materialization may have to be run again in order that the triple store contain the correct set of materialized triples.

The rules that the materializer uses are subset of the OWL 2 RL rules described at http://www.w3.org/TR/2009/REC-owl2-profiles-20091027/.

OWL 2 RL is the subset of OWL 2 that is designed to support 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 these OWL 2 RL rules and we plan to add more rules in future versions.

Limitations

The first version has some limitations that we'll describe here. Some of those limitations will be lifted in subsequent versions.

The Materializer assumes that the triple store contains triples only in the default graph. The Materializer assumes that it is free to delete triples that have the same Subject, Predicate and Object.

After the materializer is finished the original triples will still be present and there will be a set of triples in a newly created graph. This newly created graph is a special kind of triple part that cannot be expressed in nquad format. Therefore you cannot serialize the triple store and then load it back in. This is a limitation of the current version. This aspect of graph assignment will be changed in a future version.

You can run queries over the triple store and SPARQL or Prolog will look both in the default graph and the materialized triples graph.

API

There is a AGWebView interface (see WebView, particularly the Repository Overview Page section), a Java interface (see AGMaterializer#newInstance() and AGRepositoryConnection#materialize), and a Python interface, as well as the Lisp interface described next.

materialize-entailed-triples

The main function is

materialize-entailed-triples (&key (db *db*) verbose  
				      print-ontology  
				      (commit 100000)  
				      (ruleset 0 ruleset-p)  
				      with  
				      without  
				      use-type-subproperty  
				      ) 

where

The symbolic names for the rulesets (which are written as string) are as follows. We'll describe what they mean in detail below

Note that "values-from" is a special set of "restriction" rules. If "restriction" is specified then you can also specify "values-from" to enable that set of restriction rules

Examples of how to specify rulesets

(materialize-entailed-triples) 

will add do 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 basis 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:

(delete-materialized-triples commitp) 

This function deletes any materialized triples in the database and returns a count of the number deleted. If commitp is true then a commit will be done after the delete.

The materialize-entailed-triples function will first call delete-materialized-triples before starting to add triples.

Materialization 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 done 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.

Key:

Not done:

  1. not done -- due to database clutter that would result. May be an option in the future.
  2. not done – is a consistency check and not something that materializes triples
  3. not done – 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 RDF.

Done:

10. done -- using initial RDFS++ code

11. done -- as a rule

 

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)

false

 

eq-diff2

2

T(?x, rdf:type, owl:AllDifferent)
T(?x, owl:members, ?y)
LIST[?y, ?z1, ..., ?zn]
T(?zi, owl:sameAs, ?zj)

false

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)

false

for each 1 ≤ i < j ≤ n

 





notes

if

then

 

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)

false

 

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)

false

 

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)

false

 

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)

false

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)

false

 

prp-npa2

2

T(?x, owl:sourceIndividual, ?i)
T(?x, owl:assertionProperty, ?p)
T(?x, owl:targetValue, ?lt)
T(?i, ?p, ?lt)

false

 

 

 

 



notes

If

then

 

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)

false

 

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)

false

 

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

11restriction & 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)

false

 

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)

false

 

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)

false

 

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)

 

 



 

If

then

 

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)

false

 

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)

false

for each 1 ≤ i < j ≤ n

 

 

 



 

If

then

 

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)

false

for each literal lt and each datatype dt supported in OWL 2 RL
such that t

 



 

If

then

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)