using owl:imports

Like XInclude, or #include, or xsl:include and xsl:import, but trickier.

I’ve had problems getting OWL’s import mechanism to work before, and once I got a simple demo of it to work I wanted to make it available. owl:imports is great because it helps make your ontologies more modular, even letting you separate your ontology from the data it describes, sort of like—dare I say it—a schema.

To avoid a simple typo that I made, note that the OWL property uses the third person singular form of the verb “imports” instead of the second person “import” command used by XSLT (or the “include” used by XSLT and other programming languages). We’re not saying “Hey compiler or interpreter! Import this other file!” Instead we’re saying, in subject-predicate-object RDF fashion, “this ontology imports this other one”.

What makes owl:imports tricky is that we’re not just importing a file, but importing an ontology, and because the importing file, the imported file, the terms being defined, and, well, pretty much everything all have URLs to represent their full names, the use of relative names, prefixes, and xml:base can make things easier or add to the confusion. As a starting point, the example below does work.

Here’s the data file to import, which I called addressbook.rdf:

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:id="http://www.snee.com/ns/id#"
    xmlns="http://www.snee.com/ns/addressbook#">


  <rdf:Description rdf:about="id:NormaS">
    <firstName>Norma</firstName>
    <lastName>Smith</lastName>
    <homePhone>(445) 138-6676</homePhone>
    <workPhone>(326) 852-7714</workPhone>
  </rdf:Description>


  <rdf:Description rdf:about="id:andy-g">
    <firstName>Andy</firstName>
    <lastName>Gibson</lastName>
    <homePhone>(652) 348-2796</homePhone>
  </rdf:Description>


</rdf:RDF>

Here’s a short ontology that I named addressbook.owl. It importes addressbook.rdf and adds some metadata asserting that the mobile, workPhone, and homePhone properties are subproperties of the datatype property “phone”:

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">


  <owl:Ontology>
    <owl:imports>
      <owl:Ontology rdf:about="addressbook.rdf"/>
    </owl:imports>
  </owl:Ontology>


  <owl:DatatypeProperty rdf:about="http://www.snee.com/ns/addressbook#phone"/>


  <owl:DatatypeProperty rdf:about="http://www.snee.com/ns/addressbook#mobile">
    <rdfs:subPropertyOf>
      <owl:DatatypeProperty rdf:about="http://www.snee.com/ns/addressbook#phone"/>
    </rdfs:subPropertyOf>
  </owl:DatatypeProperty>


  <owl:DatatypeProperty rdf:about="http://www.snee.com/ns/addressbook#workPhone">
    <rdfs:subPropertyOf>
      <owl:DatatypeProperty rdf:about="http://www.snee.com/ns/addressbook#phone"/>
    </rdfs:subPropertyOf>
  </owl:DatatypeProperty>


  <owl:DatatypeProperty rdf:about="http://www.snee.com/ns/addressbook#homePhone">
    <rdfs:subPropertyOf>
      <owl:DatatypeProperty rdf:about="http://www.snee.com/ns/addressbook#phone"/>
    </rdfs:subPropertyOf>
  </owl:DatatypeProperty>
</rdf:RDF>

The following SPARQL query, stored in the file normaPhone.spq, asks for any phone numbers that NormaS has, even though the person issuing the query may not know which of her phone numbers are in the database:

PREFIX t: <http://www.snee.com/ns/addressbook#>


SELECT ?phoneType ?value
WHERE {
    <id:NormaS> t:phone ?value.
    <id:NormaS> ?phoneType ?value
}

The following command line tells pellet to run the normaPhone.spq query against addressbook.owl:

pellet -if addressbook.owl -qf normaPhone.spq

Pellet gives me the following answer:

Query Results (2 answers):
phoneType  | value
=============================
:workPhone | "(326) 852-7714"
:homePhone | "(445) 138-6676"

(It also gives me a report on the non-DL aspects of my ontology and what I can add to make it more DL compliant, but I’m not including that here.) The query is an important part of my owl:imports demo because it shows how the separate OWL ontology actually adds to the usefulness of the simple address book data that has no ontology information: it lets me get Norma’s phone numbers without knowing exactly which kind are stored. (As a bonus, this also demonstrates the value of the rdfs:subPropertyOf property.) Of course, the query also forces me to run the whole setup with some software that will complain if I didn’t do it properly.

I’m open to suggestions on ways to improve all of this.

4 Comments

By Jeni Tennison on August 23, 2007 11:15 AM

Why do you include the data in the ontology rather than the other way around? Doesn’t this mean that if someone wants to reuse your ontology, they get all your data along for the ride?

(Analogously, you point to a schema from an XML document rather than the other way around.)

By Bob DuCharme on August 23, 2007 11:28 AM

Jeni,

I did it that way because I really like the OWL use case of creating an ontology around existing data: “for the data in such-and-such a file, here is some metadata to go with it.”

You don’t always point to a schema from an XML document; James Clark has some arguments against that that make sense to me. What makes the most sense to me, which would be easy enough using owl:includes, would be to have a separate skeleton document that has one pointer to the data document and another pointer to the ontology to say that, for a given processing need, these two are to be used together.

Bob\

By Richard Cyganiak on August 23, 2007 12:07 PM

I’m a bit confused, shouldn’t you say owl:imports rather than owl:includes throughout your post?

By Bob DuCharme on August 23, 2007 12:24 PM

Richard,

You’re absolutely right. I’m suitably embarrassed and just corrected it. (I’ll blame my usage of XSLT, with it’s slightly different xsl:import and xsl:include commands, for the confusion.)

Bob\