owlobject-property

OWL Object Property domain/range restrictions to the same level classes


I want to design an object property which is always linked only between the same level of classes. For example,

enter image description here

I want to limit the property isCounterPartOf to be an arc of the sibling nodes which belong to the same upper class, such as

house isCounterPartOf cars
bad isCounterPartOf good
slow isCounterPartOf fast

and the property should NOT link between classes of different levels (those having different ancestors), like

cars isCounterPartOf bad
cars isCounterPartOf object
cars isCounterPartOf Entity

Is there a way to do this with defining only one property?


Solution

  • Assuming your objective is when :isCounterPartOf links two individuals, and one is a member of e.g. :Bad, then the other should be classified as :Good, you don't need to define domain and range of :isCounterPartOf, just that it is owl:SymmetricProperty. You only need to define your classes, :Bad to be equivalent of :isCounterPartOf some :Good and :Good to be equivalent of :isCounterPartOf some :Bad, and for all "pairs" of classes respectively.

    Then if:

    :A :isCounterPartOf :B

    :C :isCounterPartOf :B

    :A a :Slow

    :C a :Bad

    then :B will be classified as :Fast and :Good.

    Clarification (based on the comments)

    In the example above, 1. :isCouterPartOf is a symetric object property:

    :isCounterPartOf rdf:type owl:ObjectProperty ,
                              owl:SymmetricProperty .
    
    1. :Good, :Bad, :Slow and :Fast are OWL classes, for which: (no idea why the code formatting doesn't work)

      :Bad rdf:type owl:Class ; owl:equivalentClass [ rdf:type owl:Restriction ; owl:onProperty :isCounterPartOf ; owl:someValuesFrom :Good ] .

      :Fast rdf:type owl:Class ; owl:equivalentClass [ rdf:type owl:Restriction ; owl:onProperty :isCounterPartOf ; owl:someValuesFrom :Slow ] .

      :Good rdf:type owl:Class ; owl:equivalentClass [ rdf:type owl:Restriction ; owl:onProperty :isCounterPartOf ; owl:someValuesFrom :Bad ] .

      :Slow rdf:type owl:Class ; owl:equivalentClass [ rdf:type owl:Restriction ; owl:onProperty :isCounterPartOf ; owl:someValuesFrom :Fast ] .

    2. :A, :B, and :C are individuals, for which it is asserted that: (again, no idea why the code formatting doesn't work)

      :A rdf:type owl:NamedIndividual , :Slow ;

      :isCounterPartOf :B .

      :B rdf:type owl:NamedIndividual , owl:Thing .

      :C rdf:type owl:NamedIndividual , :Bad ;
      :isCounterPartOf :B .

    Based on these assertions, when you run the reasoner, you'll have the following situation:

    :A rdf:type owl:NamedIndividual ,
                :Bad , #inferred
                :Slow ;
    
       :isCounterPartOf :B .
    
    :B rdf:type owl:NamedIndividual ,
                :Fast , #inferred
                :Good , #inferred
                owl:Thing ;
    
       :isCounterPartOf :A , #inferred
                        :C . #inferred
    
    :C rdf:type owl:NamedIndividual ,
                :Bad ,
                :Slow ; #inferred
    
       :isCounterPartOf :B .