How can I generate all the possible sets of the elements of a list with current length?
?- get_set(X, [1,2,3]).
X = [1,1,1] ;
X = [1,1,2] ;
X = [1,1,3] ;
X = [1,2,1] ;
X = [1,2,2] ;
X = [1,2,3] ;
X = [1,3,1] ;
X = [1,3,2] ;
X = [1,3,3] ;
.....
X = [3,3,2] ;
X = [3,3,3].
UPD: there is good answer given by Sharky. But maybe it's not the best. Here is another:
get_set(X,L) :- get_set(X,L,L).
get_set([],[],_).
get_set([X|Xs],[_|T],L) :- member(X,L), get_set(Xs,T,L).
Based on library predicate
same_length/2
, we can make it work safely in "both" directions!Simply define
get_set/2
like this, using meta-predicatemaplist/2
:First, the sample query suggested by the OP:
Let's try the other way round!
Consider:
Explanation:
Determining the length of the input list
L
asLen
allows us to generate a list of unique variables,L0
, vialength/2
. Then, we simply apply elements ofL
to all members ofL0
viamember/2
, which leaves choicepoints for options, should they exist (i.e., if the listL
is of length > 1). Prolog will backtrack to generate all possible combinations of elements ofL
into the listL0
, as required.