Я в следующей ситуации: у меня есть список, и я бы удалить из него только последний элемент.Как удалить последний элемент из списка в Prolog?
У меня есть реализовать следующее правило (которые не работают хорошо):
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 по-прежнему остаются пустым списком.
Это не хорошо.
Я думал осуществить это делать следующие операции:
- Подсчитать количество элементов в списке, прежде чем вызвать предикат, удалить последний элемент.
- Iterate рекурсии и уменьшение значения числа элементов каждый раз, когда
- Если это верно, что число элементов равно 0, это означает, что это последний элемент, поэтому я удалить его из исходного списка
Но это кажется мне непонятным и не очень хорошим, я бы знал, есть ли декларативное хорошее решение этой проблемы.
+1 для 'append (WithoutLast, [_], List)' трюк. –