1

我想制定一个利用继承的规则。例如,这里有一个在许多序言书中使用的著名示例,用于描述继承。

一只忙碌的猫
(来源:unak.is

以下是这些关系的事实:

%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.

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

4

2 回答 2

2

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

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
于 2013-11-10T20:07:59.397 回答
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。

于 2013-11-10T21:27:24.447 回答