2012-03-16 12 views
6

Pisałem Collatz przypuszczenie na schemacie:Dlaczego rekurencyjne spekulacje na temat Collasta powodują przepełnienie stosu w systemie?

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

To jest ogon wywołanie rekurencyjne, ale otrzymuję przepełnienie stosu, gdy zgłoszę (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) 

Dlaczego właściwa rekurencji ogon powodując przepełnienie? Jak widzisz, używam Guile'a jako tłumacza Scheme (wersja 1.8.7).

+0

Co stanie się, gdy nie prześledzisz wywołania funkcji? Co dzieje się podczas korzystania z innego systemu? – knivil

+0

Wyłączenie śledzenia nie pomaga. Rakieta ma się dobrze z podanym przykładem. –

+7

To może być błąd: ta definicja wygląda na rekursywną. (Większość bibliotek śledzenia zniszczy jednak rekursywność ogona). –

Odpowiedz

2

Procedura zgodnie z definicją działa poprawnie w Racket. Wydaje mi się, że to błąd, lub coś bardzo specyficznego dla twojego środowiska.

Prawie na pewno nie jest to związane z twoim problemem, ale odrobina wybijania nitek: użyj porównania (= n 1) dla liczb zamiast (eq? n 1).

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

To wygląda jak zawsze zwraca 1 (lub pętle nieskończenie - pozostaje niesprawdzona hipoteza). Czy występuje błąd transkrypcji ukrywający (+1 ...) wokół wywołań rekursywnych?

Powiązane problemy