SICP练习1.10:Ackermann函数的方案评估

时间:2014-09-24 08:46:49

标签: scheme evaluation sicp

我正在通过Structure and Interpretation of Computer Programs工作,并对练习1.10提出了一个问题,即使用Ackermann定义为

的函数
(define (A x y)
  (cond ((= y 0) 0)
    ((= x 0) (* 2 y))
    ((= y 1) 2)
    (else (A (- x 1)
             (A x (- y 1))))))

确定表达式(A 1 10)的值。

现在,我知道答案应该是(A 1 10) = 2^10 = 1024,但在完成计算时,我得到以下内容:

(A 1 10)
(A (- 1 1) (A 1 (- 10 1)))
(A 0 (A 1 9))
(A 0 (A 0 (A 1 8)))
...
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0(A 0 (A 0 (A 0(A 0 (A 0 (A 0 ( A 0 0)))))))))))))

现在,按照我理解的方式,Scheme首先评估最深的表达式,即最右边的(A 0 0)。它的值为0,因为函数的第一个条件是(= y 0)。同样的情况发生在下一步,我们最终会减少所有括号,直到我们最后得到(A 0 0),因为类似的原因,它也会有0的值。现在,我知道最后一行应该是

(*2 (*2 (*2 (*2 (*2 (*2 (*2 (*2 (*2 (*2 (*2 (A 0 0)))))))))))))

所以,如果所有这些都是正确的,为什么最后(A 0 0)会产生2而不是0?或者,更一般地说,您能否发现我的推理错误在哪里?我很确定它与递归调用的评估过程或者如何评估条件语句有关。

已解决:正如leppie所述,首先评估(= y 1),在2之前获取(A 0 1)作为(A 0 0)的值}}

1 个答案:

答案 0 :(得分:3)

你永远不会一直到

(A 0 0)

扩张计划

(A 0 (A 1 9))
(A 0 (A 0 (A 1 8)))
(A 0 (A 0 (A 0 (A 1 7))))
...
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 1 1))))))))))

现在(A 1 1)评估为2