//
// Course: BU CAS CS 520, Fall 2010
// Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
// Lecture on Thursday, Oct 21, 2010
//

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

datatype brauntree
  (a:t@ype+, int(*length*)) =
  | brauntree_nil (a, 0) of ()
  | {n1,n2:nat | n2 <= n1; n1 <= n2+1}
    brauntree_cons (a, n1+n2+1) of
      (brauntree (a, n1), a, brauntree (a, n2))
// end of [brauntree]

stadef bt = brauntree
#define nil brauntree_nil
#define cons brauntree_cons

extern
fun{a:t@ype}
brauntree_length {n:int} (t: bt (a, n)): int n
implement{a}
brauntree_length (t) =
  case+ t of
  | cons (t1, _, t2) => 1 + brauntree_length<a> (t1) + brauntree_length<a> (t2)
  | nil () => 0
// end of [brauntree_length]

extern
fun{a:t@ype}
brauntree_uncons {n:pos}
  (t: bt (a, n), x0: &a? >> a): bt (a, n-1)
implement{a}
brauntree_uncons
  (t, x0) = let
  val+ cons (t1, x, t2) = t
in
  case+ t1 of
  | nil () => (x0 := x; t2)
  | cons _ => let
      val t1 = brauntree_uncons (t1, x0)
    in
      cons (t2, x, t1)
    end
end // end of [brauntree_uncons]

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

(* end of [brauntree.dats] *)