Permute into a list SWI-Prolog

后端 未结 2 610
感动是毒
感动是毒 2020-12-21 01:41

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.

相关标签:
2条回答
  • 2020-12-21 02:32

    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, i.e. metaprogramming, I think...

    0 讨论(0)
  • 2020-12-21 02:33

    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.

    0 讨论(0)
提交回复
热议问题