Deep Recursion
Summary:
In this laboratory, you will further explore issues of deep recursion
introduced in the reading on pairs and pair structures and continued
in the reading on deep recursion.
Preparation
a. Make sure that you have the reading on pairs and pair structures
and the reading on deep recursion open in separate tabs and windows.
b. Make sure that you have a piece of paper and writing instrument handy.
Exercises
Exercise 1: Number Trees
Recall that a list is a data structure defined recursively as follows:
The empty list is a list.
Cons of a value and a list is a list.
In the reading on pairs and pair structures, the section entitled
Recursion with Pairs
includes a procedure that works
on number trees
, nested structures built with the
pair procedure.
Write a recursive definition for number trees,
trees built from only numbers and cons cells, similar to that for lists.
Exercise 2: A Number Tree Predicate
Using your recursive definition of number
trees from the previous problem, write a procedure,
(number-tree? val) that returns true
if val is a number tree and false otherwise.
Exercise 3: Summing Number Trees
Consider again the sum-of-number-tree procedure from the
reading, reproduced here.
a. Verify that sum-of-number-tree works as
advertised on a single number.
b. Verify that sum-of-number-tree works as
advertised on a pair of numbers.
c. Verify that it works as advertised on the first example.
> (sum-of-number-tree (cons (cons (cons 0 1)
(cons 2 3))
(cons (cons 4 5)
(cons 6 7))))
d. What do you expect sum-of-number-tree to return
when given (cons 10 11) as a parameter? Verify your
answer experimentally.
e. What do you expect sum-of-number-tree to return when
given the empty list as a parameter? Verify your answer experimentally.
f. What do you expect sum-of-number-tree to return when
given (list 1 2 3 4 5) as a parameter? Verify your answer
experimentally.
Exercise 4: Preconditions
a. What preconditions should sum-of-number-tree have?
b. Use the number-tree? predicate from earlier
to rewrite sum-of-number-tree so that it reports an
appropriate error if its preconditions are not met. Use husk-and-kernel
style, checking the preconditions in the husk.
c. Some programmers consider it inappropriate to scan a tree twice,
once to make sure that it's valid and once to compute a value based on
the tree. Rewrite sum-of-number-tree so that it checks
for and reports errors only when it is at one of the non-pair values.
Exercise 5: Counting Cons Cells
a. Define and test a procedure named
cons-cell-count that takes any Scheme value and
determines how many boxes would appear in its box-and-pointer diagram.
(The data structure that is represented by such a box, or the region
of a computer's memory in which such a structure is stored is called a
cons cell. Every time the cons
procedure is used, explicitly or implicitly, in the construction of
a Scheme value, a new cons cell is allocated, to store information
about the car and the cdr. Thus cons-cell-count also
tallies the number of times cons was invoked during the
construction of its argument.)
For example, the structure in the following box-and-pointer
diagram contains seven cons-cells, so when you apply
cons-cell-count to that structure, it should
return 7. On the other hand, the string "sample" contains
no cons-cells, so the value of (cons-cell-count "sample")
is 0.
In answering this question, you should consider whether each value, in
turn, is a pair using the pair? predicate.
b. Use cons-cell-count to find out how many cons
cells are needed to construct the list
(0 (1 (2 (3 (4)))))
See the notes at the end of the lab if you have trouble creating that list.
c. Draw a box-and-pointer diagram of this list to check the answer.
Explorations
Exploration 1: Rendering Color Trees
Recall the render-color-tree from the
reading.
a. Add render-color-tree to your definitions window.
b. Create a new 200x200 image named canvas.
c. What effect do you expect the following instruction to have?
> (render-color-tree color-blue canvas 0 0 200 200)
d. Check your answer experimentally.
e. What effect do you expect the following instruction to have?
> (render-color-tree (cons color-black color-red) canvas 0 0 200 200)
f. Check your answer experimentally.
g. What effect do you expect the following instruction to have?
> (render-color-tree (cons (cons color-green color-yellow) color-orange) canvas 0 0 200 200)
h. Check your answer experimentally.
i. Create a color tree that you might be able to render in some interesting
fashion.
j. Rewrite render-color-tree so that it splits the
image vertically rather than horizontally.
j. Write a procedure that, given a list of colors and a maximum depth,
generates an interesting color tree. Render your trees to see what they
look like!
Exploration 2: Color Trees,
Revisited: Splitting the Space Horizontally and Vertically
Create a new version of render-color-tree that
has an extra parameter, vsplit?, a Boolean value. If the
Boolean is true, when render-color-tree should
split the area vertically (as it currently does). If the Boolean is
false, render-color-tree should split the area
horizontally. In both cases, the recursive calls should negate that
Boolean value so that the splits alternate between vertical and
horizontal.
Notes
Notes on Exercise 5
If, for some reason, you are having trouble creating the list
(0 (1 (2 (3 (4)))))
try
(list 0 (list 1 (list 2 (list 3 (list 4)))))