5

Sto imparando Prolog e, come esercizio, sto sperimentando un semplice database che calcola la somma di tutti i numeri fino al numero specificato (cioè 0 = 0, 1 = 1, 2 = 3, 3 = 6 , 4 = 10, ...). Abbastanza facile:Questo può essere fatto ricorsivo in coda in Prolog?

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

che soffia da qualche parte intorno counting_sum(150000, X). con un overflow dello stack. Capisco che Prolog può fare ricorsione in coda, ma se mi trasferisco la chiamata ricorsiva alla fine della regola, ottengo

error(instantiation_error,(is)/2) 

che ammetto mi sta dicendo che non posso usare PrevSum prima che è stato unificato con counting_sum(PrevNum, PrevSum) . È corretto, e c'è un modo per rendere questa coda ricorsiva? Sto usando GNU Prolog 1.3.1 se questo fa alcuna differenza.

P.S. Sono ancora traballante sulla terminologia. Fammi sapere se ho usato i termini in modo errato.

+1

Hai ragione circa la causa dell'errore di un'istanza. –

risposta

8

provare qualcosa di simile (utilizzare un accumulatore):

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

Grazie. Non avevo incontrato gli accumulatori. [Sembra un utile idioma] (http://www.lix.polytechnique.fr/~liberti/public/computing/prog/prolog/prolog-tutorial.html#iteration). Avendo letto e capito cos'è un accumulatore, sono stato in grado di scrivere una nuova implementazione utilizzando uno e quindi controllarlo dal tuo codice. Sono venuto con la stessa cosa. Problema: continuo ad avere un overflow dello stack di circa 'counting_sum (350000, X).» Qualche idea sul perché? –

+1

Questo è strano. Ho provato il codice che ho fornito con SWI con '3500000' (dieci volte la tua cifra) e lo gestisce facilmente. – gusbro

+2

Sto speculando, ma GNU Prolog potrebbe non eseguire l'ottimizzazione della coda in modalità interpretata (ma SWI Prolog lo fa). @RyanStewart: che ne dici di confermare se hai usato un eseguibile gprolog compilato, o solo l'interprete? – hardmath