Я пытаюсь получить представление о программировании Пролога, просмотрев заметки лекций "Уолл Эндрисс" . Когда мое решение упражнения не ведет себя так, как ожидалось, мне трудно дать хорошее объяснение. Я думаю, что это связано с моим шатким пониманием того, как Prolog оценивает выражения.
Упражнение 2.6 на стр. 20 вызывает рекурсивную реализацию предиката last1
, который ведет себя как встроенный предикат last
. Моя попытка такова:
last1([_ | Rest], Last) :- last1(Rest, Last). last1([Last], Last).
Он дает правильный ответ, но для списков с более чем одним элементом я должен указать точку с запятой, чтобы завершить запрос. Это делает last1
отличным от встроенного last
.
?- last1([1], Last).
Last = 1.
?- last1([1, 2], Last).
Last = 2 ;
false.
Если я переключу порядок, в котором я объявил правило и факт, тогда мне нужно указать точку с запятой в обоих случаях.
Думаю, я знаю, почему Prolog считает, что last1
может иметь еще одно решение (таким образом, точка с запятой). Я предполагаю, что это следует за последовательностью оценки
last1([1, 2], Last).
==> last1([2], Last).
==> last1([], Last). OR Last = 2.
==> false OR Last = 2.
Это похоже на то, что я должен искать способ избежать сопоставления Rest
с []
. Несмотря на это, у меня нет объяснений, почему изменение порядка декларации должно иметь какой-либо эффект.
Вопрос 1: Какое правильное объяснение поведения last1
?
Вопрос 2: Как реализовать предикат last1
, который неотличим от встроенного last
?