2016-09-29 3 views
0

Итак, я в процессе обучения пролога.Достигнув результата, он возвращается в исходное состояние

Все, что я хочу сделать, это изменить порядок элементов и получить новый список в качестве результата.

При отслеживании решения я получаю правильный ответ, однако, как только я дойду до базового случая, Prolog снова начинает очищать список и возвращает и пустым списком в результате.

Код:

accRev([], [], _) :- !. 
accRev([], A, R) :- accRev(A, [], R), !. 
accRev([H, H2 |T], A, R):- 
    append(R, [H], R1), 
    append(A, [H2], A1), 
    accRev(T, A1, R1), !. 
accRev([H], A, R):- 
    append(R, [H], R1), 
    accRev(A, [], R1), !. 

accRevT([], [], _) :- !. 
accRevT([], A, R) :- accRev(A, [], R), !. 
accRevT([H, H2 |T], A, R):- 
    append(R, [H], R1), 
    append(A, [H2], A1), 
    accRevT(T, [H2 | A], [H | R]), !. 
accRevT([H], A, R):- 
    append(R, [H], R1), 
    accRevT(A, [], [H | R]), !. 

Изображение следа

Обратите внимание, как он достигает accRev ([], [], [1, 3, 2, 4]) (это что хотелось бы, чтобы стать R, R = [1, 3, 2, 4])

enter image description here

Так что не так?

+1

См. [Этот ответ] (http://stackoverflow.com/a/15259282/1812457). Вы должны _not_ иметь анонимную переменную '_' в своей статье о конце рекурсии при использовании аккумуляторов. Предложение обычно читает 'foo ([], Acc, Acc) .', а не' foo ([], [], _). ' –

+2

Еще одна серьезная проблема с вашим кодом: слишком много разрезов. Вы действительно знаете, что делает каждый из них? Знаете ли вы, что если они оставят их вне программы? –

+1

Что именно вы хотите в качестве вывода? Какова цель вашей программы, потому что «изменить порядок элементов» не очень понятно ... – coder

ответ

0

Если правильно понял, что вы пытаетесь сделать, вы могли бы написать:

accRev([],[]). 
    accRev([X|Y], Lout):- 
    split_list([X|Y],Z1), 
    split_list(Y,Z2), 
    accRev(Z2,Z3), 
    append(Z1,Z3,Lout). 


split_list([],[]). 
split_list([X|[]], [X]). 
split_list([X,_|T], [X|R]):-split_list(T,R). 

Пример:

?- accRev([1,2,3,4],R). 
R = [1, 3, 2, 4] ; 
false. 

В вашем решении я думаю, что некоторые проблемы были вызваны из-за использования слишком много сокращений и accRev([], [], _), как писал Борис, а также, как мне кажется, вам не нужен средний список, потому что, например, оговорки:

accRev([], [], _) :- !. 
accRev([], A, R) :- accRev(A, [], R), !. 

приведет к проблемам, так как если первый список - это пустой список, оба предложения совпадают.

Смежные вопросы