The result is a list of terms pair(X, Y) where X and Y are elements of the input list L.
:-mode ordered_pairs(+,-).
ordered_pairs(L,K):-
ordered_pairs_lp(L,[],K).
ordered_pairs_lp([],L,L).
ordered_pairs_lp([H|T],In,Out):-
ordered_pairs_lp2(H,T,In,In1),
ordered_pairs_lp(T,In1,Out).
ordered_pairs_lp2(H,[],L,L).
ordered_pairs_lp2(H,[A|A1],In,Out):-
ordered_pairs_lp2(H,A1,[pair(H,A)|In],Out).
This concept can also be implemented with nested do loops. The recursive version seems more natural.
ordered_pairs(L,K):-
(fromto(L,[El|Rest],Rest,[_]),
fromto(K,TPairs,RPairs,[]) do
(foreach(R,Rest),
param(El),
fromto(TPairs,[pair(El,R)|Pairs],Pairs,RPairs) do
true
)
).