Another abandoned server code base... this is kind of an ancestor of taskrambler.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1398 lines
47 KiB

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>OWL Web Ontology Language Parsing OWL in RDF/XML</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
pre.code {
background: #dde;
margin-left: 20px;
padding-left: 10px;
width: auto;
border: 1px solid #aaa;
}
pre.abstract {
background: #edd;
margin-left: 20px;
padding-left: 10px;
width: auto;
border: 1px solid #aaa;
}
</style>
<link href="http://www.w3.org/StyleSheets/TR/W3C-WG-NOTE"
rel="stylesheet" type="text/css" />
</head>
<body>
<div class="head"><a href="http://www.w3.org/"><img height="48"
width="72" alt="W3C" src="http://www.w3.org/Icons/w3c_home" /></a>
<h1>OWL Web Ontology Language <br/> Parsing OWL in RDF/XML</h1>
<h2>W3C Working Group Note 21 January 2004</h2>
<div id="owl_2_notice" style="border: solid black 1px; padding: 0.5em; background: #FFB;">
<p style="margin-top: 0; font-weight: bold;">New Version
Available: OWL 2 <span style="padding-left: 2em;"></span>
(Document Status Update, 12 November 2009)</p>
<p style="margin-bottom: 0;">The OWL Working Group has produced
a W3C Recommendation for a new version of OWL which adds
features to this 2004 version, while remaining compatible.
Please see <a href="http://www.w3.org/TR/owl2-overview">OWL 2
Document Overview</a> for an introduction to OWL 2 and a guide
to the OWL 2 document set.</p>
</div>
<dl>
<dt>This version:</dt><dd><a href="http://www.w3.org/TR/2004/NOTE-owl-parsing-20040121">http://www.w3.org/TR/2004/NOTE-owl-parsing-20040121</a></dd>
<dt>Latest version:</dt><dd><a href="http://www.w3.org/TR/owl-parsing">http://www.w3.org/TR/owl-parsing</a></dd>
<dt>Author:</dt>
<dd>Sean Bechhofer (<a href="mailto:seanb@cs.man.ac.uk">seanb@cs.man.ac.uk</a>), University of Manchester.</dd>
</dl>
<p class="copyright"><a href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright"> Copyright</a> &#xa9; 2004 <a href="http://www.w3.org/"><acronym title="World Wide Web Consortium">W3C</acronym></a><sup>&#xae;</sup> (<a href="http://www.lcs.mit.edu/"><acronym title="Massachusetts Institute of Technology">MIT</acronym></a>, <a href="http://www.ercim.org/"><acronym title="European Research Consortium for Informatics and Mathematics">ERCIM</acronym></a>, <a href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved. W3C <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>, <a href="http://www.w3.org/Consortium/Legal/copyright-documents">document use</a> and <a href="http://www.w3.org/Consortium/Legal/copyright-software">software licensing</a> rules apply.</p>
<hr />
</div>
<!-- ================================================================== -->
<h2>Abstract</h2>
<p>An OWL-RDF parser takes an RDF/XML file and attempts to construct
an OWL ontology that corresponds to the triples represented in the
RDF. This document describes a basic strategy that could be used in such a
parser. Note that this is not intended as a complete specification,
but hopefully provides enough information to point the way towards how
one would build a parser that will deal with a majority of (valid) OWL
ontologies.</p>
<p>For example, we do not discuss the implementation or handling of
<code>owl:imports</code> here, nor do we address in depth issues
concerned with spotting some of the more obscure violations of the
DL/Lite rules.</p>
<h2><a id="Status" name="Status"></a>Status of This Document</h2>
<div class="status">
<p><em>This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the <a href="http://www.w3.org/TR/">W3C technical reports index</a> at http://www.w3.org/TR/.</em></p>
<p><em>Publication as a Working Group Note does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. </em></p>
<p>This document was produced as part of the <a
href="http://www.w3.org/2001/sw/WebOnt/">Web Ontology Working
Group's</a> effort to develop the <a
href="http://www.w3.org/TR/owl-features">OWL Web Ontology
Language</a>. It is <em>not</em> part of the OWL language
specification, but contains additional non-normative information which
the Working Group expects will be useful to some users.</p>
<p>The author and the Working Group welcome comments on this document,
but do not guarantee a reply or any further action. Please send
comments to <a
href="mailto:public-webont-comments@w3.org">public-webont-comments@w3.org</a>
(<a
href="http://lists.w3.org/Archives/Public/public-webont-comments/">public
archive</a>). </p>
<p>The Web Ontology Working Group is part of the <a
href="http://www.w3.org/2001/sw/">W3C Semantic Web Activity</a> (<a
href="http://www.w3.org/2001/sw/Activity">Activity Statement</a>, <a
href="http://www.w3.org/2001/sw/WebOnt/charter">Group
Charter</a>).</p>
<p>The W3C maintains a list of <a
href="http://www.w3.org/2001/sw/WebOnt/discl" rel="disclosure">any
patent disclosures related to this work</a>.</p>
</div>
<h2 id="toc">Table of Contents</h2>
<ul class="toc">
<li>1. <a href="#sec-intro">Introduction</a>
</li>
<li>2. <a href="#sec-rdf">OWL in RDF</a>
<ul class="toc">
<li>2.1 <a href="#subsec-errors">Errors</a></li>
</ul>
</li>
<li>3. <a href="#sec-implementation">Parser Implementation</a>
<ul class="toc">
<li>3.1 <a href="#subsec-streaming">Streaming vs. non-streaming</a></li>
<li>3.2 <a href="#subsec-named">Named Objects</a></li>
<li>3.3 <a href="#subsec-axioms">Axioms</a></li>
<li>3.4 <a href="#subsec-lists">Translating Lists</a></li>
<li>3.5 <a href="#subsec-descriptions">Translating Class Descriptions</a></li>
<li>3.6 <a href="#subsec-data">Translating Data Ranges</a></li>
<li>3.7 <a href="#subsec-structure-sharing">Structure Sharing</a></li>
<li>3.8 <a href="#subsec-everything-else">Everything Else</a></li>
</ul>
</li>
<li>4. <a href="#sec-error-recovery">Error Recovery</a></li>
<li><a href="#sec-references">References</a></li>
</ul>
<hr />
<h2 id="sec-intro">1 Introduction</h2>
<p>An OWL-RDF parser takes an RDF/XML file and attempts to construct
an OWL ontology that corresponds to the triples represented in the
RDF. This document describes a basic strategy that could be used in such a
parser. Note that this is not intended as a complete specification,
but hopefully provides enough information to point the way towards how
one would build a parser that will deal with a majority of (valid) OWL
ontologies.</p>
<p>For example, we do not discuss the implementation or handling of
<code>owl:imports</code> here, nor do we address in depth issues
concerned with spotting some of the more obscure violations of the
DL/Lite rules.</p>
<p>The scope of this discussion is OWL DL and OWL Lite, and the
procedure described below is targeted primarily at parsing OWL DL
ontologies. For example, whenever
<code>rdfs:subPropertyOf</code> is used, OWL DL requires that the
subject and object of the triple have corresponding types (e.g. both
are either <code>owl:ObjectProperty</code> or
<code>owl:DatatypeProperty</code>). If this is not the case, the
parser will raise an error. An OWL Full parser should allow this (but
it is not necessarily clear what the corresponding abstract syntax for
such a construct would be).</p>
<h2 id="sec-rdf">2 OWL in RDF</h2>
<p>The OWL Semantics and Abstract Syntax [<a
href="#ref-owl-semantics">OWL S&amp;AS</a>] document provides a
characterisation of OWL ontologies in terms of an abstract
syntax. This is a high level description of the way in which we can
define the characteristics of classes and properties.</p>
<p>In addition, S&amp;AS gives a mapping to RDF triples. This tells us
how such an abstract description of an OWL ontology can be transformed
to a collection of RDF triples (which can then be represented in a
concrete fashion using, for example RDF/XML). </p>
<p><a name="ambiguity"></a>In order to parse an OWL-RDF file into some
structure closer to the abstract syntax we need to reverse this
mapping, i.e. determine what the class and property definitions were
that lead to those particular triples. Note that this reverse mapping
is not necessarily unique. For example, the following two ontology
fragments:</p>
<pre class="abstract">
Class( a )
Class( b )
SubClassOf( b a )
</pre>
<p>and</p>
<pre class="abstract">
Class( a )
Class( b partial a )
</pre>
<p>both give rise to the same collection of triples under the mapping:</p>
<pre class="code">
a rdf:type owl:Class
b rdf:type owl:Class
b rdfs:subClassOf a
</pre>
<p>For many purposes, e.g. species validation, this is not necessarily
a problem. For other situations, e.g. where an editing tool is being
used, we would at least expect a parser to be consistent in the
strategy it employed to produce abstract syntax descriptions.</p>
<p>An arbitrary RDF graph may not necessarily correspond to an OWL
Lite or DL ontology. In other words, there may not be an OWL Lite or
DL ontology which when transformed using the mapping produces the
given graph. This is what a species validator attempts to determine:
if such an ontology exists. A parser (as described here) will go one
step further and actually attempt to construct such an ontology. </p>
<h3 id="subsec-errors">2.1 Errors</h3>
<p>There are, in general, two ways in which an RDF graph may fail to
correspond to an OWL [Lite|DL] ontology.</p>
<ol>
<!--
<li>There does not exist an OWL ontology in abstract syntax form that
maps to the given triples.</li>
<li>There is an ontology in abstract syntax form that maps to the
triples, but the ontology violates some of the restrictions for
membership of the OWL [Lite|OWL] subspecies.</li>
-->
<li>There is an OWL Lite or DL ontology in abstract syntax form which
maps to a superset of the given triples but some of the triples have
been forgotten and are not in the graph.</li>
<li>The ontologies in abstract syntax form that map to the triples or
any superset of the triples violate some of the restrictions for
membership of the OWL Lite or DL subspecies. (This includes the case
where there are no such ontologies).</li>
</ol>
<p>We might (loosely) describe the first as <em>external</em> errors,
and the second as <em>internal</em> errors. Examples of
<em>external</em> errors include:</p>
<ul>
<li>Using a URI reference in an <code>owl:Class</code> context
(e.g. as the object of an <code>owl:someValuesFrom</code> property
whose subject is an <code>owl:Restriction</code> which has an
<code>owl:onProperty</code> property with an
<code>owl:ObjectProperty</code> as its object) without explicitly
including a statement that the URI reference is an
<code>owl:Class</code> or <code>owl:Restriction</code>. The AS&amp;S
requires that all such usages are given an explicit typing. </li>
<li>Using a malformed <code>owl:Restriction</code>, e.g. missing an
<code>owl:onProperty</code> property.</li>
<li>Using the wrong vocabulary, e.g. <code>rdf:Property</code> instead
of the more specific <code>owl:ObjectProperty</code> and
<code>owl:DatatypeProperty</code>.</li>
<li>Violation of rules concerning structure sharing (see <a
href="#subsec-structure-sharing">below</a>).</li>
</ul>
<p>Once we have an ontology in abstract form, we can then check for
internal errors. For example, there are restrictions on the
expressiveness that can be used in OWL Lite (no unions or enumerations
and limited cardinality restrictions). The Lite and DL subspecies also
have a constraint that effectively says that the collections of URI
references of classes, individuals and properties must be
disjoint. Thus in OWL Lite and DL we can not use metamodelling devices
such as <em>classes as instances</em>.
</p>
<h2 id="sec-implementation">3 Parser Implementation</h2>
<p>The following discussion assumes that we have some implementation
of a data structure representing the ontology which is close to the
abstract syntax description (something along the lines of our proposed
<a href="http://owl.man.ac.uk/api.shtml">OWL API</a>). We do not
discuss the details of such an implementation here &mdash; hopefully
the meaning of actions such as <em>add a class x</em> or <em>set the
functional flag on a property</em> will be clear.</p>
<h3 id="subsec-streaming">3.1 Streaming vs. non-streaming</h3>
<p>Many XML parsers operate in a <em>streaming</em> fashion &mdash;
elements are reported to the parser as they are encountered during the
parse, and the file is processed incrementally. It is difficult to do
this when parsing RDF models (or at least when performing a task such
as producing an abstract syntax representation of an OWL ontology from
a given RDF/XML file). The problem is that we have no guarantee of the
order in which the triples in the graph are processed (and thus
reported by the streaming parser). A particular syntactic construct
may actually be split across several locations in the RDF file. In
order to parse in a streaming fashion, we may have to make note of
triples encountered earlier on and then come back to process them
later. As a concrete example of this, consider a situation where an
<code>owl:AnnotationPRoperty</code> is used to make an annotation
about a particular individual:</p>
<pre class="abstract">
AnnotationProperty( hasName )
Individual( fred hasName "Frederick" )
</pre>
<p>This results in the triples:</p>
<pre class="code">
[1] hasName rdf:type owl:AnnotationProperty
[2] fred hasName "Frederick"
</pre>
<p>If we encounter <code>[1]</code> before <code>[2]</code> during the
parse, we know that the property is an annotation property, and can
thus process <code>[2]</code> as an annotation. If, however, we
encounter <code>[2]</code> first, we do not know whether to process
<code>[2]</code> as an annotation or a value on the individual. As
there is no way of knowing whether or not
<code>[1]</code> will occur until we have seen all the triples, we
must wait until we have seen all triples before processing
<code>[2]</code>.</p>
<p>Because of this, our strategy is that the parser does not attempt
to process <em>anything</em> until all triples are available. Although
it may be possible to process some information in a streaming manner,
it reduces the conceptual complexity of the parser if we first collect
the triples then process them. Note that this has ramifications on the
resources that will be required when parsing &mdash; when parsing
large RDF graphs, large amounts of memory may be needed.</p>
<!--
<p>If we are interested in detecting OWL DL ontologies, there are some
things that <em>can</em> be done during the collection of triples
&mdash; for example any node with <code>rdf:type</code>
<code>owl:Restriction</code> must be a bnode. Thus if we encounter a
triple:</p>
<pre class="code">
x rdf:type owl:Restriction
</pre>
<p>where <code>x</code> is not a bnode, the triples cannot be the result
of a transformation of an OWL Lite or DL ontology. </p>
-->
<p>We assume that while parsing we have access to the objects in
the ontology already created, e.g.. if an ObjectProperty
<code>p</code> has been introduced we can get access to it. When we
refer to, for example, <em>the ObjectProperty <code>p</code></em>, we
mean the ObjectProperty that has been defined with name
<code>p</code>.
</p>
<p>In addition, we assume that we can query the RDF graph to determine
the presence or absence of particular arcs (e.g. precisely the kind of
functionality provided by an RDF API such as <a
href="http://www.hpl.hp.com/semweb/jena.htm">Jena</a>).</p>
<h4 id="subsubsec-using-triples">Using Triples</h4>
<p>While processing the graph, we keep a record of any triples that
have been <em>used</em> in the translation. For example, if there is a
triple:</p>
<pre class="code">
x rdf:type owl:Class
</pre>
<p>which results in the introduction of a class <code>x</code>.</p>
<pre class="abstract">
Class( c )
</pre>
<p>then we consider that triple to have been <em>used</em>.</p>
<h3 id="subsec-named">3.2 Named Objects</h3>
<p>We first identify the name classes and properties
that make up the ontology.</p>
<h4 id="subsubsec-classes">Classes</h4>
<p>For any <strong>non-bnode</strong> <code>x</code> in the graph
s.t. there is a triple:</p>
<pre class="code">
x rdf:type owl:Class
</pre>
<p>introduce a new class <code>x</code>.</p>
<pre class="abstract">
Class( c )
</pre>
<p>We will refer to any such classes that have been introduced in
this manner as <em>named classes</em>.</p>
<h4 id="subsubsec-properties">Properties</h4>
<p>Properties should all be introduced with an explicit type.</p>
<h5>ObjectProperty</h5>
<p>For any node <code>p</code> in the graph where there is one of the
following triples: </p>
<pre class="code">
p rdf:type owl:ObjectProperty
p rdf:type owl:TransitiveProperty
p rdf:type owl:InverseFunctionalProperty
p rdf:type owl:SymmetricProperty
</pre>
<p>introduce a new ObjectProperty <code>p</code>.</p>
<pre class="abstract">
ObjectProperty( p )
</pre>
<p>In addition, if any of the latter three triples are present, the
appropriate flag should be set on the property, e.g.:</p>
<pre class="abstract">
ObjectProperty( p Transitive )
</pre>
<p>If there is also a triple of the form:</p>
<pre class="code">
p rdf:type FunctionalProperty
</pre>
<p>then the property should be set as functional.</p>
<p>For any object property <code>p</code> dealt with as
above, there may also be an (optional) triple:</p>
<pre class="code">
p rdf:type rdf:Property
</pre>
<h5>DatatypeProperty</h5>
<p>For any node <code>p</code> in the graph where there is a triple: </p>
<pre class="code">
q rdf:type owl:DatatypeProperty
</pre>
<p>introduce a new DatatypeProperty <code>q</code>:</p>
<pre class="abstract">
DatatypeProperty( q )
</pre>
<p>If there is also a triple of the form:</p>
<pre class="code">
q rdf:type FunctionalProperty
</pre>
<p>then the property should be set as functional.</p>
<p>For any data property <code>p</code>
dealt with as above, there may also be an (optional) triple:</p>
<pre class="code">
p rdf:type rdf:Property
</pre>
<h5>AnnotationProperty</h5>
<p>For any node <code>a</code> in the graph where there is a triple: </p>
<pre class="code">
a rdf:type owl:AnnotationProperty
</pre>
<p>introduce a new AnnotationProperty <code>a</code>.</p>
<pre class="abstract">
AnnotationProperty( a )
</pre>
<p>For any annotation property <code>p</code> dealt with as above,
there may also be an (optional) triple:</p>
<pre class="code">
p rdf:type rdf:Property
</pre>
<h4 id="subsubsec-datatypes">Datatypes</h4>
<p>For any node <code>d</code> in the graph where there is a triple: </p>
<pre class="code">
d rdf:type rdfs:Datatype
</pre>
<p>introduce a new Datatype <code>d</code>.</p>
<pre class="abstract">
Datatype( d )
</pre>
<p>There may also be an (optional) triple:</p>
<pre class="code">
d rdf:type rdfs:Class
</pre>
<!-- <h3>Individuals</h3>
<p>For any triples of the form:</p>
<pre class="code">
x rdf:type c
</pre>
<p>where <code>c</code> is not part of the reserved vocabulary
(e.g. it's not in the <code>owl</code>, <code>rdf</code> or
<code>rdfs</code> namespaces), add a new fact:</p>
<pre class="abstract">
Individual( x type( ct ) )
</pre>
<p>where <code>ct</code> is the translation of the node <code>c</code>
to a class expression.</p> -->
<h3 id="subsec-axioms">3.3 Axioms</h3>
<p>Now that the named classes and properties have been identified, we
can determine the axioms that have been asserted.</p>
<h4 id="subsubsec-property-axioms">Property Axioms</h4>
<p>Property axioms assert characteristics of properties.</p>
<h5>Domain</h5>
<p>For any triples of the form:</p>
<pre class="code">
p rdfs:domain d
</pre>
<p><a href="#subsec-descriptions">translate</a> <code>d</code> to a
class description, and add the resulting class description to the
domains of the property <code>p</code>. If <code>p</code> is not a
property, raise an error.</p>
<h5>Range</h5>
<p>For any triples of the form:</p>
<pre class="code">
p rdfs:range r
</pre>
<p>if <code>p</code> is an ObjectProperty, then <a
href="#subsec-descriptions">translate</a>
<code>r</code> to a class description, and add the resulting class
description to the ranges of the property <code>p</code>. If
<code>p</code> is a data property, convert <code>r</code> to a
<a href="#subsec-data">data range</a> and add the result to the ranges of the property.</p>
<h5>subProperty &amp; equivalentProperty</h5>
<p>For any triples of the form:</p>
<pre class="code">
p rdfs:subPropertyOf q
</pre>
<p>or</p>
<pre class="code">
p owl:equivalentProperty q
</pre>
<p>first check that either:</p>
<ol>
<li><code>p</code> and <code>q</code> are ObjectProperties;
<br/>or</li>
<li><code>p</code> and <code>q</code> are DatatypeProperties.</li>
</ol>
<p>If so, add an axiom asserting that
<code>q</code> is a superproperty or equivalent property of
<code>p</code> as appropriate. If neither of the above are true, raise
an error.</p>
<h5>inverseOf</h5>
<p>For any triples of the form:</p>
<pre class="code">
p owl:inverseOf q
</pre>
<p>Check that <code>p</code> and <code>q</code> are
ObjectProperties. If not, raise an error. If so, add <code>q</code>
to the collection of inverses of <code>p</code>.</p>
<h4 id="subsubsec-class-definitions">Class Definitions</h4>
<p>We have to deal with any class definitions that occur in the
ontology. For example, the following RDF fragment:</p>
<pre class="code">
&lt;class rdf:about="#a"&gt;
&lt;intersectionOf rdf:parseType="Collection"&gt;
&lt;class rdf:about="#b"/&gt;
&lt;class rdf:about="#c"/&gt;
&lt;/intersectionOf&gt;
&lt;/class&gt;
</pre>
<p>arises when a class <code>a</code> has been given a complete
definition involving an intersection.</p>
<p>For any named class <code>x</code>, do the following.</p>
<ul>
<li>
<p>For all triples:</p>
<pre class="code">
x owl:oneOf l
</pre>
<p><code>l</code> should be a node representing a <a
href="#subsec-lists">list</a> of named individuals (e.g. URI references). Add
the axiom:</p>
<pre class="abstract">
Class( x complete oneOf(i<span><sub>1</sub></span> i<span><sub>2</sub></span>...i<span><sub>n</sub></span>) )
</pre>
<p>where <code>i<span><sub>1</sub></span> i<span><sub>2</sub></span> ... i<span><sub>n</sub></span></code> are
the individuals in the list <code>l</code>. If <code>l</code> is not a
list (of named individuals), raise an error.</p>
</li>
<li>
<p>For all triples:</p>
<pre class="code">
x owl:intersectionOf l
</pre>
<p><code>l</code> should be a node representing a <a
href="#subsec-lists">list</a> of class descriptions. Add the axiom:</p>
<pre class="abstract">
Class( x complete lt<span><sub>1</sub></span> lt<span><sub>2</sub></span>...lt<span><sub>n</sub></span> )
</pre>
<p>where <code>lt<span><sub>1</sub></span> lt<span><sub>2</sub></span>
... lt<span><sub>n</sub></span></code> are the translated descriptions
in the list <code>l</code>. If <code>l</code> is not a list (of class
descriptions), raise an error.</p> </li>
<li>
<p>For all triples:</p>
<pre class="code">
x owl:unionOf l
</pre>
<p><code>l</code> should be a node representing a <a
href="#subsec-lists">list</a> of class descriptions. Add the axiom:</p>
<pre class="abstract">
Class( x complete unionOf(lt<span><sub>1</sub></span> lt<span><sub>2</sub></span>...lt<span><sub>n</sub></span>) )
</pre>
<p>where <code>lt<span><sub>1</sub></span> lt<span><sub>2</sub></span>
... lt<span><sub>n</sub></span></code> are the translated descriptions
in the list <code>l</code>. If <code>l</code> is not a list (of class descriptions), raise an
error.</p>
</li>
<li>
<p>For all triples:</p>
<pre class="code">
x owl:complementOf n
</pre>
<p><code>n</code> should be a node representing a class
description. Add the axiom:</p>
<pre class="abstract">
Class( x complete complementOf( nt ) )
</pre>
<p>where <code>nt</code> is the translation of <code>n</code>. If
<code>nt</code> is not a class description, raise an error.</p> </li>
</ul>
<h4 id="subsubsec-class-axioms">Class Axioms</h4>
<p>Class axioms can provide relationships and characteristics of
arbitrary class descriptions.</p>
<h5>SubClass</h5>
<p>For all triples of the form:</p>
<pre class="code">
c rdfs:subClassOf d
</pre>
<p>add a new axiom:</p>
<pre class="abstract">
SubClassOf( ct dt )
</pre>
<p>where <code>ct</code> is the translation of <code>c</code> to a
class description, and <code>dt</code> the translation of
<code>d</code>. If <code>c</code> is a named class, then due to
the <a href="#ambiguity">ambiguity</a> of the reverse mapping, an
alternative here is to include the assertion as part of the definition
of the class and add the axiom:</p>
<pre class="abstract">
Class( c partial dt )
</pre>
<p>to the ontology. Note that in this case, if the class already has a
partial description in the ontology, e.g. there is an axiom:</p>
<pre class="abstract">
Class( c partial e<span><sub>1</sub> </span>e<span><sub>2</sub></span>...e<span><sub>n</sub></span> )
</pre>
<p>then we can simply add <code>dt</code> to this axiom to get:</p>
<pre class="abstract">
Class( c partial e<span><sub>1</sub> </span>e<span><sub>2</sub></span>...e<span><sub>n</sub></span> dt )
</pre>
<p>rather than introducing a new axiom.</p>
<h5>EquivalentClass</h5>
<p>See <a href="#equivalentClass">below</a>.</p>
<h5>DisjointClass</h5>
<p>See <a href="#disjointClass">below</a>.</p>
<h4 id="subsubsec-individual-axioms">Individual Axioms</h4>
<p>Individual axioms assert relationships about the equality and
inequality of individuals.</p>
<h5>Same</h5>
<p>For all triples of the form:</p>
<pre class="code">
x owl:sameAs y
</pre>
<p>where <code>x</code> and <code>y</code> are individualIDs, add
individuals <code>x</code> and <code>y</code> (if necessary) and an
axiom:</p>
<pre class="abstract">
SameIndividual( x y )
</pre>
<h5>Different</h5>
<p>For all triples of the form:</p>
<pre class="code">
x owl:differentFrom y
</pre>
<p>where <code>x</code> and <code>y</code> are individualIDs, add
individuals <code>x</code> and <code>y</code> (if necessary) and an
axiom:</p>
<pre class="abstract">
DifferentIndividuals( x y )
</pre>
<h5>AllDifferent</h5>
<p>For all triples of the form:</p>
<pre class="code">
x rdf:type owl:AllDifferent
</pre>
<p>where <code>x</code> is a bnode, there should also be a triple:</p>
<pre class="code">
x owl:distinctMembers l
</pre>
<p>where <code>l</code> is a <a href="#subsec-lists">list</a>. Add an
axiom:</p>
<pre class="abstract">
DifferentIndividuals( i<span><sub>1</sub></span> i<span><sub>2</sub></span>...i<span><sub>n</sub></span> )
</pre>
<p>where <code>i<span><sub>1</sub></span> i<span><sub>2</sub></span> ... i<span><sub>n</sub></span></code> are
the individuals in the list <code>l</code>. If <code>l</code> is not a
list (of named individuals), <code>x</code> is not a bnode or the
<code>owl:distinctMembers</code> triple is missing, raise an
error.</p>
<h3 id="subsec-lists">3.4 Translating Lists</h3>
<p>Lists are used in a number of places in OWL ontologies: for example
to represent the arguments of boolean expressions or the individuals
listed in an enumeration (oneOf). For the purposes of producing a OWL
ontology, order is not particularly important &mdash; the order of the
operands in an intersection or union does not alter their semantics,
so for simplicitly, we consider converting a node representing a list
to a set of nodes. Lists are thus handled using the following simple
recursive procedure.</p>
<p>The node <code>rdf:nil</code> is translated to the empty set.</p>
<p>For a node <code>l</code> s.t. there is a triple:</p>
<pre class="code">
l rdf:type rdf:List
</pre>
<p>find the node <code>r</code> s.t. there is a triple:</p>
<pre class="code">
l rdf:rest r
</pre>
<p>If such a node does not exist, or there are are multiple nodes
which are the objects of such triples, raise an error. The node
<code>r</code> should be a list node itself. Convert this node to a
set of nodes <code>rs</code>. Now find the node s.t. there is a
triple:</p>
<pre class="code">
l rdf:first f
</pre>
<p>Again, there should be a single such node &mdash; if not, raise an
error. Return the result of adding this node to the set
<code>rs</code>.</p>
<p>For cases where we expect a list of class descriptions, we do the
obvious thing, e.g. convert to a collection of nodes, then <a
href="#subsec-descriptions">translate</a> each node using the
procedure described below. </p>
<p>For any node <code>l</code> which is used as a list (e.g. as the
subject of a <code>rdf:first</code> or <code>rdf:rest</code>, the
object of a <code>rdf:rest</code>, or in a place where a list is
expected, there may be an (optional) triple:</p>
<pre class="code">
l rdf:type rdf:List
</pre>
<p>Circular lists are forbidden. If we have:</p>
<pre class="code">
l rdf:rest r
</pre>
<p>and we encounter the node <code>l</code> used as the object of an
<code>rdf:rest</code> triple while translating
<code>r</code>, then an error should be raised.</p>
<h3 id="subsec-descriptions">3.5 Translating Class Decriptions</h3>
<p>If a node is used in particular contexts (e.g. as the subject or
object of an <code>owl:subClassOf</code> triple) then we know that the
node is intended to represent a class expression. In order to handle
this, we define a procedure which takes a node in the RDF graph and
yields a class expression.</p>
<p>If <code>n</code> is a named class, then return <code>n</code>.</p>
<p>If this is not the case, <code>n</code> must be the subject of the
subject of an
<code>rdf:type</code> triple with object
<code>owl:Restriction</code> or be the subject of exactly one triple
involving <code>owl:oneOf</code>,
<code>owl:intersectionOf</code>, <code>owl:unionOf</code>,
<code>owl:complementOf</code>. If not, raise an error.</p>
<p>The node may also be the subject of triple:</p>
<pre class="code">
n rdf:type owl:Class
</pre>
<p>or</p>
<pre class="code">
n rdf:type rdfs:Class
</pre>
<p>Translation then proceeds on a case-analysis of the particular
triple found. </p>
<ul>
<li>
<p>If there is a triple:</p>
<pre class="code">
n rdf:type owl:Restriction
</pre>
<p>then <code>n</code> needs to be translated as a restriction. There
should be now be exactly one triple:</p>
<pre class="code">
n owl:onProperty p
</pre>
<p>where <code>p</code> is an ObjectProperty or DatatypeProperty. If
not, raise an error. In addition, <code>n</code> should be the subject
of exactly one triple involving <code>owl:minCardinality</code>,
<code>owl:maxCardinality</code> or
<code>owl:cardinality</code>, <code>owl:someValuesFrom</code>,
<code>owl:allValuesFrom</code> or <code>owl:hasValue</code>. If not,
raise an error. Translation then again proceeds on a case-analysis of
the type of the property and the triple it is involved in.</p>
<ul>
<li>
<pre class="code">
n owl:cardinality k
</pre>
<p>Return a cardinality restriction
whose numerical value is the non negative integer which should be the
object of the cardinality triple, e.g.:</p>
<pre class="abstract">
restriction( p cardinality( k ) )
</pre>
</li>
<li>
<pre class="code">
n owl:minCardinality k
</pre>
<p>Return a cardinality restriction
whose numerical value is the non negative integer which should be the
object of the cardinality triple, e.g.:</p>
<pre class="abstract">
restriction( p minCardinality( k ) )
</pre>
</li>
<li>
<pre class="code">
n owl:maxCardinality k
</pre>
<p>Return a cardinality restriction
whose numerical value is the non negative integer which should be the
object of the cardinality triple, e.g.:</p>
<pre class="abstract">
restriction( p maxCardinality( k ) )
</pre>
</li>
<li>
<pre class="code">
n owl:someValuesFrom v
</pre>
<p>If <code>p</code> is an ObjectProperty, return:</p>
<pre class="abstract">
restriction( p someValuesFrom ( vt ) )
</pre>
<p>where <code>vt</code> is the translation of v to a class
description. If <code>p</code> is a DatatypeProperty, then return:</p>
<pre class="abstract">
restriction( p someValuesFrom ( vdt ) )
</pre>
<p>where <code>vdt</code> is the translation of v to a <a href="#subsec-data">data range</a>.</p>
</li>
<li>
<pre class="code">
n owl:allValuesFrom v
</pre>
<p>If <code>p</code> is an ObjectProperty, return:</p>
<pre class="abstract">
restriction( p allValuesFrom ( vt ) )
</pre>
<p>where <code>vt</code> is the translation of v to a class
description. If <code>p</code> is a DatatypeProperty, then return:</p>
<pre class="abstract">
restriction( p allValuesFrom ( vdt ) )
</pre>
<p>where <code>vdt</code> is the translation of v to a <a href="#subsec-data">data range</a>.</p>
</li>
<li>
<pre class="code">
n owl:hasValue v
</pre>
<p>If <code>p</code> is an ObjectProperty, return:</p>
<pre class="abstract">
restriction( p value ( v ) )
</pre>
<p>where <code>v</code> is translation of v as an individual. If
<code>p</code> is a DatatypeProperty, then return:</p>
<pre class="abstract">
restriction( p value ( vdt ) )
</pre>
<p>where <code>vdt</code> is the translation of v as a data value.</p>
</li>
</ul>
</li>
<li>
<p>If there is a triple:</p>
<pre class="code">
n owl:oneOf l
</pre>
<p>then <code>l</code> should be a <a href="#subsec-lists">list</a> of named
individuals (e.g. URI references). Return:</p>
<pre class="abstract">
oneOf(i<span><sub>1</sub></span> i<span><sub>2</sub></span>...i<span><sub>n</sub></span>)
</pre>
<p>where <code>i<span><sub>1</sub></span> i<span><sub>2</sub></span>
... i<span><sub>n</sub></span></code> are the individuals in the list
<code>l</code>. If <code>l</code> is not a list (of named
individuals), raise an error.</p>
</li>
<li>
<p>If there is a triple:</p>
<pre class="code">
n owl:intersectionOf l
</pre>
<p>return:</p>
<pre class="abstract">
intersectionOf( lt<span><sub>1</sub></span> lt<span><sub>2</sub></span>...lt<span><sub>n</sub></span> )
</pre>
<p>where <code>lt<span><sub>1</sub></span> lt<span><sub>2</sub></span>
... lt<span><sub>n</sub></span></code> are the translated descriptions
in the list <code>l</code>. If <code>l</code> is not a list, raise an
error.</p>
</li>
<li>
<p>If there is a triple:</p>
<pre class="code">
n owl:unionOf l
</pre>
<p>return:</p>
<pre class="abstract">
unionOf( lt<span><sub>1</sub></span> lt<span><sub>2</sub></span>...lt<span><sub>n</sub></span> )
</pre>
<p>where <code>lt<span><sub>1</sub></span> lt<span><sub>2</sub></span>
... lt<span><sub>n</sub></span></code> are the translated descriptions
in the list <code>l</code>. If <code>l</code> is not a list, raise an
error.</p>
</li>
<li>
<p>If there is a triple:</p>
<pre class="code">
n owl:complementOf m
</pre>
<p>return:</p>
<pre class="abstract">
complementOf( mt )
</pre>
<p>where <code>mt</code> is the translation of <code>m</code> as a
class description.</p>
</li>
</ul>
<h3 id="subsec-data">3.6 Translating Data Ranges</h3>
<p>If <code>n</code> is an XML schema data type or
<code>rdf:XMLLiteral</code>, then return that type.</p>
<p>If <code>n</code> is a datatype introduced as <a href="#subsubsec-datatypes">above</a>,
then return that datatype.</p>
<p>If <code>n</code> is a blank node and there is a triple:</p>
<pre class="code">
n owl:oneOf l
</pre>
<p>then <code>l</code> should be a <a href="#subsec-lists">list</a> of
data values. Return:</p>
<pre class="abstract">
oneOf(d<span><sub>1</sub></span> d<span><sub>2</sub></span>...d<span><sub>n</sub></span>)
</pre>
<p>where <code>d<span><sub>1</sub></span> d<span><sub>2</sub></span>
... d<span><sub>n</sub></span></code> are the data values in the list
<code>l</code>. If <code>l</code> is not a list, raise an error.</p>
<h3 id="subsec-structure-sharing">3.7 Structure Sharing</h3>
<p>[<a href="#ref-owl-semantics">OWL S&amp;AS</a>] includes the
following comment relating to translation from abstract syntax to RDF
graphs:</p>
<p style='margin-left:50px;margin-right:50px'><em>
For many directives these transformation rules call for the
transformation of components of the directive using other
transformation rules. When the transformation of a component is used
as the subject, predicate, or object of a triple, even an optional
triple, the transformation of the component is part of the production
(but only once per production) and the main node of that
transformation should be used in the triple.</em>
</p>
<p>In practice, this means that blank nodes (i.e. those with no name)
which are produced during the transformation and represent arbitrary
expressions in the abstract syntax form should not be "re-used".</p>
<p>Consider the following example:</p>
<pre class="abstract">
Class(A partial intersectionOf(C D))
</pre>
<p>In this case, translation to an RDF graph would result in a blank
node representing the intersection of C and D. This would then be used
as the object of a <code>rdfs:subClassOf</code> triple with
<code>A</code> as subject.</p>
<p>Now consider if the ontology also included a second axiom as below.</p>
<pre class="abstract">
Class(A partial intersectionOf(C D))
Class(B partial intersectionOf(C D))
</pre>
<p>In this case, we are <strong>not</strong> allowed to "re-use" the
blank node, but must instead produce a new node to represent the
intersection being used in the definition of <code>B</code>, even
though the expressions are identical.</p>
<p>There are, however, two cases where a blank node corresponding to
an expression can be used in more than one place &mdash; when the
translation results from an <code>EquivalentClasses</code> or
<code>DisjointClasses</code> axiom. These are discussed in more detail
below.</p>
<p>In order to check whether an RDF graph corresponds to an OWL
[Lite|DL] ontology, we must check that the rules for structure sharing
have not been violated. We describe strategies for doing
this.</p>
<h4 id="subsubsec-marking-used-blank-nodes">Marking Used Blank Nodes</h4>
<p>We keep track of all the blank nodes that have been <em>used</em> during
the parsing process. Effectively, this means that whenever we see a
blank node that occurs as the object of a triple involving
<code>owl:complementOf</code>, <code>rdf:type</code>,
<code>owl:someValuesFrom</code>, <code>owl:allValuesFrom</code> or <code>rdfs:subClassOf</code>, occurs as a value in a list which is the object of an
<code>owl:intersectionOf</code> or <code>owl:unionOf</code>, or occurs
as the subject of a triple involving
<code>rdfs:subClassOf</code>, we first check to see whether the node
has been <em>used</em>. If so, then structure sharing has occurred and
the ontology is <strong>not</strong> in DL. If not, then we mark the
node as <em>used</em> and carry on. Processing
<code>owl:equivalentClass</code> and
<code>owl:disjointWith</code> triples is slightly more complicated as
the mapping rules permit us to share structure in particular ways.</p>
<h5><a name="equivalentClass"></a>EquivalentClass</h5>
<p>In general, an equivalence axiom</p>
<pre class="abstract">
EquivalentClasses( D<span><sub>1</sub></span> D<span><sub>2</sub></span>...D<span><sub>n</sub></span> )
</pre>
<p>is translated to a collection of nodes, one for each expression in
the equivalence, and a number of <code>owl:equivalentClass</code>
triples between these nodes such that those triples form a connected
graph over the nodes. In other words, starting from any node in the
collection, we can get to any other node in the collection along a
path that only traverses <code>owl:equivalentClass</code> edges in
either direction.</p>
<p>In practice, this means that a blank node may participate in more
than one <code>owl:equivalentClass</code> triple (but note that it
cannot also participate in other triples).</p>
<p>A possible strategy for dealing with
<code>owl:equivalentClass</code> triples is as follows.</p>
<ol>
<li>Collect all <code>owl:equivalentClass</code> triples that occur in
the graph. </li>
<li>Partition the nodes that occur in these triples into sets, where
each set consists of connected blank nodes and URI references
connected to them, or pairs of URI references: if <code>n</code> and
<code>m</code> are in a set, there is a path between them consisting
only of <code>owl:equivalentClass</code> edges.</li>
<li>For each set of nodes <code>n<span><sub>1</sub></span>
n<span><sub>2</sub></span>...n<span><sub>n</sub></span></code>, add an
equivalence axiom:
<pre class="abstract">
EquivalentClasses( tn<span><sub>1</sub></span>tn<span><sub>2</sub></span>...tn<span><sub>n</sub></span> )
</pre>
where <code>tn<span><sub>i</sub></span></code> is the translated
description of <code>n<span><sub>i</sub></span></code>. In addition,
if any of the <code>n<span><sub>i</sub></span></code> are blank nodes,
check that they have not been <em>used</em>. If they have, this is
<strong>not</strong> an OWL DL ontology. If they are not used, mark as
<em>used</em></li>
</ol>
<p>An improvement to this strategy is to attempt to identify the
situations where the <code>owl:equivalentClass</code> triple may have
come from a class definition (recall the <a
href="#ambiguity">ambiguity</a> of the mapping). To address this, if
any of the node sets have size 2, and have been produced because of a
single triple:</p>
<pre class="code">
c owl:equivalentClass d
</pre>
<p>where <code>c</code> is a named class, then we translate the
assertion as a definition of the class and add the axiom:</p>
<pre class="abstract">
Class( c complete dt )
</pre>
<p>to the ontology. In order to correctly parse OWL Lite ontologies,
this approach is essential, as it ensures that a situation such
as:</p>
<pre class="code">
c owl:equivalentClass _:a
_:a rdf:type owl:Restriction
_:a owl:onProperty p
_:a owl:minCardinality 0
</pre>
<p>is translated to a definition of the class rather than a class
axiom (the resulting axiom would <strong>not</strong> be permitted in
OWL Lite).</p>
<h5><a name="disjointClass"></a>DisjointClass</h5>
<p>The rules for <code>DisjointClasses</code> axioms tell us that an
axiom:</p>
<pre class="abstract">
DisjointClasses( D<span><sub>1</sub></span> D<span><sub>2</sub></span>...D<span><sub>n</sub></span> )
</pre>
<p>is translated to a collection of nodes, one for each expression in
the equivalence, and a number of <code>owl:disjointWith</code>
triples, such that every node in the collection is connected to every
other node by <em>at least</em> one triple (in either
direction). Again, this may lead to blank nodes being used in more
than one place.</p>
<p>A possible strategy for dealing with <code>owl:disjointWith</code>
triples is as follows:</p>
<ul>
<li>Collect all <code>owl:disjointWith</code> triples that occur in
the graph. </li>
<li>While there are blank nodes in the collection of nodes that we
have not already dealt with, do the following:
<ul>
<li>Pick a blank node from the collection of nodes involved in those
triples that we haven't already dealt with.</li>
<li>Gather together all the nodes <code>n<span><sub>1</sub></span>
n<span><sub>2</sub></span>...n<span><sub>n</sub></span></code> that
can be reached from
<code>n</code> via a path that consists of
<code>owl:disjointWith</code> triples, and which does not pass
<strong>through</strong> a named class node &mdash; in other words the
traversal stops when we reach a named node. Include <code>n</code> in
this collection.</li>
<li>In order for the graph to be in OWL DL, the subgraph formed from
these nodes considering <code>owl:disjointWith</code> edges must be
fully connected: every node must have an edge to every other node. If
this is not the case, the graph is not in DL.</li>
<li>Add a new disjoint axiom:
<pre class="abstract">
DisjointClasses( tn<span><sub>1</sub></span>tn<span><sub>2</sub></span>...tn<span><sub>n</sub></span>)
</pre>
where <code>tn<span><sub>i</sub></span></code> is the translated
description of <code>n<span><sub>i</sub></span></code>. In addition,
if any of the <code>n<span><sub>i</sub></span></code> are blank nodes,
check that they have not been <em>used</em>. If they have, this is
<strong>not</strong> an OWL DL ontology. If they are not used, mark as
<em>used</em>.</li>
</ul>
</li>
<li>For any remaining pairs of nodes related by a triple:
<pre class="code">
c owl:disjointWith d
</pre>
(where <code>c</code> and <code>d</code> must be URI references), if
the two nodes have not already been included in a single axiom
produced by the process above, introduce a new axiom:
<pre class="abstract">
DisjointClasses( ct dt )
</pre>
<!--where <code>ct</code> is the translation of <code>c</code> to a
class description, and <code>dt</code> the translation of
<code>d</code>.-->
</li>
</ul>
<h4 id="subsubsec-structure-sharing-tests">Tests for Structure Sharing</h4>
<p>There are a number of tests in the OWL Test Cases [<a
href="#ref-owl-tests">OWL Tests</a>] which are
designed to illustrate these issues, in particular:</p>
<ul>
<li><a href="http://www.w3.org/TR/owl-test/byFunction#function-disjointWith"><code>owl:disjointWith</code></a> tests.</li>
<li><a href="http://www.w3.org/TR/owl-test/byFunction#function-equivalentClass"><code>owl:equivalentClass</code></a> tests.</li>
</ul>
<h3 id="subsec-everything-else">3.8 Everything Else</h3>
<p>Once all the triples that relate to primitive object definitions
and axioms have been processed, (more or less) everything else is
assumed to be a fact relating to individuals. For all remaining
triples:</p>
<pre class="code">
x p y
</pre>
<p>the action taken depends on the type of <code>p</code>. If no
explicit type has been given for the property <code>p</code>, raise an
error.</p>
<p>If <code>p</code> is an annotation property, then add an
appropriate annotation to the object <code>x</code> (which should
correspond to a named class, property, datatype, ontology, individual
or unnamed ontology or individual).</p>
<p>If <code>p</code> is an ObjectProperty, assume that the subject and
object are individuals and add a fact:</p>
<pre class="abstract">
Individual( x value( p y ) )
</pre>
<p>If <code>p</code> is an DatatypeProperty, assume that the subject
is an individual and add a fact:</p>
<pre class="abstract">
Individual( x value( p dy ) )
</pre>
<p>where <code>dy</code> is the translation of <code>y</code> to a
literal value. </p>
<h2 id="sec-error-recovery">4 Error Recovery</h2>
<p>There are many cases in the above discussion where errors may be
raised &mdash; for example if properties are used without explicit
typing. Strictly speaking, an OWL DL or Lite parser could choose to
fail when encountering such situations. Of course, in practice, we
might expect parsers to be more resilient and be able to recover. So
for example, if the parser detects the following use of a property
<code>p</code>:</p>
<pre class="code">
x rdf:type owl:Thing
y rdf:type owl:Thing
x p y
</pre>
<p>it is reasonable to assume that the property <code>p</code> is
intended to be an <code>owl:ObjectProperty</code>. In this case, we
might expect the parser to <em>assume</em> that <code>p</code> is an
ObjectProperty and try and proceed with the parse (but would of course
warn the user about the assumption being made).</p>
<h2 id="sec-references">References</h2>
<dl>
<dt>[<a name="ref-owl-semantics" id="ref-owl-semantics"></a>OWL S&amp;AS]</dt>
<dd>
<a href="http://www.w3.org/TR/2003/PR-owl-semantics-20031215/">
<cite>OWL Web Ontology Language Semantics and Abstract Syntax</cite></a>
Peter F. Patel-Schneider, Patrick Hayes and Ian Horrocks, eds.
W3C Proposed Recommendation, 15 December 2003.
<br /><br />
</dd>
<dt>[<a name="ref-owl-tests" id="ref-owl-tests">OWL Tests</a>]</dt>
<dd>
<a href="http://www.w3.org/TR/2003/PR-owl-test-20031215/">
<cite>OWL Web Ontology Language Test Cases</cite></a>
Jeremy J. Carroll and Jos De Roo, eds.
W3C Proposed Recommendation, 15 December 2003.
<br /><br />
</dd>
</dl>
<hr/>
<div style="text-align:center;">
<a href="#toc">contents</a>
</div>
<p style="margin-top:-1em;">
<a href="http://validator.w3.org/check/referer">
<img src="http://www.w3.org/Icons/valid-xhtml10"
alt="Valid XHTML 1.0!" height="31" width="88" /></a>
</p>
</body>
</html>