2012-04-27 43 views

回答

1

請注意,根據您的具體需要,findall/3可能不是一個適合:

考慮到與自由變量的L成員結合E謂詞test/2 : test(+L, -E)

test(L, E) :- 
    member(E, L), 
    var(E). 

現在,讓我們說你想通過使用這個謂詞找到一個列表的所有自由變量(注意:如果你真的想這樣做,那不是正確的方式,它只是指出findall/3行爲):

?- findall(X, test([A, 3, C], X), Xs). 
Xs = [_G32, _G29]. 

findall/3回答你一個很好的答案,但模數變量重命名!

?- bagof(X, test([A, 3, C], X), Xs). 
Xs = [A, C]. 

?- setof(X, test([A, 3, C], X), Xs). 
Xs = [A, C]. 

做的伎倆,雖然。

我不確定我在這裏說的是否適用於除SWI-Prolog之外的其他Prolog系統。

這裏是相應的doc page

+0

非常有趣和有用。我喜歡這 – noted 2012-04-27 09:55:46

+0

這不是特定於SWI。所有3個都是ISO內置插件。但'bagof/3'和'setof/3'有更多的細節可供探討...... – false 2012-04-27 17:23:18

+0

這是對問題的錯誤答案。我已經更新了我的答案。 – 2012-04-28 12:36:05

0

通過使用findall。你有somepred(X),它給你你指定的答案。現在嘗試運行findall(X,somepred(X),List)以查看List與所有答案的列表進行統一。

編輯:使用setofbagof代替findall是錯誤的問題的背景下,作爲問道。

setof顯然是錯誤的,因爲它跳過了碰巧是重複的有效解決方案。 bagof失敗當沒有解決方案,而findall正確「返回」空列表[](按OP所要求)。哦,既bagofsetof對自由變量替代綁定原路返回,而OP明確要求的解決方案的一個列表是「返回」,即沒有回溯。即:

?- [user]. 
|: test(L,E):- member(E,L),var(E). 
|: 
% user://2 compiled 0.00 sec, 124 bytes 

Yes 
?- findall(X, (test([A,3,A],X) , member(A,[1,2])) , Xs). 

X = _G546 
A = _G536 
Xs = [1, 2, 1, 2] ; 

No 
?- bagof(X, (test([A,3,A],X) , member(A,[1,2]))  , Xs). 

X = _G534 
A = 1 
Xs = [1, 1] ; 

X = _G534 
A = 2 
Xs = [2, 2] ; 

No 
?- 

但OP要求要返回「包含所有可能的答案單一列表」。

編輯:沒有答案時的所有答案的列表是一個空的列表。

+0

哦,是的,幾乎忘了findall()。關於@WillNess編輯,非常感謝 – noted 2012-04-27 08:43:27

+0

,必須精確地說明bagof和setof有​​一個控制機制('^'),如果需要的話不要回溯,並且由於OP中沒有給出精確的語義,所以「錯誤的聲明「對於沒有解決方案的失敗沒有正確的論證。 – m09 2012-04-28 19:16:35

+0

@Mog我只是假設當「包含所有可能的解決方案的一個列表」被需要時,空列表自然代表沒有解決方案的列表。 – 2012-04-28 19:19:15