COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### Find all possible pairs

• Follow

```Hello everyone,

I wrote this code to identify all possible pairs present in a set.
For example, if I have List = [1,2,3,4,5] then i want to get this:
PairsList = [ [1-2], [1-3], [1-4], [1-5],
[2-3], [2-4], [2-5],
[3-4], [3-5],
[4-5]
]

The code is:
--------------------------------------------------
possible_pairs( List, PairsList) :-
possible_pairs(List, List, [], PairsList).

% if there are at least 3 elements in the list
possible_pairs( [Elem1, Elem2|Tail], List, PairsListTmp, PairsL ):-
length(Tail, Len),
Len > 0,
append( PairsListTmp, [ [Elem1, Elem2] ], PairsList ),
append( [Elem1], Tail, NewList ),
possible_pairs( NewList, List, PairsList, PairsL ).

%if there are 2 elements in the list
possible_pairs([SecondLastElem, LastElem|Tail], List, PairsListTmp,
PairsL):-
length(Tail, Len),
Len is 0,
append( PairsListTmp, [ [SecondLastElem, LastElem] ], PairsList),
% remove the first element
nth0( 0, List, FirstElem ),
select( FirstElem, List, NewSmallerList),
possible_pairs( NewSmallerList, NewSmallerList, PairsList, PairsL).

% if there is 1 element in the list
possible_pairs( List, _, PairsListTmp, PairsL ):-
length(List, Len),
Len is 1,
possible_pairs( [], PairsListTmp, PairsL ).
--------------------------------------------------------

Is there a better way to find all the pairs without using length?

Thanks in advance and sorry for my english
```
 0

```On Nov 25, 11:44=A0am, Nick <nicola1...@tiscalinet.it> wrote:
> Hello everyone,
>
> I wrote this code to identify all possible pairs present in a set.
> For example, if I have List =3D [1,2,3,4,5] then i want to get this:
> PairsList =3D [ [1-2], [1-3], [1-4], [1-5],
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 [2-3], [2-4], [2-5],
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 [3-4], [3-5],
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 [4-5]
> =A0 =A0 =A0 =A0 =A0 =A0 =A0]
>
> The code is:
> --------------------------------------------------
> possible_pairs( List, PairsList) :-
> =A0 =A0 =A0 =A0 possible_pairs(List, List, [], PairsList).
>
> % if there are at least 3 elements in the list
> possible_pairs( [Elem1, Elem2|Tail], List, PairsListTmp, PairsL ):-
> =A0 =A0 =A0 =A0 length(Tail, Len),
> =A0 =A0 =A0 =A0 Len > 0,
> =A0 =A0 =A0 =A0 append( PairsListTmp, [ [Elem1, Elem2] ], PairsList ),
> =A0 =A0 =A0 =A0 append( [Elem1], Tail, NewList ),
> =A0 =A0 =A0 =A0 possible_pairs( NewList, List, PairsList, PairsL ).
>
> %if there are 2 elements in the list
> possible_pairs([SecondLastElem, LastElem|Tail], List, PairsListTmp,
> PairsL):-
> =A0 =A0 =A0 =A0 length(Tail, Len),
> =A0 =A0 =A0 =A0 Len is 0,
> =A0 =A0 =A0 =A0 append( PairsListTmp, [ [SecondLastElem, LastElem] ], Pai=
rsList),
> =A0 =A0 =A0 =A0 % remove the first element
> =A0 =A0 =A0 =A0 nth0( 0, List, FirstElem ),
> =A0 =A0 =A0 =A0 select( FirstElem, List, NewSmallerList),
> =A0 =A0 =A0 =A0 possible_pairs( NewSmallerList, NewSmallerList, PairsList=
, PairsL).
>
> % if there is 1 element in the list
> possible_pairs( List, _, PairsListTmp, PairsL ):-
> =A0 =A0 =A0 =A0 length(List, Len),
> =A0 =A0 =A0 =A0 Len is 1,
> =A0 =A0 =A0 =A0 possible_pairs( [], PairsListTmp, PairsL ).
> --------------------------------------------------------
>
> Is there a better way to find all the pairs without using length?
>
> Thanks in advance and sorry for my english

The example suggests you want the unordered pairs
(any two "distinct" items, provided all the items
in the list are different).  findall/3 can be used
to collect them into a list, if that's desired.

splitSet(List,[A,B],_)

where:

/*  splitSet/3 splits a list into two sublists */
splitSet([ ],[ ],[ ]).
splitSet([H|T],[H|L],R) :-
splitSet(T,L,R).
splitSet([H|T],L,[H|R]) :-
splitSet(T,L,R).

This allows you to get distinct triples, etc.
by the same method.  If you're only interested
in distinct pairs with infix "-", you could do:

pairs([A|T],[A-B]) :- member(B,T).
pairs([_|T],[A-B]) :- pairs(T,[A-B]).

regards, chip
```
 0

