You may have noticed that I said a certain thing was impossible last post. Well, I’m prepared to revise my position on that.
- I have built a very simple taxonomy out of the TDWG components – Mammal, Cat, Lion, Tiger, Felis.
There are no relationships between these taxa – they just stand alone.
- I have created TDWG relationship objects linking them together – parent, child, synonym.
These are OWL Individuals – reified properties. Each relationship object has three properties: fronTaxon, toTaxon, and relationshipCategory.
- I have defined a simple vocabulary based on properties which link the taxa together: parentof, childof, ancestorof, descentantof, synonymfor.
This vocabulary does the work that tree-structuring properties should do: parentod extends ancestorof, ancestorof is transitive, synonymfor is symmetric, and so on.
- I have created a set of rules that automatically imply the property vocabulary items from the TDWG items.
This is the interesting bit. The existence of a TDWG relationship object that has a “relationship kind” property of “is parent of” will result in a parentof relationship being inferred between the two taxa it connects.
Source code is here Doing the impossible with owl2 reflexive properties – code sample/.
Reading this into protege, the hermit reasoner correctly infers that Mammal is an ancestor of Tiger, even though no parentOf properties are explicitly asserted.
the magic code is:
- Create a property “iamaParentRelationship” on any Relationship object with the appropriate relationshipCategory
SubClassOf( ObjectHasValue( tdwg_tc:relationshipCategory tdwg_tc:IsParentOf ) ObjectHasSelf(myvoc:iamaParentofRelationship) )
- Create a “hasRelationship” property, and make it the inverse of “fromTaxon”
InverseObjectProperties( myvoc:hasRelationship tdwg_tc:fromTaxon )
(I think that this step might be unnecessary – I could have just used ObjectInverseOf(fromTaxon) in the property chain)
- Declare a property chain, inferring the existence of a “parentof” relationship
SubObjectPropertyOf( ObjectPropertyChain( myvoc:hasRelationship myvoc:iamaParentofRelationship tdwg_tc:toTaxon ) myvoc:parentof )
Success! And the other rules over the myvoc:parentof properties do the rest of the work.
This is somewhat more exciting that it might seem. It potentially takes care of the whole “properties with properties” problem. Since ObjectHasValue is simply a class, it also suggests an interesting way to take care of “class as a value” – an alternative to the mechanisms suggested in Representing Classes As Property Values on the Semantic Web.
Most importantly, it demonstrates a way of creating complex conditional property chains. A property chain can be made conditional on anything capable of being put into a class expression – which (BTW) includes using regular expressions on string properties.
Actually, I think the first rule can be made an equivalent classes declaration:
EquivlaentClasses( ObjectHasValue( tdwg_tc:relationshipCategory tdwg_tc:IsParentOf ) ObjectHasSelf(myvoc:iamaParentofRelationship) )
And the second and third rules can be collapsed into one, allowing us to dispense with the “hasRelationship” property:
SubObjectPropertyOf( ObjectPropertyChain( ObjectInverseOf(tdwg_tc:fromTaxon) myvoc:iamaParentofRelationship tdwg_tc:toTaxon ) myvoc:parentof )
So we can do it in two rules.