I want to design an object property which is always linked only between the same level of classes. For example,
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?
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 .
: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 ] .
: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 .