首先快速回答,它向您展示了Prolog程序員如何看待您的程序,其解釋如下。你的程序不會終止,因爲以下failure-slice不會終止:
black(root).
black(v1) :- false.
black(v3) :- false.
black(v4) :- false.
edge(root,root).
edge(v1,root) :- false.
edge(v2,v1) :- false.
edge(v3,v1) :- false.
edge(v4,v3) :- false.
edge(v5,v2) :- false.
edge(v5,v4) :- false.
edge(v6,v5) :- false.
foo(root) :- false.
foo(X) :- X = root, Y = root,
edge(X,Y),
black(Y),
foo(Y), false.
所有通striken文本無關了解未結束。正如你所看到的,其餘部分相對較短,因此需要很快掌握。
Prolog無法直接檢測到此循環。但是,您可以使用closure0/3
定義here爲了這個目的:
edge_toblack(X, Y) :-
edge(X, Y),
black(Y).
foo(X) :-
closure0(edge_toblack, X,root).
現在的細節。
在回答您的問題之前,爲什麼會發生這種情況,讓我們退後一步。我們首先需要找到一個觀察問題的好方法。目標foo(X)
確實產生答案,實際上只有X = root
。所以也許你只是不耐煩地等待Prolog完成?通過詢問foo(X), false
來代替,我們擺脫了這些令人煩惱的,令人eye目結舌的答案,我們將等待false
作爲回答。
我們仍然無法確定程序的非終止屬性。但我們可以通過插入目標false
(以及(=)/2
)來縮小實際原因。在上面的失敗片中,我插入了最大值。如果您剛剛開始,只需添加一個false,然後重新加載程序並重試查詢。憑藉一些經驗,您很快就能夠快速識別這些部件。所以,現在我們只需要瞭解
foo(root) :-
edge(root,root), % always true
black(root), % always true
foo(root), false.
,甚至更短的
foo(root) :-
foo(root).
的Prolog的非常簡單而有效的執行機制沒有檢測到這種循環。基本上有幾種出路:
手動添加循環檢測。這通常是很容易出錯
使用closure0/3
- 見上
寫自己的元解釋檢測循環一般
使用語言擴展一樣桌遊戲,在B-Prolog的提供或XSB-Prolog。
這個答案確實需要一些upvoting。 – bitoiu 2015-01-27 15:05:53