Problems for Section 6.12

The problems listed here are essentially the same as what appears as "Project 6.(A-D)" in the book. However, I've made some changes to the code that affect 6.A and 6.B. and so here is an updated version of the problems.

You'll need the code from class to do these and test them in the interpreter, but you need to submit only the function you write for each problem. Enter them into the automatic grading system as "6.A" etc. You may do these with a partner, in which case simply include both your names when you submit.

6.A Finish the following function adjoinSet, which takes a tree and a list of trees and places the tree in the right place in the list to maintain that list as sorted by frequency (least frequent to most frequent as in class, not as it is in the book).

fun adjoinSet(x, []) = [x]
  | adjoinSet(x, fst::rest) =
     if freq(x) < freq(fst)
     then ??
     else ??

6.B Finish the function successiveMerge. Assume the list it receives is sorted. It should merge the first two items, put the newly merged item into the right place in the list (hint: use adjoinSet), and keep merging.

fun successiveMerge([x]) = x 
  | successiveMerge(x::y::rest) = ??;

6.C Finish the function encodeSymbol. It uses the case and option ML language features described in Section 2.5.

fun encodeSymbol(sym, tree) = 
   let 
      fun encodeSymbol1(sy, Leaf(st, f)) = 
          if sy = st then SOME [] else NONE
        | encodeSymbol1(sy, Internal(left, right, st, f)) =
             case (encodeSymbol1(sy, left), encodeSymbol1(sy, right)) of
                (NONE, NONE) => ??
              | (NONE, SOME bits) => ??
              | (SOME bits, x) => ??
    in
      valOf(encodeSymbol1(sym,tree))
    end;

(This all assumes that every character in the message actually occurs somewhere in the tree. If not, encodeSymbol1 will return NONE, and the line valOf(encodeSymbol1(sym, tree)) will crash. Furthermore, the pattern (SOME bits, x) assumes x will always be NONE.)

6.D Finish the function decode. It makes use of a function called implode, which is a standard ML function and does the opposite of what explode does: it turns a list of characters into a string.

fun chooseBranch(Zero, Internal(left, right, s, f)) = left
  | chooseBranch(One, Internal(left, right, s, f)) = right;

fun decode(bits, tree) =
   let
      fun decode1([], currentBranch) = []
        | decode1(b::rest, currentBranch) =
           let val nextBranch = chooseBranch(b, currentBranch) in
           case nextBranch of
             Leaf(sym, w) => ??
           | Internal(left, right, syms, w) => ??
           end;
   in
     implode(decode1(bits, tree))
   end;

Thomas VanDrunen
Last modified: Wed Dec 7 15:23:15 CST 2016