获取prolog中的所有列表

时间:2011-01-11 03:02:22

标签: prolog

如何使用当前长度生成列表中所有可能的元素集?

?- 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:Sharky给出了很好的答案。 但也许这不是最好的。这是另一个:

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).

2 个答案:

答案 0 :(得分:3)

考虑:

get_set(L0, L) :-
    length(L, Len),
    length(L0, Len),
    apply_elem(L0, L).

apply_elem([], _).
apply_elem([X|Xs], L) :-
    member(X, L),
    apply_elem(Xs, L).

说明:

确定输入列表L的长度为Len,我们可以通过L0生成唯一变量列表length/2。然后,我们只需将L的元素通过L0应用于member/2的所有成员,如果存在选项,则为选项留下选择点(即,如果列表L是长度> 1)。 Prolog将根据需要回溯以将L的所有元素组合生成到列表L0中。

答案 1 :(得分:2)

基于库谓词same_length/2,我们可以让它在“两个”方向安全地工作!

使用 maplist/2

简单地定义get_set/2
get_set(Xs,Ys) :-
   same_length(Xs,Ys),
   maplist(list_member(Ys),Xs).

list_member(Xs,X) :- 
   member(X,Xs).

首先,OP建议的样本查询:

?- get_set(Xs,[1,2,3]).
Xs = [1,1,1] ;
Xs = [1,1,2] ;
Xs = [1,1,3] ;
Xs = [1,2,1] ;
Xs = [1,2,2] ;
Xs = [1,2,3] ;
Xs = [1,3,1] ;
Xs = [1,3,2] ;
Xs = [1,3,3] ;
Xs = [2,1,1] ;
Xs = [2,1,2] ;
Xs = [2,1,3] ;
Xs = [2,2,1] ;
Xs = [2,2,2] ;
Xs = [2,2,3] ;
Xs = [2,3,1] ;
Xs = [2,3,2] ;
Xs = [2,3,3] ;
Xs = [3,1,1] ;
Xs = [3,1,2] ;
Xs = [3,1,3] ;
Xs = [3,2,1] ;
Xs = [3,2,2] ;
Xs = [3,2,3] ;
Xs = [3,3,1] ;
Xs = [3,3,2] ;
Xs = [3,3,3] ;
false.                      % terminates universally

让我们尝试相反的方式!

?- get_set([1,2,3],Ys).
Ys = [1,2,3] ;
Ys = [1,3,2] ;
Ys = [2,1,3] ;
Ys = [3,1,2] ;
Ys = [2,3,1] ;
Ys = [3,2,1] ;
false.                      % terminates universally