Question

How to get Least Common Subsumer(LCS) of individuals in ontology using SPARQL Query? (I want to get common concept of two individuals. Here i have mentioned owl file code)

<!DOCTYPE rdf:RDF [
    <!ENTITY owl "http://www.w3.org/2002/07/owl#" >
    <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
    <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
    <!ENTITY ace_lexicon "http://attempto.ifi.uzh.ch/ace_lexicon#" >
    <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
]>

<rdf:RDF xmlns="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#"
     xml:base="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:ace_lexicon="http://attempto.ifi.uzh.ch/ace_lexicon#">
    <owl:Ontology rdf:about="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8"/>

    <owl:AnnotationProperty rdf:about="&ace_lexicon;CN_pl"/>

    <owl:AnnotationProperty rdf:about="&ace_lexicon;CN_sg"/>

    <owl:AnnotationProperty rdf:about="&ace_lexicon;PN_sg"/>

    <owl:Class rdf:about="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#BollwormsPests_Pesticide">
        <rdfs:subClassOf rdf:resource="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#Pesticide"/>
        <ace_lexicon:CN_pl>Bollworms_Pesticides</ace_lexicon:CN_pl>
        <ace_lexicon:CN_sg>Bollworms_Pesticide</ace_lexicon:CN_sg>
    </owl:Class>

    <owl:Class rdf:about="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#Carbamate">
        <rdfs:subClassOf rdf:resource="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#BollwormsPests_Pesticide"/>
        <ace_lexicon:CN_pl>Carbamates</ace_lexicon:CN_pl>
        <ace_lexicon:CN_sg>Carbamate</ace_lexicon:CN_sg>
    </owl:Class>

    <owl:Class rdf:about="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#Organophosphates">
        <rdfs:subClassOf rdf:resource="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#BollwormsPests_Pesticide"/>
        <ace_lexicon:CN_pl>Organophosphateses</ace_lexicon:CN_pl>
        <ace_lexicon:CN_sg>Organophosphates</ace_lexicon:CN_sg>
    </owl:Class>

    <owl:Class rdf:about="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#Pesticide">
        <ace_lexicon:CN_pl>Pesticides</ace_lexicon:CN_pl>
        <ace_lexicon:CN_sg>Pesticide</ace_lexicon:CN_sg>
    </owl:Class>

    <owl:NamedIndividual rdf:about="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#Carbaryl">
        <rdf:type rdf:resource="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#Carbamate"/>
        <ace_lexicon:PN_sg>Carbaryl</ace_lexicon:PN_sg>
    </owl:NamedIndividual>

    <owl:NamedIndividual rdf:about="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#Ethion">
        <rdf:type rdf:resource="http://www.semanticweb.org/chetan/ontologies/2014/5/untitled-ontology-8#Organophosphates"/>
        <ace_lexicon:PN_sg>Ethion</ace_lexicon:PN_sg>
    </owl:NamedIndividual>
</rdf:RDF>

Answer must be here BollwormsPests_Pesticide:

My Java code is :

package sparql;

import com.hp.hpl.jena.iri.impl.Main;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.InfModel;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.reasoner.Reasoner;
import com.hp.hpl.jena.reasoner.ReasonerRegistry;
import com.hp.hpl.jena.util.FileManager;
import com.hp.hpl.jena.sparql.syntax.*;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SPARQLReasoningQuery {

    public static void main(String args[]) throws FileNotFoundException, IOException {

        BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\Chetan\\Desktop\\Final Cotton Ontology\\query.txt"));
        String sparqlQuery;
        String[] finalStringArray = new String[2];
        String subString[];
        int i = 0;
        try {
            StringBuilder sb = new StringBuilder();
            String line = br.readLine();

            while (line != null) {
                sb.append(line);
                sb.append("\n");
                line = br.readLine();
            }
            sparqlQuery = sb.toString();
        } finally {
            br.close();
        }
        subString = sparqlQuery.split("\n", 2);

        Pattern pattern = Pattern.compile("\\?(\\w+)");
        Matcher matcher = pattern.matcher(subString[0]);

        while (matcher.find()) {
            finalStringArray[i] = matcher.group(1);
            i++;
        }
        sparqlTest(sparqlQuery, finalStringArray);
    }

    public static void sparqlTest(String sparqlQuery, String[] param) {
        FileManager.get().addLocatorClassLoader(Main.class.getClassLoader());
        Model model = FileManager.get().loadModel("C:\\Users\\Chetan\\Desktop\\Final Cotton Ontology\\CottonCropOntology.owl");
        Reasoner reasoner = ReasonerRegistry.getOWLReasoner().bindSchema(model);
        InfModel infmodel = ModelFactory.createInfModel(reasoner, model);
        String queryString = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
                + "PREFIX owl: <http://www.w3.org/2002/07/owl#> "
                + "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
                + "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> "
                + "PREFIX : <http://www.owl-ontologies.com/Ontology1359542935.owl#> " + sparqlQuery;
        Query query = QueryFactory.create(queryString);
        QueryExecution qexec = QueryExecutionFactory.create(queryString, infmodel);
        System.out.println("\t\t" + param[0] + "\t\t\t\t\t\t\t\t\t" +((param[1] != null)?param[1]:""));
        try {
            ResultSet results = qexec.execSelect();
            while (results.hasNext()) {
                QuerySolution soln = results.nextSolution();
                Resource r = soln.getResource(param[0]);
                System.out.print(r);
                if (param[1] != null) {
                    Literal name = soln.getLiteral(param[1]);
                    System.out.print("\t" + name.getString());
                }
                System.out.println();
            }
        } finally {
            qexec.close();
        }
    }
}

