Prolog-如何在语义网络中过度覆盖事实?

时间:2019-03-17 16:13:22

标签: prolog semantic-web swi-prolog

我有一个语义网络,具有以下层次结构:

Person: has body = true
Man: is a Person, height = 170
Sport Star: is a Man, height = 190

然后我要创建这些实例,例如:

Mark: is a Sport Star

但是,当我打电话时,例如height(Mark, X),我得到X = 170,需要按;才能得到X = 190。有没有办法让190马上获得?

2 个答案:

答案 0 :(得分:3)

您指出正在使用的

SWI-Prolog对语义Web技术具有广泛的支持。但是如果您的语义网络仅由 is-a 层次结构关系组成,则您还可以使用Logtalk轻松表达它们,可以将其与SWI-Prolog和大多数Prolog系统一起运行,使其具有广泛的便携性:

% Person: has body = true
:- object(person).

    :- public(has/1).
    has(body).

:- end_object.

% Man: is a Person, default height = 170
:- object(man, extends(person)).

    :- public(height/1).
    height(170).

:- end_object.

% Sport Star: is a Man, default height = 190
:- object(sport_star, extends(man)).

    % override inherited height
    height(190).

:- end_object.

% Mark: is a Sport Star
:- object(mark, extends(sport_star)).

:- end_object.

% Spencer: is another Sport Star, but slim
:- object(spencer, extends(sport_star)).

    % override inherited height
    height(165).

:- end_object.

此解决方案使用原型的层次结构。样本调用(确定性;没有虚假的选择点):

?- mark::height(Height).
Height = 190.

?- mark::has(What).
What = body.

?- spencer::height(Height).
Height = 165.

您可以根据需要创建任意数量的原型,这些原型可以在源文件中定义,也可以在运行时动态创建。例如

?- create_object(alan, [extends(man)], [], []).
true.

?- alan::height(Height).
Height = 170.

如果需要区分抽象的抽象具体示例,也可以使用类代替原型。

答案 1 :(得分:0)

Paulo Moura的答案很好地说明了Prolog扩展和库的可能性。如果要构建实际的应用程序,则最好使用类似的方法。但是,如果您正在学习Prolog,并且想知道它的工作原理,请在此处获得一个纯粹的Prolog答案。

您观察到的行为与您的知识库一致,这允许两种可能的解释:马克是一个人,因此他的身高是170,或者马克是一个运动员,因此他的身高是195。这两个都是有效的推导在知识库的支持下,因此Prolog依次返回每个。

您可以对规则施加额外限制,以在遇到第一个事实时立即停止推导。然后将规则表述为“ X的高度或者是X类型事物的基本事实,或者如果没有基本事实,请遵循isa关系并重试”。这要求基本事实必须获得除规则以外的其他名称。否定运算符\+可以表示没有部分。

代码:

% isa: general facts
isa(father,man).
isa(man,person).
% isa: specific facts
isa(mark,sportsman).
% height: general facts
height_base(person,170).
height_base(sportsman,195).
% height: rules
height(X,H) :- height_base(X,H).
height(X,H) :- \+height_base(X,_), isa(X,T), height(T,H).

查询:

?- height(man,X).
X = 170 ;
false.

?- height(mark,X).
X = 195 ;
false.

?- height(sportsman,X).
X = 195 ;
false.

?- height(person,X).
X = 170 ;
false.