Как удалить последний элемент из списка в Прологе?
Я нахожусь в следующей ситуации: у меня есть список, и я хотел бы удалить из него только последний элемент.
Я реализовал следующее правило (это нехорошо работают):
deleteLastElement([Only],WithoutLast) :-
!,
delete([Only],Only,WithoutLast).
deleteLastElement([_|Tail],WithoutLast) :-
!,
deleteLastElement(Tail,WithoutLast).
Проблема в том, что когда я вызываю его, все элементы в списке удаляются, фактически, если я выполняю следующее утверждение, которое я получаю:
[debug] ?- deleteLastElement([a,b,c], List).
List = [].
Глядя на след, я думаю, что причина этой проблемы ясна:
[trace] ?- deleteLastElement([a,b], List).
Call: (7) deleteLastElement([a, b], _G396) ? creep
Call: (8) deleteLastElement([b], _G396) ? creep
Call: (9) lists:delete([b], b, _G396) ? creep
Exit: (9) lists:delete([b], b, []) ? creep
Exit: (8) deleteLastElement([b], []) ? creep
Exit: (7) deleteLastElement([a, b], []) ? creep
List = [].
Когда базовый случай достигнут,WithoutLast список объединен спустой список [] и когда выполняется возвратWithoutLast все еще остается пустой список.
Это не хорошо.
Я думал реализовать это, выполнив следующую операцию:
Подсчитайте количество элементов в списке перед вызовом предиката, удаляющего последний элемент.Итерация по рекурсии и уменьшение значения номера элемента каждый разЕсли это правда, что номер элемента равен 0, это означает, что это последний элемент, поэтому я удаляю его из исходного спискаНо это кажется мне неясным и не очень хорошим, я бы знал, есть ли декларативное хорошее решение этой проблемы.