Search code examples
sparqlrdfontologyprotegeobject-property

SPARQL Query that retrieves individuals of a subclass that owned by another individual of a class in Protégé?


I started using Protégé as required by my job and currently learning how to use SPARQL Query for it.

I got a question in my mind as following:

Let's say that I have an ontology as this:

👇owl:think
     👇 Fruit
          - Apples
          - Bananas
     -Owner

Now, I have an individual for the subclass "Apples" and let's name it "GreenApple". Also for the subclass "Bananas" and called "SweetyBanana".

I have many individuals for the class "Owner", but let's name one of them through a data property "hasName" as "Jimmy".

The individual which hasName of "Jimmy" has a relationship through an object property called "hasFruit" and it links him to the "GreenApple" and to the "SweetyBanana" individuals as following:

{ Individual (which is named "Jimmy" by the hasName property) hasFruit GreenApple }.
{ Individual (which is named "Jimmy" by the hasName property) hasFruit SweetyBanana }.

Now my question is that if I want to do SPARQL Query that retrieves the Fruits that owned by the individual "Jimmy" and belong to the "Apples" subclass. What would be the right structure of such query. I tried many but non is working perfectly.

I tried this but no hope:

?ID :hasName "Jimmy"^^xsd:string .
?ID rdf:subClassOf :Fruit .
?ID rdf:subClassOf ?FruitList  .
?FruitList :hasFruit ?JimmyFruit . 

Also tried this, but no hope too:

?ID :hasName "Jimmy"^^xsd:string .
?ID rdf:subClassOf :Apples .
?ID rdf:subClassOf ?AppleFruit  .
?AppleFruit :hasFruit ?JimmyFruit .

So simply that I just want the query to show me the fruit that owned by Jimmy which is under the subclass of Apples. I don't want to see the Bananas individuals, nor that fruits which are owned by other owners.

Remmber: hasName is a Data Proprty. hasFriut is an Object Property. Apples is a subclass of the class Fruit. Bananas is a subclass of the class Fruit. Owner is a class . "Jimmy" is a value. GreenApple is an individual that in the Apples subclass. SweetyBanana is an individual that in the Bananas subclass.


Solution

  • You would need something like:

    SELECT *
    WHERE {
    ?id :hasName "Jimmy" ;
        :hasFruit ?fruit .
    ?fruit rdf:type/rdfs:subClassOf* :Apples }
    

    Now, it doesn't matter if :Apples is a subclass of :Fruit, as you are only interested in apples anyway.

    In response to your comment, we can use a property path:

    ?fruit rdf:type/rdfs:subClassOf* :Apples
    

    means that ?fruit is either an instance of :Apples, or an instance of a (direct or indirect) subclass of :Apples.