```On 25 Nov, 18:59, Chip Eastham <hardm...@gmail.com> wrote:
> On Nov 25, 11:44=A0am, Nick <nicola1...@tiscalinet.it> wrote:
>
>
>
> > Hello everyone,
>
> > I wrote this code to identify all possible pairs present in a set.
> > For example, if I have List =3D [1,2,3,4,5] then i want to get this:
> > PairsList =3D [ [1-2], [1-3], [1-4], [1-5],
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 [2-3], [2-4], [2-5],
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 [3-4], [3-5],
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 [4-5]
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0]
>
> > The code is:
> > --------------------------------------------------
> > possible_pairs( List, PairsList) :-
> > =A0 =A0 =A0 =A0 possible_pairs(List, List, [], PairsList).
>
> > % if there are at least 3 elements in the list
> > possible_pairs( [Elem1, Elem2|Tail], List, PairsListTmp, PairsL ):-
> > =A0 =A0 =A0 =A0 length(Tail, Len),
> > =A0 =A0 =A0 =A0 Len > 0,
> > =A0 =A0 =A0 =A0 append( PairsListTmp, [ [Elem1, Elem2] ], PairsList ),
> > =A0 =A0 =A0 =A0 append( [Elem1], Tail, NewList ),
> > =A0 =A0 =A0 =A0 possible_pairs( NewList, List, PairsList, PairsL ).
>
> > %if there are 2 elements in the list
> > possible_pairs([SecondLastElem, LastElem|Tail], List, PairsListTmp,
> > PairsL):-
> > =A0 =A0 =A0 =A0 length(Tail, Len),
> > =A0 =A0 =A0 =A0 Len is 0,
> > =A0 =A0 =A0 =A0 append( PairsListTmp, [ [SecondLastElem, LastElem] ], P=
airsList),
> > =A0 =A0 =A0 =A0 % remove the first element
> > =A0 =A0 =A0 =A0 nth0( 0, List, FirstElem ),
> > =A0 =A0 =A0 =A0 select( FirstElem, List, NewSmallerList),
> > =A0 =A0 =A0 =A0 possible_pairs( NewSmallerList, NewSmallerList, PairsLi=
st, PairsL).
>
> > % if there is 1 element in the list
> > possible_pairs( List, _, PairsListTmp, PairsL ):-
> > =A0 =A0 =A0 =A0 length(List, Len),
> > =A0 =A0 =A0 =A0 Len is 1,
> > =A0 =A0 =A0 =A0 possible_pairs( [], PairsListTmp, PairsL ).
> > --------------------------------------------------------
>
> > Is there a better way to find all the pairs without using length?
>
> > Thanks in advance and sorry for my english
>
> The example suggests you want the unordered pairs
> (any two "distinct" items, provided all the items
> in the list are different). =A0findall/3 can be used
> to collect them into a list, if that's desired.
>
>
> splitSet(List,[A,B],_)
>
> where:
>
> /* =A0splitSet/3 splits a list into two sublists */
> splitSet([ ],[ ],[ ]).
> splitSet([H|T],[H|L],R) :-
> =A0 =A0 splitSet(T,L,R).
> splitSet([H|T],L,[H|R]) :-
> =A0 =A0 splitSet(T,L,R).
>
> This allows you to get distinct triples, etc.
> by the same method. =A0If you're only interested
> in distinct pairs with infix "-", you could do:
>
> pairs([A|T],[A-B]) :- member(B,T).
> pairs([_|T],[A-B]) :- pairs(T,[A-B]).
>
> regards, chip

no, i don't want to use the infix "-", it's has been my mistake...so
the outcome should be:

PairsList =3D [ [1,2], [1,3], [1,4], [1,5],
[2,3], [2,4], [2,5],
[3,4], [3,5],
[4,5]
]
....

but ...could you explain better the use of spiltSet? i don't
understand how i could use that in my problem:(

thanks again
```
 0

