Вы можете увидеть, как работает интерпретатор, набрав (ну, по крайней мере, в swi-pl, должно быть что-то похожее в других реализациях):
?- trace, del(c, [a,b,c],X).
Кстати, вы, конечно, забыли включить строку, такую как:
del(_, [], []).
В противном случае алгоритм не инициализирует список результатов.
Тогда это действительно просто: если первый элемент списка не подходит для того, который вы хотите удалить, вы пропускаете его, иначе вы включаете его в список результатов.
По сути, здесь все будет работать так:
del (c, [a, b, c], X) => c не может быть объединен с a, поэтому мы будем включать его при построении списка с конца.
del (c, [b, c], X) => c нельзя объединить с b, поэтому мы будем включать b при построении списка с конца.
del (c, [c], X) => c можно объединить с c, поэтому мы не будем включать c при построении списка с конца.
del (c, [], X) => [] истинно, когда X = [], поэтому, скажем, X = [], и теперь давайте построим наш список результатов, взбираясь по рекурсии:
X = [] при подъеме на один шаг вверх, потому что c не включен.
X = [b] при подъеме на один шаг вверх, потому что b включено.
X = [a, b] при подъеме на одну ступеньку, потому что включен a.