Zapytanie do prologu: jakie znaczenie ma dodawanie w przypadku zapytań rekurencyjnych

Nov 22 2020

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 + 1moją odpowiedzią.

PS: Myślę, że tytuł pytania można poprawić, ale nie jestem pewien jak. Jeśli masz sugestie, daj mi znać!

Odpowiedzi

3 rajashekar Nov 22 2020 at 14:56

is/2nie jest kompletnym narzędziem do rozwiązywania ograniczeń. Więc N is M + 1i M is N - 1wyglą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 > 0ponieważ wystąpienie M nie zostało już utworzone.

Również żaden program nie będzie działał w przypadku generatywnym.