Skip to main content

Using standard ontologies with as(...)

Posted by fabriziogiudici on November 29, 2009 at 8:02 AM EST
As I previously said, one of the advantage of using an RDF store is that you're offered with a bunch of standard “ontologies”, that are standard ways to do some common things (sounds nice, doesn't it?). Those things are related to managing relationships among things.

A common need that clearly emerges when you extensively use the as(...) pattern that I've explained in my previous blog is how to specify that two distinct object are indeed referring to the same concept. Adding some more examples to my previous post, I could write things such as:

Employee employee = new Employee();
Department department = employee.getDepartment();

employee.as(Person.class).setFirstName("John");
employee.as(Person.class).setLastName("Doe");
employee.as(AccountHolder.class).getDefaultAccount().deposit(4000); // payroll

Observation observation = observationSet.createObservation().
                                         date(when).
                                         location(castiglione).
                                         item(spoonbill, Cardinality.valueOf(23)).
                                         item(flamingo, Cardinality.rangeOf(100, 150)).
                                         observer(employee.as(Observer.class)).
                                         build();

Employee models behaviours related to the life in a corporate, while Person and AccountHolder are behaviours common to many other kind of people; in the last example you can see as I can reuse Employee with my Observation API, to model the fact that employees with the birdwatching hobby can make bird observations.

In my previous post I only focused to the API aspect, without giving any detail about how to persistently store in RDF the binding relationship among an Employee, a Person, an AccountHolder and an Observer.  In fact, one would expect that these relationships are dynamic and can be created and destroyed at runtime.

Another common problem that emerges in many object collections is the tree-shaped hierarchy. For instance, if you have to model a taxonomy of birds or a collection of geographic entities you face with the need of representing a tree-shaped hierarchic structure. Birds have phylum, class, order, family, genus, species; geographic entities have country, region, province, municipality, etc...

Two standard ontologies help us. For the former problem we can use OWL; for the latter SKOS.

As a side note, I find that stuff related to semantic technologies is often much simpler than it appears at first. If you google for OWL or SKOS you're likely to hit the W3C official documents, which offer tons of information about their specification stage etc... but you need a bit of patience to find some simple example that demonstrates how they can be used - and how they are useful. Maybe this is a factor that reduces the spread of the technology? The best online introduction about SKOS I've found so far is unfortunately in italian.  Things are much better with books such as “Semantic web for the working ontologist”, that literaly opened my mind, but for sure simpler and more readable online resources would help.

For my needs, OWL defines a concept named “Thing” and a statement “is-same-as”. This is a reasonably simple concept as it says that two things are semantically equivalent, that is all the property and statements of the former also hold for the latter and vice-versa.

In pseudo code with the as(...) pattern I can write:

Employee employee = new Employee();
Person person = new Person();

employee.as(OWLThing.class).addSameAs(person);

so later I can query the relationship:

Employee employee = person.as(Employee.class);

SKOS defines a concept named “(SKOS)Concept” and two statements “is-a-narrower-of” and “is-a-broader-of”. We can interpret “narrower” as “specialization” and “broader” as “generalization”. So, for birds “species” is a narrower (= specialization) of “genus” and “province” is a narrower of “region”. Of course you can read in in the reverse way: genus is a broader (= generalization) of species and region is a broader of province.

I think that things are much simpler if we look at some pseudo-code:

GeoLocation sausalito = new GeoLocation();
GeoLocation marinCounty = new GeoLocation();
GeoLocation california = new GeoLocation();
GeoLocation usa = new GeoLocation();

usa.as(SKOSConcept.class).addNarrower(california);
california.as(SKOSConcept.class).addNarrower(marinCounty);
marinCounty.as(SKOSConcept.class).addNarrower(sausalito);

And later, for instance:

List<GeoLocation> counties = california.as(SKOSConcept.class).findNarrowersOfType(GeoLocation.class);


As usual, in my code OWLThing and SKOSConcept are simple facades on Elmo, which provides the proper generation and query of RDF statements.

I should be able to present soon a more comprehensive example, based on one of the APIs of forceTen, the GeoLocation API. In fact, yesterday it seems I was able to perform a good bunch of refactorings that moved it into a reasonable state.

Related Topics >>