Zapytanie do prologu: jakie znaczenie ma dodawanie w przypadku zapytań rekurencyjnych
Próbuję napisać predykat, aby znaleźć n-ty element listy.
Początkowo napisałem coś takiego:
nth([X|_], 0, X).
nth([_|T],N,Z):- N > 0, nth(T, M, Z), N is M + 1.
Działa w przypadku zapytań, takich jak, nth([1, 2, 3, 4, 5], 0, X).
ale w przypadku zapytań, takich jak nth([1, 2, 3, 4, 5], N, 1).
, po wprowadzeniu „arguments niedostatecznie utworzony błąd” pojawia się komunikat „;” po otrzymaniu odpowiedzi. Wiem, że w tym przypadku będzie tylko 1 ans, ale dla porządku chcę wiedzieć dlaczego.
Czytałem na przepełnieniu stosu tutaj, że lepsze rozwiązanie jest następujące:
nth([X|_], 0, X) :- !.
nth([_|Y], N, Z) :- N > 0, M is N-1, nth(Y, M, Z).
Chcę zrozumieć, dlaczego M is N-1, nth(Y, M, Z).
ma to znaczenie w porównaniu z nth(T, M, Z), N is M + 1
moją odpowiedzią.
PS: Myślę, że tytuł pytania można poprawić, ale nie jestem pewien jak. Jeśli masz sugestie, daj mi znać!
Odpowiedzi
is/2
nie jest kompletnym narzędziem do rozwiązywania ograniczeń. Więc N is M + 1
i M is N - 1
wygląd za równoważne, ale nie są. Pierwsza powiedzie się tylko wtedy, gdy zostanie utworzona instancja M, a druga, gdy zostanie utworzona instancja N. Czy wypróbowałeś swoje rozwiązanie z indeksami innymi niż zero? Nie będą działać. Możesz użyć plus(1, M, N)
zamiast jednego z nich, aby to zadziałało. Również porządkowanie klauzul ma znaczenie, tak plus(1, M, N)
powinno być przed wywołaniem rekurencyjnym nth
.
nth([X|_], 0, X).
nth([_|T],N,Z):- N > 0, plus(1, M, N), nth(T, M, Z).
Jeśli N > 0, nth(T, M, Z), plus(1, M, N)
jest to kolejność klauzul, program spróbuje nth(T, M, Z)
najpierw spełnić wymagania i spowoduje niezainstalowany błąd, N > 0
ponieważ wystąpienie M nie zostało już utworzone.
Również żaden program nie będzie działał w przypadku generatywnym.