rdfowlontologygraphdbreasoning

Property Chains with assertions on intermediate nodes


I have a use case where I'm trying to infer if a specific user has admin access to a resource. I'm using GraphDB.

My ontology contains Users, Roles, Permissions and Resources. A User can have N roles. Each Role has different Permissions, one of which is the administration permissions. And each Role applies to a specific Resource.

So what I'm trying to infer is a direct relation indicating that a user has admin access to the resource. I'm trying to make PropertyChains and rolification fit for my use case, but I don't quite make it work. I'm not sure if that's even the right path.

I draft this piece of the ontology here:

@prefix :      <https://stackoverflow.com/myQuestion#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

<https://stackoverflow.com/myQuestion>
        a       owl:Ontology .
    
:hasRole  a           owl:ObjectProperty ;
        rdfs:domain  :User ;
        rdfs:range   :Role .

:roleHasPermission  a           owl:ObjectProperty ;
        rdfs:domain             :Role ;
        rdfs:range              :Permission ;

:appliesToResource  a           owl:ObjectProperty ;
        rdfs:domain  :Role ;
        rdfs:range   :Resource .

:userHasAdminPermission a       owl:ObjectProperty ;
        rdfs:domain  :User ;
        rdfs:range   :Resource .

:User   a     owl:Class .

:Role   a     owl:Class .

:Permission a owl:Class .

:Resource a   owl:Class .

:AdminPermission a :Permission . 
:OtherPermission a :Permission .

Solution

  • It is possible to achieve that using owl:propertyChainAxiom but it will require an introduction of unique "node spcific loops" in the data related to the specic resource (:AdminPermission) and using that in the target chain.

    The tricky part is the generation of such "loops". One way of doing that can be achieved using a combination of an inverse property and an interplay with two restrictions of owl:hasValue kind so to derive these around the specific target node.

    Let's introduce a class :AdminRole as a place holder of these:

    @prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix owl:   <http://www.w3.org/2002/07/owl#> .
    @prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
    @prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    
    :roleHasAdminPermission owl:inverseOf :adminPermissionAppliesToRole .
    
    :AdminRole rdfs:subClassOf :Role;
        owl:equivalentClass [
        a owl:Restriction ;
        owl:onProperty :roleHasPermission;
        owl:hasValue :AdminPermission 
        ];
        owl:equivalentClass [
        a owl:Restriction ;
        owl:onProperty :roleHasAdminPermission;
        owl:hasValue :AdminPermission 
        ] .
    
    :userHasAdminPermission owl:propertyChainAxiom 
       (:hasRole :roleHasPermission :adminPermissionAppliesToRole :appliesToResource) .
    

    Whenever a node is related with :roleHasPermission to :AdminPermission it became member of :AdminRole and respectively, each member of :AdminRole must be related with :roleHasAdminPermission to :AdminPermission

    Next, introduce :adminPermissionAppliesToRole as an inverse of :roleHasAdminPermission thus creating the loop we are after.

    What is left is to define the owl:propertyChainAxiom through that loop to derive the :userHasAdminPermission between the User and the Resource.

    A check with some sample data (using owl2-rl inference):

    prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> 
    prefix owl:   <http://www.w3.org/2002/07/owl#> 
    prefix xsd:   <http://www.w3.org/2001/XMLSchema#> 
    prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
    
    insert data {
        :Administrator a :Role ;
            :roleHasPermission :AdminPermission .
    
        :Administrator :appliesToResource :Archive .
    
        :Clerk a :Role ;
            :roleHasPermission :OtherPermission .
    
        :Clerk :appliesToResource :SomethingOther .
        
        :Ron a :User;
            :hasRole :Administrator .
    
        :Jane a :User;
            :hasRole :Clerk .
    }
    

    and a sample query to check:

    describe :Ron
    

    will show : :Ron :userHasAdminPermission :Archive

    HTH