clozure cl 1.9 on Macで遊んでいたら、Stack over flow した話
大きい数を計算できる、common lispで遊んでみることにした。
※この計算内容に意味はありません。
(defun f (n) (1+ n)) (defun b (m n) (cond ((<= m 0) (f n)) ((<= n 0) (b (1- m) 1)) ( t (b (1- m) (b m (1- n))))))
これで、(b 4 4)を計算すると stack over flow になる。
スタックを減らすために計算結果をキャッシュできるようにメモ化してみた。
(defvar *table* (make-hash-table :test #'equal)) (defun b-memo (m n) (let* ((key (list m n)) (val (gethash key *table* nil))) (unless val (setf val (cond ((<= m 0) (f n)) ((<= n 0) (b-memo (1- m) 1)) ( t (let ((l (b-memo m (1- n)))) (b-memo (1- m) l))))) (setf (gethash key *table*) val)) val))
それでもやっぱり (b-memo 4 4)で死ぬ。
しかたがないので、順番に進めていけば、メモを成長させるとうまくいくかも?
CL-USER> (b-memo 3 10) 8189 CL-USER> (b-memo 3 20) Invoking restart: Return to SLIME's top level. ; Evaluation aborted on #<CCL::STACK-OVERFLOW-CONDITION #x3020026800DD>.
CL-USER> (b-memo 3 11) 16381 CL-USER> (b-memo 3 12) 32765 CL-USER> (b-memo 3 13) 65533 CL-USER> (b-memo 3 14) 131069 CL-USER> (b-memo 3 15) Invoking restart: Retry SLIME REPL evaluation request. Invoking restart: Return to SLIME's top level. ; Evaluation aborted on #<CCL::STACK-OVERFLOW-CONDITION #x3020026E2C8D>.
CL-USER> (b-memo 2 10000) 20003 CL-USER> (b-memo 2 20000) 40003 CL-USER> (b-memo 2 40000) 80003 CL-USER> (b-memo 2 80000) 160003 CL-USER> (b-memo 2 100000) 200003 CL-USER> (b-memo 2 200000) Invoking restart: Return to SLIME's top level. ; Evaluation aborted on #<CCL::STACK-OVERFLOW-CONDITION #x3020037ADC2D>. CL-USER> (b-memo 2 150000) Invoking restart: Return to SLIME's top level. ; Evaluation aborted on #<CCL::STACK-OVERFLOW-CONDITION #x3020037A068D>. CL-USER> (b-memo 2 125000) 250003 CL-USER> (b-memo 2 130000) 260003 CL-USER> (b-memo 2 150000) 300003 CL-USER> (b-memo 2 160000) 320003 CL-USER> (b-memo 2 170000) 340003 CL-USER> (b-memo 2 180000) 360003 CL-USER> (b-memo 2 190000) 380003 CL-USER> (b-memo 2 200000) 400003 CL-USER> (b-memo 2 210000) 420003 CL-USER> (b-memo 2 220000) 440003 CL-USER> (b-memo 2 240000) 480003 CL-USER> (b-memo 2 260000) 520003 CL-USER> (b-memo 2 290000) 580003 CL-USER> (b-memo 3 15) 262141 CL-USER> (b-memo 3 16) 524285 CL-USER> (b-memo 3 20) Invoking restart: Return to SLIME's top level. ; Evaluation aborted on #<CCL::STACK-OVERFLOW-CONDITION #x30200563F2BD>. CL-USER> (b-memo 3 18) Invoking restart: Return to SLIME's top level. ; Evaluation aborted on #<CCL::STACK-OVERFLOW-CONDITION #x302005774A9D>. CL-USER> (b-memo 3 17) Invoking restart: Return to SLIME's top level. ; Evaluation aborted on #<CCL::STACK-OVERFLOW-CONDITION #x3020056319DD>.