SPARQL:返回指定或等效类满足的所有交集

2023-12-11

如果我将 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。

提前致谢!

UPDATE:

为了澄清,我不想匹配交集类,除非所有组成类都在提供的输入列表中。例如,如果我向查询提供 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) }

不幸的是,这返回了我的本体中包含任何输入类的每个交集。我认为这是因为剩余/第一依次根据输入列表评估每个交集的组成类,并且如果找到其中任何一个则匹配。

我想做的是(a)仅当交集中的所有类都存在于输入列表中时才匹配,(b)从与输入列表中的类等效的类推断匹配项,并且(c)返回交集类以及输入列表中与之匹配的类的子集。也许这通过 SPARQL 不可行?


首先,我不认为你能够完全做你想做的事,但我认为你将能够相当接近。特别是,我认为你提到的最大值约束将特别难以实现。以这种方式处理 SPARQL 中的一组事物通常有点困难。尽管如此,我们还是可以看到我们能做什么。

需要使用的数据

使用我们可以实际使用的一些示例数据来回答此类问题要容易得多。我还从简化问题开始,这样 ABC 只是 A、B 和 C 的交集,以及 C、D 和 E 的 CDE。还没有限制类(它们不会增加太多复杂性,实际上)。出于测试目的(能够确保我们的查询不会返回不需要的值),我还添加了类 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 的值。

因为我们过滤掉了每个具有元素的交集类not在输入列表中,我们保证我们的每个交集类keep has only元素are在输入列表中。考虑到这个措辞,我们实际上可以使查询变得更简单:

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

但这可能效率较低,因为现在您发现every交叉类并过滤掉不合格的类,而不是只找到那些might可以接受,然后过滤掉一些。这有多重要可能取决于您的实际数据。

我认为这回答了你问题的主要部分。要处理限制的交叉点,您只需要注意相关类之间的路径有点不同。您想要匹配的不是列表中的元素,而是匹配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输入列表中与交集元素等效的元素。将所有这些放在一起,您会得到以下查询:

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 实际上并不是为处理此类查询而设计的。计算交集类相交的类数量是很容易的,但是如果你能做到的话,比较这些集合的子集关系将相当困难。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SPARQL:返回指定或等效类满足的所有交集 的相关文章

随机推荐