Search code examples
semantic-webowlprotege4

OWL: property restriction based on values: is it possible at all?


I look for a clearly OWL solution to define a property that is a restriction of another property, similar to an equivalent class. Restriction is based on data properties of either the domain or the range. The restricted property is definitely a subproperty, and, must be inferred.

"kid","mother","father" are Person s father.gender = "male" data property mother.gender = "female"

(a Male subclassOf Person = equivalent class "gender value "male")

father parentOf child ' object relation mother parentOf child ' object relation

How to defined fatherOf property, based on parentOf and gender of father? Clearly it is a subproperty of parentOf.

However, equivalent object property editor in Protégé does not allow setting a property query, even I do not really see if this can be solved with a property chain.

Defining fatherOf as subproperty and (manually) setting fatherOf instead of parentOf is not an option, since this family example is an oversimplified situation of a more complex scenario.

<Declaration>
    <Class IRI="#Person"/>
</Declaration>
<Declaration>
    <ObjectProperty IRI="#fatherOf"/>
</Declaration>
<Declaration>
    <ObjectProperty IRI="#parentOf"/>
</Declaration>
<Declaration>
    <DataProperty IRI="#gender"/>
</Declaration>
<Declaration>
    <NamedIndividual IRI="#father"/>
</Declaration>
<Declaration>
    <NamedIndividual IRI="#kid"/>
</Declaration>
<Declaration>
    <NamedIndividual IRI="#mother"/>
</Declaration>
<ClassAssertion>
    <Class IRI="#Person"/>
    <NamedIndividual IRI="#father"/>
</ClassAssertion>
<ClassAssertion>
    <Class IRI="#Person"/>
    <NamedIndividual IRI="#kid"/>
</ClassAssertion>
<ClassAssertion>
    <Class IRI="#Person"/>
    <NamedIndividual IRI="#mother"/>
</ClassAssertion>
<ObjectPropertyAssertion>
    <ObjectProperty IRI="#parentOf"/>
    <NamedIndividual IRI="#father"/>
    <NamedIndividual IRI="#kid"/>
</ObjectPropertyAssertion>
<ObjectPropertyAssertion>
    <ObjectProperty IRI="#parentOf"/>
    <NamedIndividual IRI="#mother"/>
    <NamedIndividual IRI="#kid"/>
</ObjectPropertyAssertion>
<DataPropertyAssertion>
    <DataProperty IRI="#gender"/>
    <NamedIndividual IRI="#father"/>
    <Literal datatypeIRI="&rdf;PlainLiteral">male</Literal>
</DataPropertyAssertion>
<DataPropertyAssertion>
    <DataProperty IRI="#gender"/>
    <NamedIndividual IRI="#mother"/>
    <Literal datatypeIRI="&rdf;PlainLiteral">female</Literal>
</DataPropertyAssertion>
<SubObjectPropertyOf>
    <ObjectProperty IRI="#fatherOf"/>
    <ObjectProperty IRI="#parentOf"/>
</SubObjectPropertyOf>
<DataPropertyDomain>
    <DataProperty IRI="#gender"/>
    <Class IRI="#Person"/>
</DataPropertyDomain>
<DataPropertyRange>
    <DataProperty IRI="#gender"/>
    <Datatype abbreviatedIRI="xsd:string"/>
</DataPropertyRange>

Solution

  • So, you have something like the following in your data:

    :x  :parentOf  :y .
    :x  :gender  "male" .
    

    and you would like to infer that:

    :x  :fatherOf  :y .
    

    I'm afraid you cannot do this in OWL. For cases like this one, you may want to rely on a rule language like SWRL, SPIN, etc. However, for the particular case of father, mother, etc, you could do the following:

    • define :hasParent as the inverse of :parentOf;
    • restrict the cardinality of :hasParent to 2;
    • define :hasFather as the inverse of :fatherOf;
    • make :hasFather a owl:FunctionalProperty;
    • define :hasMother as the inverse of :motherOf;
    • make :hasMother a owl:FunctionalProperty;
    • define the class :Man of male people;
    • define the class :Woman of female people;
    • make :Man disjointWith :Woman;
    • set the range of :hasFather to :Man;
    • set the range of :hasMother to :Woman.

    So the ontology looks like this (in Turtle because I'm not familiar with OWL/XML):

    :Person  a  owl:Class;
      rdfs:subClassOf  [
        a  owl:Restriction;
        owl:onProperty  :hasParent;
        owl:cardinality  2
      ] .
    :Man  a  owl:Class;
      owl:equivalentclass  [
        a  owl:Class;
        owl:intersectionOf (
          :Person
          [
             a  owl:Restriction;
             owl:onProperty  :gender;
             owl:hasValue  "male";
          ]
        )
      ] .
    :Woman  a  owl:Class;
      owl:equivalentclass  [
        a  owl:Class;
        owl:intersectionOf (
          :Person
          [
             a  owl:Restriction;
             owl:onProperty  :gender;
             owl:hasValue  "female";
          ]
        )
      ] .
    :gender  a  owl:DatatypeProperty, owl:FunctionalProperty .
    :hasParent  a  owl:ObjectProperty;
      owl:inverseOf  :parentOf;
      rdfs:domain  :Person;
      rdfs:range  :Person .
    :hasFather  a  owl:ObjectProperty, owl:FunctionalProperty;
      rdfs:subPropertyOf  :hasParent;
      rdfs:range  :Man .
    :hasMother  a  owl:ObjectProperty, owl:FunctionalProperty;
      rdfs:subPropertyOf  :hasParent;
      rdfs:range  :Woman .
    

    This should do the trick, but it's a very complicated ontology and reasoning with it may be very slow.

    Edit: I added that :gender must be functional, otherwise there could be a mother who is at the same time a father and that would not work!