如何使用 SWI-Prolog 从 OWL RDF/XML 查询个体的对象 属性?

How to query an individual for its object property from an OWL RDF/XML using SWI-Prolog?

我在 Protege 中指定了一个 "isPartOf" 对象 属性,并且我断言

"Room_1 isPartOf Apartment_1"。

"Room_1"和"Apartment_1"都是个人。 OWL文件中的相关代码如下:

<rdf:RDF xmlns="http://www.xxx.come/example#"
 xml:base="http://www.xxx.come/example"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:owl="http://www.w3.org/2002/07/owl#"
 xmlns:xml="http://www.w3.org/XML/1998/namespace"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">


<!-- http://www.xxx.come/example#isPartOf -->

<owl:ObjectProperty rdf:about="http://www.xxx.come/example#isTemporalPartOf">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#AsymmetricProperty"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#TransitiveProperty"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ReflexiveProperty"/>
    <rdfs:domain rdf:resource="http://www.xxx.come/example#Room"/>
    <rdfs:range rdf:resource="http://www.xxx.come/example#Apartment"/>
</owl:ObjectProperty>


<!-- http://www.xxx.come/example#Room_1 -->

<owl:NamedIndividual rdf:about="http://www.xxx.come/example#Room_1">
    <rdf:type rdf:resource="http://www.xxx.come/example#Room"/>
    <isPartOf rdf:resource="http://http://www.xxx.come/example#Apartment_1"/>
    <hasSize rdf:datatype="http://www.w3.org/2001/XMLSchema#double">99.6</hasSize>
    <hasSize rdf:datatype="http://www.w3.org/2001/XMLSchema#double">145.5</hasSize>
</owl:NamedIndividual>
</rdf:RDF>

您将如何使用 Prolog 查询这样的三元组?我认为它会是这样的:

is_part_of(Ind1, Ind2):- 
    rdf(Ind1, 
        "http://www.w3.org/1999/02/22-rdf-syntax-ns#isPartOf, 
        Ind2).

这显然行不通。

我还从 rdf 库中看到 rdf_has(S,P,O,RealP) 看起来有点可用,但规范含糊不清。

顺着这个问题,如果两个人是类呢?如果对象 属性 是数据类型 属性 怎么办?

我想我遇到了一个简单的问题,但我已经搜索了很长时间的示例或类似问题,但没有找到任何东西。

提前致谢!

问题可能是 semweb/rdf_db documentation 中缺少快速入门示例。这是一个示例会话。


?- use_module(library(semweb/rdf_db)).
true.

?- rdf_load('example.owl', [format(xml)]).
% Parsed "example.owl" in 0.01 sec; 11 triples
true.

?- rdf(Ind1, 'http://www.xxx.come/example#isPartOf',  Ind2).
Ind1 = 'http://www.xxx.come/example#Room_1',
Ind2 = 'http://http://www.xxx.come/example#Apartment_1'.

?- rdf(Ind1, 'http://www.xxx.come/example#hasSize',  Ind2).
Ind1 = 'http://www.xxx.come/example#Room_1',
Ind2 = literal(type('http://www.w3.org/2001/XMLSchema#double', '99.6')) .

?- % is_part_of(Ind1, Ind2):- rdf(Ind1, 'http://www.xxx.come/example#isPartOf', Ind2).
|    ['rules.pl'].
true.

?- is_part_of(Ind1, Ind2).
Ind1 = 'http://www.xxx.come/example#Room_1',
Ind2 = 'http://http://www.xxx.come/example#Apartment_1'.

?- rdf_register_prefix(ex, 'http://www.xxx.come/example#').
true.

?- rdf(Ind1, ex:isPartOf,  Ind2).
Ind1 = 'http://www.xxx.come/example#Room_1',
Ind2 = 'http://http://www.xxx.come/example#Apartment_1'.

您的代码中的错误:

  1. Prolog 中的原子应该用单引号括起来。
    至于双引号——参见 this question。我的 SWI-Prolog 说:

    Type error: `atom' expected, found `"http://www.xxx.come/example#isPartOf"' (a string)

    无论如何,双引号也应该被关闭。

  2. 您应该使用正确的完整 URI:http://www.xxx.come/example#isPartOf 而不是 http://www.w3.org/1999/02/22-rdf-syntax-ns#isPartOf

  3. 这个格式错误的 URI — http://http://www.xxx.come/example#Apartment_1 — 可能会导致其他问题。

如果您已经定义了 RDFS 或 OWL 模式,您可以使用 rdfs2pl 将其转换为序言规则。

结果与 Stanislav 提供的示例大致相同。查看提供的显式代码以了解正在发生的事情很有用,但如果您有大量谓词,为它们全部编写显式规则可能会很乏味且容易出错。

生成的代码与提供的示例之间的一个区别是 rdfs2pl 在其生成的规则中使用 rdf_has/3。你问了这个谓词。它在 RDF 图上提供有限的 推理 。例如,如果您有:

ex:isPartOf owl:inverseOf ex:hasPart .
ex:apartment1 ex:hasPart ex:room1.

然后查询 rdf_has(X,myont:isPartOf,Y) 将 return 具有 X=ex:room1Y=ex:apartment1 的结果,即使没有明确说明,它也是 包含的 根据 OWL 的语义和你的 inverseOf 声明。相反 rdf/3 只会查询 asserted 模型。

何时应该 rdf/3rdf_has/3 取决于您的使用情况。在进行查询时能够使用推理非常有用。