Reputation: 35
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.
Upvotes: 0
Views: 1104
Reputation: 10102
?- 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
.
Upvotes: 3
Reputation: 10102
Here is another solution that does not need any of the higher-order predicates.
:- set_prolog_flag(double_quotes, chars). :- use_module(library(double_quotes)). list_pairwise([], []). list_pairwise([E|Es], Fs0) :- phrase(values_key(Es, E), Fs0,Fs), list_pairwise(Es, Fs). values_key([], _K) --> []. values_key([V|Vs], K) --> [K-V], values_key(Vs, K). ?- list_pairwise("abcde", KVs). KVs = [a-b,a-c,a-d,a-e,b-c,b-d,b-e,c-d,c-e,d-e]. ?- list_pairwise(L, [a-b,a-c,a-d,a-e,b-c,b-d,b-e,c-d,c-e,d-e]). L = "abcde" ; false. ?- list_pairwise(L, [A-B,A-C,A-D,A-E,B-C,B-D,B-E,C-D,C-E,D-E]). L = [A,B,C,D,E] ; false. ?- KVs = [K1-_,K1-_,K2-_|_], dif(K1,K2), list_pairwise(Ks,KVs). KVs = [K1-K2,K1-_A,K2-_A], Ks = [K1,K2,_A], dif:dif(K1,K2) ; false.
In the last query we show that a sequence starting with keys, K1, K1, K2
can only result in the sequence of three elements.
Upvotes: 3
Reputation: 66200
What about a couple of predicates as follows ?
printCouples(_, []).
printCouples(E1, [E2 | T]) :-
write(E1), write(E2), nl,
printCouples(E1, T).
printList([]).
printList([H | T]) :-
printCouples(H, T),
printList(T).
From
printList([a, b, c, d])
you get
ab
ac
ad
bc
bd
cd
Upvotes: 1