Implementacja „ostatniego” w Prologu

Staram się wyczuć programowanie Prologu, przechodząc przez Ulle Endriss ”notatki z wykładów. Kiedy moje rozwiązanie ćwiczenia nie zachowuje się zgodnie z oczekiwaniami, trudno mi dać dobre wyjaśnienie. Myślę, że ma to związek z moim chwiejnym zrozumieniem sposobu, w jaki Prolog ocenia wyrażenia.

Ćwiczenie 2.6 na stronie 20 wymaga rekurencyjnej implementacji predykatulast1 który zachowuje się jak predykat wbudowanylast. Moja próba jest następująca:

last1([_ | Rest], Last) :- last1(Rest, Last).
last1([Last], Last).

Daje poprawną odpowiedź, ale w przypadku list zawierających więcej niż jeden element muszę wprowadzić średnik, aby zakończyć zapytanie. To sprawialast1 różny od wbudowanegolast.

?- last1([1], Last).
Last = 1.

?- last1([1, 2], Last).
Last = 2 ;
false.

Jeśli zmienię kolejność, w której zadeklarowałem regułę i fakt, muszę w obu przypadkach wprowadzić średnik.

Myślę, że wiem, dlaczego Prolog tak myślilast1 może mieć jeszcze jedno rozwiązanie (a więc średnik). Wyobrażam sobie, że podąża za sekwencją oceny

last1([1, 2], Last).
==>  last1([2], Last).
==>  last1([], Last).    OR    Last = 2.
==>  false    OR    Last = 2.

Wydaje się to sugerować, że powinienem szukać sposobu na uniknięcie dopasowaniaRest z[]. Niezależnie od tego nie mam wyjaśnienia, dlaczego zmiana kolejności deklaracji powinna mieć jakikolwiek wpływ.

Pytanie 1: Jakie jest właściwe wyjaśnienie zachowanialast1?

Pytanie 2: Jak mogę zaimplementować predykatlast1 który jest nie do odróżnienia od wbudowanegolast?

questionAnswers(3)

yourAnswerToTheQuestion