2012-03-16 25 views
6

मैं योजना में Collatz अनुमान लिखा है:पूंछ रिकर्सिव कोलात्ज़ अनुमान क्यों योजना में ढेर ओवरफ्लो का कारण बनता है?

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

यह एक पूंछ पुनरावर्ती कॉल है, फिर भी मैं जब मैं (सी 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) 

क्यों उचित पूंछ प्रत्यावर्तन है एक अतिप्रवाह पैदा कर रहा है? जैसा कि आप देख सकते हैं, मैं एक योजना दुभाषिया (संस्करण 1.8.7) के रूप में गुइल का उपयोग कर रहा हूं।

+0

जब आप फ़ंक्शन कॉल का पता नहीं लगाते तो क्या होता है? जब आप किसी अन्य योजना प्रणाली का उपयोग करते हैं तो क्या होता है? – knivil

+0

ट्रेस अक्षम करने से मदद नहीं मिलती है। रैकेट दिए गए उदाहरण के साथ ठीक है। –

+7

यह एक बग हो सकता है: वह परिभाषा पूंछ-पुनरावर्ती दिखती है। (अधिकांश ट्रेसिंग लाइब्रेरी पूंछ-पुनरावर्तन को नष्ट कर देंगे, हालांकि।) –

उत्तर

2

परिभाषित प्रक्रिया प्रक्रिया रैकेट में ठीक काम करती है। यह मेरे लिए एक बग की तरह लगता है, या आपके पर्यावरण के लिए बहुत विशिष्ट है।

लगभग निश्चित रूप से आपकी समस्या से संबंधित नहीं है, लेकिन थोड़ा सा नाइट-पिकिंग: (eq? n 1) की बजाय संख्याओं के लिए तुलना (= n 1) का उपयोग करें।

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

यह लगता है कि यह हमेशा 1 रिटर्न (या असीम लूप - अनुमान अप्रमाणित बनी हुई है)। क्या रिकर्सिव कॉल के आसपास (+1 ...) छिपाने में एक प्रतिलेखन त्रुटि है?