Laboratory: TreesSummary:
In this laboratory, you will further explore issues of recursion
over trees introduced in the reading on pairs and pair structures and
continued in the reading on trees.
Preparation
a. Make sure that you have the reading on pairs and pair
structures and the
reading on trees open in separate tabs or windows.
b. Make sure that you have a piece of paper and writing instrument handy.
ExercisesExercise 1: A Color Tree Predicate
As you may recall from the reading, we have defined color trees
as follows.
Any color is a color tree.
If t1 and t2 are
color trees, then so is (cons
t1t2).
Nothing else is a color tree.
Using this recursive definition, write a procedure,
(color-tree? val) that returns true
(#t) if val is a color tree and false
(#f) otherwise.
Exercise 2: Rendering Color Trees
Recall the render-color-tree! procedure 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! "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 "black" "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 "green" "yellow") "orange") canvas 0 0 200 200)
h. Check your answer experimentally.
i. What effect do you expect the following instruction to have?
>(render-color-tree! (cons "red" (cons (cons "blue" "purple") "black")) canvas 0 0 200 200)
j. Check your answer experimentally.
k. Create a color tree that you might be able to render in some interesting
fashion.
Exercise 3: Changing Orientation
Rewrite render-color-tree! so that it splits the
image vertically rather than horizontally.
Exercise 4: Preconditions
a. What preconditions should render-color-tree! have?
b. Use the color-tree? predicate from an earlier
exercise to rewrite render-color-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. In your implementation from (b), the tree is traversed twice:
Once in color-tree? to check that the tree is valid, and
once in the kernel to do the work of rendering the tree.
Some programmers see this as inefficient.
Write another version of render-color-tree!
that does not use color-tree? to verify
preconditions. Instead, the kernel should verify as it goes along that
each leaf is a color. That is, the kernel should issue an error message if
it finds any tree value that is neither a pair nor a color.
Exercise 5: Counting Cons Cells
Let's explore trees more generally. As you've noted, trees are built
from cons cells (a.k.a. pairs). Sometimes it is useful to find out how many
cons cells are in a tree.
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
If you have extra time, you should try some of these explorations
or some of the for those with extra time problems
below.
Exploration 1: Building
Randomized Color Trees
One potentially interesting way to experiment with color trees is
to have a procedure build those trees. How? We might provide the
procedure with an intended size of the tree.
If the number of colors is 1, we return a randomly-selected color.
If the number of colors is 2, we cons together two trees of size 1.
Otherwise, we pick a random size for the left subtree (the size
should be at least 1 and strictly less than the intended size of
the whole tree). We then recursively build a tree of that size and
another tree of an appropriate size and then cons them together.
a. Using this technique, write a procedure, (random-bw-treesize), that randomly builds a black and white tree of the appropriate size.
b. Using this technique, write a procedure, (random-color-treesizecolors), that builds a random color tree of the desired size, randomly selecting the color from the list colors.
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.
For Those with Extra Time
If you find that you have extra time, you might want to attempt one
or more of the following problems.
Extra 1: Cons Cells vs. Values
As you may recall, a tree is either (a) a non-pair value or (b) the
cons of two trees. In the reading, you saw a procedure that counted
the number of values in a tree. In this lab, you wrote a procedure
that counted the number of cons cells (pairs) in a tree. What is the
relationship between the numbers returned by those two procedures?
Extra 2: Searching for Values
a. Write a procedure, (color-tree-contains?ctreecolor),
that determines whether color appears anywhere in
ctree. (We may have written a similar procedure
during the class discussion. If so, you can start with that procedure.)
b. Rewrite the procedure to determine if a color nearby to color
appears somewhere in ctree. (You might say that two colors
are nearby if their red, green, and blue components all differ by less
than sixteen.)
c. Write (tree-containstreevalue), a generalized version of
color-tree-contains that works with a
heterogeneous tree (that is, a tree that contains multiple kinds of values).
NotesNotes 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)))))
Return to the problem.