查找所有类,无需推理

Find all classes, without reasoning

当我启用前向链接时,我会做:

"...WHERE { ?class rdf:type rdfs:Class }"

现在,我想在没有推理机的情况下进行,所以我尝试了:

"...WHERE { ?class rdf:type* rdfs:Class }"

但这给了我 类 而不是所有 类 的实例。例如缺少 rdfs:Resource。有任何想法吗?我的 ontology,如果重要的话,是 here

如果没有推理,您将无法获得 100% 保证的完整结果。例如,rdfs:Resource 通常根本不会在数据集中明确使用,因此无需推理 class 根本不会出现在您的数据中。但是对于大多数实际用途,您可以接近完整性。

什么时候已知某些资源是 class?有多种可能性:

  1. 当它是 rdfs:Class 类型时;
  2. 当它是rdf:type关系的对象时;
  3. 当它是 rdfs:subClassOf 关系的主语或宾语时;
  4. 当它用作rdfs:domainrdfs:range关系的对象时。

那么,这个怎么查询呢?那么第一个很简单:

SELECT ?c WHERE { ?c a rdfs:Class } 

顺便说一句:在 SPARQL 中,关键字 ardf:type 关系的 shorthand。请注意,您不需要传递地查询它(因此不需要 *)。

第二个也很简单:

SELECT ?c WHERE { [] rdf:type ?c }

[] 位表示一个匿名变量(因为我们对主题值不感兴趣 - 此时我们只想要对象)。

第三个有点棘手。我们可以将其分为两部分:首先查询属于 rdfs:subClassOf 关系的 subject 的所有资源:

SELECT ?c WHERE { ?c rdfs:subClassOf [] } 

然后查询关系的对象的所有资源:

SELECT ?c WHERE { [] rdfs:subClassOf ?c } 

现在,让我们看看是否可以将这两种模式组合在一个查询中。我们不能像那样将两个图形模式放在同一个 WHERE 子句中,因为那样会使它成为一个逻辑 AND(这意味着我们只会取回那些都属于 and[=78 主题的资源=] subclass 关系的对象)。所以我们需要使用逻辑或。在 SPARQL 中,这可以通过 UNION:

SELECT ?c 
WHERE { 
    { ?c rdfs:subClassOf [] }
    UNION
    { [] rdfs:subClassOf ?c }
}

然而,在这种情况下,我们还可以使用 属性 路径表达式以不同的方式表达逻辑或,如下所示:

SELECT ?c 
WHERE { ?c rdfs:subClassOf|^rdfs:subClassOf [] }

路径表达式p1|p2表示"match with any of these two relations"。运算符 ^ 表示 "query the inverse of the relation"。所以如果我们把它们放在一起,上面的路径表达式就是 "match with any triples where the subject is ?c and the relation is rdfs:subClassOf, or where the relation rdfs:subClassOf is inverted and thus the object matches with ?c".

我们可以用类似的方式查询第四种可能性:

SELECT ?c 
WHERE { [] rdfs:domain|rdfs:range ?c }

综合起来

SELECT ?c 
WHERE { 
     { ?c a rdfs:Class } 
     UNION 
     { [] rdf:type ?c }
     UNION
     { [] rdfs:domain|rdfs:range ?c }
     UNION
     { ?c rdfs:subClassOf|^rdfs:subClassOf [] }         
}

这可能会进一步缩短。当然,如果您对 ontology 非常了解,则可以进一步简化它(例如,如果您知道自己从不使用域或范围属性,则可以省略该位)。