如何使用 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'.
您的代码中的错误:
Prolog 中的原子应该用单引号括起来。
至于双引号——参见 this question。我的 SWI-Prolog 说:
Type error: `atom' expected, found `"http://www.xxx.come/example#isPartOf"' (a string)
无论如何,双引号也应该被关闭。
您应该使用正确的完整 URI:http://www.xxx.come/example#isPartOf
而不是 http://www.w3.org/1999/02/22-rdf-syntax-ns#isPartOf
。
这个格式错误的 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:room1
和 Y=ex:apartment1
的结果,即使没有明确说明,它也是 包含的 根据 OWL 的语义和你的 inverseOf 声明。相反 rdf/3
只会查询 asserted 模型。
何时应该 rdf/3
与 rdf_has/3
取决于您的使用情况。在进行查询时能够使用推理非常有用。
我在 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'.
您的代码中的错误:
Prolog 中的原子应该用单引号括起来。
至于双引号——参见 this question。我的 SWI-Prolog 说:Type error: `atom' expected, found `"http://www.xxx.come/example#isPartOf"' (a string)
无论如何,双引号也应该被关闭。
您应该使用正确的完整 URI:
http://www.xxx.come/example#isPartOf
而不是http://www.w3.org/1999/02/22-rdf-syntax-ns#isPartOf
。这个格式错误的 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:room1
和 Y=ex:apartment1
的结果,即使没有明确说明,它也是 包含的 根据 OWL 的语义和你的 inverseOf 声明。相反 rdf/3
只会查询 asserted 模型。
何时应该 rdf/3
与 rdf_has/3
取决于您的使用情况。在进行查询时能够使用推理非常有用。