```(*
** Course: Concepts of Programming Languages (BU CAS CS 320)
** Semester: Summer I, 2009
** Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
*)

//
// Author: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
// Time: May 29, 2009
//

(* ****** ****** *)

#include "BUCASCS320.hats"

(* ****** ****** *)

datatype bintree =
| E of ()
| B of (bintree, int, bintree)

fun bintree_size (t: bintree): int =
case+ t of
| B (t1, _, t2) => 1 + bintree_size t1 + bintree_size t2
| E () => 0
// end of [bintree_size]

fun bintree_height (t: bintree): int =
case+ t of
| B (t1, _, t2) => 1 + max (bintree_height t1, bintree_height t2)
| E () => 0
// end of [bintree_height]

(* ****** ****** *)

// search on a binary search
fun bst_search (t: bintree, k0: int): bool =
case+ t of
| B (t1, k, t2) =>
if k0 < k then bst_search (t1, k0)
else if k0 > k then bst_search (t2, k0)
else true // k0 = k
| E () => false
// end of [bst_search]

// insertion on a binary search tree
fun bst_insert (t: bintree, k0: int): bintree =
case+ t of
| B (t1, k, t2) => begin
if k0 <= k then B (bst_insert (t1, k0), k, t2)
else B (t1, k, bst_insert (t2, k0))
end // end of [B]
| E () => B (E (), k0, E ())
// end of [bst_insert]

// root insertion on a binary search tree
fun bst_insertRT (t: bintree, k0: int): bintree =
case+ t of
| B (t1, k, t2) when k0 <= k => let
val t1_new = bst_insertRT (t1, k0)
val- B (t11_new, k0, t12_new) = t1_new
in
B (t11_new, k0, B (t12_new, k, t2))
end // end of [B when ...]
| B (t1, k, t2) (* k0 > k *) => let
val t2_new = bst_insertRT (t2, k0)
val- B (t21_new, k0, t22_new) = t2_new
in
B (B (t1, k, t21_new), k0, t22_new)
end // end of [B when ...]
| E () => B (E (), k0, E ())
// end of [bst_insertRT]

(* ****** ****** *)

// Braun trees

datatype tree (a:t@ype) =
| Lf(a) of ()
| Br(a) of (a(*elt*), tree a(*left*), tree a(*right*))

exception Subscript of ()

fun{a:t@ype} subscript (t: tree a, k: int): a =
case+ t of
| Br (v, t1, t2) =>
if k = 1 then v
else if k mod 2 = 0
then subscript (t1, k / 2)
else subscript (t2, k / 2)
| Lf () => \$raise Subscript ()
// end of [subscript]

fun{a:t@ype}
update (t: tree a, k: int, w: a): tree a =
case+ t of
| Br (v, t1, t2) =>
if k = 1 then Br (w, t1, t2)
else if k mod 2 = 0
then Br (v, update (t1, k / 2, w), t2)
else Br (v, t1, update (t2, k / 2, w))
| Lf () => \$raise Subscript ()
// end of [update]

fun{a:t@ype} brauntree_size (t: tree a): int =
case+ t of
| Br (_, t1, t2) => 1 + brauntree_size (t1) + brauntree_size (t2)
| Lf () => 0
// end of [brauntree_size]

(* ****** ****** *)

(* end of [code-2009-05-29.dats] *)
```