Efficienty SPARQL查询以排除析取类

时间:2015-07-03 14:51:19

标签: rdf sparql jena owl

我正在开发一种本体论来模拟制造系统中的关系。我把它分解成类似的菜肴计划:

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

所以我有一些分离类,我想查询这样的模型:如果有人说他想要,请排除每个包含析取类的菜(这里是鱼和土豆)。经过一些研究后,我有这样的想法:

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

有更有效的方法吗?似乎不必要的复杂。并且必须使用&#34; FILTER NOT EXISTS {添加整个块                          ?z rdfs:subClassOf?x。                          ?z owl:disjointWith ex:chicken。 } 每次? 有什么建议吗?

1 个答案:

答案 0 :(得分:2)

我已经修改了一些数据,使一些表示更直接,并且没有关于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 |
----------

如果你真的关心空间,你甚至可以将两行结合起来

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

进入

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

我认为这有点难以阅读,因为隐含的是列表中的值(通过以下:ingredients / rdf:rest * / rdf:first 得到的)是菜中的成分。