There are six (6) problems on this exam. Please check now that you have a complete exam booklet with seven (7) numbered pages. Write your name or id number on each page of the exam. Be sure to try all of the problems, as some are more difficult than others (i.e., don't waste a lot of time on a problem that is giving you a hard time -- move on to another problem and then return to it later).
This exam is closed book. No papers, books or notes may be used. However, we will provide you with a copy of the Dylan cheatsheet.
There is space provided to answer each question. You may request extra paper if necessary. Do not put any answers on the backs of pages (THEY WILL NOT BE GRADED), ask for an extra piece of paper if you need more space to answer a problem.
To help ensure that you don't accidentally miss any of the questions, we have marked those sections where an answer is requested with a --> in the right margin.
The staff reserves the right to ignore illegible answers. ``Pretty printing'' (proper indentation) of your code will aid in the grading process.
(head (tail (head (tail '(5 (2 (6 3)) 4)))))
(((method (x) x) 3) 4)
(((method (car cdr) (method (x) (if x car cdr))) 1 2) #t)
(define except (method (test expr1 expr2) (if (not test) expr1 expr2))) (except #t (/ 1 0) 3)
(define reverse (method ((l < list >)) (if (null? l) l (append (reverse (tail l)) (list (head l))))))
Consider the following code, which defines a tree and some operations on it:
(define-class < tree > (< object > ) (left < object > ) (right < object > )) (define leaf? (method ((t < object > )) (not (instance? t < tree > )))) (define count-leaves (method ((t < object > )) (if (leaf? t) 1 (+ (count-leaves (left t)) (count-leaves (right t))))))Consider a binary tree
t , with left and right subtreest.l andt.r respectively. The depth oft is defined to be one larger than the depth of its deeper subtree, that isdepth(t) = 1 + max(depth(t.l), depth(t.r)) . Whent is a leaf node, meaning it has neither left nor right subtrees, its depth is 0.Assume that for a binary tree
t , represented using the class < tree > , that (leaf?t ) is true only whent is a leaf node. Moreover assume that when (leaf?t ) is false that (leftt )= t.l and (rightt )= t.r , that is that the accessors return the left and right subtrees respectively.Using induction and the substitution model, prove that (count-leaves
t ) counts the number of leaf nodes in any treet . We will break the question up into three parts: what you are inducting over, the induction hypothesis, and then the proof itself.
- What are you inducting over?
- Give a clear, concise statement of your induction hypothesis.
- Give an inductive proof that (count-leaves
t ) counts the number of leaf nodes in any treet . Remember to have clear, separate base case and induction step. Use the induction hypothesis you gave above.
(running-sum '(1 2 3 4)) --> (1 3 6 10) (running-sum '(7)) --> (7)Write a recursive procedure to compute running-sum, which runs in time linear in the length of the list. Your answer may not use any helper procedures either by defining other top-level procedures or by having internal methods (in particular you cannot use bind-methods or any other way of creating a method inside a method).
As with this entire exam, you may not use set!.
The composition of two functions (or procedures) is simply the application of one followed by the other. Consider the following procedure:
(define compose (method ((f < function > ) (g < function > )) (method ((x < object > )) (f (g x)))))
Thus ((compose f g) x) is equivalent to (f (g x)).
This idea can be extended to a list of functions, where ((compose-list (list f g h)) x) is equivalent to (f (g (h x))). Write a procedure compose-list that takes a list of procedures and computes the composition of those procedures. For example, your procedure should behave as follows,
((compose-list (list square inc)) 2)=9 ((compose-list (list list head reverse)) '(1 2 3))=(3) ((compose-list (list inc)) 3)=4 ((compose-list '() 3))=3
Your procedure should run in time linear in the length of the list of functions. It should not use any helper procedures (including ones defined internally to compose-list) and should not use set!. You need not necessarily use the function compose defined above in your solution.
(define-generic-function f ((a < object > ))) (add-method f (method ((a < object > )) (print "apple"))) (add-method f (method ((a < nurble > )) (print "lemon"))) (define-generic-function g ((b < object > ))) (add-method g (method ((b < glorp > )) (print "diamond"))) (add-method g (method ((b < foo > )) (print "sapphire"))) (add-method g (method ((b < object > )) (print "ruby")))
Assume that the types < nurble > , < glorp > , < foo > and < bar > have been defined such that the following output is generated:
(f (make < glorp > )) = "apple" (f (make < foo > )) = "lemon" (f (make < bar > )) = "lemon" (g (make < bar > )) = "ruby"
What are the definitions of the classes < nurble > , < glorp > , < foo > and < bar > that must have been defined to obtain this output?