[rdfweb-dev] Using FOAF and OWL Ontologies
ronwalf at volus.net
Fri Jul 15 21:25:03 UTC 2005
== Motivation ==
When creating new ontologies on the web, it's often useful to extend
other ontologies in order to promote more understanding between tools.
In the case extending of FOAF, using OWL as the extension language makes
sense, since FOAF is already using some of the expressive power of OWL.
Unfortunately, since FOAF makes only partial use of OWL (along with some
quirks), it is difficult for many OWL tools to understand the FOAF
ontology. Thus, it is necessary to process the FOAF ontology into a
== FOAF and OWL Issues ==
There are roughly two levels of issues that deter OWL tools from using
the FOAF ontology. The first of those are just syntactic issues, which
are relatively easy to fix. The rest are modeling issues, which require
=== Syntactic Differences ===
The syntactic issues with OWL compatibility are solely a matter of
missing triples. These involve properly typing properties and classes
so they're relatively easy to fix.
==== Labeling Classes ====
Classes in OWL need to be labeled as OWL:Class. Most tools understand
it enough when you use RDFS:Class, but it's good form (and less
warnings) to go ahead and label it.
==== Labeling Properties ====
Labeling properties is important to OWL tools - it tells them how to
handle the various uses of them. Some tools, like OWLApi, try to guess
the type of the property in the presence of instances, but can often get
it wrong otherwise.
The three main categories of properties are Annotation, Datatype, and
Annotation properties are usually meant to have extra-reasoning meaning,
and thus aren't dealt with by the standard tableaux algorithms.
'wot:assurance' is one such property, and 'foaf:membershipClass' is
Annotation properties are also properties that have to deal with
non-individuals (classes, properties, ontologies) that aren't in the
rdf, rdfs, or owl namespaces. dc:description and dc:date are examples
of these uses (at least as used in foaf).
Datatype properties deal with relating instances to literal values, such
as foaf:name is one such property.
Object properties relate instances to other instances, such as
foaf:knows and foaf:fundedBy.
One advantage of labeling the properties is that you can now drop the
range and domain restrictions that point to rdf:Resource or rdf:Literal.
=== Picking your OWL Level ===
OWL Full is a subset of first order logic, and is theoretically
implementable in reasoners like Vampire. However, to my knowledge, no
one has implemented all of it yet. Thus, depending on your tool set,
you may need to adjust the ontology.
==== Fitting into OWL-Full ====
Although FOAF is technically sitting in OWL-Full, the less you can be in
it, the better the tools can handle it. Thus, in the spirit of this,
these are changes that minimally effect the meaning of the foaf ontology.
The first change is to rip out the imports of the OWL and RDFS
ontologies. The owl ontology itself states:
We do not expect people to import this file
explicitly into their ontology. People that do import this file
should expect their ontology to be an OWL Full ontology.
There are valid reasons to import the OWL ontology, but they mostly deal
with extending OWL itself. Since FOAF isn't particularly extending the
language (foaf:membershipClass excluded), dropping the imports of owl
and rdfs is a painless change.
==== Down to OWL-DL ====
Going down to OWL-DL is a little bit more painful.
The least painful of these changes is removing the domains and ranges
that point to rdf:Resource. Since in the rdfs schema rdfs:Class is a
subclass of rdf:Resource, this means that any of these properties could
point to a class as well as an instance. Since this isn't the usual
intention (judgment call here), it's safe to either drop the restriction
since it can be inferred by the label of owl:ObjectProperty, or replace
the restriction with a pointer to owl:Thing.
Also, since annotation properties can't have ranges or domains, the
domain and range of foaf:membershipClass needs to be removed. It may be
that foaf:membershipClass should just be removed altogether, since it
can be more generally modeled with standard owl constructs.
A little bit bit more annoying is the subPropertyOf relationship between
foaf:name and rdfs:label. Since in OWL, rdfs:label is defined as an
annotation property, it can't have any sub properties. There is work in
reasoners such as Pellet to support this, but it isn't supported by the
standard. Thus, to be in OWL-DL, you need to drop this relationship.
Once it's dropped, it's safe to have foaf:name as an owl:ObjectProperty.
Finally, annoying as it is, owl:InverseFunctionalProperty is not
supported on datatype properties. Again, there is work going on to
support this, but it's more annoying to implement in a complete fashion
than annotation property relationships. So the IFP type needs to be
dropped on mbox_sha1sum and some of the foaf:nick sub properties.
Note that jabber (as xmpp) has a uri scheme (xmpp:), and thus probably
shouldn't be a sub property of foaf:nick as it's more similar to a
As a side-side rant, IFPs are useful for data merging, but make a lousy
system for identification (in the place of URIs). See the last two
months of comments dawg for example problems that arise:
==== Little bit more to OWL-Lite ====
Finally, if your system can only handle owl:Lite, then once you complete
the above changes, removing owl:disjointWith will put you into OWL-Lite.
== Automating the Changes ==
If you want to be compatible with various OWL tools, yet want to keep up
with recent changes to the foaf ontology, you need to automate the
processing of the spec.
In short, if you've identified which level of OWL that your application
needs, you can download foaf_cleaner.py at
and run it with '--level=<LEVEL>' where <LEVEL> is 'full', 'dl', or
'lite'. foaf_cleaner provides simple command line help with '--help'.
foaf_cleaner requires python 2.4 and rdflib 2.1, and is distributed
under the MIT license.
RDFLib output is a little rough, so you might want to run it through
your own rdf prettifier. Unfortunately, rdf unparsing is in a sad state
at the moment, and I wish there were more apis that facilitated custom
I've run the foaf spec through foaf_cleaner with '--level=dl --clean',
cleaned up the output with a devel copy of swoop, plus a couple of minor
hand edits to produce http://www.mindswap.org/2003/owl/foaf
which is used by a number of mindswap ontologies.
As a side note, it's not clear which copyright license applies to the
schema as it exists in rdf (there's no markup on index.rdf). I'll be
happy to shove in attribution markup.
As a side-side note, the foaf spec is not longer strict xhtml according
to the little icon link on the side of the page.
== Suggestions for the spec ==
Applying the syntactic changes, plus removing owl:imports of rdfs and
owl, plus changing the restrictions that point to rdf:Resource and
removing the domain and range of membershipClass would put FOAF on a
much better footing with most OWL tools. The rest of the changes are
either much less likely to confuse systems, or would drop important
restrictions that the community relies on. This level corresponds to
the options '--full --restrictions' to foaf_cleaner.py
As a supplement, official variants of the spec corresponding to the
various owl levels could be published, and ontology (extension) writers
could choose which spec would best fit with their application.
This note is also published at http://www.mindswap.org/2005/foaf/
More information about the foaf-dev