2010-01-15 123 views
3

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

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. 

我试图

每当Y是X的超例如is_a(X, Y)谓语应返回true定义它显然的方式,但我陷入了无限循环:

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

有什么建议吗?

回答

5

避免无限循环的一种方法是添加一个谓词,它显示“直接”继承(不可传递),即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 

我不知道这正是你所求的不过。

+0

正是我在找的:) 非常感谢你,3lectrolyte – 2010-01-16 02:30:15

2

喜欢的东西

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的回答,谁更努力,以保持它就像你的原代码。