2011-01-11 31 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 
相關問題