2010-01-15 91 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的回答,誰更努力,以保持它就像你的原代碼。