```On Nov 25, 1:51=A0pm, Nick <nicola1...@tiscalinet.it> wrote:

This can be easily done using list comprehension in B-Prolog:

?- List=3D[1,2,3,4,5], Pairs @=3D [[I-J] : I in List, J in List, I<J]

List =3D [1,2,3,4,5]
Pairs =3D [[1-2],[1-3],[1-4],[1-5],[2-3],[2-4],[2-5],[3-4],[3-5],[4-5]]

Cheers,
Neng-Fa
```
 0

```On 25 Nov, 21:27, afa <neng.z...@gmail.com> wrote:
> On Nov 25, 1:51=A0pm, Nick <nicola1...@tiscalinet.it> wrote:
>
> This can be easily done using list comprehension in B-Prolog:
>
> ?- List=3D[1,2,3,4,5], Pairs @=3D [[I-J] : I in List, J in List, I<J]
>
> List =3D [1,2,3,4,5]
> Pairs =3D [[1-2],[1-3],[1-4],[1-5],[2-3],[2-4],[2-5],[3-4],[3-5],[4-5]]
>
> Cheers,
> Neng-Fa

i'm using Swi-prolog... :(

```
 0

```On Nov 25, 1:51=A0pm, Nick <nicola1...@tiscalinet.it> wrote:
> On 25 Nov, 18:59, Chip Eastham <hardm...@gmail.com> wrote:
>
>
>
> > On Nov 25, 11:44=A0am, Nick <nicola1...@tiscalinet.it> wrote:
>
> > > Hello everyone,
>
> > > I wrote this code to identify all possible pairs present in a set.
> > > For example, if I have List =3D [1,2,3,4,5] then i want to get this:
> > > PairsList =3D [ [1-2], [1-3], [1-4], [1-5],
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 [2-3], [2-4], [2-5],
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 [3-4], [3-5],
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 [4-5]
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0]
>
> > > The code is:
> > > --------------------------------------------------
> > > possible_pairs( List, PairsList) :-
> > > =A0 =A0 =A0 =A0 possible_pairs(List, List, [], PairsList).
>
> > > % if there are at least 3 elements in the list
> > > possible_pairs( [Elem1, Elem2|Tail], List, PairsListTmp, PairsL ):-
> > > =A0 =A0 =A0 =A0 length(Tail, Len),
> > > =A0 =A0 =A0 =A0 Len > 0,
> > > =A0 =A0 =A0 =A0 append( PairsListTmp, [ [Elem1, Elem2] ], PairsList )=
,
> > > =A0 =A0 =A0 =A0 append( [Elem1], Tail, NewList ),
> > > =A0 =A0 =A0 =A0 possible_pairs( NewList, List, PairsList, PairsL ).
>
> > > %if there are 2 elements in the list
> > > possible_pairs([SecondLastElem, LastElem|Tail], List, PairsListTmp,
> > > PairsL):-
> > > =A0 =A0 =A0 =A0 length(Tail, Len),
> > > =A0 =A0 =A0 =A0 Len is 0,
> > > =A0 =A0 =A0 =A0 append( PairsListTmp, [ [SecondLastElem, LastElem] ],=
PairsList),
> > > =A0 =A0 =A0 =A0 % remove the first element
> > > =A0 =A0 =A0 =A0 nth0( 0, List, FirstElem ),
> > > =A0 =A0 =A0 =A0 select( FirstElem, List, NewSmallerList),
> > > =A0 =A0 =A0 =A0 possible_pairs( NewSmallerList, NewSmallerList, Pairs=
List, PairsL).
>
> > > % if there is 1 element in the list
> > > possible_pairs( List, _, PairsListTmp, PairsL ):-
> > > =A0 =A0 =A0 =A0 length(List, Len),
> > > =A0 =A0 =A0 =A0 Len is 1,
> > > =A0 =A0 =A0 =A0 possible_pairs( [], PairsListTmp, PairsL ).
> > > --------------------------------------------------------
>
> > > Is there a better way to find all the pairs without using length?
>
> > > Thanks in advance and sorry for my english
>
> > The example suggests you want the unordered pairs
> > (any two "distinct" items, provided all the items
> > in the list are different). =A0findall/3 can be used
> > to collect them into a list, if that's desired.
>
> > How about something like:
>
> > splitSet(List,[A,B],_)
>
> > where:
>
> > /* =A0splitSet/3 splits a list into two sublists */
> > splitSet([ ],[ ],[ ]).
> > splitSet([H|T],[H|L],R) :-
> > =A0 =A0 splitSet(T,L,R).
> > splitSet([H|T],L,[H|R]) :-
> > =A0 =A0 splitSet(T,L,R).
>
> > This allows you to get distinct triples, etc.
> > by the same method. =A0If you're only interested
> > in distinct pairs with infix "-", you could do:
>
> > pairs([A|T],[A-B]) :- member(B,T).
> > pairs([_|T],[A-B]) :- pairs(T,[A-B]).
>
> > regards, chip
>
> no, i don't want to use the infix "-", it's has been my mistake...so
> the outcome should be:
>
> PairsList =3D [ [1,2], [1,3], [1,4], [1,5],
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 [2,3], [2,4], [2,5],
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 [3,4], [3,5],
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 [4,5]
> =A0 =A0 =A0 =A0 =A0 =A0 =A0]
> ...
>
> but ...could you explain better the use of spiltSet? i don't
> understand how i could use that in my problem:(
>
> thanks again

I did the following experiment with SWI-Prolog.

Start SWI-Prolog's console, and from "top level"
enter consult mode for the [user] module.  Cut
and paste the splitSet/3 predicate definition
given above, and then type Ctrl-D to exit the
consulting mode.

Now give as our first goal:

?- splitSet([1,2,3,4,5],[A,B],_).

Type semicolon repeatedly with each "success"
to verify the ten solutions for pairs A,B.

Now give as our second goal:

?- findall([X,Y],splitSet([1,2,3,4,5],[X,Y],_),List),
write(List).

and verify that the resulting List contains all
ten solution pairs [1,2] through [4,5] as
desired.

regards, chip
```
 0