I use following query as taylor suggested me:

select ?lcs where {
  ?lcs ^rdf:type :Carbaryl, :Ethion ;
       a owl:Class .
  filter not exists { 
    ?llcs ^rdf:type :Carbaryl, :Ethion ;
          a owl:Class ;
          rdfs:subClassOf+ ?lcs .
  }
}

Still getting blank in answer

Was it helpful?

Solution

This may be a duplicate of finding common superclass and length of path in class hierarchies, but that question doesn't have an accepted answer, and is also asking about path length, which makes things more complicated. In general, you can find common superclasses of classes ?subclass1 and ?subclass2 with:

?subclass1 rdfs:subClassOf* ?superclass .
?subclass2 rdfs:subClassOf* ?superclass .

You can make that shorter with:

?superclass ^rdfs:subClassOf* ?subclass1, ?subclass2 .

That will find all common superclasses of the two subclasses. There may not be a single most specific common superclass, but you can find those that are as specific as possible by asking for only those superclasses that are not subclasses of any other superclass:

?superclass ^rdfs:subClassOf* ?subclass1, ?subclass2 .
filter not exists { 
  ?moreSpecificSuperclass rdfs:subClassOf ?superclass ;
                          ^rdfs:subClassOf* ?subclass1, ?subclass2 .
}

To find the LCS of some particular instances, you'd need to do something like this:

?instance1 rdf:type/rdfs:subClassOf* ?lcs .
?instance2 rdf:type/rdfs:subClassOf* ?lcs .
filter not exists {
  ?instance1 rdf:type/rdfs:subClassOf* ?sublcs .
  ?instance2 rdf:type/rdfs:subClassOf* ?sublcs .
  ?sublcs rdfs:subClassOf ?lcs .
}

As before, you can shorten that bit to:

?lcs ^(rdf:type/rdfs:subClassOf*) ?instance1, ?instance2 .
filter not exists {
  ?sublcs ^(rdf:type/rdfs:subClassOf*) ?instance1, ?instance2 ;
          rdfs:subClassOf ?lcs . 
}

The first line ensures that ?type is a common type of ?x and ?y, and the filter expression ensures that there's no subclass of ?type that is also a common type of ?x and ?y.

Here's a minimal example that shows that this approach works. Here's an ontology with the class hierarchy:

owl:Thing
  A
    B
      C {c}
      D {d}
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns="https://stackoverflow.com/q/23510851/1281433/lcs#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
  <owl:Ontology rdf:about="https://stackoverflow.com/q/23510851/1281433/lcs"/>
  <owl:Class rdf:about="https://stackoverflow.com/q/23510851/1281433/lcs#A"/>
  <owl:Class rdf:about="https://stackoverflow.com/q/23510851/1281433/lcs#B">
    <rdfs:subClassOf rdf:resource="https://stackoverflow.com/q/23510851/1281433/lcs#A"/>
  </owl:Class>
  <owl:Class rdf:about="https://stackoverflow.com/q/23510851/1281433/lcs#C">
    <rdfs:subClassOf rdf:resource="https://stackoverflow.com/q/23510851/1281433/lcs#B"/>
  </owl:Class>
  <owl:Class rdf:about="https://stackoverflow.com/q/23510851/1281433/lcs#D">
    <rdfs:subClassOf rdf:resource="https://stackoverflow.com/q/23510851/1281433/lcs#B"/>
  </owl:Class>
  <owl:NamedIndividual rdf:about="https://stackoverflow.com/q/23510851/1281433/lcs#c">
    <rdf:type rdf:resource="https://stackoverflow.com/q/23510851/1281433/lcs#C"/>
  </owl:NamedIndividual>
  <owl:NamedIndividual rdf:about="https://stackoverflow.com/q/23510851/1281433/lcs#d">
    <rdf:type rdf:resource="https://stackoverflow.com/q/23510851/1281433/lcs#D"/>
  </owl:NamedIndividual>
</rdf:RDF>

The individuals c and d are elements of the classes C and D, respectively. The LCS is B. Here's the query and its results:

prefix :      <https://stackoverflow.com/q/23510851/1281433/lcs#> 
prefix owl:   <http://www.w3.org/2002/07/owl#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>

select ?lcs where {
  ?lcs ^(rdf:type/rdfs:subClassOf*) :c, :d ;
       a owl:Class .
  filter not exists { 
    ?llcs ^(rdf:type/rdfs:subClassOf*) :c, :d ;
          a owl:Class ;
          rdfs:subClassOf+ ?lcs .
  }
}
-------
| lcs |
=======
| :B  |
-------
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top