回答您的問題:如預期no_duplicates([1,2,3,3])
您的解決方案實際上是失敗。所以沒有問題。
現在採取的查詢:
?- A = 1, no_duplicates([A, 2]).
A = 1.
?- no_duplicates([A, 2]), A = 1.
他們都意味着同樣的,所以我們應該預料到的Prolog會產生相同的答案。 (更準確地說,我們期望相同的忽略錯誤和不終止)。
然而,四種提出的解決方案不同!而不是,差異爲:
?- A = 2, no_duplicates([A, 2]).
false.
?- no_duplicates([A, 2]), A = 2.
請注意,它總是第二個查詢,使麻煩。要解決這個問題,我們需要一個很好的答案no_duplicates([A, 2])
。它不能是false
,因爲A
有一些值可以使其成立。像A = 1
。它也不是真的,因爲有些值不適合,比如A = 2
。
另一種可能性是在這種情況下發出instantiation_error
。含義:我沒有足夠的信息,所以我最好停下來解決可能不正確的信息。
理想情況下,我們得到一個涵蓋所有可能解決方案的答案。這個答案是dif(A, 2)
,這意味着所有不同於2的A
都是解決方案。
dif/2
是最古老的內置謂詞之一,已經Prolog 0擁有它。不幸的是,後來的開發在Prolog I中丟棄了它,因此在愛丁堡Prolog和ISO Prolog中丟棄了它。
但是,目前的系統包括SICStus,YAP,SWI都提供它。並有一個安全的方式來approximate dif/2
safely在ISO-Prolog的
no_duplicates(Xs) :-
all_different(Xs). % the common name
all_different([]).
all_different([X|Xs]) :-
maplist(dif(X),Xs).
all_different(Xs).
參見:prolog-dif
我假設你正在使用SWI Prolog的(因爲你有問題的SWI-Prolog的標籤)。我用SWI 6.6.6測試了你的程序,它適用於你提到的情況,給了我'錯誤'。 – Jay 2014-09-25 20:25:19
這很奇怪..我也使用6.6.6,它給了我真實的。 – Nathan 2014-09-25 20:39:00
你是如何加載代碼的?你有沒有把它放在一個文件中(比如說''dup.prolog'「),然後用'['dup.prolog']將它加載到SWI中''在詢問查詢之前? – Jay 2014-09-25 22:44:57