```//
//
// Some dependently typed operations on Braun Trees
//
// Hongwei Xi (hwxi AT cs DOT bu DOT edu)
// October 2008
//

datatype brauntree (a:t@ype, int) =
| {m:nat} {n:nat | n <= m; m <= n+1}
Br (a, m+n+1) of (a, brauntree(a, m), brauntree(a, n))
| Lf (a, 0)

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

extern fun{a:t@ype} brauntree_size
{n:nat} (t: brauntree (a, n)):<> int n

extern fun{a:t@ype} brauntree_get_at
{n,i:nat | i < n} (t: brauntree (a, n), i: int i):<> a

extern fun{a:t@ype} brauntree_loext
{n:nat} (t: brauntree (a, n), x0: a):<> brauntree (a, n+1)

extern fun{a:t@ype} brauntree_lorem
{n:pos} (t: brauntree (a, n)):<> brauntree (a, n-1)

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

(*
** The size function is implemented using Okasaki's algorithm:
** its time-complexity is O(log^2 n)
*)

typedef bt (a:t@ype, n: int) = brauntree (a, n)

implement{a}
brauntree_size (t) = size (t) where {
fun diff {n,k:nat | k <= n && n <= k+1} .<k>.
(k: int k, t: bt (a, n)):<> int (n-k) = begin case+ t of
| Br (_, l, r) => begin
if k > 0 then
if k nmod 2 = 1 then diff (k/2, l) else diff (k/2-1, r)
else 1
end // end of [Br]
| Lf () => 0
end // end of [diff]

fun size {n:nat} .<n>. (t: bt (a, n)):<> int n = begin
case+ t of
| Br (_, l, r) => begin
let val k = size r in 1 + k + k + diff (k, l) end
end // end of [Br]
| Lf () => 0
end // end of [size]
} // end of [brauntree_size]

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

implement{a}
brauntree_get_at (t, i) = get_at (t, i) where {
fun get_at {n,i:nat | i < n} .<n>. (t: bt (a, n), i: int i):<> a =
if i > 0 then let
val+ Br (_, l, r) = t
in
if i nmod 2 = 1 then get_at (l, (i-1)/2) else get_at (r, i/2-1)
end else let
val+ Br (x, _, _) = t in x
end // end of [if]
} // end of [brauntree_get_at]

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

// insertion

implement{a}
brauntree_loext (t, x0) = loext (t, x0) where {
fun loext {n:nat} .<n>.
(t: bt (a, n), x0: a):<> bt (a, n+1) = begin
case+ t of
| Br (x, l, r) => Br (x0, loext (r, x), l)
| Lf () => Br (x0, Lf (), Lf ())
end
} // end of [brauntree_loext]

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

// deletion

implement{a}
brauntree_lorem (t) = lorem (t) where {
fun lorem {n:int | n > 0} .<n>.
(t: bt (a, n)):<> bt (a, n-1) = let
val+ Br (_, l, r) = t
in
case+ l of Br (x, _, _) => Br (x, r, lorem l) | Lf () => Lf ()
end
} // end of [brauntree_lorem]

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

(* end of [brauntree-2008-10-02.dats] *)
```