staload _ = "prelude/DATS/list.dats"
staload _ = "prelude/DATS/list0.dats"
#define nil list0_nil
#define cons list0_cons
#define :: list0_cons
extern fun list0_cross_with {a,b,c:type}
(xs: list0 a, ys: list0 b, f: (a, b) -> c, res: list0 c): list0 c
implement list0_cross_with {a,b,c} (xs, ys, f, res) = let
fun loop1
(x: a, ys: list0 b, res: list0 c):<cloref1> list0 c = case+ ys of
| y :: ys => loop1 (x, ys, f (x, y) :: res)
| nil () => res
fun loop2 (xs: list0 a, res: list0 c):<cloref1> list0 c = case+ xs of
| x :: xs => loop2 (xs, loop1 (x, ys, res))
| nil () => res
in
loop2 (xs, res)
end
datatype bt = B of (bt, bt) | E of ()
typedef bts = list0 (bt)
extern fun bintree_list_gen (n: int): bts
implement bintree_list_gen (n) = case+ 0 of
| _ when n > 0 => list0_reverse (loop (0, n-1, nil ())) where {
fun loop (i: int, j: int, res: bts): bts =
if j >= 0 then let
val ts1 = bintree_list_gen (i) and ts2 = bintree_list_gen (j)
val res = begin
list0_cross_with {bt,bt,bt} (ts1, ts2, lam (t1, t2) => B (t1, t2), res)
end
in
loop (i+1, j-1, res)
end else begin
res
end } | _ => cons (E (), nil ())
implement main () = let
val ts1 = bintree_list_gen (1); val n1 = list0_length (ts1)
val () = printf ("length(ts1) = %i\n", @(n1))
val ts2 = bintree_list_gen (2); val n2 = list0_length (ts2)
val () = printf ("length(ts2) = %i\n", @(n2))
val ts3 = bintree_list_gen (3); val n3 = list0_length (ts3)
val () = printf ("length(ts3) = %i\n", @(n3))
val ts4 = bintree_list_gen (4); val n4 = list0_length (ts4)
val () = printf ("length(ts4) = %i\n", @(n4))
val ts5 = bintree_list_gen (5); val n5 = list0_length (ts5)
val () = printf ("length(ts5) = %i\n", @(n5))
val ts10 = bintree_list_gen (10); val n10 = list0_length (ts10)
val () = printf ("length(ts10) = %i\n", @(n10))
in
end