Search code examples
listrecursionprologaccumulator

Prolog selecting elements from list of lists


Given a list of lists (e.g., [[1],[1,2,3],[3,4]]) I want to create every possible permutation of the member of the sublists so the expected result from the mentioned example would look like:

?- get_elements([[1], [1,2,3], [3,4]], R).
R = [[1,1,3],[1,1,4],[1,2,3],[1,2,4],[1,3,3],[1,3,4]] ? ;
no

What I have is the following:

get_elements([], []).
get_elements([[H|_]|Lists], [H|L]) :-
    get_elements(Lists, L).
get_elements([[_,H|T]|Lists], L) :-
    get_elements([[H|T]|Lists], L).

This works great but returns the elements one by one, so the output is as follows:

?- get_elements([[1],[1,2,3],[3,4]], R).
R = [1,1,3] ? ; 
R = [1,1,4] ? ;
R = [1,2,3] ? ;
R = [1,2,4] ? ;
R = [1,3,3] ? ;
R = [1,3,4] ? ;
no

I guess I should add another parameter for accumulating the elements, but just can't clearly see how. Any help would be appreciated.


Solution

  • Just use findall/3 to gather all the outputs:

    Rename get_elements/2 with something like get_elements1/2 and add this procedure:

    get_elements(L, R):-
      findall(E, get_elements1(L, E), R).