如何使用SPARQL查询在本体中获得最小公共子方法?

时间:2014-05-07 06:58:05

标签: sparql

如何使用SPARQL查询获取本体中个体的最小公共子(LCS)? (我想得到两个人的共同概念。这里我提到了猫头鹰文件代码)

<!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>

答案必须在这里BollwormsPests_Pesticide:

我的Java代码是:

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();
        }
    }
}

我使用以下查询,因为泰勒建议我:

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 .
  }
}

答案仍然空白

1 个答案:

答案 0 :(得分:3)

这可能是finding common superclass and length of path in class hierarchies的副本,但该问题没有得到接受的答案,并且还询问路径长度,这会使事情变得更复杂。通常,您可以找到类?subclass1?subclass2的常见超类:

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

您可以使用以下内容缩短时间:

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

这将找到两个子类的所有公共超类。可能没有单个最具体的公共超类,但您可以通过仅请求那些不是任何其他超类的子类的超类来找到那些尽可能具体的超类:

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

要查找某些特定实例的LCS,您需要执行以下操作:

?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 .
}

和以前一样,您可以将该位缩短为:

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

第一行确保?类型是?x和?y的常见类型,并且过滤器表达式确保没有?类型的子类,它也是?x和?y的常见类型。

这是一个最小的例子,表明这种方法有效。这是一个具有类层次结构的本体:

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>

个体c和d分别是C和D类的元素。 LCS是B.这里是查询及其结果:

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  |
-------