5

Uczę się Prologu, a jako ćwiczenie eksperymentuję z prostą bazą danych, która oblicza sumę wszystkich liczb aż do podanej liczby (tj. 0 = 0, 1 = 1, 2 = 3, 3 = 6 , 4 = 10, ...). dość proste:Czy to może być rekurencyjne w Prologu?

counting_sum(0, 0). 
counting_sum(Num, Sum) :- Num > 0, PrevNum is Num - 1, 
    counting_sum(PrevNum, PrevSum), Sum is Num + PrevSum. 

To wysadza gdzieś counting_sum(150000, X). z przepełnienie stosu. Rozumiem, że Prolog może zrobić ogon rekursji, ale jeśli przenieść rekurencyjne wywołanie do końca rządów, mam

error(instantiation_error,(is)/2) 

które zakładam, że mówi mi, że nie można używać PrevSum zanim został zunifikowany z counting_sum(PrevNum, PrevSum) . Czy to prawda, i czy istnieje sposób na rekursję tego ogona? Używam GNU Prolog 1.3.1, jeśli to robi jakąkolwiek różnicę.

P.S. Wciąż jestem niepewny terminologii. Daj mi znać, jeśli użyłem tych terminów niepoprawnie.

+1

Masz rację o przyczynie błędu konkretyzacji. –

Odpowiedz

8

Spróbuj coś takiego (użyj akumulator):

counting_sum(Count, Sum):- 
    counting_sum(Count, 0, Sum). 

counting_sum(0, Sum, Sum). 
counting_sum(Num, PrevSum, Sum):- Num > 0, PrevNum is Num - 1, 
    NextSum is PrevSum + Num, 
    counting_sum(PrevNum, NextSum, Sum). 
+1

Dzięki. Nie spotkałem się z akumulatorami. To [wygląda jak przydatny idiom] (http://www.lix.polytechnique.fr/~liberti/public/computing/prog/prolog/prolog-tutorial.html#iteration). Po przeczytaniu i zrozumieniu, czym jest akumulator, udało mi się napisać nową implementację za pomocą jednego, a następnie sprawdzić ją pod kątem kodu. Wymyśliłem to samo. Problem: Nadal dostaję przepełnienie stosu około 'counting_sum (350000, X).' Czy jest jakiś pomysł, dlaczego tak się dzieje? –

+1

To dziwne. Próbowałem kodu, który dostarczyłem SWI z '3500000' (dziesięciokrotnie większą od twojej figury) i łatwo go obsługuje. – gusbro

+2

Spekuluję, ale GNU Prolog może nie optymalizować ogona w trybie zinterpretowanym (ale robi to SWI Prolog). @RyanStewart: co powiesz na potwierdzenie, czy użyłeś skompilowanego pliku wykonywalnego gprolog, czy tylko tłumacza? – hardmath

Powiązane problemy