2011-01-11 29 views
5

如何生成当前长度的列表中所有可能的元素集合?获取序言中的所有列表集合

?- 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). 
+0

您是否需要一次生成所有这些文件,或者只是定义关系并允许搜索来启动所有结果? – 2011-01-11 03:30:26

回答

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

说明:

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

2

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

简单地定义get_set/2这样,使用maplist/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 
相关问题