Many possible XML encodings could be imagined (e.g., a RuleML based syntax as proposed in http://www.daml.org/listarchive/joint-committee/1460.html), but the most obvious solution is to extend the existing OWL Web Ontology Language XML Presentation Syntax [OWL XML], which can be straightforwardly modified to deal with OWL Rules. This has several advantages:
In the first place, the ontology root element is extended to include "imp" and "var" axioms as found under the rulebase root of RuleML.
<Ontology name = xsd:anyURI > Content: (VersionInfo | PriorVersion | BackwardCompatibleWith | IncompatibleWith | Imports | Annotation | Class[axiom] | EnumeratedClass(D,F) | SubClassOf(D,F) | EquivalentClasses | DisjointClasses(D,F) | DatatypeProperty | ObjectProperty | SubPropertyOf | EquivalentProperties | Individual[axiom] | SameIndividual | DifferentIndividuals | imp[axiom] | var[axiom])* </Ontology>
Attribute: | name - refers to a name of this ontology, which is the base URI of this element. |
Note: | This is the root element of OWL documents in the XML presentation syntax, while rdf:RDF is used as the document root for OWL in RDF/XML. |
We then simply need to add the relevant syntax for variables and rules.
Variable (var) axioms are statements about variables, indicating that the given string is to be used as a variable.
A var axiom simply defines the existence of a variable. This is taken from the RuleML namespace. For example:
<ruleml:var>x1</ruleml:var>
Rule (imp) axioms are similar to SubClassOf axioms. They are taken from the RuleML namespace and can be read as a logical implication between the antecedent (_body) and consequent (_head). Like SubClassOf axioms, rules may include annotations.
<imp> Content: ( Annotation*, _body, _head ) </imp>
Parents: | Ontology |
Note: | This element allows one to say that every binding that satisfies the _body of the rule must also satisfy the _head of the rule. |
Both _body and _head are lists of atoms and are read as the conjunction of the component atoms.
Atoms can be formed from unary predicates (classes), binary predicates (properties), equalities or inequalities.
Class atoms consist of a description and either an individual name or a variable name.
The description in a class atom may be a class name, or may be a complex description using boolean combinations, restrictions, etc. For example:
<owlx:classAtom> <owlx:Class owlx:name="Person" /> <ruleml:var>x1</ruleml:var> </owlx:classAtom> <owlx:classAtom> <owlx:IntersectionOf> <owlx:Class owlx:name="Person" /> <owlx:ObjectRestriction owlx:property="hasParent"> <owlx:someValuesFrom owlx:class="Physician" /> </owlx:ObjectRestriction> </owlx:IntersectionOf> <ruleml:var>x2</ruleml:var> </owlx:classAtom>
Property atoms consist of a property name and two elements that can be individual names, variable names or data values.
<individualPropertyAtom property = xsd:anyURI {required} > Content: ( iObject, iObject ) </individualPropertyAtom>
Attribute: | property - a reference to an individual property name |
Parents: | atom |
<datavaluedPropertyAtom property = xsd:anyURI {required} > Content: ( iObject, dObject ) </datavaluedPropertyAtom>
Attribute: | property - a reference to an datavalued property name |
Parents: | atom |
As OWL does not support complex property descriptions, a property atom takes only a property name. For example:
<owlx:individualPropertyAtom owlx:property="hasParent"> <ruleml:var>x1</ruleml:var> <owlx:Individual owlx:name="John" /> </owlx:individualPropertyAtom> <owlx:datavaluedPropertyAtom owlx:property="grade"> <ruleml:var>x1</ruleml:var> <owlx:DataValue owlx:datatype="&xsd;integer">4</owlx:DataValue> </owlx:datavaluedPropertyAtom>
Same (different) individual atoms assert equality (inequality) between sets individual and variable names.
<sameIndividualAtom> Content: ( iObject* ) </sameIndividualAtom>
Parents: | atom |
<differentIndividualsAtom> Content: ( iObject* ) </differentIndividualsAtom>
Parents: | atom |
Note that (in)equalities can be asserted between arbitrary combinations of variable names and individual names. For example:
<owlx:sameIndividualAtom> <ruleml:var>x1</ruleml:var> <ruleml:var>x2</ruleml:var> <owlx:Individual owlx:name="Clinton" /> <owlx:Individual owlx:name="Bill_Clinton" /> </owlx:sameIndividualAtom>
Content: ( Individual[ID] | var[ID] )
<ruleml:var>xsd:string</ruleml:var>
We can use OWL rules to assert that the combination of the hasParent and hasBrother properties implies the hasUncle property:
<ruleml:imp> <ruleml:_body> <owlx:individualPropertyAtom owlx:property="hasParent"> <ruleml:var>x1</ruleml:var> <ruleml:var>x2</ruleml:var> </owlx:individualPropertyAtom> <owlx:individualPropertyAtom owlx:property="hasBrother"> <ruleml:var>x2</ruleml:var> <ruleml:var>x3</ruleml:var> </owlx:individualPropertyAtom> </ruleml:_body> <ruleml:_head> <owlx:individualPropertyAtom owlx:property="hasUncle"> <ruleml:var>x1</ruleml:var> <ruleml:var>x3</ruleml:var> </owlx:individualPropertyAtom> </ruleml:_head> </ruleml:imp>
An alternative formulation for the hasUncle rule given in Example 5.1-1 would be to assert that if x1 hasParent x2, x2 hasSibling x3, and x3 hasSex male, then x1 hasUncle x3:
<ruleml:imp> <ruleml:_body> <owlx:individualPropertyAtom owlx:property="hasParent"> <ruleml:var>x1</ruleml:var> <ruleml:var>x2</ruleml:var> </owlx:individualPropertyAtom> <owlx:individualPropertyAtom owlx:property="hasSibling"> <ruleml:var>x2</ruleml:var> <ruleml:var>x3</ruleml:var> <owlx:individualPropertyAtom owlx:property="hasSex"> <ruleml:var>x3</ruleml:var> <owlx:Individual owlx:name="#male" /> </owlx:individualPropertyAtom> </ruleml:_body> <ruleml:_head> <owlx:individualPropertyAtom owlx:property="hasUncle"> <ruleml:var>x1</ruleml:var> <ruleml:var>x3</ruleml:var> </owlx:individualPropertyAtom> </ruleml:_head> </ruleml:imp>
The following example is due to Guus Schreiber, and is based on ontologies used in an image annotation demo.
The rule expresses the fact that, given knowledge about the AAT style of certain ULAN artists (e.g., van Gogh is an Impressionist painter), we can derive the style of an art object (represented with the VRA element "style/period") from the value of the creator of the art object (represented by the VRA element "creator", a subproperty of dc:creator):
<ruleml:imp> <ruleml:_body> <owlx:classAtom> <owlx:class="&ulan;Artist" /> <ruleml:var>_x</ruleml:var> </owlx:classAtom> <owlx:classAtom> <owlx:class="&aat;Style" /> <ruleml:var>_y</ruleml:var> </owlx:classAtom> <owlx:individualPropertyAtom owlx:property="&aatulan;artistStyle"> <ruleml:var>_x</ruleml:var> <ruleml:var>_y</ruleml:var> </owlx:individualPropertyAtom> <owlx:individualPropertyAtom owlx:property="&vra;creator"> <ruleml:var>_x</ruleml:var> <ruleml:var>_z</ruleml:var> </owlx:individualPropertyAtom> </ruleml:_body> <ruleml:_head> <owlx:individualPropertyAtom owlx:property="&vra;style/period"> <ruleml:var>_z</ruleml:var> <ruleml:var>_y</ruleml:var> </owlx:individualPropertyAtom> </ruleml:_head> </ruleml:imp>
The following is taken from an extended example due to Mike Dean. It expresses the fact that for every Airport there is a map Point that has the same location (latitude and longitude) as the Airport and that is an object of "layer" (a map DrawingLayer). Moreover, this map point has the Airport as an underlyingObject and has the Airport name as its Label
Note how the expressive power of OWL Rules allows "existentials" to be expressed in the head of a ruleit is asserted that, for every airport, there must exist such a map point.
<!-- Background knowledge about airports and maps: --> <owlx:DatatypeProperty owlx:name="latitude"/> <owlx:DatatypeProperty owlx:name="longitude"/> <owlx:SubClassOf> <owlx:sub> <owlx:class="Location" /> </owlx:sub> <owlx:super> <owlx:IntersectionOf> <owlx:ObjectRestriction owlx:property="latitude"> <owlx:allValuesFrom owlx:datatype="&xsd;double"/> </owlx:ObjectRestriction> <owlx:ObjectRestriction owlx:property="longitude"> <owlx:allValuesFrom owlx:datatype="&xsd;double"/> </owlx:ObjectRestriction> </owlx:IntersectionOf> </owlx:super> </owlx:SubClassOf> <owlx:Individual owlx:name="&airport;GEC"> <owlx:type owlx:name="&airport-ont;Airport" /> <owlx:DataPropertyValue owlx:property="airport-ont:name"> <owlx:DataValue owlx:datatype="&xsd;string">Spokane Intl</owlx:DataValue> </owlx:DataPropertyValue> <owlx:ObjectPropertyValue owlx:property="location"> <owlx:Individual> <owlx:DataPropertyValue owlx:property="latitude"> <owlx:DataValue>47.6197</owlx:DataValue> </owlx:DataPropertyValue> <owlx:DataPropertyValue owlx:property="longitude"> <owlx:DataValue>-117.5336</owlx:DataValue> </owlx:DataPropertyValue> </owlx:Individual> </owlx:ObjectPropertyValue> </owlx:Individual> <owlx:Individual owlx:name="layer"> <owlx:type owlx:name="↦DrawingLayer" /> </owlx:Individual> <owlx:Individual owlx:name="map"> <owlx:type owlx:name="↦Map" /> <owlx:DataPropertyValue owlx:property="↦name"> <owlx:DataValue owlx:datatype="&xsd;string">Airports</owlx:DataValue> </owlx:DataPropertyValue> <owlx:ObjectPropertyValue owlx:property="map:layer"> <owlx:Individual owlx:name="layer"/> </owlx:ObjectPropertyValue> </owlx:Individual> <!-- A map:Location has latitude and longitude, both of which are doubles: --> <owlx:SubClassOf> <owlx:sub> <owlx:class="↦Location" /> </owlx:sub> <owlx:super> <owlx:IntersectionOf> <owlx:ObjectRestriction owlx:property="↦latitude"> <owlx:someValuesFrom owlx:datatype="&xsd;double"/> </owlx:ObjectRestriction> <owlx:ObjectRestriction owlx:property="↦latitude"> <owlx:allValuesFrom owlx:datatype="&xsd;double"/> </owlx:ObjectRestriction> <owlx:ObjectRestriction owlx:property="↦longitude"> <owlx:someValuesFrom owlx:datatype="&xsd;double"/> </owlx:ObjectRestriction> <owlx:ObjectRestriction owlx:property="↦longitude"> <owlx:allValuesFrom owlx:datatype="&xsd;double"/> </owlx:ObjectRestriction> </owlx:IntersectionOf> </owlx:super> </owlx:SubClassOf> <!-- If a map:Location is the sameLocation as another location, then it has the same values for latitude and longitude. --> <ruleml:imp> <ruleml:_body> <owlx:classAtom> <owlx:class="↦Location" /> <ruleml:var>_maploc</ruleml:var> </owlx:classAtom> <owlx:individualPropertyAtom owlx:property="sameLocation"> <ruleml:var>_loc</ruleml:var> <ruleml:var>_maploc</ruleml:var> </owlx:individualPropertyAtom> <owlx:datavaluedPropertyAtom owlx:property="latitude"> <ruleml:var>_loc</ruleml:var> <ruleml:var>_lat</ruleml:var> </owlx:datavaluedPropertyAtom> <owlx:datavaluedPropertyAtom owlx:property="longitude"> <ruleml:var>_loc</ruleml:var> <ruleml:var>_lon</ruleml:var> </owlx:datavaluedPropertyAtom> </ruleml:_body> <ruleml:_head> <owlx:datavaluedPropertyAtom owlx:property="↦latitude"> <ruleml:var>_maploc</ruleml:var> <ruleml:var>_lat</ruleml:var> </owlx:datavaluedPropertyAtom> <owlx:datavaluedPropertyAtom owlx:property="↦longitude"> <ruleml:var>_maploc</ruleml:var> <ruleml:var>_lon</ruleml:var> </owlx:datavaluedPropertyAtom> </ruleml:_head> </ruleml:imp> <!-- 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 that is an object of the map:DrawingLayer "layer": --> <owlx:ObjectProperty owlx:name="↦location" owlx:inverseOf="↦isLocationOf" /> <owlx:ObjectProperty owlx:name="↦object" owlx:inverseOf="↦isObjectOf" /> <ruleml:imp> <ruleml:_body> <owlx:classAtom> <owlx:class="&airport-ont;Airport" /> <ruleml:var>_airport</ruleml:var> </owlx:classAtom> <owlx:individualPropertyAtom owlx:property="location"> <ruleml:var>_airport</ruleml:var> <ruleml:var>_loc</ruleml:var> </owlx:individualPropertyAtom> <owlx:datavaluedPropertyAtom owlx:property="latitude"> <ruleml:var>_loc</ruleml:var> <ruleml:var>_lat</ruleml:var> </owlx:datavaluedPropertyAtom> <owlx:datavaluedPropertyAtom owlx:property="longitude"> <ruleml:var>_loc</ruleml:var> <ruleml:var>_lon</ruleml:var> </owlx:datavaluedPropertyAtom> </ruleml:_body> <ruleml:_head> <owlx:classAtom> <owlx:ObjectRestriction owlx:property="sameLocation"> <owlx:someValuesFrom> <owlx:IntersectionOf> <owlx:class="↦Location" /> <owlx:ObjectRestriction owlx:property="↦isLocationOf"> <owlx:someValuesFrom> <owlx:IntersectionOf> <owlx:class="↦Point" /> <owlx:ObjectRestriction owlx:property="↦isObjectOf"> <owlx:someValuesFrom> <owlx:OneOf> <owlx:Individual owlx:name="#layer" /> </owlx:OneOf> </owlx:someValuesFrom> </owlx:ObjectRestriction owlx:property="↦isObjectOf"> </owlx:IntersectionOf> </owlx:someValuesFrom> </owlx:ObjectRestriction owlx:property="↦isLocationOf"> </owlx:IntersectionOf> </owlx:someValuesFrom> </owlx:ObjectRestriction> <ruleml:var>_loc</ruleml:var> </owlx:classAtom> </ruleml:_head> </ruleml:imp> <!-- The 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. --> <ruleml:imp> <ruleml:_body> <owlx:classAtom> <owlx:class="&airport-ont;Airport" /> <ruleml:var>_airport</ruleml:var> </owlx:classAtom> <owlx:individualPropertyAtom owlx:property="location"> <ruleml:var>_airport</ruleml:var> <ruleml:var>_loc</ruleml:var> </owlx:individualPropertyAtom> <owlx:individualPropertyAtom owlx:property="sameLocation"> <ruleml:var>_loc</ruleml:var> <ruleml:var>_maploc</ruleml:var> </owlx:individualPropertyAtom> <owlx:individualPropertyAtom owlx:property="↦location"> <ruleml:var>_point</ruleml:var> <ruleml:var>_maploc</ruleml:var> </owlx:individualPropertyAtom> <owlx:datavaluedPropertyAtom owlx:property="&airport-ont;name"> <ruleml:var>_airport</ruleml:var> <ruleml:var>_name</ruleml:var> </owlx:datavaluedPropertyAtom> </ruleml:_body> <ruleml:_head> <owlx:individualPropertyAtom owlx:property="↦underlyingObject"> <ruleml:var>_point</ruleml:var> <ruleml:var>_airport</ruleml:var> </owlx:individualPropertyAtom> <owlx:datavaluedPropertyAtom owlx:property="↦label"> <ruleml:var>_point</ruleml:var> <ruleml:var>_name</ruleml:var> </owlx:datavaluedPropertyAtom> </ruleml:_head> </ruleml:imp>