简体   繁体   中英

Permute into a list SWI-Prolog

How do you use the permute predicate to output into a list in SWI prolog?

The permutation/2 predicate only returns one result at a time.

The most straight forward way to describe all permutations is using bagof/3 . Note that findall/3 cannot be used directly, since findall produces literal copies of the original list.

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

So that's the no-brainer version. But you can even implement it directly in pure Prolog without any auxiliary built-ins.

If you want a list of all permutations, findall/3 is the way to go. If you want to print, you can use forall/2. Either case:

case_a(In, L) :- findall(Perm, permutation(In, Perm), L).
case_b(In) :- forall(permutation(In, Perm), writeln(Perm)).

forall it's a general purpose builtin, implementing a failure driven loop, amazing for its' simplicity. I report the definition from SWI-Prolog library, I think it's interesting.

%%  forall(+Condition, +Action)
%
%   True if Action if true for all variable bindings for which Condition
%   if true.

forall(Cond, Action) :-
    \+ (Cond, \+ Action).

EDIT:

As noted by false, if you have variables in your list, you should be aware of the different behaviour of 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]].

Note that each variable in in the second query output is different: that could be the request outcome, or not, depending on the problem at hand. Deciding the appropriate behaviour WRT the variable quantification is mandatory in the restricted class of problems where variables are data, ie metaprogramming, I think...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM