簡體   English   中英

置換成SWI-Prolog列表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM