staload "prelude/DATS/lazy.dats"
staload "prelude/DATS/list.dats"
staload "prelude/DATS/list0.dats"
datatype BraunTree = E | B of (BraunTree, BraunTree)
typedef BT = BraunTree
fun braunToString (t: BT): string = case t of
| E () => "E"
| B (l, r) => "B(" + braunToString(l) + ", " + braunToString(r) + ")"
fun printBT (t: BT): void = print (braunToString t)
fun heightBT (t: BT):<1,~ref> int =
case+ t of E () => 0 | B (l, _) => 1 + heightBT l
fun genBT (n: int):<1,~ref> BT =
if n > 0 then B (genBT (n/2), genBT ((n-1)/2)) else E ()
val theBraunTreeList = fromBT 0 where {
fun fromBT (n: int):<1,~ref> stream BT = $delay (stream_cons (genBT n, fromBT (n+1)))
}
fun listBT (h: int): list0 BT = let
fun aux (h: int, ts: stream BT): list0 BT =
case+ !ts of
| stream_cons (t, ts) => let
val h1 = heightBT t in
if h1 < h then aux (h, ts) else
(if h1 > h then list0_nil () else list0_cons (t, aux (h, ts)))
end | stream_nil () => list0_nil ()
in
aux (h, theBraunTreeList)
end
val listBT9 = listBT 9
val n = list0_length (listBT9)
val () = printf ("length-of-listBT9 (256) = %i\n", @(n))
implement main () = ()