Решения для извлечения перестановок Prolog

permutation([], []).
permutation(L, [X|Xs]) :- select(X, L, Rest), permutation(Rest, Xs).

Если я наберу permutation([1,2,3],R), первое решение будет "[1,2,3]", но как перейти ко второму без использования ";" или «неудача». Мне нужно использовать второе решение, например «[1,3,2]» или около того, чтобы сравнить его с другим списком.

Я имею в виду:

permutation([], []).
permutation(L, [X|Xs]) :- select(X, L, Rest), permutation(Rest, Xs).

go_perm(L,P) :-     
        L = P,
        write(P),nl.

go_perm(L,P) :- 
        permutation(P,P2), % in this case i wanna get the next solution -.- 
        go_perm(L,P2).

Если L = P, то он заканчивается. Перестановка первого решения для «[1,2,3]» — это «[1,2,3]». Но это втягивает меня в stackoverflow, потому что это приводит к бесконечным вещам. Возможно, вы меня понимаете. Спасибо!


person viktor    schedule 01.06.2011    source источник
comment
Что на самом деле пытается сделать ваш код? В настоящее время это кажется бессмысленным; permutation(L, P) уже сравнивает списки, поэтому вам не нужно сравнивать снова.   -  person Neil    schedule 02.06.2011
comment
перестановка ([], []). перестановка(L, [X|Xs]):- выбор(X, L, Остальное), перестановка(Остальное, Xs).   -  person viktor    schedule 02.06.2011


Ответы (3)


Предполагая, что вы хотите перебрать решения, чтобы распечатать их

Один из стандартных способов добиться этого — потерпеть неудачу и вернуться назад, например:

print_all_permutations(X)
  :- permutation(X, Y), print(Y), nl, fail ; true.

Предполагая, что вы просто хотите проверить правильность данного решения

Вы уже сделали. Просто вызовите функцию со списком ссылок и списком, который вы хотите протестировать:

permutation([1, 2, 3], [2, 1, 3]).

вернет true, потому что [2, 1, 3] является перестановкой [1, 2, 3]. Если второй аргумент не является перестановкой, цель будет оценена как ложная.

В этом заключается магия пролога: найти решение или проверить правильность данного решения — одно и то же.

Между: частичное решение

Те же рассуждения по-прежнему применимы:

permutation([1, 2, 3], [2, X, 3]).

отобразит единственное возможное значение для X.

Или, если вы хотите, чтобы весь список был результатом:

X = [2, X, 3], permutation([1, 2, 3], X).
person Jerome    schedule 01.06.2011
comment
хорошо, я пытался использовать ваш код, но я просто хочу получить решения [1,2,3] шаг за шагом, а затем сравнить его с фиксированным списком [2,1,3] и закончить ифф перестановку [1 ,2,3] достиг [2,1,3]... - person viktor; 02.06.2011

Вам нужно посмотреть на различные агрегатные предикаты. Здесь findall подойдет. вы можете вызвать его:

ListIn=[1,2,3], findall(Perm, permutation(ListIn, Perm), Permutations).

Это вызовет перестановку в ListIn до тех пор, пока она не завершится ошибкой. Каждая Perm, возвращенная перестановкой, будет собрана в переменную Permutations.

person DaveEdelstein    schedule 03.06.2011

permutation — это предикат, который выполняется успешно, когда один список является перестановкой другого. На самом деле вам не нужно их перечислять; просто напишите permutation([1, 2, 3], [2, 1, 3]) и Пролог скажет вам "true".

person Neil    schedule 01.06.2011
comment
и как показать решение для перестановки ([2, _, 1, _], [1,2,3,4])? нужно распечатать судоку :/ - person viktor; 02.06.2011
comment
@viktor: ты же не серьезно пытаешься решать судоку, перечисляя перестановки, не так ли? - person Fred Foo; 02.06.2011