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
:isCounterPartOflinks 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 isowl:SymmetricProperty. You only need to define your classes,:Badto be equivalent of:isCounterPartOf some :Goodand:Goodto 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 :Badthen
:Bwill be classified as:Fastand:Good.Clarification (based on the comments)
In the example above, 1.
:isCouterPartOfis a symetric object property::Good,:Bad,:Slowand:Fastare 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:Care 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: