2011-10-21 6 views
3

私は簡単な知識ベースを作ろうとしています。しかし、私はカテゴリシステムを動作させるのに苦労しています。ここでこのプロローグプログラムが無限再帰を引き起こすのはなぜですか?

プログラムは、これまでのところです:

subset(tomatoes, fruits). 
subset(fruits, food). 
subset(X, Z) :- subset(X, Y), subset(Y, Z), not(X==Y), not(Y==Z), not(X==Z). 
member(X, Z) :- member(X, Y), subset(Y, Z). 
member(t1, tomatoes). 

クエリ:

member(t1,tomatoes). 
ERROR: Out of local stack 
    Exception: (1,765,494) member(t1, _G28504) ? abort 
% Execution Aborted 
+0

私はPrologで少し錆びますが、あなたの事実を最初に入れてみましたか?のように、移動するメンバー(t1、トマト)再帰的なルールの上に? – acjay

答えて

4

あなたは左再帰と呼ばれる現象に遭遇しました。 subset(X, Z)の目標を解決することは、subset(X, Y)という目標を新しい非結合変数Yで解決することに還元され、同じ目標であるsubset(X, Z)などを無限に解決することにつながります。左回帰は避けるべきです。

通常の方法は、基本的な事実と推移的閉包の規則を区別することです。試してみることができます:

subset1(tomatoes, fruits). 
subset1(fruits, food). 

subset(X, Y) :- subset1(X, Y). 
subset(X, Z) :- subset1(X, Y), subset(Y, Z). 

member1(t1, tomatoes). 
member1(t2, tomatoes). 

member(X, Y) :- member1(X, Y). 
member(X, Z) :- member1(X, Y), subset(Y, Z). 

?- member(t1, food).  ===> TRUE 

この処方では左回帰はありません。まず、再帰を終了できる直接的な事実が試される。事実がない場合にのみ、再帰呼び出しが実行されます。

関連する問題