Note: the portion below has been compiled by Harlan Crystal.
Induction proofs in cs312 are formulaic. These proofs should be fairly easy and you should get full credit you follow the following structure:
For induction just run over the 4 steps:
Key things to look for:
Canonical example: fact(n) = n! This example has been presented in detail in the lecture notes; see lecture 6, part "Induction on the Set of Natural Numbers".
Static scope: Variables in a function are bound to the values at declaration time.
Dynamic scope: Variables in a function are bound to values at evaluation time.
Example:
let
val x = 1
in
let
val f = fn(y) => x
in
let
val x = 2
in
f(20) + 1
end
end
end
What is the value of this expression if we have static scope? What is the value if we have dynamic scope?
Tail recursive function do not need to have any more computation after the recursive call. The recursive call is the last operation in the function. Tail-recursive functions can be more memory efficient and can be compiled down to a while-loop internally.
The following is not tail recursive:
fun fact(n:int):int = if n = 1 then 1else n * fact(n-1)
You can tell this function is not tail recursive because the value returned by the recursive call is used for further computation. To make a function tail recursive, add another input to the function which accumulates the final value.Then wrap up the function inside another function which seed the accumulator argument correctly. The translation of the above example is:
fun fact(n:int):int =
let
fun inner(n:int, acc:int):int =
if n = 1 then acc
else inner(n - 1, acc * n)
in
inner(n, 1)
end
The class can try to formulate the following translation:
fun length(l:'a list):int =
if l = [] then 0
else 1 + length(tl l)
fun length(l:'a list):int =
let
fun inner(l:'a list, acc:int):int =
if l = [] then acc
else inner(length(tl l), 1 + acc)
in
inner(l, 0)
end
Give valid inputs which make the expression equal 42.
let
val f:string list = XXXXXXX
in
case List.map(fn(x) => case Int.fromString x of
SOME n => n
| _ => 0) f of
x::y::_ => x * 10 + y
| _ => 41
end
let
fun zardoz(x:int):int list = if x = 0 then [] else x::zardoz(x-1)
in
case zardoz(XXXXXXX) of
w::x::y::z:: => x * y
end
let fun zardoz(b:bool list):int =
case b of
[] => 0
| true::b2 => 1 + 2 * zardoz(b2)
| false::b2 => 2 * zardoz(b2)
in
XXXXXXX
end
let
val f = XXXXX
in
17 + (#2 (f(12, ``hello''))) + (#1 (f(``goodbye'', 13)))
end
Answer: fn(a,b) => (b,a)
let
val x = 4
val x = x + 1
val x = 1 - x
in
x * x
end
16
(fn x => fn y => y - x) 2 3
~1
let
val s:string = "xyzzy"
val c:char = #"c"
val x:int * int = String.size s * Char.ord c
in
~x
end
(type mismatch in declaration of x)
let
fun shuffle(x:int list) (y:int list):int list =
case x of
[] => y
| u::z => u::(shuffle y z)
in
shuffle [1,2,3] [4,5]
end
[1,4,2,5,3]
let
val x = 3
val y = 4
val y = let
val x = 5
in
x + yend
in
x + y
end
12
foldl (op ^) "2" (map Int.toString [1,3])
"312"
let
val imp = String.implode
val chr = List.map Char.chr
val inc = List.map (fn x => x + 1)
val ord = List.map Char.ord
val exp = String.explode
in
(imp o chr o inc o ord o exp) ``Mississippi''
end
"Njttjttjqqj"