[英]Permute into a list SWI-Prolog
如何使用permute謂詞輸出到SWI prolog中的列表?
permutation / 2謂詞一次只返回一個結果。
描述所有排列的最直接的方法是使用bagof/3
。 請注意, findall/3
不能直接使用,因為findall
會生成原始列表的文字副本。
list_allperms(L, Ps) :-
bagof(P, permutation(L,P), Ps).
?- L = [A,B,C], list_allperms(L, Ps).
L = [A, B, C],
Ps = [[A, B, C], [A, C, B], [B, A, C], [B, C, A], [C, A, B], [C, B, A]].
所以這是毫無疑問的版本。 但是你甚至可以在沒有任何輔助內置函數的情況下直接在純Prolog中實現它。
如果你想要一個所有排列的列表,findall / 3就是你要走的路。 如果要打印,可以使用forall / 2。 兩種情況:
case_a(In, L) :- findall(Perm, permutation(In, Perm), L).
case_b(In) :- forall(permutation(In, Perm), writeln(Perm)).
forall它是一個通用的內置程序,實現了一個故障驅動的循環,其簡單性令人驚嘆。 我從SWI-Prolog庫中報告了這個定義,我覺得它很有意思。
%% forall(+Condition, +Action)
%
% True if Action if true for all variable bindings for which Condition
% if true.
forall(Cond, Action) :-
\+ (Cond, \+ Action).
編輯:
如上所述,如果你的列表中有變量,你應該知道findall / 3 WRT bagof / 3的不同行為:
?- case_a([1,2,3],X).
X = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]].
?- case_a([A,B,C],X).
X = [[_G467, _G470, _G473], [_G455, _G458, _G461], [_G443, _G446, _G449], [_G431, _G434, _G437], [_G419, _G422, _G425], [_G407, _G410, _G413]].
請注意,第二個查詢輸出中的每個變量都是不同的:可能是請求結果,也可能不是,具體取決於手頭的問題。 確定適當的行為WRT變量量化在變量是數據的限制類問題中是強制性的,即元編程,我認為......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.