Search code examples
listprolog

Listing elemets of a list as i want, in Prolog


This is my list in Prolog:

myList([a,b,c,d,e]).

I am trying to write a predicate. That predicate should give me this result:

ab
ac
ad
ae
bc
bd
be
cd
ce
de

I found a solution that's near to my goal. But it is not exactly what I want.

?- L=[a,b,c], findall(foo(X,Y), (member(X,L),member(Y,L)), R).

L = [a, b, c],

R = [foo(a, a), foo(a, b), foo(a, c), foo(b, a), foo(b, b), foo(b, c), foo(c, a), foo(c, b), foo(..., ...)].

For example i dont want to aa or bb or cc. Also, there is already ac result. So i dont want to again ca.

Sorry for my English. Thanks.


Solution

  • ?- set_prolog_flag(double_quotes, chars).
       true.
    ?- List = "abcde",
       bagof(X-Y, Pre^Ys^( append(Pre, [X|Ys], List), member(Y,Ys) ), XYs).
       List = "abcde", XYs = [a-b,a-c,a-d,a-e,b-c,b-d,b-e,c-d,c-e,d-e].
    ?- List = [A,B,C,D,E],
       bagof(X-Y, Pre^Ys^( append(Pre, [X|Ys], List), member(Y,Ys) ), XYs).
       List = [A,B,C,D,E], XYs = [A-B,A-C,A-D,A-E,B-C,B-D,B-E,C-D,C-E,D-E].
    

    From your question it is not that evident what you want but it seems you are happy to use findall/3. Above solutions use bagof/3 which is a somewhat more civilized version of findall/3. bagof/3 takes into account variables, and thus you get the same result with concrete characters [a,b,c,d,e] or with a list of variables [A,B,C,D,E].

    You have used terms foo(a,b), in such situations it is more common (and convenient) to say a-b.