```On 2010-11-25, Nick <nicola1983@tiscalinet.it> wrote:
> On 25 Nov, 21:27, afa <neng.z...@gmail.com> wrote:
>> On Nov 25, 1:51 pm, Nick <nicola1...@tiscalinet.it> wrote:
>>
>> This can be easily done using list comprehension in B-Prolog:
>>
>> ?- List=[1,2,3,4,5], Pairs @= [[I-J] : I in List, J in List, I<J]
>>
>> List = [1,2,3,4,5]
>> Pairs = [[1-2],[1-3],[1-4],[1-5],[2-3],[2-4],[2-5],[3-4],[3-5],[4-5]]
>>
>> Cheers,
>> Neng-Fa
>
>
> i'm using Swi-prolog... :(

The above is (AFAIK), syntactic sugar for the following traditional
Prolog program:

pairs_in(Set, Pairs) :-
findall(Pair, pair_in(Set, Pair), Pairs).

pair_in(Set, I-J) :-
member(I, Set),
member(J, Set),
I<J.

This is the readable variation.  If you want the short one:

?- List = [1,2,3,4,5], findall(I-J, (member(I,List), member(J,List), I<J), Pairs).

:- op(500, xfx, in).

in(E,List) :- member(E,List).

This becomes pretty close to the B-Prolog code:

?- List = [1,2,3,4,5], findall(I-J, (I in List, J in List, I<J), Pairs).

We've seen a lot of these syntactical layers lately, but personally I
still prefer the first alternative.  It reads comfortably, if anything
weird happens you can more easily debug pair_in/2 and finally you can
use pair_in/2 directly instead of being tempted to use the list
comprehension followed by a member/2 call.

Cheers --- Jan
```
 0

```On Nov 25, 7:51=A0pm, Nick <nicola1...@tiscalinet.it> wrote:
> On 25 Nov, 18:59, Chip Eastham <hardm...@gmail.com> wrote:
>
>
>
> > On Nov 25, 11:44=A0am, Nick <nicola1...@tiscalinet.it> wrote:
>
> > > Hello everyone,
>
> > > I wrote this code to identify all possible pairs present in a set.
> > > For example, if I have List =3D [1,2,3,4,5] then i want to get this:
> > > PairsList =3D [ [1-2], [1-3], [1-4], [1-5],
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 [2-3], [2-4], [2-5],
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 [3-4], [3-5],
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 [4-5]
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0]
>
> [...]

> no, i don't want to use the infix "-", it's has been my mistake...so
> the outcome should be:
>
> PairsList =3D [ [1,2], [1,3], [1,4], [1,5],
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 [2,3], [2,4], [2,5],
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 [3,4], [3,5],
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 [4,5]
> =A0 =A0 =A0 =A0 =A0 =A0 =A0]
> ...

Here is how to solve it with logical loops (ECLiPSe/SICStus):

all_pairs(L) -->
(   fromto(L,[X|R],R,[_])
do  (   foreach(Y,R),
param(X)
do  [[X,Y]]
)
).

| ?- all_pairs([1,2,3,4,5], Pairs, []).
Pairs =3D [[1,2],[1,3],[1,4],[1,5],[2,3],[2,4],[2,5],[3,4],[3,5],
[4,5]] ?
yes

--Mats
```
 0

