SPARQL:返回由指定或等效类完成的所有交叉点

时间:2014-03-14 04:25:18

标签: java rdf sparql jena owl

如果我将ABC和CDE类定义为A,B,C,D,E类的交叉点,如下所示:

<Class rdf:about="&blah;ABC">
    <equivalentClass>
        <Class>
            <intersectionOf rdf:parseType="Collection">
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;A"/>
                </Restriction>
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;B"/>
                </Restriction>
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;C"/>
                </Restriction>
            </intersectionOf>
        </Class>
    </equivalentClass>
</Class>

<Class rdf:about="&blah;CDE">
    <equivalentClass>
        <Class>
            <intersectionOf rdf:parseType="Collection">
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;C"/>
                </Restriction>
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;D"/>
                </Restriction>
                <Restriction>
                    <onProperty rdf:resource="&blah;hasMarker"/>
                    <someValuesFrom rdf:resource="&blah;E"/>
                </Restriction>
            </intersectionOf>
        </Class>
    </equivalentClass>
</Class>

如何查询SPARQL中给定输入类集满足其限制的所有交集类?例如,如果我将A,B,C,D,E,F,G输入此查询,我希望能够回来

ABC A
    B
    C
CDE C
    D
    E

另外两个皱纹:如果我查询A,Z,C,其中Z是B的等价类,那么这应该匹配并理想地返回

ABC A
    Z
    C

其次,结果应该只返回最大匹配;因此,如果存在ABCD类并且我在A,B,C,D之间进行查询,则它将返回ABCD而不是ABC。

提前致谢!

更新

为了澄清,除非所有组成类都在提供的输入列表中,否则我不希望与交集类匹配。例如,如果我向查询提供A,B,我不想让ABC回来。如果我提供A,B,C,D,我确实想要回ABC。

我的用例是这样的:我有一组数据点,在每个数据点中我都识别出一组任意的基本概念A,B,C,D ......等等,每个都有不同的可能性。我想问一下本体“这个列表包含哪些更高级别的概念(即交叉点)?”

目前,我的查询看起来像这样(考虑到我在上面概述的本体中的限制和onProperty):

SELECT DISTINCT ?intclass ?inputclasses
WHERE
{
  ?intclass owl:equivalentClass /
    owl:intersectionOf /
    rdf:rest*/rdf:first /
    owl:someValuesFrom ?inputclasses
}
ORDER BY ?intclass
BINDINGS ?inputclasses { (:A) (:B) (:C) (:D) }

不幸的是,这回馈了我的本体中包含任何输入类的每个交集。我认为这是因为rest / first依次对输入列表依次评估每个交集的组成类,如果找到任何一个,则匹配。

我想要做的是(a)只有当交集中的所有类都出现在输入列表中时才会匹配,(b)推断来自类的匹配等效于输入列表中的类,(c)返回交集类以及与其匹配的输入列表中的类子集。也许这只是通过SPARQL不可行的?

1 个答案:

答案 0 :(得分:2)

首先,我不认为你能够完成你想做的事情,但我认为你能够相当接近。特别是,我认为你提到的最大限度约束将特别难以实现。通过这种方式处理SPARQL中的一组内容通常很困难。尽管如此,我们可以看到我们能做些什么。

使用

的数据

使用我们可以实际使用的一些示例数据来回答这些问题要容易得多。我也从简化问题开始,因此ABC只是A,B和C的交叉点,以及C,D和E的CDE。目前还没有限制类(它们赢得了&t; t实际上增加了很多复杂性。出于测试目的(能够确保我们的查询不会返回不想要的值),我还添加了类F和DEF。在Turtle序列化中查看数据也更容易,因为它更接近SPARQL模式语法。这是简化的本体论:

@prefix :      <http://stackoverflow.com/q/22396095/1281433/intersections#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

<http://stackoverflow.com/q/22396095/1281433/intersections>
        a       owl:Ontology .

:A      a       owl:Class .
:B      a       owl:Class .
:C      a       owl:Class .
:D      a       owl:Class .
:E      a       owl:Class .
:F      a       owl:Class .

:ABC    a                    owl:Class ;
        owl:equivalentClass  [ a                   owl:Class ;
                               owl:intersectionOf  ( :A :B :C )
                             ] .

:CDE    a                    owl:Class ;
        owl:equivalentClass  [ a                   owl:Class ;
                               owl:intersectionOf  ( :C :D :E )
                             ] .

:DEF    a                    owl:Class ;
        owl:equivalentClass  [ a                   owl:Class ;
                               owl:intersectionOf  ( :D :E :F )
                             ] .

查找类的交叉点

对于每个等同于交集类的类,有一个从类到每个相交类的路径。我们可以利用这个事实来找到相当于包含A,B和C的交叉点的任何类:

prefix :      <http://stackoverflow.com/q/22396095/1281433/intersections#>
prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
prefix owl:   <http://www.w3.org/2002/07/owl#>
prefix xsd:   <http://www.w3.org/2001/XMLSchema#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select distinct ?class where {
  ?class owl:equivalentClass/
         owl:intersectionOf/
         rdf:rest*/rdf:first :A, :B, :C .
}
---------
| class |
=========
| :ABC  |
---------

