Получить все наборы списка в прологе - PullRequest
5 голосов
/ 11 января 2011

Как я могу сгенерировать все возможные наборы элементов списка с текущей длиной?

?- 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: есть хороший ответ, данный Шарки.Но, возможно, это не самый лучший.Вот еще один:

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 ]

3 голосов
/ 11 января 2011

Рассмотрим:

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).Пролог откатится назад, чтобы сгенерировать все возможные комбинации элементов L в списке L0, как требуется.

2 голосов
/ 02 июня 2015

Основываясь на предикате библиотеки 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...