This is a description of a proposed rules extension to the OWL Web Ontology Language. It includes a high-level abstract syntax for Horn clause rules in both the OWL DL and OWL Lite sublanguages of OWL. A model-theoretic semantics is given to provide a formal meaning for OWL ontologies including rules written in this abstract syntax. An XML syntax based on the OWL XML presentation syntax and a mapping to RDF graphs based on the OWL RDF/XML exchange syntax are also given, along with several examples.
axiom ::= rule rule ::= 'Implies(' { annotation } antecedent consequent ')' antecedent ::= 'Antecedent(' { atom } ')' consequent ::= 'Consequent(' { atom } ')' atom ::= description '(' i-object ')' | individualvaluedPropertyID '(' i-object i-object ')' | datavaluedPropertyID '(' i-object d-object ')' | sameAs '(' i-object i-object ')' | differentFrom '(' i-object i-object ')' i-object ::= i-variable | individualID d-object ::= d-variable | dataLiteral i-variable ::= 'I-variable(' URIreference ')' d-variable ::= 'D-variable(' URIreference ')'
Assert that the combination of the hasParent and hasBrother properties implies the hasUncle property:
hasParent(?x1,?x2) ∧ hasBrother(?x2,?x3) ⇒ hasUncle(?x1,?x3)
Implies(Antecedent(hasParent(I-variable(x1) I-variable(x2)) hasBrother(I-variable(x2) I-variable(x3))) Consequent(hasUncle(I-variable(x1) I-variable(x3))))
Gets you just what you want (and a bit more)
If John has Mary as a parent and Mary has Bill has a brother
then John has Bill as an uncle
An alternative formulation of the first example:
hasParent(?x1,?x2) ∧ hasSibling(?x2,?x3) ∧ hasSex(?x3,Male) ⇒ hasUncle(?x1,?x3)
Implies(Antecedent(hasParent(I-variable(x1) I-variable(x2)) hasSibling(I-variable(x2) I-variable(x3)) hasSex(I-variable(x3) Male)) Consequent(hasUncle(I-variable(x1) I-variable(x3))))
Note use of OWL individual (Male)
Assert that art objects inherit the style/period of the artist that created them:
Artist(?x1) ∧ Style(?x2) ∧ artistStyle(?x1,?x2) ∧ creator(?x1,?x3) ⇒ styleOrPeriod(?x3,?x2)
Implies(Antecedent(Artist(I-variable(x1)) Style(I-variable(x2)) artistStyle(I-variable(x1) I-variable(x2)) creator(I-variable(x1) I-variable(x3))) Consequent(styleOrPeriod(I-variable(x3) I-variable(x2))))
Subset of OWL DL can be transformed into equivalent rules (and vice versa)
For example (trivially):
SubClassOf(C D)is equivalent to
Implies(Antecedent(C(I-variable(x1))) Consequent(D(I-variable(x1))))
Also:
SubClassOf(intersectionOf(A restriction(P someValuesFrom(B))) intersectionOf(C restriction(Q allValuesFrom(D))))is equivalent to
Implies(Antecedent(A(I-variable(x1)) P(I-variable(x1) I-variable(x2)) B(I-variable(x2))) Consequent(C(I-variable(x2)))) Implies(Antecedent(A(I-variable(x1)) P(I-variable(x1) I-variable(x2)) B(I-variable(x2)) Q(I-variable(x1) I-variable(x3))) Consequent(D(I-variable(x2))))
Atom | Condition on B(I) |
---|---|
description(x) | S(x) ∈ EC(description) |
property(x,y) | <S(x),S(y)> ∈ ER(property) |
sameAs(x,y) | S(x) = S(y) |
differentFrom(x,y) | S(x) ≠ S(y) |
<owlx:Rule> <owlx:antecedent> <owlx:individualPropertyAtom owlx:property="hasParent"> <owlx:Variable owlx:name="x1" /> <owlx:Variable owlx:name="x2" /> </owlx:individualPropertyAtom> <owlx:individualPropertyAtom owlx:property="hasBrother"> <owlx:Variable owlx:name="x2" /> <owlx:Variable owlx:name="x3" /> </owlx:individualPropertyAtom> </owlx:antecedent> <owlx:consequent> <owlx:individualPropertyAtom owlx:property="hasUncle"> <owlx:Variable owlx:name="x1" /> <owlx:Variable owlx:name="x3" /> </owlx:individualPropertyAtom> </owlx:consequent> </owlx:Rule>
<owlx:Rule> <owlx:antecedent> <owlx:individualPropertyAtom owlx:property="hasParent"> <owlx:Variable owlx:name="x1" /> <owlx:Variable owlx:name="x2" /> </owlx:individualPropertyAtom> <owlx:individualPropertyAtom owlx:property="hasSibling"> <owlx:Variable owlx:name="x2" /> <owlx:Variable owlx:name="x3" /> <owlx:individualPropertyAtom owlx:property="hasSex"> <owlx:Variable owlx:name="x3" /> <owlx:Individual owlx:name="#male" /> </owlx:individualPropertyAtom> </owlx:antecedent> <owlx:consequent> <owlx:individualPropertyAtom owlx:property="hasUncle"> <owlx:Variable owlx:name="x1" /> <owlx:Variable owlx:name="x3" /> </owlx:individualPropertyAtom> </owlx:consequent> </owlx:Rule>
<owlx:Rule> <owlx:antecedent> <owlx:classAtom> <owlx:class="&ulan;Artist" /> <owlx:Variable owlx:name="_x" /> </owlx:classAtom> <owlx:classAtom> <owlx:class="&aat;Style" /> <owlx:Variable owlx:name="_y" /> </owlx:classAtom> <owlx:individualPropertyAtom owlx:property="&aatulan;artistStyle"> <owlx:Variable owlx:name="_x" /> <owlx:Variable owlx:name="_y" /> </owlx:individualPropertyAtom> <owlx:individualPropertyAtom owlx:property="&vra;creator"> <owlx:Variable owlx:name="_x" /> <owlx:Variable owlx:name="_z" /> </owlx:individualPropertyAtom> </owlx:antecedent> <owlx:consequent> <owlx:individualPropertyAtom owlx:property="&vra;style/period"> <owlx:Variable owlx:name="_z" /> <owlx:Variable owlx:name="_y" /> </owlx:individualPropertyAtom> </owlx:consequent> </owlx:Rule>
<owlr:Variable rdf:ID="_x1"/> <owlr:Variable rdf:ID="_x2"/> <owlr:Variable rdf:ID="_x3"/> <owlr:Rule> <owlr:antecedent rdf:parseType="Collection"> <owlr:individualPropertyAtom> <owlr:propertyPredicate rdf:resource="⪚hasParent"/> <owlr:argument1 rdf:about="#_x1" /> <owlr:argument2 rdf:about="#_x2" /> </owlr:individualPropertyAtom> <owlr:individualPropertyAtom> <owlr:propertyPredicate rdf:resource="⪚hasSibling"/> <owlr:argument1 rdf:about="#_x2" /> <owlr:argument2 rdf:about="#_x3" /> </owlr:individualPropertyAtom> <owlr:individualPropertyAtom> <owlr:propertyPredicate rdf:resource="⪚hasSex"/> <owlr:argument1 rdf:about="#_x3" /> <owlr:argument2 rdf:about="#male" /> </owlr:individualPropertyAtom> </owlr:antecedent> <owlr:consequent rdf:parseType="Collection"> <owlr:individualPropertyAtom> <owlr:propertyPredicate rdf:resource="⪚hasUncle"/> <owlr:argument1 rdf:about="#_x1" /> <owlr:argument2 rdf:about="#_x3" /> </owlr:individualPropertyAtom> </owlr:consequent> </owlr:Rule>
From http://www.daml.org/2003/06/ruletests/translation-3.n3 (due to Mike Dean)
For every Airport there is a map Point that has the same location (latitude & longitude) as the Airport, that has the Airport as an underlyingObject and that has the Airport name as its Label
First some background knowledge (OWL axioms):
DataTypeProperty(latitude) DataTypeProperty(longitude) SubClassOf(map:Location intersectionOf( restriction(map:latitude someValuesFrom(xsd:double)) restriction(map:latitude allValuesFrom(xsd:double)) restriction(map:longitude someValuesFrom(xsd:double)) restriction(map:longitude allValuesFrom(xsd:double)) ))
Rule asserting that if a map:Location is the sameLocation as another location, then it has the same values for latitude and longitude:
Implies( Antecedent(map:Location(I-variable(maploc)) sameLocation(I-variable(loc) I-variable(maploc)) latitude(I-variable(loc) I-variable(lat)) longitude(I-variable(loc) I-variable(lon))) Consequent(map:latitude(I-variable(maploc) I-variable(lat)) map:longitude(I-variable(maploc) I-variable(lon))))
Rule asserting that wherever an Airport is located, there is some map:Location that is the sameLocation as the Airport's location and that is the location of a map Point:
ObjectProperty(map:location (inverseOf map:isLocationOf)) Implies(Antecedent(airports:Airport(I-variable(airport)) location(I-variable(airport) I-variable(loc)) latitude(I-variable(loc) I-variable(lat)) longitude(I-variable(loc) I-variable(lon))) Consequent(restriction (sameLocation someValuesFrom (intersectionOf (map:Location restriction (map:isLocationOf someValuesFrom (map:Point)))))))
Note use of complex OWL description as predicate in rule;
use of OWL:someValuesFrom to assert existence of map location
Rule asserting that a map:Point whose map:location is the map:Location of an Airport has the airport as a map:underlyingObject and has a map:label which is the name of the Airport.
ObjectProperty(map:location (inverseOf map:isLocationOf)) Implies( Antecedent(airports:Airport(I-variable(airport)) location(I-variable(airport) I-variable(loc)) sameLocation(I-variable(loc) I-variable(maploc)) map:location(I-variable(point) I-variable(maploc)) airports:name(I-variable(airport) I-variable(name))) Consequent(map:underlyingObject(I-variable(point) I-variable(airport)) map:label(I-variable(point) I-variable(name))))