2012-03-16 14 views
6

ho scritto Collatz congetture nello Schema:Perché la congettura collassica ricorsiva della coda causa uno straripamento dello stack in Scheme?

(define C 
    (lambda (n) 
    (cond 
    ((eq? n 1) 1) 
    ((even? n) (C (/ n 2))) 
    (else (C (+ (* n 3) 1)))))) 

Questa è una chiamata ricorsiva di coda, ma ottengo overflow dello stack quando chiamo (C 121):

guile> (trace C) 
(C) 
guile> (C 121) 
[C 121] 
[C 364] 
[C 182] 
[C 91] 
[C 274] 
[C 137] 
[C 412] 
[C 206] 
[C 103] 
[C 310] 
[C 155] 
[C 466] 
[C 233] 
[C 700] 
[C 350] 
[C 175] 
[C 526] 
[C 263] 
[C 790] 
[C 395] 
[C 1186] 
ERROR: Stack overflow 
ABORT: (stack-overflow) 

Perché è corretta ricorsione di coda causando un overflow? Come puoi vedere, sto usando Guile come interprete di Scheme (versione 1.8.7).

+0

Cosa succede quando non si traccia la chiamata di funzione? Cosa succede quando usi un altro sistema di schemi? – knivil

+0

La disabilitazione della traccia non aiuta. La racchetta funziona bene con l'esempio fornito. –

+7

Questo potrebbe essere un bug: quella definizione sembra ricorsiva in coda. (La maggior parte delle librerie traccianti distruggerà comunque la ricorsione della coda.) –

risposta

2

La procedura come definita funziona correttamente in Racket. Sembra un bug per me, o qualcosa di molto specifico per il tuo ambiente.

Quasi certamente non correlato al problema, ma un po 'di nit-picking: utilizzare il confronto (= n 1) per i numeri anziché (eq? n 1).

0
(define C 
    (lambda (n) 
    (cond 
    ((eq? n 1) 1) 
    ((even? n) (C (/ n 2))) 
    (else (C (+ (* n 3) 1)))))) 

Questo appare come ritorna sempre 1 (o loop all'infinito - la congettura ancora da dimostrare). C'è un errore di trascrizione che nasconde un (+1 ...) attorno alle chiamate ricorsive?