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

Prolog 如何在语义网络中重写事实?,prolog,semantic-web,swi-prolog,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?您所使用的SWI Prolog对语义Web技术有着广泛的支持。但是如果您的语义

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

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

您所使用的SWI Prolog对语义Web技术有着广泛的支持。但是如果您的语义网络仅由is-a层次关系组成,您还可以使用Logtalk轻松表达它们,您可以使用SWI Prolog和大多数Prolog系统运行Logtalk,从而使其具有广泛的可移植性:

% 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.
此解决方案使用原型的层次结构。示例调用(确定性;无虚假选择点):

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

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

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

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

您表示正在使用的SWI Prolog广泛支持语义Web技术。但是如果您的语义网络仅由is-a层次关系组成,您还可以使用Logtalk轻松表达它们,您可以使用SWI Prolog和大多数Prolog系统运行Logtalk,从而使其具有广泛的可移植性:

% 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.
此解决方案使用原型的层次结构。示例调用(确定性;无虚假选择点):

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

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

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

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

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

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

您可以对规则施加额外的限制,以便在遇到第一个事实时立即停止派生。然后,该规则被表述为“X的高度要么是X类型事物的基本事实,要么,如果没有基本事实,则遵循isa关系并重试”。这要求基本事实使用规则以外的名称。“没有零件”可以用否定运算符
\+
表示

代码:

%isa:一般事实
伊萨(父亲,男人)。
isa(人,人)。
%isa:具体事实
isa(马克,运动员)。
%高度:一般事实
身高(人,170)。
身高(运动员,195)。
%高度:规则
高度(X,H):-底部高度(X,H)。
高度(X,H):-\+高度(X,u),isa(X,T),高度(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.

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

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

您可以对规则施加额外的限制,以便在遇到第一个事实时立即停止派生。然后,该规则被表述为“X的高度要么是X类型事物的基本事实,要么,如果没有基本事实,则遵循isa关系并重试”。这要求基本事实使用规则以外的名称。“没有零件”可以用否定运算符
\+
表示

代码:

%isa:一般事实
伊萨(父亲,男人)。
isa(人,人)。
%isa:具体事实
isa(马克,运动员)。
%高度:一般事实
身高(人,170)。
身高(运动员,195)。
%高度:规则
高度(X,H):-底部高度(X,H)。
高度(X,H):-\+高度(X,u),isa(X,T),高度(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.

请向我们展示您的代码和/或查询!请向我们展示您的代码和/或查询!