Не существует эффективного способа определения reverse/2
с одним рекурсивным определением без использования некоторого вспомогательного предиката.Однако, если это все же разрешено, простое решение, которое не зависит от каких-либо встроенных программ, таких как append/3
(и должно применяться для большинства реализаций Prolog), заключалось бы в использовании списка аккумуляторов , так какследует:
rev([],[]).
rev([X|Xs], R) :-
rev_acc(Xs, [X], R).
rev_acc([], R, R).
rev_acc([X|Xs], Acc, R) :-
rev_acc(Xs, [X|Acc], R).
rev/2
- это предикат обращения, который просто «делегирует» (или упаковывает) версию на основе аккумулятора, называемую rev-acc/2
, которая рекурсивно добавляет элементы списка ввода в аккумуляторв обратном порядке.
Выполнение этого:
?- rev([1,3,2,x,4],L).
L = [4, x, 2, 3, 1].
И действительно, как @false уже указал (+1),
palindrome(X) :- rev(X,X).