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

时间:2017-08-16 00:34:13

标签: xml rdf owl swi-prolog protege

我在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)看起来很有用,但规范很模糊。

在这个问题之后,如果两个人都上课怎么办?如果object属性是数据类型属性,该怎么办?

我认为我遇到了一个简单的问题,但我已经搜索了很长时间的例子或类似问题,但没有发现任何问题。

提前致谢!

2 个答案:

答案 0 :(得分:2)

问题可能是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 - 可能会导致其他问题。

答案 1 :(得分:1)

如果您已经定义了RDFS或OWL架构,则可以使用rdfs2pl将其转换为prolog规则。

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

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

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

然后,查询rdf_has(X,myont:isPartOf,Y)将返回X=ex:room1Y=ex:apartment1的结果,即使未明确说明,也是包含的语义OWL和您的inverseOf声明。相反,rdf/3只会查询断言的模型。

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