我有一个语义网络,具有以下层次结构:
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
马上获得?
答案 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.