owlswrl

SWRL rule on n-ary relation in OWL


I want to use OWL (in Protege) to encode the ternary relation ancestorOf(x, y, p); saying that y is the ancestor of x with probability p. Because object properties only support binary relations, my relation has to be represented as a Relation class and a relation individual, with relations to x, y and p (like in this design pattern).

I really do not know how to write an SWRL rule to infer a transitive relation. I.e. that

ancestorOf(x, y, p1) ^ ancestorOf(y, z, p2) -> ancestorOf(x, z, p1 * p2)

I would be thankful is somebody could point me in the correct direction.

Thanks in advance!


Solution

  • The first thing to do is to ensure your ontology is correctly designed for the task. As you rightly pointed out you will need reification to achieve this. This means you will need to introduce a class for representing your n-ary relation, i.e.: AncestorProbability representing n-ary relation

    The related ontology with rules and some individuals to test with will look as follows:

    ObjectProperty: ancestor
        Domain: AncestorProbability
        Range: Person
    
    ObjectProperty: descendant
        Domain: AncestorProbability
        Range: Person
    
    DataProperty: probability
        Domain: AncestorProbability
        Range: xsd:decimal
    
    Class: AncestorProbability
    
    Class: Person
    
    Individual: _a1
        Types: 
            AncestorProbability
        Facts:  
         ancestor  _y,
         descendant  _x,
         probability  0.2
    
    
    Individual: _a2
        Types: 
            AncestorProbability
        Facts:  
         ancestor  _z,
         descendant  _y,
         probability  0.31
    Individual: _a3
        Types: 
            AncestorProbability
        Facts: 
            descendant  _x
    
    Individual: _x
        Types: Person
    
    Individual: _y
        Types: Person
    
    Individual: _z
        Types: Person
    
    DifferentIndividuals: 
        _a1,_a2,_a3
    
    DifferentIndividuals: 
        _x,_y,_z
    
    Rule: 
        ancestor(?a1, ?y), descendant(?a1, ?x), probability(?a1, ?p1), 
        ancestor(?a2, ?z), descendant(?a2, ?y), probability(?a2, ?p2),
        descendant(?a3, ?x), swrlm:eval(?p3, "p1 * p2", ?p1, ?p2) 
        -> ancestor(?a3, ?z), probability(?a3, ?p3) 
    

    One important thing to note is that since there is no ancestorOf(x, y, p) property and you have to use reification, you have to specify your rule component-wise, where ancestor, descendant and probability are properties representing components of your AncestorProbability n-ary relation.

    Another important thing to note is that descendant(?a3, ?x) must be added to indicate on which AncestorProbability individual the rule must be applied for which descendant.

    One possible problem is that the reasoner you use may not support swrlm:eval(?p3, "p1 * p2", ?p1, ?p2), which is the problem I found when testing this with Protege and the HermiT reasoner. It is possible that some commercial reasoner does support this.