Prolog - 如何在语义网络中重写事实?

问题描述 投票:1回答:2

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

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

prolog semantic-web swi-prolog
2个回答
3
投票

您表示正在使用的SWI-Prolog对语义Web技术有广泛的支持。但是,如果您的语义网络仅包含is-a层次关系,您还可以使用Logtalk轻松表达它们,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.

如果您需要区分抽象和这些抽象的具体示例,也可以使用类而不是原型。


0
投票

Paulo Moura的答案是Prolog扩展和库的可能性的一个很好的例子。如果您正在构建一个实际的应用程序,那么最好使用类似的东西。但是,如果你正在学习Prolog而你想知道它是如何工作的,这里还有一个纯粹的Prolog答案。

您观察到的行为与您的知识库一致,这允许两种可能的解释:Mark是一个人,因此他的身高是170,或者Mark是一个运动员,因此他的身高是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.
© www.soinside.com 2019 - 2024. All rights reserved.