但是,这并不能找到CDE,因为此查询要求的内容具有指定值的 all 。听起来你想要的是要求具有至少一个指定值的东西,而不是非指定值。您可能需要两次编写类列表,但您可以这样做:

prefix :      <http://stackoverflow.com/q/22396095/1281433/intersections#>
prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
prefix owl:   <http://www.w3.org/2002/07/owl#>
prefix xsd:   <http://www.w3.org/2001/XMLSchema#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?class ?i where {
  values ?i { :A :B :C :D :E }
  ?class owl:equivalentClass/
         owl:intersectionOf/
         rdf:rest*/rdf:first ?i .

  filter not exists { 
    ?class owl:equivalentClass/
           owl:intersectionOf/
           rdf:rest*/rdf:first ?j .
    filter( !(?j in (:A, :B, :C, :D, :E )) )
  }
}
order by ?class ?i
--------------
| class | i  |
==============
| :ABC  | :A |
| :ABC  | :B |
| :ABC  | :C |
| :CDE  | :C |
| :CDE  | :D |
| :CDE  | :E |
--------------

请注意,DEF不在结果中,因为虽然它有D和E,但它的值也不是任何指定的类,F。

由于我们过滤掉了输入列表中包含 元素的每个交集类,我们保证我们保留的每个交集类在输入列表中只有 元素。鉴于这种措辞,我们实际上可以使查询更简单:

prefix :      <http://stackoverflow.com/q/22396095/1281433/intersections#>
prefix owl:   <http://www.w3.org/2002/07/owl#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?class ?i where {
  # find each ?class that's equivalent to an intersection
  ?class owl:equivalentClass/owl:intersectionOf ?list .

  # and grab the intersecting classes for the results
  ?list rdf:rest*/rdf:first ?i .

  # but filter out any ?class that has an intersecting
  # class that's not in the input list.
  filter not exists { 
    ?list rdf:rest*/rdf:first ?element .
    filter( !(?element in (:A, :B, :C, :D, :E )) )
  }
}
--------------
| class | i  |
==============
| :ABC  | :A |
| :ABC  | :B |
| :ABC  | :C |
| :CDE  | :C |
| :CDE  | :D |
| :CDE  | :E |
--------------

这可能效率较低,因为现在您正在找到每个交集类并过滤掉不合格的交集类,而不是只找到可能可接受的那些,然后过滤掉一些。这有多大可能取决于您的实际数据。

我认为这回答了你问题的主要部分。要处理限制的交集,您只需要注意所讨论的类之间的路径有点不同。您希望匹配列表元素的owl:someValuesFrom属性的值,而不是匹配列表中的元素,因此路径需要最终owl:someValuesFrom

?class owl:equivalentClass/
       owl:intersectionOf/
       rdf:rest*/rdf:first/
       owl:someValuesFrom ?i .

超越这个

处理其他等价物

  

如果我查询A,Z,C,其中Z是B的等价类,那么这个   应匹配并理想地返回

ABC A
    Z
    C

这里的查询开始变得有点复杂,但它仍然可以管理。诀窍在于,不是选择?i作为交集列表的简单成员,而是需要选择?i作为列出交集列表元素等效的输入的成员。然后,过滤 out 交叉点也有点复杂。您需要确保有 no 元素,以使输入列表的 no 元素等同于intersection元素。把这些放在一起,你会得到这个问题:

prefix :      <http://stackoverflow.com/q/22396095/1281433/intersections#>
prefix owl:   <http://www.w3.org/2002/07/owl#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?class ?i where {
  ?class owl:equivalentClass/
         owl:intersectionOf ?list .
  ?list rdf:rest*/rdf:first/(owl:equivalentClass|^owl:equivalentClass)* ?i .
  filter( ?i in (:A, :B, :C, :D, :E ))

  filter not exists { 
    ?list rdf:rest*/rdf:first ?element .
    filter not exists {
      ?element (owl:equivalentClass|^owl:equivalentClass)* ?j
      filter( ?j in (:A, :B, :C, :D, :E ))
    }
  }
}

如果添加以下数据

:Z      a       owl:Class ;
        owl:equivalentClass :B .

:AZC    a                    owl:Class ;
        owl:equivalentClass  [ a                   owl:Class ;
                               owl:intersectionOf  ( :A :Z :C )
                             ] .

然后你会得到这些结果:

--------------
| class | i  |
==============
| :ABC  | :A |
| :ABC  | :B |
| :ABC  | :C |
| :AZC  | :A |
| :AZC  | :B |
| :AZC  | :C |
| :CDE  | :C |
| :CDE  | :D |
| :CDE  | :E |
--------------

这可能不会太难(尽管获得最终查询会有点棘手)。重要的是,等效的类将通过路径(owl:equivalentClass|^owl:equivalentClass)*相关联。

最大结果

  

其次,结果应该只返回最大匹配;所以,如果有   存在一个ABCD类,我查询A,B,C,D,它将返回ABCD   而不是ABC。

如果你能做到这一点,这部分可能会相当困难。 SPARQL实际上并不是为处理这种查询而设计的。可以很容易地计算交集类相交的类数,但是如果可以的话,比较这些子集关系的集合会相当困难。