```"Nick" <nicola1983@tiscalinet.it> a �crit dans le message de
the outcome should be:

PairsList = [ [1,2], [1,3], [1,4], [1,5],
[2,3], [2,4], [2,5],
[3,4], [3,5],
[4,5]
]

Here's a version that doesn't use findall/3, but does use difference lists,
and is tail-recursive:

% e.g. pairs([1,2,3,4,5],X)
%   gives X=[[1,2],[1,3],[1,4],[1,5],[2,3],[2,4],[2,5],[3,4],[3,5],[4,5]]
pairs(Xs, Ys):-pairs_1(Xs, Ys-[]).

pairs_1([], Ys-Ys).
pairs_1([X|Xs], Ys-As):-
pairs_2(Xs, X, Ys-Bs),
pairs_1(Xs, Bs-As).

pairs_2([], _, Zs-Zs).
pairs_2([X|Xs], Y, [[Y,X]|Zs]-As):-
pairs_2(Xs, Y, Zs-As).

If you don't like the "-" in the clauses, replace tham by ",".
--
Colin

```
 0

```On 26 Nov, 13:45, "Colin Barker" <colin.bar...@wanadoo.fr> wrote:

> % e.g. pairs([1,2,3,4,5],X)
> % =A0 gives X=3D[[1,2],[1,3],[1,4],[1,5],[2,3],[2,4],[2,5],[3,4],[3,5],[4=
,5]]
> pairs(Xs, Ys):-pairs_1(Xs, Ys-[]).
>
> pairs_1([], Ys-Ys).
> pairs_1([X|Xs], Ys-As):-
> =A0 pairs_2(Xs, X, Ys-Bs),
> =A0 pairs_1(Xs, Bs-As).
>
> pairs_2([], _, Zs-Zs).
> pairs_2([X|Xs], Y, [[Y,X]|Zs]-As):-
> =A0 pairs_2(Xs, Y, Zs-As).
>
> If you don't like the "-" in the clauses, replace tham by ",".
> --
> Colin

thanks to all for the replies!

Last question: i don't know  the use of "-" in the cluases (e.g.
pairs_2(Xs, X, Ys-Bs)). What is "-"?

```
 0

```On Nov 26, 4:13=A0am, Jan Wielemaker <j...@nospam.ct> wrote:
> On 2010-11-25, Nick <nicola1...@tiscalinet.it> wrote:
>
> > On 25 Nov, 21:27, afa <neng.z...@gmail.com> wrote:
> >> On Nov 25, 1:51=A0pm, Nick <nicola1...@tiscalinet.it> wrote:
>
> >> This can be easily done using list comprehension in B-Prolog:
>
> >> ?- List=3D[1,2,3,4,5], Pairs @=3D [[I-J] : I in List, J in List, I<J]
>
> >> List =3D [1,2,3,4,5]
> >> Pairs =3D [[1-2],[1-3],[1-4],[1-5],[2-3],[2-4],[2-5],[3-4],[3-5],[4-5]=
]
>
> >> Cheers,
> >> Neng-Fa
>
> > i'm using Swi-prolog... :(
>
> The above is (AFAIK), syntactic sugar for the following traditional
> Prolog program:
>
> pairs_in(Set, Pairs) :-
> =A0 =A0 =A0 =A0 findall(Pair, pair_in(Set, Pair), Pairs).
>
> pair_in(Set, I-J) :-
> =A0 =A0 =A0 =A0 member(I, Set),
> =A0 =A0 =A0 =A0 member(J, Set),
> =A0 =A0 =A0 =A0 I<J.
>
> This is the readable variation. =A0If you want the short one:
>
> ?- List =3D [1,2,3,4,5], findall(I-J, (member(I,List), member(J,List), I<=
J), Pairs).
>
>
> :- op(500, xfx, in).
>
> in(E,List) :- member(E,List).
>
> This becomes pretty close to the B-Prolog code:
>
> ?- List =3D [1,2,3,4,5], findall(I-J, (I in List, J in List, I<J), Pairs)=
..
>
> We've seen a lot of these syntactical layers lately, but personally I
> still prefer the first alternative. =A0It reads comfortably, if anything
> weird happens you can more easily debug pair_in/2 and finally you can
> use pair_in/2 directly instead of being tempted to use the list
> comprehension followed by a member/2 call.
>
> =A0 =A0 =A0 =A0 Cheers --- Jan

Yes, the foreach in B-Prolog is a kind of syntax sugar, but it is
translated into tail-recursive predicates not failure-driven loops.
There are two problems with failure-driven loops: first, it's not
efficient and using findall makes it even worse; and second, it's
impossible to retain bindings of variables (variables shared by all
iterations). I like list comprehension better than the logical loops
in ECLiPSe/SICStus because list comprehension is similar with the the
set-builder notation and everybody is familiar with it already.

Cheers,
Neng-Fa
```
 0

