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)
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 mod 2 = 1 then diff (k/2, l) else diff (k/2-1, r)
else 1
end | Lf () => 0
end
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 | Lf () => 0
end }
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 mod 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 }
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
}
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
}