爲了清楚起見,感嘆號是切割操作符,它確實是而不是表現爲「完全停止」。它只是向您提供在運行前所做的選擇。通過跟蹤我們可以看到,它確實是不相關的,你遇到的問題:
?- getNo(a,[[a,2],[b,1]],X).
X = 2 ; [trace]
Redo: (6) getNo(a, [[a, 2], [b, 1]], _G221) ? creep
Call: (7) getNo(a, [[b, 1]], _G221) ? creep
Call: (8) getNo(a, [], _G221) ? creep
Exit: (8) getNo(a, [], 0) ? creep
Exit: (7) getNo(a, [[b, 1]], 0) ? creep
Exit: (6) getNo(a, [[a, 2], [b, 1]], 0) ? creep
X = 0.
所以,你可以在這裏看到getNo(a, [], 0)
也將取得成功。而它自身也因爲沒有什麼可以阻止它:
?- getNo(a,[],X).
X = 0.
沒有理由期望,它可以在外殼之間時,它已經通過遞歸調用或通過直接到達一個空列表區分簡單地通過使用切割來調用。我認爲你必須重構謂詞來獲得你想要的行爲。例如:
get_number(A, [[A,X]|_], X).
get_number(A, [_|Tail], X) :- get_number(A, Tail, X).
getNo(A, L, X) :- get_number(A, L, X), !.
getNo(_, _, 0).
至於如何使用Prolog的一個括號備註,它經常發生,你需要創建另一個謂語。不要害怕創建助手謂詞。除此之外,沒有其他方法可以真正處理需要初始條件設置或後期處理的循環。在其他語言中,您可以完全隔離單個函數接口後面需要做的所有工作,但在Prolog中通常不可能,您將不得不委託給助手。
確實解決了這個問題。謝謝你。花了我一點時間來理解爲什麼getNo(b,[],0)不是一個選項。但是,在比較我的代碼和您的代碼之後,我現在明白了原因。謝謝! – 2013-04-22 22:52:25
@ArturKäpp沒問題。 :)請看我剛剛添加在底部的段落,這可能會說明相同的實現。 – 2013-04-22 22:54:11