```"Nick" <nicola1983@tiscalinet.it> a �crit dans le message de
Last question: i don't know  the use of "-" in the cluases (e.g.
pairs_2(Xs, X, Ys-Bs)). What is "-"?

I believe that historically "-" was used to indicate that Ys and Bs
represent a difference list. I will leave it to someone else to say whether
or not Ys-Bs is exactly equivalent to Ys,Bs in this context.
--
Colin

```
 0

```On 26 Nov, 17:33, "Colin Barker" <colin.bar...@wanadoo.fr> wrote:
> I believe that historically "-" was used to indicate that Ys and Bs
> represent a difference list. I will leave it to someone else to say whether
> or not Ys-Bs is exactly equivalent to Ys,Bs in this context.
> --
> Colin

I tried to replace "-" with "," and it works good

```
 0

```"Colin Barker" <colin.barker@wanadoo.fr> writes:

> If you don't like the "-" in the clauses, replace tham by ",".

Or use DCG notation and leave the representation to the system:

pairs([])     --> [].
pairs([L|Ls]) --> pairs_(Ls, L), pairs(Ls).

pairs_([], _)     --> [].
pairs_([R|Rs], L) --> [[L,R]], pairs_(Rs, L).

Example:

%?- phrase(pairs([a,b,c]), Ps).
%@ Ps = [[a, b], [a, c], [b, c]].

--
comp.lang.prolog FAQ: http://www.logic.at/prolog/faq/
```
 0

```On 2010-11-26, afa <neng.zhou@gmail.com> wrote:
> On Nov 26, 4:13 am, Jan Wielemaker <j...@nospam.ct> wrote:
>> On 2010-11-25, Nick <nicola1...@tiscalinet.it> wrote:
>>
>> > On 25 Nov, 21:27, afa <neng.z...@gmail.com> wrote:
>> >> On Nov 25, 1:51 pm, Nick <nicola1...@tiscalinet.it> wrote:
>>
>> >> This can be easily done using list comprehension in B-Prolog:
>>
>> >> ?- List=[1,2,3,4,5], Pairs @= [[I-J] : I in List, J in List, I<J]

....

>> This becomes pretty close to the B-Prolog code:
>>
>> ?- List = [1,2,3,4,5], findall(I-J, (I in List, J in List, I<J), Pairs).
>>
>> We've seen a lot of these syntactical layers lately, but personally I
>> still prefer the first alternative.  It reads comfortably, if anything
>> weird happens you can more easily debug pair_in/2 and finally you can
>> use pair_in/2 directly instead of being tempted to use the list
>> comprehension followed by a member/2 call.
>>
>>         Cheers --- Jan
>
> Yes, the foreach in B-Prolog is a kind of syntax sugar, but it is
> translated into tail-recursive predicates not failure-driven loops.
> There are two problems with failure-driven loops: first, it's not
> efficient and using findall makes it even worse; and second, it's
> impossible to retain bindings of variables (variables shared by all
> iterations). I like list comprehension better than the logical loops
> in ECLiPSe/SICStus because list comprehension is similar with the the
> set-builder notation and everybody is familiar with it already.

I think your arguments make sense.  Well, there is no fundamental
reason while failure driven loops must be slow, but findall does
involve copying.  Sometimes the compiler should be able to avoid
the actual copying, but in general that is very hard.

I like the syntax (at least for this case), though it makes one think

Is there a free implementation of the translator?

Cheers --- Jan
```
 0

14 Replies
268 Views

Similiar Articles:

7/22/2012 11:00:22 PM