2012-03-16 31 views
6

Tôi đã viết Collatz phỏng đoán trong Đề án:Tại sao đuôi đệ quy Collatz phỏng đoán gây tràn ngăn xếp trong Đề án?

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

Đây là một cái đuôi gọi đệ quy, nhưng tôi nhận được stack overflow khi tôi gọi số (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) 

Tại sao là thích hợp đệ quy đuôi gây tràn? Như bạn có thể thấy, tôi đang sử dụng Guile như một trình thông dịch Scheme (phiên bản 1.8.7).

+0

Điều gì sẽ xảy ra khi bạn không theo dõi cuộc gọi chức năng? Điều gì xảy ra khi bạn sử dụng một hệ thống lược đồ khác? – knivil

+0

Tắt theo dõi không hiệu quả. Vợt không tốt với ví dụ đã cho. –

+7

Đây có thể là lỗi: định nghĩa đó trông có vẻ đệ quy. (Hầu hết các thư viện truy tìm sẽ phá hủy đuôi đệ quy, mặc dù.) –

Trả lời

2

Quy trình được xác định hoạt động tốt trong Vợt. Nó có vẻ như một lỗi đối với tôi, hoặc một cái gì đó rất cụ thể đối với môi trường của bạn.

Hầu như chắc chắn không liên quan đến vấn đề của bạn, nhưng một chút chọn nitro: sử dụng so sánh (= n 1) cho số thay vì (eq? n 1).

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

Có vẻ như nó luôn trả về 1 (hoặc vòng lặp vô hạn - phỏng đoán vẫn chưa được chứng minh). Có một lỗi phiên mã ẩn một số (+1 ...) xung quanh các cuộc gọi đệ quy không?