我正在尝试在Prolog中定义继承检查谓词is_a/2
,但到目前为止我的所有试验都失败了。
只要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).
有什么建议吗?
答案 0 :(得分: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
我不确定这正是你所要求的。
答案 1 :(得分: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的回答相同,他更加努力地保留原来的代码。