11 June 2009

Learning OWL: a simple Ontology for contributions

This post is a simple reminder for creating a simple OWL ontology, I know RDFS (RDF schema) but I'm not at all an expert with the OWL language, so feel free to make any comment about the following ontology.

OK...

at the beginning there is an empty RDF document:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE rdf:RDF [
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
]>
<rdf:RDF xmlns:rdf="&rdf;">
</rdf:RDF>


We're going to use a few more namespaces:
  • DC: the Dublin core provides the basic metadata to describe a resource (title, author...)
  • RDFS: the namespace for the simpliest RDF ontology
  • OWL a more precise language for describing an ontology extendings RDFs
  • FOAF. defines the People, the Images, the Documents, etc...
  • biogang: this will be the prefix for our ontology


<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE rdf:RDF [
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
<!ENTITY owl "http://www.w3.org/2002/07/owl#">
<!ENTITY dc "http://purl.org/dc/elements/1.1/">
<!ENTITY biogang "urn:biogang/ontology/contribution#">
<!ENTITY foaf "http://xmlns.com/foaf/0.1/">
]>
<rdf:RDF xmlns:rdf="&rdf;"
xmlns:rdfs="&rdfs;"
xmlns:owl="&owl;"
xmlns:foaf="&foaf;"
xmlns:dc="&dc;"
xmlns:biogang="&biogang;">

</rdf:RDF>


In a first statement We describe our Ontology (label, comment,...)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE rdf:RDF [
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
<!ENTITY owl "http://www.w3.org/2002/07/owl#">
<!ENTITY dc "http://purl.org/dc/elements/1.1/">
<!ENTITY foaf "http://xmlns.com/foaf/0.1/">
<!ENTITY biogang "urn:biogang/ontology/contribution#">
]>
<rdf:RDF xmlns:rdf="&rdf;" xmlns:rdfs="&rdfs;" xmlns:owl="&owl;" xmlns:dc="&dc;" xmlns:foaf="&foaf;" xmlns:biogang="&biogang;">

<owl:Ontology rdf:about="">
<dc:date>2009-06-11</dc:date>
<dc:creator>Pierre Lindenbaum</dc:creator>
<rdfs:label>The Attribution Ontology</rdfs:label>
<rdfs:comment>
An ontology used to provide a quantitative citation
for every unique author of a document
</rdfs:comment>
</owl:Ontology>
</rdf:RDF>

Let's declare our main class, an Attribution:
<owl:Class rdf:about="&biogang;Contribution">
<rdfs:label xml:lang="en">Contribution</rdfs:label>
<rdfs:label xml:lang="fr">Contribution</rdfs:label>
<rdfs:comment xml:lang="en">A contribution</rdfs:comment>
<rdfs:comment xml:lang="fr">Une contribution</rdfs:comment>
</owl:Class>

An attribution is a link between an author and a document.
An author is a foaf:Person as defined in the FOAF ontology.
A document is a foaf:Document as defined in the FOAF ontology (this could be an article but also a picture, a song, a web site, etc...).
So, an Attribution is a Class with two properties: contributor and contributedTo.
The domain of both contributor and contributedTo is an object of type Contribution.
The range of a "contributor" is NOT the name of the author (aka a Literal, aka a DataTypeProperty) but it is a link to a resource describing the Person. So its range is an ObjectProperty pointing to a foaf:Person. Also contributedTo extends the Dublin-Core property dc:creator
<owl:ObjectProperty rdf:about="&biogang;contributor">
<rdfs:domain rdf:resource="&biogang;Contribution"/>
<rdfs:range rdf:resource="&foaf;Person"/>
<rdfs:label>contributor</rdfs:label>
<rdfs:subPropertyOf rdf:resource="&dc;creator"/>
</owl:ObjectProperty>

The range of contributedTo" is NOT the literal description of the document but it is a link to a resource describing the Document. So its range is an ObjectProperty pointing to a foaf:Document.
<owl:ObjectProperty rdf:about="&biogang;contributedTo">
<rdfs:domain rdf:resource="&biogang;Contribution"/>
<rdfs:range rdf:resource="&foaf;Document"/>
<rdfs:label>contributed to</rdfs:label>
</owl:ObjectProperty>


We can also add a Literal property to describe the nature of the contribution.
<owl:DatatypeProperty rdf:about="&biogang;comment">
<rdfs:domain rdf:resource="&biogang;Contribution"/>
<rdfs:range rdf:resource="&rdfs;Literal"/>
<rdfs:label>description of this contribution</rdfs:label>
<rdfs:subPropertyOf rdf:resource="&dc;description"/>
</owl:DatatypeProperty>


But a Contribution should contain one 'contributor' and one 'contributedTo', so we add a restriction on the cardinality of those properties:


<owl:Class rdf:about="&biogang;Contribution">
<rdfs:label xml:lang="en">Contribution</rdfs:label>
<rdfs:label xml:lang="fr">Contribution</rdfs:label>
<rdfs:comment xml:lang="en">A contribution</rdfs:comment>
<rdfs:comment xml:lang="fr">Une contribution</rdfs:comment>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="&biogang;contributor"/>
<owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:cardinality>
</owl:Restriction>
</rdfs:subClassOf>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="&biogang;contributedTo"/>
<owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:cardinality>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>

