2

我正在尝试is_a/2在 Prolog 中定义继承检查谓词,但到目前为止我所有的试验都失败了。

只要 Y 是 X的is_a(X, Y)超类,谓词就应该返回 true。例如:

object(bare).
object(mammal).
object(animal).
object(bird).
is_a(bare, mammal).
is_a(mammal, animal).
is_a(bird, animal).
is_a(X, Y):- <definition goes here>.

定义应使以下查询返回 true:

?- is_a(bare, animal).
true.

我试图以明显的方式定义它,但我陷入了无限循环:

is_a(X, Y):- X\==Y, object(X), object(Y), object(Z), is_a(X, Z), is_a(Z, Y).

有什么建议么?

4

2 回答 2

4

避免无限循环的一种方法是添加一个谓词,它显示“直接”继承(无传递),即direct/2. 然后你可以写这样的东西:

object(bare).
object(mammal).
object(animal).
object(bird).

direct(bare, mammal).
direct(mammal, animal).
direct(bird, animal).

isa(X, Y) :- object(X), object(Y), direct(X, Y).
isa(X, Y) :- object(X), object(Y), object(Z), direct(X, Z), isa(Z, Y).

然后你得到:

?- findall(X, isa(X, animal), L).
   L = [mammal,bird,bare] ? ;
   no

我不确定这是否正是您所要求的。

于 2010-01-15T21:02:32.220 回答
1

就像是

is_a(X, X).
is_a(X, Y) :- X \== Y, is_a_1(X, Z), is_a(Z, Y).
is_a_1(bear, mammal).
is_a_1(mammal, animal).
is_a_1(bird, animal).

编辑:与electrologos3的答案相同,他们更努力地保持它像您的原始代码一样。

于 2010-01-15T21:02:38.500 回答