Due: Wednesday, November 7, 2001
This assignment involves two recursive programs to draw tree data structures; the second one will introduce object-oriented programming.
We will use a form of object-oriented programming (OOP) to write the program in a data-independent form. In OOP, we send messages to objects rather than calling functions on data. Sending a message is in fact a function call, but the system determines what function to call from the class of the object to which the message is sent and the selector (abstract function name) of the message; the function that implements the message for a given class of objects is called a method.
Examine the file droop.scm to see the simple object-oriented system that we will use for this assignment. All of the methods mentioned in the list *methods* will be needed; some are defined in this file, and you will need to write the others. Your function draw-tree will send messages to the objects it deals with to avoid having to know about their implementations.
Load the file droop.scm and try the following examples to see how messages work.
(drclass 5) (drsend 5 'terminal) (drclass 'foo) (drsend '(a b) 'terminal) (drclass '(a b)) (drsend '(a b) 'left) (drclass '(box 30)) (drsend '(a b) 'right)
For purposes of drawing binary trees, we assume that objects
can respond to the following messages. The argument self is the
object to which the message is sent;
e.g., in (drsend 5 'terminal) self would be 5.
|terminal self||True if self is a terminal node (has no children)|
|draw self x y size||Draw self in a box whose upper-left corner is (x,y) with size size|
|left self||Left subtree of self|
|right self||Right subtree of self|
|leftx self x size||x position of line from the drawing of self to its left subtree|
|lefty self y size|
|rightx self x size||x position of line from the drawing of self to its right subtree|
|righty self y size|
|width self size||width of the drawing of self|
|drawline self x y xto yto||Draw a line from (x,y) to (xto,yto)|
draw-tree will follow the convention that its input position (x,y) is the upper-left position of the tree to be drawn; it will always return the rightmost x value of the tree that it draws. draw-tree should work as follows:
As one example of binary trees, we will use Lisp trees. A Lisp pair should be drawn as a pair box, with its arrow positions at the centers of the two halves of the pair drawing. Add a method to draw an empty list as a small square.
As a second example of binary trees, we will define a mobile object. A mobile node has two subtrees: (mobile left right ). The subtrees may be other mobiles, Lisp atoms (symbols or integers), or a box or triangle or diamond: (box width ), (triangle width ), (diamond width ). A mobile node should be drawn as a vertical line (zero width) with both connecting line positions at the bottom. A connecting line for a mobile should be drawn as vertical, horizontal, then vertical.
Demonstrate that the same program will draw both a Lisp tree and a mobile. Test data are provided in the file droop.scm . What happens if mobiles and Lisp trees are mixed in the same data structure?