Lightweight RDFS Ontologies
This is another quick tutorial for those wanting to serialize data to RDF. Languages like OWL provide heavyweight description logic modeling capabilities for RDF, but most people find that lightweight RDFs modeling is the most appropriate.
I’ll cover three things in this posts: labels, classes, properties. This post assumes the following three namespaces:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> @prefix xsd: <http://www.w3.org/2001/XMLSchema#> @prefix ex: <http://www.example.org/lightweight_classes#>
And it uses the Turtle syntax.
Labels
In the last post I said an important rdf property was rdf:type, which says that the <subject> is an item of type <object>. Another important property is rdfs:label (note that it is in the RDFS namespace, not RDF). rdfs:label is RDF’s equivalent of Java’s toString() method. If you want to give some resource a human-readable name, you should set this by saying
<some object> rdfs:label "The Human Readable Name"^^xsd:string .
It is customary among people who hand-write Turtle files to put the label definition as the last property on an object. That way if an object definition is more than one screenful tall, the person knows they can look at either the top line of the definition (the resource) or the bottom line of the definition (the label) to remind them what they’re looking at.
Classes
You can declare a class like this:
ex:MotorVehicle rdf:type rdfs:Class ;
rdfs:label "Motor Vehicle"^^xsd:string .
Classes are usually given a capital letter in their local name. (The local name is the portion of the URI that comes after the namespace. So URI ::= Namespace + LocalName).
You can write a subclass like this:
ex:Van rdf:type rdfs:Class ;
rdfs:subClassOf ex:MotorVehicle ;
rdfs:label "Van"^^xsd:string .
And, as in the previous post, you can say that an object is a type of class by saying:
ex:aCar rdf:type ex:Van ;
Notice how the same property defines a class and also declares class membership. Also know that you can make as many class assignments as you want — multiple inheiretance is fine in RDF.
Properties
The Basics
You can declare a property like this
ex:topSpeed rdf:type rdf:Property ;
rdfs:label "Top Speed" .
It is customary to start of the local names of properties with a lower-case letter.
Subclassing Properties
Just like you can make subclasses, you can subclass properties like this:
ex:driver rdf:type rdf:Property . ex:primaryDriver rdf:type rdf:Property . ex:primaryDriver rdfs:subPropertyOf ex:driver .
Domains and Ranges
You can also specify the domains and ranges of properties:
ex:age rdfs:domain ex:MotorVehicle . ex:age rdfs:range xsd:integer .
but this is dangerous terrirory with RDFS, and IMHO it sort of breaks the nice notion of edges of the graph being able to connect any node to any other (but of course, now we’re in object modeling territory instead of graph land).
The reason that RDFS domains and ranges are dangerous is that if a property P has a domain of C, where |C|>1, and a tuple states <X P something>, then every class c in C must apply to X. The same goes for ranges (with appropriate modifications to the previous sentence).
Here is an example of why you have to be careful. It is perfectly reasonable for both a person and a car to have an age, but if you say:
ex:age rdfs:domain ex:MotorVehicle . ex:age rdfs:domain ex:Person .
And then you say
ex:mycar ex:age "15"^^xsd:integer .
Then you have just stated that your car is both a MotorVehicle and a Person! Probably not what you wanted to say. Of course, you will only feel the ill effects of this when you turn on an RDFS reasoner, but that is a pretty common thing to do because it is lightweight and gets you the goodness of class and property inheritance.
—————————-
That’s about it. Much of the example RDF on this post was borroed from the Turtle version of the W3’s RDF Primer, so if you want more information you can look there.