排除析取的高效 SPARQL 查询 类

Efficienty SPARQL query to exclude disjunct classes

我正在开发 ontology 来模拟制造系统中的关系。我把它分解成一个类似的盘子方案:

ex:potatoes  rdf:type            owl:Class .
ex:fish  rdf:type                owl:Class .
ex:beef  rdf:type                owl:Class .

ex:rice  rdf:type                owl:Class ;
         owl:disjointWith        ex:potatoes .

ex:chicken  rdf:type             owl:Class ;
            owl:disjointWith     ex:fish .

ex:pork  rdf:type                owl:Class ;
         owl:disjointWith        ex:beef .

ex:dish1  rdf:type              owl:Class ;
          rdfs:subClassOf       ex:dishes ;
          owl:unionOf      ( ex:pork ex:potatoes ) .

ex:dish2  rdf:type           owl:Class ;
          rdfs:subClassOf    ex:dishes ;
          owl:unionOf      ( ex:rice ex:chicken ) .

ex:dish3  rdf:type           owl:Class ;
          rdfs:subClassOf    ex:dishes ;
          owl:unionOf      ( ex:fish ex:potatoes ) .

ex:dish4  rdf:type           owl:Class ;
          rdfs:subClassOf   ex:dishes ;
          owl:unionOf      ( ex:beef ex:rice ) .

所以我有一些分离 类 我想这样查询模型:如果有人说他想要 ricechicken,排除所有包含分离词 类 的菜肴(这里是鱼和土豆)。经过一些研究,我得到了这样的结果:

              "PREFIX ex:   <http://example.org/>"+
             "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"+
              "PREFIX owl: <http://www.w3.org/2002/07/owl#>"+
              "PREFIX list: <http://jena.hpl.hp.com/ARQ/list#>"+
              "PREFIX  rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>"+    
                "SELECT ?x "+
                        "WHERE {"+
                           "?x rdfs:subClassOf ex:dishes. "+
                           "FILTER (!isBlank(?x))"+
                           "FILTER NOT EXISTS { "+
                             "?x rdfs:subClassOf ?y ."+
                             "?y rdfs:subClassOf ex:dishes ."+
                             "FILTER (?x!=?y)"+
                           "}"+
                           "FILTER NOT EXISTS {"+
                         "?z rdfs:subClassOf ?x ." +
                         "?z owl:disjointWith ex:chicken . }" +
                         "FILTER NOT EXISTS {"+
                         "?z rdfs:subClassOf ?x ." +
                         "?z owl:disjointWith ex:rice . }" +
                        "}";

有效,我得到了正确的结果:

------------
| x        |
============
| ex:dish4 |
| ex:dish2 |
------------

有没有更有效的方法来做到这一点?似乎不必要的复杂。并且必须使用“FILTER NOT EXISTS { ?z rdfs:subClassOf ?x 。 ?z owl:disjointWith ex:chicken 。 } 每次? 有什么建议吗?

我对数据做了一些修改,使一些表示更直接,并且没有对 OWL 语义的混淆。但是,它直接类似于您正在使用的表示,因此您应该能够更改属性并使它起作用。首先,这是数据。你有一些成分,某些成分与其他成分不相容。 (不相容意味着不相交,但不相交并不意味着不相容。毕竟,鸡肉和米饭显然是不同的东西,因此不相交类,但这并不意味着它们作为成分不相容。)

@prefix : <urn:ex:>

# Incompatibities

:rice     :incompatibleWith :potatoes .
:potatoes :incompatibleWith :rice .
:chicken  :incompatibleWith :fish .
:fish     :incompatibleWith :chicken .
:beef     :incompatibleWith :pork .
:pork     :incompatibleWith :beef .

# Ingredients
:dish1 a :Dish ; :ingredients (:pork :potatoes) .
:dish2 a :Dish ; :ingredients (:rice :chicken) .
:dish3 a :Dish ; :ingredients (:fish :potatoes) .
:dish4 a :Dish ; :ingredients (:beef :rice) .

现在,查询只需要询问菜肴,然后检查菜肴中的每种成分与鸡肉或米饭不相容。

prefix : <urn:ex:>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?dish where {
  ?dish a :Dish .
  filter not exists {
    ?dish :ingredients/rdf:rest*/rdf:first ?ingredient .
    ?ingredient :incompatibleWith ?incompatibleIngredient .
    filter (?incompatibleIngredient in (:rice, :chicken))
  }
}
----------
| dish   |
==========
| :dish4 |
| :dish2 |
----------

如果你真的很在意space,你甚至可以把这两行结合起来

?dish :ingredients/rdf:rest*/rdf:first ?ingredient .
?ingredient :incompatibleWith ?incompatibleIngredient .

进入

?dish :ingredients/rdf:rest*/rdf:first/:incompatibleWith ?incompatibleIngredient .

我认为这有点难读,因为它隐含了列表中的值(通过 :ingredients/rdf:rest*/rdf:first) 是这道菜的配料。