Ответ в теме: Удаление элемента списка

      Комментарии к записи Ответ в теме: Удаление элемента списка отключены
#1737

В статье с теорией по спискам описаны предикаты delete и nth0. Вы могли бы последовательно получить элемент, а затем удалить его из списка. Однако, delete удаляет все вхождения заданного значения в списке (аналогичным образом работают стандартные предикаты в соответствии с ISO).

Однако, вы можете использовать вместо delete стандартный предикат select с отсечением – это позволит выбрать элемент из списка, получить список остальных элементов и остановить перебор отсечением.

Можно написать и специальный предикат, решающий вашу задачу:

delete_nth0(List, Index, List):-
  List = [], !; 
  Index < 0, !.
delete_nth0([_Head|Tail], 0, Tail):-!. 
delete_nth0([Head|Tail], Index, [Head|TailWithoutNth0]):- 
  TailIndex is Index - 1, 
  delete_nth0(Tail, TailIndex, TailWithoutNth0).

Первое правило обрабатывает некорректные исходные данные – случаи, когда на вход подан список, в котором нет элемента с заданным индексом. В данном случае на выход подается исходный список, однако, можно было бы завершать вычисления неудачей. Обработку случая с отрицательным индексом можно вынести в отдельную функцию – это повысит эффективность программы.
Если индекс равен нулю – то результатом является исходный список за исключением первого элемента. Во всех остальных случаях выполняется рекурсивная обработка хвоста.