We can also create a set of sub-Classes to extend the Class Contribution to give a quantifiable view of the contribution.
<owl:Class rdf:about="&biogang;MajorContribution">
<rdfs:subClassOf rdf:resource="&biogang;Contribution"/>
<rdfs:label>Major contribution</rdfs:label>
</owl:Class>

<owl:Class rdf:about="&biogang;MediumContribution">
<rdfs:subClassOf rdf:resource="&biogang;Contribution"/>
<rdfs:label>Medium contribution</rdfs:label>
</owl:Class>

<owl:Class rdf:about="&biogang;MicroContribution">
<rdfs:subClassOf rdf:resource="&biogang;Contribution"/>
<rdfs:label>Micro contribution</rdfs:label>
</owl:Class>

It would be also nice, to extends this ontology to describe the 'nature' of the contribution (drawing figures, useful discussions, writing the paper). This would allow to easily find the person who are good with a given task.
Anyway, at the end, here is the full ontology:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:biogang="urn:biogang/ontology/contribution#">

<owl:Ontology rdf:about="">
<dc:date>2009-06-11</dc:date>
<dc:creator>Pierre Lindenbaum</dc:creator>
<rdfs:label>The Attribution Ontology</rdfs:label>
<rdfs:comment>
An ontology used to provide a quantitative citation
for every unique author of a document
</rdfs:comment>
</owl:Ontology>

<owl:Class rdf:about="urn:biogang/ontology/contribution#Contribution">
<rdfs:label xml:lang="en">Contribution</rdfs:label>
<rdfs:label xml:lang="fr">Contribution</rdfs:label>
<rdfs:comment xml:lang="en">A contribution</rdfs:comment>
<rdfs:comment xml:lang="fr">Une contribution</rdfs:comment>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="urn:biogang/ontology/contribution#contributor"/>
<owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:cardinality>
</owl:Restriction>
</rdfs:subClassOf>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="urn:biogang/ontology/contribution#contributedTo"/>
<owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:cardinality>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>


<owl:ObjectProperty rdf:about="urn:biogang/ontology/contribution#contributor">
<rdfs:domain rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:range rdf:resource="http://xmlns.com/foaf/0.1/Person"/>
<rdfs:label>contributor</rdfs:label>
<rdfs:subPropertyOf rdf:resource="http://purl.org/dc/elements/1.1/creator"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:about="urn:biogang/ontology/contribution#contributedTo">
<rdfs:domain rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:range rdf:resource="http://xmlns.com/foaf/0.1/Document"/>
<rdfs:label>contributed to</rdfs:label>
</owl:ObjectProperty>

<owl:DatatypeProperty rdf:about="urn:biogang/ontology/contribution#comment">
<rdfs:domain rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:range rdf:resource="http://www.w3.org/2000/01/rdf-schema#Literal"/>
<rdfs:label>description of this contribution</rdfs:label>
<rdfs:subPropertyOf rdf:resource="http://purl.org/dc/elements/1.1/description"/>
</owl:DatatypeProperty>

<owl:Class rdf:about="urn:biogang/ontology/contribution#MajorContribution">
<rdfs:subClassOf rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:label>Major contribution</rdfs:label>
</owl:Class>

<owl:Class rdf:about="urn:biogang/ontology/contribution#MediumContribution">
<rdfs:subClassOf rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:label>Medium contribution</rdfs:label>
</owl:Class>

<owl:Class rdf:about="urn:biogang/ontology/contribution#MicroContribution">
<rdfs:subClassOf rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:label>Micro contribution</rdfs:label>
</owl:Class>

</rdf:RDF>


At the end, we can create some new instances of contributions just like this:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:biogang="urn:biogang/ontology/contribution#" (...) >
<biogang:MajorContribution>
<biogang:comment>Made the Y2H experiments</biogang:comment>
<biogang:contributor rdf:resource="mailto:plindenbaum@yahoo.fr"/>
<biogang:contributedTo rdf:resource="http://www.ncbi.nlm.nih.gov/pubmed/8985320"/>
</biogang:MajorContribution>

<foaf:Person rdf:about="mailto:plindenbaum@yahoo.fr">
<foaf:name>Pierre</foaf:name>
</foaf:Person>

<foaf:Document rdf:about="http://www.ncbi.nlm.nih.gov/pubmed/8985320">
<dc:title>In vivo and in vitro phosphorylation of rotavirus NSP5 correlates with its localization in viroplasms</dc:title>
</foaf:Document>
</rdf:RDF>


That's it
Pierre

2 comments:

Olivier Dameron said...

Hi Pierre, some nitpicking and some remarks:

1. it is usually good practice (but certainly not mandatory) to use a "is" or "has" prefix to properties names, so that it is easier to understand in which direction it should be read. For example, whithout having the domain and range in mind, should "contributor" be interpreted as "is contributor of" or "has contributor"? That would give you hasContributor and hasContributedTo

2. it is not explicit in your article, but you only need the Contribution class if you want to add complementary information to the Person-Document relation, such as documenting the nature of the contribution. One other argument would be your further subclassing Contribution in major, medium and minor, but you could just as well have created three subproperties of the Person<-Document object property

3. your MajorContribution, MediumContribution and MicroContribution classes should be mutually disjoint. And if you feel like it, you could also add a necessary and sufficient coverage definition for the Contribution class saying that a contribution is either major, medium or minor.

Pierre Lindenbaum said...

Thanks Olivier ! This is very helpful !!