如何在PROLOG中覆盖继承关系中的属性?

时间:2013-11-10 19:31:31

标签: inheritance prolog override

我想制定一个利用继承的规则。 例如,这是一个着名的例子,在许多prolog书籍中使用,描述继承。

a busy cat http://staff.unak.is/not/tony/teaching/ai/lectures/09bSemanticNet/lab18/birdSemanticNet.gif

以下是这些关系的事实:

%Bird
%animal's childs
isa(bird, animal).
isa(fish, animal).

%bird's childs
isa(ostrich, bird).
isa(penguin, bird).
isa(canary, bird).
isa(robin, bird).

%penguin's childs
isa(opus, penguin).

%canary's childs
isa(tweety, canary).

%animal's property
hasprop(animal, covering, skin).

%bird's property
hasprop(bird, travel, fly).
hasprop(bird, covering, feathers).

%fish's property
hasprop(fish, travel, swim).

%ostrich's property
hasprop(ostrich, travel, walk).

%penguin's property
hasprop(penguin, travel, walk).
hasprop(penguin, color, brown).

%canary's property
hasprop(canary, color, yellow).
hasprop(canary, sound, sing).

%robin's property
hasprop(robin, color, red).
hasprop(robin, sound, sing).

%tweety's property
hasprop(tweety, color, white).

%rules
hasproperty(Object, Property, Value) :- hasprop(Object, Property, Value),!.

hasproperty(Object, Property, Value) :- isa(Object, Parent),
                                        hasproperty(Parent, Property, Value).

在这个网络中,当我查询像hasproperty(penguin,X,Y)这样的语句时,我只能得到一个结果(我知道这是因为cut运算符。)。我想要的是像这样的结果:

?- hasproperty(penguin, X, Y).

X = travel,
Y = walk.

X = color,
Y = brown.

X = covering,
Y = feathers.

在此结果中,较低级别的属性,旅行和覆盖覆盖了较高级别的属性。但我不知道处理这些覆盖。如果您对此有任何解决方案,请告诉我。

2 个答案:

答案 0 :(得分:2)

可能的方法是检查第二个hasproperty/3子句中的immediate对象属性:

hasproperty(Object, Property, Value) :-
    hasprop(Object, Property, Value).

hasproperty(Object, Property, Value) :-
   isa(Object, Parent),
   hasproperty(Parent, Property, Value),
   \+ hasprop(Object, Property, _).  % Let object property override

答案 1 :(得分:2)

另一种解决方案是使用Logtalk对象简单地表示层次结构,并声明和定义用于表示属性的对象谓词。您可以使用SWI-Prolog作为后端Prolog编译器或任何其他受支持的Prolog编译器来运行Logtalk。鉴于您的层次结构中的节点数量,我将仅举几例:

:- object(animal).

    :- public(covering/1).
    covering(skin).  % default covering

    :- public(travel/1).

:- end_object.


:- object(fish, extends(animal)).

    travel(swim).

:- end_object.


:- object(bird, extends(animal)).

    covering(feathers).
    travel(fly).

:- end_object.

在定义所有必需的对象和谓词之后,向特定对象询问其属性或属性值是微不足道的。例如:

?- bird::current_predicate(Property).
Property = covering/1 ;
Property = travel
true.

?- bird::travel(Travel).
T = fly
true.

继承,包括覆盖,免费提供。 hasproperty/3谓词的等价物如下:

?- current_object(Object), Object::current_predicate(Functor/Arity), functor(Property, Functor, Arity), Object::Property.

您的层次结构现在很好地表示,易于修改,您甚至可以使用Logtalk的图表工具来获取类似于上图的PDF。