Modified the explicit evaluator to a lazy one. And here are the main blocks I added.
actual-value
(save continue)
(save env)
(save exp)
(assign continue (label force-it))
(goto (label eval-dispatch))
force-it
(test (op thunk?) (reg val))
(branch (label thunk-extract))
(restore exp)
(restore env)
(restore continue)
(goto (reg continue))
thunk-extract
(assign env (op thunk-env) (reg val))
(assign exp (op thunk-exp) (reg val))
(goto (label actual-value))
Here is the whole source file
Tuesday, November 29, 2011
Playing with Fibonacci - solution of SICP exercise 5.29
Here is the exercise and my answer.
Exercise 5.29. Monitor the stack operations in the tree-recursive Fibonacci computation:
(define (fib n)
(if (< n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))
b. Give a formula for the total number of pushes used to compute Fib(n) for n > 2. You should find that the number of pushes (which correlates well with the time used) grows exponentially with n. Hint: Let S(n) be the number of pushes used in computing Fib(n). You should be able to argue that there is a formula that expresses S(n) in terms of S(n - 1), S(n - 2), and some fixed ``overhead'' constant k that is independent of n. Give the formula, and say what k is. Then show that S(n) can be expressed as a Fib(n + 1) + b and give the values of a and b.
My answer:
From Fibonacci function definition above, we can make the conclusion that
S(n) = S(n-1) + S(n-2) + k.
This looks already like the orignal Fibnacci sequence but let's have a look at S(0) and S(1).
S(0) contains only the overhead pushes, let's say this is [a], but not the k above.
S(1) is same.
For S(n) and n>2, k includes not only [a] but also pushes before computation of [+] of S(n-1) and S(n-2).
So S(n) should look like below:
a, a, 2a + k, 3a + 2k, 5a + 4k, ... ...
And the original Fibonacci is:
0, 1, 1, 2, 3, 5, ... ...
Then S(n) must has the format below.
aFib(n+1) + b.
And if given 2 total pushes, etc., S(1) and S(2), we can calculate the value of [a] and [k] as below.
a=16 and k=40.
Experiment:
Exercise 5.29. Monitor the stack operations in the tree-recursive Fibonacci computation:
(define (fib n)
(if (< n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))
b. Give a formula for the total number of pushes used to compute Fib(n) for n > 2. You should find that the number of pushes (which correlates well with the time used) grows exponentially with n. Hint: Let S(n) be the number of pushes used in computing Fib(n). You should be able to argue that there is a formula that expresses S(n) in terms of S(n - 1), S(n - 2), and some fixed ``overhead'' constant k that is independent of n. Give the formula, and say what k is. Then show that S(n) can be expressed as a Fib(n + 1) + b and give the values of a and b.
My answer:
From Fibonacci function definition above, we can make the conclusion that
S(n) = S(n-1) + S(n-2) + k.
This looks already like the orignal Fibnacci sequence but let's have a look at S(0) and S(1).
S(0) contains only the overhead pushes, let's say this is [a], but not the k above.
S(1) is same.
For S(n) and n>2, k includes not only [a] but also pushes before computation of [+] of S(n-1) and S(n-2).
So S(n) should look like below:
a, a, 2a + k, 3a + 2k, 5a + 4k, ... ...
And the original Fibonacci is:
0, 1, 1, 2, 3, 5, ... ...
Then S(n) must has the format below.
aFib(n+1) + b.
And if given 2 total pushes, etc., S(1) and S(2), we can calculate the value of [a] and [k] as below.
a=16 and k=40.
Experiment:
Subscribe to:
Posts (Atom)