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
?