Announcements (verbatim from Tibor)

  1. The exam will have 5-6 problems (with subproblems), most will have short solutions, some will even be one liners.
  2. All material discussed in class, assigned in homeworks, or presented in section is fair game. The reference for section material is posted on the web(students should be aware that there are some differences between sections).
  3. Students will not be asked to reproduce an algorithm (e.g. red-black tree deletion), they are expected, however, to know to apply it to a specific problem. Same for the substitution model - they don't have to memorize the rules (we will give them a handout if needed), but they need to be able to use the substitution model.
  4. Without being exhaustive, there are the types of problems that can come up on the exam:
  5. Students should know the most important list manipulation functions and they should be intimately acquainted with various versions of fold and map.We will give them a handout with reminders if they need to use functions that are less familiar.
  6. There will be a review session in the evening of October 13, precise time and place will be announced on the web.

Note: the portion below has been compiled by Harlan Crystal.

Induction Proofs

Review of Problem Type

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:

  1. State what you want to prove
  2. State what you will do induction on (often one or two words like "positive integers," is appropriate)
  3. Prove the base case (e.g. P[0])

Key things to look for:

Induction Example: Factorial

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".

Dynamic vs Static Scope

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 Recursion

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

Zardoz Problems

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) 

Evaluation ML Expressions

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"