最初の質問は、プログラムがクラッシュする理由でした。使用している Prolog システムの種類はわかりませんが、多くのシステムでは、Prolog 内から処理できるクリーンな「リソース エラー」が生成されます。
実際の問題は、プログラムがクエリで終了しないことlikes(john, X)
です。それはあなたに期待される答えを与え、それから初めてループします。
?- いいね(ジョン、X)。
X = 本。
X = メアリー;
X = トム;
エラー: ローカル スタックが不足しています
その問題を非常に迅速に検出できたことは、非常に幸運でした。より多くの答えを想像してみてください。すべての答えを調べる忍耐力があるかどうかは明らかではありませんでした。しかし、そのためのショートカットがあります。代わりに尋ねる:
?- likes(john, X), false .
このfalse
目標は決して真実ではありません。したがって、それは簡単に答えを防ぎます。せいぜい、false
末尾にあるクエリは終了します。現在、これは当てはまりません。この非終了の理由は、次の障害スライスを検討するときに最もよくわかります(詳細については、他の回答を参照してください)。
?- likes(john,X), false .
いいね(トム、ジェリー) :- false .
likes(mary,john) :- false .
likes(mary,mary) :- false .
いいね(トム、マウス) :- false .
likes(jerry,jerry) :- false .
likes(ジェリー、チーズ) :- false .
likes(mary,fruit) :- false .
likes(john,book) :- false .
likes(mary,book) :- false .
いいね(トム、ジョン) :- false .
いいね(ジョン、X) :-
likes(X,john), false ,
X\=john .
したがって、スタック オーバーフローの原因はプログラムのこの小さな部分です。問題を解決するには、その小さな部分で何かをしなければなりません。dif(X, john)
1 つ:ルールが次のようになるように目標を追加します。
いいね(ジョン、X) :-
dif(X, ジョン),
いいね(X、ジョン)。
dif/2
SICStus、SWI、YAP、B、IF などの多くの Prolog システムで利用できます。