OWL 2 in Action – Property Chains

This is the second article in our series that expands the code example from Chapter 5 of Semantic Web Programming to cover the semantics of OWL 2. This article covers property chains. The code can be downloaded from here (zip, 7z, tar.gz) and includes an Eclipse project with all required dependencies.
This article focuses on the semantics of property chains and how they are interpreted and applied in a reasoner that supports most of OWL 2 semantics (Pellet 2.0 RC6 – see the Pellet documentation for a full list of the semantics supported in each release candidate).
As I said in the first article, for a more in-depth exploration of OWL and Semantic Web, feel free to reference the book as needed or buy a copy so you can learn about the cool stuff in this article and more. Click the link below to read the rest of the article…
Recall from Chapter 4 in the book that property chains are a way to define a property in terms of a chain of object properties that connect resources. One of the most common examples of a property that is defined in terms of a property chain is the hasUncle relationship, which is our first example and is defined in OWL below:
ex:Ryan rdf:type ex:Person; ex:hasParent ex:Jean. ex:Jean rdf:type ex:Person; ex:hasBrother ex:Doug. ex:Doug rdf:type ex:Person. ex:hasUncle rdf:type owl:ObjectProperty. ex:hasParent rdf:type owl:ObjectProperty. ex:hasBrother rdf:type owl:ObjectProperty. [] rdfs:subPropertyOf ex:hasUncle; owl:propertyChain ( ex:hasParent ex:hasBrother ).
The excerpt above is in the file pc_1.ttl. As you can see, we’ve defined that there exists a sub-property of ex:hasUncle that is the property chain consisting of ex:hasParent and ex:hasBrother. This means that the any time the property chain exists, the super-property (ex:hasUncle) exists. More precisely stated: if A ex:hasParent B and B ex:hasBrother C then A ex:hasUncle C. Note that I didn’t say if and only if. The implication only goes in the one direction. The existence of a statement A ex:hasUncle B alone does not imply anything in this context. In OWL 2 you can’t make a property chain an equivalent-property or a super-property of another property. Despite these limitations, we will soon see that property chains enable the definition of properties that cannot be defined in any other way.
Executing the code in the accompanying project with the input file pc_1.ttl (input parameters: test/pc_1.ttl TTL output1.txt owl) produces the following output:
Individual: Doug
type : http://example.org#Person
type : http://www.w3.org/2002/07/owl#Thing
sameAs : http://example.org#Doug
Individual: Ryan
type : http://example.org#Person
type : http://www.w3.org/2002/07/owl#Thing
sameAs : http://example.org#Ryan
hasUncle : http://example.org#Doug
hasParent : http://example.org#Jean
Individual: Jean
type : http://example.org#Person
type : http://www.w3.org/2002/07/owl#Thing
sameAs : http://example.org#Jean
hasBrother : http://example.org#Doug
As you can see, Pellet correctly infers that Ryan hasUncle Doug. All we said in the input file was (ex:Ryan ex:hasParent ex:Jean) and (ex:Jean ex:hasBrother ex:Doug). This chain of relationships combined with the property chain definition implied the existence of the statement (ex:Ryan ex:hasUncle ex:Doug). As an exercise for yourself, try defining the ex:hasAunt relationship and give ex:Jean a sister.
This was a relatively simple example, so let’s explore some more interesting applications of property chains. For the first example, consider a trust management system in which a user is a trusted user if he or she is trusted by a trusted user. One way to express this concept is to say that the property trusts is transitive. That way, if A trusts B and B trusts C, A will trust C. The following RDF captures these concepts (from pc_2.ttl):
ex:Person rdf:type owl:Class. ex:trusts rdf:type owl:ObjectProperty; rdf:type owl:TransitiveProperty. ex:Ryan rdf:type ex:Person; ex:trusts ex:John. ex:John rdf:type ex:Person; ex:trusts ex:Matt; ex:trusts ex:Ryan. ex:Matt rdf:type ex:Person; ex:trusts ex:Andrew. ex:Andrew rdf:type ex:Person; ex:trusts ex:Mike. ex:Mike rdf:type ex:Person.
Focus on ex:Ryan. As the excerpt specifies, Ryan trusts John, who trusts Matt. Matt trusts Andrew, and Andrew trusts Mike. Apparently Mike doesn’t trust anyone. Running this example produces the following output (only the statements about Ryan are included):
Individual: Ryan
type : http://example.org#Person
type : http://www.w3.org/2002/07/owl#Thing
sameAs : http://example.org#Ryan
trusts : http://example.org#Andrew
trusts : http://example.org#John
trusts : http://example.org#Ryan
trusts : http://example.org#Mike
trusts : http://example.org#Matt
As you can see, Pellet entails that Ryan trusts everyone. While this is logically correct given our ontology, it isn’t really practical to chain a relationship such as trusts in this manner. This illustrates the potential limitation to this approach using transitivity – there is no way to constrain how far the transitivity is applied. In other words, Ryan trusts John, and may be comfortable trusting someone John trusts. But that trust will likely diminish as the relationship becomes less and less direct. Does Ryan really trust Mike? After all, it took a chain of Ryan trusts John trusts Matt trusts Andrew trusts Mike in order to entail the fact that Ryan trusts Mike. That’s quite a lot of indirection. Let’s see if we can use property chains to introduce some finer grain control over this situation.
As shown below, in pc_3.ttl we define a new property ex:indirectlyTrusts as the super-property of the property chain of two ex:trusts relationships.
ex:Person rdf:type owl:Class. ex:trusts rdf:type owl:ObjectProperty. ex:indirectlyTrusts rdf:type owl:ObjectProperty. ex:Ryan rdf:type ex:Person; ex:trusts ex:John. ex:John rdf:type ex:Person; ex:trusts ex:Matt; ex:trusts ex:Ryan. ex:Matt rdf:type ex:Person; ex:trusts ex:Andrew. ex:Andrew rdf:type ex:Person; ex:trusts ex:Mike. ex:Mike rdf:type ex:Person. [] rdfs:subPropertyOf ex:indirectlyTrusts; owl:propertyChain ( ex:trusts ex:trusts ).
Running pc_3.ttl produces the following output for Ryan:
Individual: Ryan
type : http://example.org#Person
type : http://www.w3.org/2002/07/owl#Thing
sameAs : http://example.org#Ryan
indirectlyTrusts : http://example.org#Ryan
indirectlyTrusts : http://example.org#Matt
trusts : http://example.org#John
As you can see, Ryan trusts John and indirectly trusts Matt (and Ryan), and that is the extent to which Ryan has any trust relationship with anyone. Even if we added the indirectly-trusts relationship to our ontology, transitivity wouldn’t be enough to achieve this same result that we just achieved with property chains. This isn’t to say that transitive properties aren’t useful, it’s just to highlight a scenario in which we may need something else to model our relationships.
For the next and final example, we’ll apply property chains to a slightly more complex example, the ontology for which is shown below (from pc_4.ttl):
ex:User rdf:type owl:Class. ex:System rdf:type owl:Class. ex:trusts rdf:type owl:ObjectProperty. ex:authorizes rdf:type owl:ObjectProperty. ex:grantsReadTo rdf:type owl:ObjectProperty. ex:grantsWriteTo rdf:type owl:ObjectProperty; rdfs:subPropertyOf ex:grantsReadTo. [] rdfs:subPropertyOf ex:grantsWriteTo; owl:propertyChain ( ex:trusts ex:authorizes ). [] rdfs:subPropertyOf ex:grantsReadTo; owl:propertyChain ( ex:trusts ex:authorizes ex:trusts ex:authorizes ).
What we’ve done here is described a very simple authorization protocol. In this protocol there are Systems and Users. Systems authorize users and Users trust Systems. A User decides who to grant read and write access to based on the set of Users who are authorized by the Systems the original user trust. Now, property chains don’t allow you to constrain the resources that are endpoints for the properties in the chain. As such, we can’t actually specify that the (trusts, authorizes) chain is specific to “trusts System” and “authorizes User.” All we can do is specify that any three resources associated by the chain of properties (trusts, authorizes). So, with that said – a resource grants write access to those resources who are authorized by the resources they trust. Read access is granted based on the same property chain, only with an additional step. So, a resource grants read access to those resources who are authorized by resources that are trusted by resources that are authorized by resources that are trusted by them (confused yet?). Anyways, take a look at the rest of the contents of pc_4.ttl:
ex:Ryan rdf:type ex:User; ex:trusts ex:System1. ex:John rdf:type ex:User; ex:trusts ex:System1; ex:trusts ex:System2. ex:Matt rdf:type ex:User. ex:Andrew rdf:type ex:User; ex:trusts ex:System3. ex:Mike rdf:type ex:User; ex:trusts ex:System3. ex:System1 rdf:type ex:System; ex:authorizes ex:Ryan; ex:authorizes ex:John. ex:System2 rdf:type ex:System; ex:authorizes ex:Matt; ex:authorizes ex:Mike; ex:authorizes ex:John. ex:System3 rdf:type ex:System; ex:authorizes ex:Andrew; ex:authorizes ex:Mike.
Take a look at the output generated describing Ryan when we run this example in the Pellet reasoning application:
Individual: Ryan type : http://example.org#User type : http://www.w3.org/2002/07/owl#Thing sameAs : http://example.org#Ryan grantsWriteTo : http://example.org#John grantsWriteTo : http://example.org#Ryan trusts : http://example.org#System1 grantsReadTo : http://example.org#John grantsReadTo : http://example.org#Ryan grantsReadTo : http://example.org#Mike grantsReadTo : http://example.org#Matt
As we would expect, Pellet has entailed that Ryan grants write access to John (and Ryan) because Ryan trusts System1 which authorizes John and Ryan. Read access is granted to John, Mike, and Matt. This is because John trusts the system that authorizes Mike and Matt and because ex:grantsReadTo is a sub-property of ex:grantsWriteTo.
Hopefully this article has given you some more insight into the semantics of property chains. Have fun tweaking these examples and building those knowledge models! Excited for more? Make comments, leave feedback, request a tutorial on a specific topic! And above all else – stay tuned for the next article…
