The XML Concrete Syntax is a combination of the OWL Web Ontology Language XML Presentation Syntax [OWL XML] with the RuleML XML syntax [RuleML]. This has several advantages:
An XML Schema for the SWRL XML Concrete Syntax is swrlx.xsd. swrlx.xsd currently references a local copy of the XML Schema for the OWL XML Presentation Syntax modified to allow external references to several of its elements and attributes and to define owlx:datarange, which appears to be a missing piece of the OWL XML Presentation Syntax.
The SWRL XML Concrete Syntax uses the namespaces http://www.w3.org/2003/11/swrlx, http://www.w3.org/2003/11/ruleml, http://www.w3.org/2003/05/owl-xml (owlx), and http://www.w3.org/2001/XMLSchema (xsd).
The Ontology root element of the OWL XML Presentation Syntax is extended to include "imp" (implication rule) and "var" (variable declaration) axioms as found under the rulebase root of RuleML.
<swrlx:Ontology swrlx:name = xsd:anyURI > Content: (owlx:VersionInfo | owlx:PriorVersion | owlx:BackwardCompatibleWith | owlx:IncompatibleWith | owlx:Imports | owlx:Annotation | owlx:Class[axiom] | owlx:EnumeratedClass(D,F) | owlx:SubClassOf(D,F) | owlx:EquivalentClasses | owlx:DisjointClasses(D,F) | owlx:DatatypeProperty | owlx:ObjectProperty | owlx:SubPropertyOf | owlx:EquivalentProperties | owlx:Individual[axiom] | owlx:SameIndividual | owlx:DifferentIndividuals | ruleml:imp[axiom] | ruleml:var[axiom])* </swrlx:Ontology>
Attribute: | swrlx: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 axioms (imp elements) are similar to SubClassOf axioms. They are taken from the RuleML namespace. A rule axiom can be read as a logical implication between the antecedent (_body) and consequent (_head). Like SubClassOf axioms, rules may include annotations. A rule axiom may optionally be named.
<ruleml:imp> Content: ( _rlab?, owlx:Annotation*, _body, _head ) </ruleml:imp>
Parents: | swrlx: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. |
A rule axiom may optionally be named using a URI.
<ruleml:_rlab ruleml:href = xsd:anyURI (required) > Content: ( ) </ruleml:_rlab>
Parents: | ruleml:imp |
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.
Content: (swrlx:classAtom | swrlx:datarangeAtom | swrlx:individualPropertyAtom | swrlx:datavaluedPropertyAtom | swrlx:sameIndividualAtom | swrlx:differentIndividualsAtom | swrlx:builtinAtom)
Parents: | ruleml:_body, ruleml:_head |
Class atoms consist of a description and either an individual name or a variable name.
<swrlx:classAtom> Content: ( owlx:description, swrlx:iObject ) </swrlx:classAtom>
Parents: | swrlx:atom |
The description in a class atom may be a class name, or may be a complex description using boolean combinations, restrictions, etc. For example:
<swrlx:classAtom> <owlx:Class owlx:name="Person" /> <ruleml:var>x1</ruleml:var> </swrlx:classAtom> <swrlx: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> </swrlx:classAtom>
Datarange atoms consist of a data range and either a literal or a variable name.
<swrlx:datarangeAtom> Content: ( owlx:datarange, swrlx:dObject ) </swrlx:datarangeAtom>
Parents: | swrlx:atom |
The description in a datarange atom may be a datatype ID, or may be a set of literals. For example:
<swrlx:datarangeAtom> <owlx:Datatype owlx:name="&xsd;int" /> <ruleml:var>x1</ruleml:var> </swrlx:datarangeAtom> <swrlx:datarangeAtom> <owlx:OneOf> <owlx:DataValue owlx:datatype="&xsd;int">5</owlx:DataValue> <owlx:DataValue owlx:datatype="&xsd;int">10</owlx:DataValue> </owlx:OneOf> <ruleml:var>x2</ruleml:var> </swrlx:datarangeAtom>
Property atoms consist of a property name and two elements that can be individual names, variable names or data values.
<swrlx:individualPropertyAtom swrlx:property = xsd:anyURI {required} > Content: ( swrlx:iObject, swrlx:iObject ) </swrlx:individualPropertyAtom>
Attribute: | swrlx:property - a reference to an individual property name |
Parents: | swrlx:atom |
<swrlx:datavaluedPropertyAtom swrlx:property = xsd:anyURI {required} > Content: ( swrlx:iObject, swrlx:dObject ) </swrlx:datavaluedPropertyAtom>
Attribute: | swrlx:property - a reference to an datavalued property name |
Parents: | swrlx:atom |
As OWL does not support complex property descriptions, a property atom takes only a property name. For example:
<swrlx:individualPropertyAtom swrlx:property="hasParent"> <ruleml:var>x1</ruleml:var> <owlx:Individual owlx:name="John" /> </swrlx:individualPropertyAtom> <swrlx:datavaluedPropertyAtom swrlx:property="grade"> <ruleml:var>x1</ruleml:var> <owlx:DataValue owlx:datatype="&xsd;int">4</owlx:DataValue> </swrlx:datavaluedPropertyAtom>
Same (different) individual atoms assert equality (inequality) between sets of individual and variable names.
<swrlx:sameIndividualAtom> Content: ( swrlx:iObject* ) </swrlx:sameIndividualAtom>
Parents: | swrlx:atom |
<swrlx:differentIndividualsAtom> Content: ( swrlx:iObject* ) </swrlx:differentIndividualsAtom>
Parents: | swrlx:atom |
Note that (in)equalities can be asserted between arbitrary combinations of variable names and individual names. For example:
<swrlx:sameIndividualAtom> <ruleml:var>x1</ruleml:var> <ruleml:var>x2</ruleml:var> <owlx:Individual owlx:name="Clinton" /> <owlx:Individual owlx:name="Bill_Clinton" /> </swrlx:sameIndividualAtom>
Builtin atoms provide an interface to the built-ins.
<swrlx:builtinAtom swrlx:builtin = xsd:anyURI {required} > Content: ( swrlx:dObject* ) </swrlx:builtinAtom>
Attribute: | swrlx:builtin - a reference to a built-in defined in Section 8 |
Parents: | swrlx:atom |
Content: ( owlx:Individual[ID] | ruleml:var[ID] )
Content: ( owlx:DataValue | ruleml:var[ID] )
Parents: | swrlx:datavaluedPropertyAtom |
<ruleml:var>xsd:string</ruleml:var>
Parents: | swrlx:iObject, swrlx:dObject |
Note: | This element is used for solely referring to a variable ID, and does not actually define any variable, unlike a var axiom. |
We can use SWRL to assert that the combination of the hasParent and hasBrother properties implies the hasUncle property:
<ruleml:imp> <ruleml:_rlab ruleml:href="#example1"/> <ruleml:_body> <swrlx:individualPropertyAtom swrlx:property="hasParent"> <ruleml:var>x1</ruleml:var> <ruleml:var>x2</ruleml:var> </swrlx:individualPropertyAtom> <swrlx:individualPropertyAtom swrlx:property="hasBrother"> <ruleml:var>x2</ruleml:var> <ruleml:var>x3</ruleml:var> </swrlx:individualPropertyAtom> </ruleml:_body> <ruleml:_head> <swrlx:individualPropertyAtom swrlx:property="hasUncle"> <ruleml:var>x1</ruleml:var> <ruleml:var>x3</ruleml:var> </swrlx: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:_rlab ruleml:href="#example2"/> <ruleml:_body> <swrlx:individualPropertyAtom swrlx:property="hasParent"> <ruleml:var>x1</ruleml:var> <ruleml:var>x2</ruleml:var> </swrlx:individualPropertyAtom> <swrlx:individualPropertyAtom swrlx:property="hasSibling"> <ruleml:var>x2</ruleml:var> <ruleml:var>x3</ruleml:var> </swrlx:individualPropertyAtom> <swrlx:individualPropertyAtom swrlx:property="hasSex"> <ruleml:var>x3</ruleml:var> <owlx:Individual owlx:name="#male" /> </swrlx:individualPropertyAtom> </ruleml:_body> <ruleml:_head> <swrlx:individualPropertyAtom swrlx:property="hasUncle"> <ruleml:var>x1</ruleml:var> <ruleml:var>x3</ruleml:var> </swrlx: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> <swrlx:classAtom> <owlx:Class owlx:name="&ulan;Artist" /> <ruleml:var>x</ruleml:var> </swrlx:classAtom> <swrlx:classAtom> <owlx:Class owlx:name="&aat;Style" /> <ruleml:var>y</ruleml:var> </swrlx:classAtom> <swrlx:individualPropertyAtom swrlx:property="&aatulan;artistStyle"> <ruleml:var>x</ruleml:var> <ruleml:var>y</ruleml:var> </swrlx:individualPropertyAtom> <swrlx:individualPropertyAtom swrlx:property="&vra;creator"> <ruleml:var>x</ruleml:var> <ruleml:var>z</ruleml:var> </swrlx:individualPropertyAtom> </ruleml:_body> <ruleml:_head> <swrlx:individualPropertyAtom swrlx:property="&vra;style/period"> <ruleml:var>z</ruleml:var> <ruleml:var>y</ruleml:var> </swrlx: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 SWRL allows "existentials" to be expressed in the head of a rule--it 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 owlx:name="Location" /> </owlx:sub> <owlx:super> <owlx:IntersectionOf> <owlx:DataRestriction owlx:property="latitude"> <owlx:allValuesFrom owlx:datatype="&xsd;double"/> </owlx:DataRestriction> <owlx:DataRestriction owlx:property="longitude"> <owlx:allValuesFrom owlx:datatype="&xsd;double"/> </owlx:DataRestriction> </owlx:IntersectionOf> </owlx:super> </owlx:SubClassOf> <owlx:Individual owlx:name="&airport;GEG"> <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 owlx:name="↦Location" /> </owlx:sub> <owlx:super> <owlx:IntersectionOf> <owlx:DataRestriction owlx:property="↦latitude"> <owlx:someValuesFrom owlx:datatype="&xsd;double"/> </owlx:DataRestriction> <owlx:DataRestriction owlx:property="↦latitude"> <owlx:allValuesFrom owlx:datatype="&xsd;double"/> </owlx:DataRestriction> <owlx:DataRestriction owlx:property="↦longitude"> <owlx:someValuesFrom owlx:datatype="&xsd;double"/> </owlx:DataRestriction> <owlx:DataRestriction owlx:property="↦longitude"> <owlx:allValuesFrom owlx:datatype="&xsd;double"/> </owlx:DataRestriction> </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> <swrlx:classAtom> <owlx:Class owlx:name="↦Location" /> <ruleml:var>maploc</ruleml:var> </swrlx:classAtom> <swrlx:individualPropertyAtom swrlx:property="sameLocation"> <ruleml:var>loc</ruleml:var> <ruleml:var>maploc</ruleml:var> </swrlx:individualPropertyAtom> <swrlx:datavaluedPropertyAtom swrlx:property="latitude"> <ruleml:var>loc</ruleml:var> <ruleml:var>lat</ruleml:var> </swrlx:datavaluedPropertyAtom> <swrlx:datavaluedPropertyAtom swrlx:property="longitude"> <ruleml:var>loc</ruleml:var> <ruleml:var>lon</ruleml:var> </swrlx:datavaluedPropertyAtom> </ruleml:_body> <ruleml:_head> <swrlx:datavaluedPropertyAtom swrlx:property="↦latitude"> <ruleml:var>maploc</ruleml:var> <ruleml:var>lat</ruleml:var> </swrlx:datavaluedPropertyAtom> <swrlx:datavaluedPropertyAtom swrlx:property="↦longitude"> <ruleml:var>maploc</ruleml:var> <ruleml:var>lon</ruleml:var> </swrlx: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> <swrlx:classAtom> <owlx:Class owlx:name="&airport-ont;Airport" /> <ruleml:var>airport</ruleml:var> </swrlx:classAtom> <swrlx:individualPropertyAtom swrlx:property="location"> <ruleml:var>airport</ruleml:var> <ruleml:var>loc</ruleml:var> </swrlx:individualPropertyAtom> <swrlx:datavaluedPropertyAtom swrlx:property="latitude"> <ruleml:var>loc</ruleml:var> <ruleml:var>lat</ruleml:var> </swrlx:datavaluedPropertyAtom> <swrlx:datavaluedPropertyAtom swrlx:property="longitude"> <ruleml:var>loc</ruleml:var> <ruleml:var>lon</ruleml:var> </swrlx:datavaluedPropertyAtom> </ruleml:_body> <ruleml:_head> <swrlx:classAtom> <owlx:ObjectRestriction owlx:property="sameLocation"> <owlx:someValuesFrom> <owlx:IntersectionOf> <owlx:Class owlx:name="↦Location" /> <owlx:ObjectRestriction owlx:property="↦isLocationOf"> <owlx:someValuesFrom> <owlx:IntersectionOf> <owlx:Class owlx:name="↦Point" /> <owlx:ObjectRestriction owlx:property="↦isObjectOf"> <owlx:someValuesFrom> <owlx:OneOf> <owlx:Individual owlx:name="#layer" /> </owlx:OneOf> </owlx:someValuesFrom> </owlx:ObjectRestriction> </owlx:IntersectionOf> </owlx:someValuesFrom> </owlx:ObjectRestriction> </owlx:IntersectionOf> </owlx:someValuesFrom> </owlx:ObjectRestriction> <ruleml:var>loc</ruleml:var> </swrlx: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> <swrlx:classAtom> <owlx:Class owlx:name="&airport-ont;Airport" /> <ruleml:var>airport</ruleml:var> </swrlx:classAtom> <swrlx:individualPropertyAtom swrlx:property="location"> <ruleml:var>airport</ruleml:var> <ruleml:var>loc</ruleml:var> </swrlx:individualPropertyAtom> <swrlx:individualPropertyAtom swrlx:property="sameLocation"> <ruleml:var>loc</ruleml:var> <ruleml:var>maploc</ruleml:var> </swrlx:individualPropertyAtom> <swrlx:individualPropertyAtom swrlx:property="↦location"> <ruleml:var>point</ruleml:var> <ruleml:var>maploc</ruleml:var> </swrlx:individualPropertyAtom> <swrlx:datavaluedPropertyAtom swrlx:property="&airport-ont;name"> <ruleml:var>airport</ruleml:var> <ruleml:var>name</ruleml:var> </swrlx:datavaluedPropertyAtom> </ruleml:_body> <ruleml:_head> <swrlx:individualPropertyAtom swrlx:property="↦underlyingObject"> <ruleml:var>point</ruleml:var> <ruleml:var>airport</ruleml:var> </swrlx:individualPropertyAtom> <swrlx:datavaluedPropertyAtom swrlx:property="↦label"> <ruleml:var>point</ruleml:var> <ruleml:var>name</ruleml:var> </swrlx:datavaluedPropertyAtom> </ruleml:_head> </ruleml:imp>
The following ontology translation example shows the use of built-ins to convert units of measure:
<ruleml:imp> <ruleml:_rlab ruleml:href="#convertLength"/> <owlx:Annotation> <owlx:Documentation>ex2:lengthInInches = ex1:lengthInFeet * 12</owlx:Documentation> </owlx:Annotation> <ruleml:_body> <swrlx:datavaluedPropertyAtom swrlx:property="&ex1;#lengthInFeet"> <ruleml:var>instance</ruleml:var> <ruleml:var>feet</ruleml:var> </swrlx:datavaluedPropertyAtom> </ruleml:_body> <ruleml:_head> <swrlx:builtinAtom swrlx:builtin="&swrlb;#multiply"> <ruleml:var>inches</ruleml:var> <ruleml:var>feet</ruleml:var> <owlx:DataValue owlx:datatype="&xsd;#int">12</owlx:DataValue> </swrlx:builtinAtom> <swrlx:datavaluedPropertyAtom swrlx:property="&ex2;#lengthInInches"> <ruleml:var>instance</ruleml:var> <ruleml:var>inches</ruleml:var> </swrlx:datavaluedPropertyAtom> </ruleml:_head> </ruleml:imp>
The following example shows the use of built-ins to perform comparisons necessary to compute a discount:
<ruleml:imp> <ruleml:_rlab ruleml:href="#goldDiscount"/> <owlx:Annotation> <owlx:Documentation>Gold customers get a 10% discount on purchases of $500 or more</owlx:Documentation> </owlx:Annotation> <ruleml:_body> <swrlx:individualPropertyAtom swrlx:property="&ex;#hasStatus"> <ruleml:var>customer</ruleml:var> <owlx:Individual owlx:name="&ex;#gold"/> </swrlx:individualPropertyAtom> <swrlx:datavaluedPropertyAtom swrlx:property="&ex;#hasTotalPurchase"> <ruleml:var>customer</ruleml:var> <ruleml:var>total</ruleml:var> </swrlx:datavaluedPropertyAtom> <swrlx:builtinAtom swrlx:builtin="&swrlb;#greaterThanOrEqual"> <ruleml:var>total</ruleml:var> <owlx:DataValue owlx:datatype="&xsd;#int">500</owlx:DataValue> </swrlx:builtinAtom> </ruleml:_body> <ruleml:_head> <swrlx:datavaluedPropertyAtom swrlx:property="&ex;#hasDiscount"> <ruleml:var>customer</ruleml:var> <owlx:DataValue owlx:datatype="&xsd;#int">10</owlx:DataValue> </swrlx:datavaluedPropertyAtom> </ruleml:_head> </ruleml:imp>
These examples are also provided as example5.1-1.swrlx, example5.1-2.swrlx, example5.1-3.swrlx, example5.1-4.swrlx, example5.1-5.swrlx, and example5.1-6.swrlx.