Search code examples
schemeevaluationsicp

SICP exercise 1.10: Scheme evaluation of Ackermann's function


I'm working through Structure and Interpretation of Computer Programs and have a question concerning exercise 1.10, which, using Ackermann's function defined as

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

determine the value of the expression (A 1 10).

Now, I know the answer should be (A 1 10) = 2^10 = 1024, but when working through the computation, I get the following:

(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)))))))))))))

Now, the way I understood it, Scheme will start by evaluating the deepest expressions first, i.e. the (A 0 0) on the far right. This has the value 0, as the first condition of the function is met with (= y 0). The same happens for the next step and we end up reducing all brackets until we end up with the last (A 0 0) which will also have the value 0 for analogous reasons. Now, I get that the last line should be something like

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

So, if all of this is correct, why does the last (A 0 0) yield 2 instead of 0? Or, more generally, can you spot where the error in my reasoning is? I'm pretty sure it either has something do to with the evaluation procedure of recursive calls OR with how conditional statements are evaluated.

Solved: As noted by leppie the (= y 1) gets evaluated first, getting 2 as value for (A 0 1) before getting to (A 0 0)


Solution

  • You never get all the way to

    (A 0 0)
    

    The expansion proceeds

    (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))))))))))
    

    and now the (A 1 1) is evaluated to 2.