Administrivia: PS#3 due in about 36 hours. PS#4 won't be out until after the prelim (studying for the prelim is a better use of your time...)
Write a recursive function that takes an 'a list and returns a copy of it. Prove that your function is correct, using induction and the substitution model. You may assume that the list primitives null,hd,tl,:: operate correctly.
fun copy(l:'a list):'a list = if null(l) then l else hd(l)::copy(tl(l))
Correctness proof:
eval(let fun copy(l) = if null?(l) then l else hd(l)::copy(tl(l)) in fact(1st) end) � eval((fun copy(l) = if null?(l) then l else hd(l)::copy(tl(l))) (1st)) � eval(if null?(lst) then lst else ((fun copy(l) = if null?(l) then l else hd(l)::copy(tl(l)))(lst)) � [because length of lst = 0] lstInduction case: lst has length m+1, copy works on lists of length m.
eval(let fun copy(l) = if null?(l) then l else hd(l)::copy(tl(l)) in fact(1st) end) � eval((fun copy(l) = if null?(l) then l else hd(l)::copy(tl(l))) (1st)) � eval(if null?(lst) then lst else ((fun copy(l) = if null?(l) then l else hd(l)::copy(tl(l)))(lst)) � [because length of lst = m+1 which is >0] eval(hd(lst)::copy(tl(lst))) � [by IH, since tl(lst) has length m+1-1= m] eval(hd(lst)::tl(lst)) � [by the semantics of the list primitives] lst
Evaluate each of the following ML expressions and say what value (if any) is produced by the code. You need not justify each and every step of the evaluation, but if you get the wrong answer, then we are likely to give partial credit if we can follow your reasoning using the Substitution Model.
a. let val (x,y) = (2+4, 8-1) in y*x end Answer: 42 b. (((fn x => (fn y => y*x)) (2*3)) (5+2)) Answer: 42 c. let val f = (fn x => (fn y => (fn z => x*z+y))) val g = f(2) in (g(3))(5) end Answer: 13 e. let val f = let val x = (fn x => (fn y => x)) val y = (fn x => (fn y => (fn z => ((x z) (y z))))) in (y x) x end in f end Answer: fn z => (((fn x => (fn y => x)) z) ((fn x => (fn y => x)) z))) f. let fun f (g: 'a -> 'b -> 'b) (x: 'b) (y: 'a list): 'b = case y of nil => x | h::t => f g (g h x) t val r = f (fn x => (fn y => (x+1)::y)) nil in r (1::2::3::nil) end Answer: 4::3::2::nil = [4,3,2] g. let fun f(x:int):int = let fun g(y:int):int = if (y > 0) then f(y-1) else y in g(x+1) end in f(~1) end Answer: 0
Recall the definition of foldl:
fun foldl (f: ('a*'b) -> 'b) (base:'b) (x:'a list):'b = case x of nil => base | hd::tl => foldl f (f (hd,base)) tlFor each of the following tasks, show how foldl can be used to do that task in one line of code.
a. Sum the elements of a list of integers x. Sample Answer: foldl (op +) 0 x b. Count the number of elements in a list x. Sample Answer: foldl (fn (_,i) => i+1) 0 x c. Filter out all of the numbers less than zero in a list of integers x. Sample Answer: foldl (fn (i,xs) => if i < 0 then xs else i::xs) [] x
Complete each of the following let-expressions by replacing "???" with a value that causes the whole thing to evaluate to the integer 42. Again, you can simply write down an answer, but to receive partial credit for the wrong answer, you should justify your choice using the Substitution Model.
a. let fun zardoz(x: int list):int = case x of nil => 0 | x::nil => 41 | x::y::nil => x | _ => 3 in zardoz(???) end Sample Answer: 42::1::nil = [42,1] (any value other than 1 will work too) b. let fun zardoz(x: int list, y: int list, z:int list):int = case (x, y, z) of (x1::nil, _, c) => 0 | (a, 3::b::c, d) => 1 | (nil, nil, nil) => 2 | (a, b, 2::d::e) => 3 | (a::_, b::_, _) => a+b | _ => 43 in zardoz(???) end Sample Answer: (42::1::nil, 0::nil, nil) c. type t = {foo:(int*real), bar:(real*int)} let fun zardoz(x:t) = let val p = #bar x val q = #foo x in (#2 p) - (#1 q) end in zardoz(???) end Sample Answer: {foo=(0,3.14), bar=(2.17,42)} d. let val x = (2,5) val y = (3,7) val f = (fn (x:int*int,y:int*int) => (#1 x,(#2 x)*(#2 y))) val g = (fn (x:int,y:int) => (y,x)) val h = (fn (x:int,y:int) => x) fun zardoz(f:int*int->int*int, g:(int*int)*(int*int)->int*int):int = h(f(g(g(f(x),f(y)),y))) in zardoz(???) end Sample Answer: zardoz(g, f) - hint, look at the type of zardoz
CS312 � 2002 Cornell University Computer Science |