datatype BraunTree = E | B of (BraunTree, BraunTree)
typedef BT = BraunTree
extern fun print_BraunTree (t: BraunTree): void
overload print with print_BraunTree
implement print_BraunTree (t) = case+ t of
| E () => print "E" | B (t1, t2) => begin
print "B("; print t1; print ", "; print t2; print ")"
end
fun addOneNode (t: BT): BT = case+ t of
| E () => B(E, E) | B (t1, t2) => B (addOneNode t2, t1)
fun makeBraunTreeFrom (t: BT, n :int): BT = begin
case+ n of 0 => t | _ => makeBraunTreeFrom (addOneNode t, n-1)
end
fun pow2 (n: int): int = if n > 0 then 2 * pow2 (n-1) else 1
fn list0_reverse {a:type} (xs: list0 a): list0 a = let
fun loop (xs: list0 a, ys: list0 a): list0 a = case+ xs of
| list0_cons (x, xs) => loop (xs, list0_cons (x, ys)) | _ => ys
in
loop (xs, list0_nil ())
end
fun list0_length {a:type} (xs: list0 a): int = begin
case+ xs of list0_cons (_, xs) => 1 + list0_length (xs) | _ => 0
end
extern fun listBraunTreesOfGivenHeight (height: int) : list0 BT
implement listBraunTreesOfGivenHeight (height) = let
val base = pow2 (height - 1)
val templateTree = makeBraunTreeFrom (E, base)
fun loop (
start: int, stop: int, stack: list0 BT, lastTempTree: BT
) : list0 BT =
if (start > stop) then list0_reverse (stack) else let
val newTree = addOneNode (lastTempTree)
in
loop (start + 1, stop, list0_cons (lastTempTree, stack), newTree)
end in
loop (base, pow2 height - 1, list0_nil (), templateTree)
end
implement main () = let
val BTS10 = listBraunTreesOfGivenHeight (10)
val len10 = list0_length (BTS10)
val BTS12 = listBraunTreesOfGivenHeight (12)
val len12 = list0_length (BTS12)
in
printf ("len10(%i) = %i\n", @(pow2 9, len10));
printf ("len12(%i) = %i\n", @(pow2 11, len12));
end