SPARQL:找到具有相同三元组的主题?

SPARQL: find subjects with the same set of triples?

我正在尝试识别具有完全相同的“一组”三元组的主题。在此示例数据中,:Set2 应被标识为与 :Set1 的唯一完全匹配,而 :Set1:Set3 不是完全匹配,因为值 :VAL_E.

@prefix :  <https://www.example.org/Eg#>.

:Set1 :hasValue  :VAL_A, :VAL_B, :VAL_C, :VAL_D .
:Set2 :hasValue  :VAL_A, :VAL_B, :VAL_C, :VAL_D .
:Set3 :hasValue  :VAL_A, :VAL_B, :VAL_C, :VAL_D, :VAL_E .
:Set4 :hasValue  :VAL_A, :VAL_B .
:Set5 :hasValue  :VAL_F, :VAL_G, :VAL_H, :VAL_I, :VAL_J .

我在 Whosebug 上找到了 SPARQL 示例,它可以识别在 :Set1 和其他组之间匹配的单个三元组,甚至 number of matches ,但没有找到如何识别一组三元组的精确匹配作为一个整体。我希望需要 FILTER NOT EXISTS!SAMETERM 的组合,但我无法获得正确的语法。

更新: 我改编了@StanislavKralin 的 SPARQL 以找到与 :Set1 相同的其他集合。它几乎可以工作。

SELECT DISTINCT  ?s2 {
  :Set1 ?p ?o .
  ?s2 ?p ?o .
  FILTER NOT EXISTS { :Set1 ?p1 ?o1 . FILTER NOT EXISTS { ?s2 ?p1 ?o1 } }
  FILTER NOT EXISTS { ?s2 ?p2 ?o2 . FILTER NOT EXISTS { :Set1 ?p2 ?o2 } } # omits match from :Set3 to :Set1
  FILTER (STR(:Set1) < STR(?s2))
}

但是,我的查询结果中包含:Set4,这是不正确的。

:Set2
:Set4

我错过了什么?

[更新] 如以下评论所述,Stanislav 在 Stardog 社区论坛上提供了进一步的解释和代码:https://community.stardog.com/t/unexpected-sparql-filter-results/2745/14,以及 Pavel Klinov 解释 Stardog 当前行为的其他信息。正如您在那里看到的那样,已打开一张票以供解决。同时,Stanislav 提供的这段代码提供了正确的结果:

SELECT DISTINCT ?s1 ?s2 {
  ?s1 ?p ?o .   
  ?s2 ?p ?o .
  FILTER NOT EXISTS {
    ?s1 ?p ?o . 
    ?s2 ?p ?o . 
    ?s1 ?p1 ?o1 . 
    FILTER NOT EXISTS { ?s2 ?p1 ?o1 } }
  FILTER NOT EXISTS {
    ?s1 ?p ?o . 
    ?s2 ?p ?o .
    ?s2 ?p2 ?o2 . 
    FILTER NOT EXISTS { ?s1 ?p2 ?o2 } }
  FILTER (STR(?s1) < STR(?s2))
}

在 Apache Jena Fuseki 和 Ontotext GraphDB 中测试:

SELECT DISTINCT ?s1 ?s2 {
  ?s1 ?p ?o .
  ?s2 ?p ?o .
  FILTER NOT EXISTS { ?s1 ?p1 ?o1 . FILTER NOT EXISTS { ?s2 ?p1 ?o1 } }
  FILTER NOT EXISTS { ?s2 ?p2 ?o2 . FILTER NOT EXISTS { ?s1 ?p2 ?o2 } }
  FILTER (STR(?s1) < STR(?s2))
}

说明

S1S2分别为以:s1:s2为主体的三元组。
S1 ≡ S2 是什么意思?这意味着 S1 ⊆ S2S2 ⊆ S1.
S1 ⊆ S2 是什么意思?这意味着 ∀x(x ∈ S1 → x ∈ S2).
不幸的是,在 SPARQL 中没有类似 ('for all') 的东西。
但是,可以改写 ¬∃x¬(x ∈ S1 → x ∈ S2) 并使用 SPARQL 的 NOT EXISTS.
最后,x ∈ S1可以翻译成:s1 ?p ?o.

另见