datasort bt = B of (bt, bt) | E of ()
dataprop btsz (bt, int) =
| {t1,t2:bt} {s1,s2:nat}
btsz_B (B (t1, t2), 1 + s1 + s2) of (btsz (t1, s1), btsz (t2, s2))
| btsz_E (E (), 0)
dataprop btht (bt, int) =
| {t1,t2:bt} {h1,h2:nat}
btht_B (B (t1, t2), 1 + max (h1, h2)) of (btht (t1, h1), btht (t2, h2))
| btht_E (E (), 0)
dataprop POW2 (int, int) =
| POW2bas (0, 1) | {p:nat} {n:nat} POW2ind (p+1, n+n) of POW2 (p, n)
prfun pow2_total_lemma {p:nat} .<p>. (): [n:nat] POW2 (p, n) =
sif p > 0 then POW2ind (pow2_total_lemma {p-1} ()) else POW2bas ()
prfun pow2_monotone_lemma
{p1,p2:nat | p1 <= p2} {n1,n2:nat} .<p2>.
(pf1: POW2 (p1, n1), pf2: POW2 (p2, n2)): [n1 <= n2] void =
case+ pf2 of
| POW2ind (pf2) => begin case+ pf1 of
| POW2ind (pf1) => pow2_monotone_lemma (pf1, pf2)
| POW2bas () => pow2_monotone_lemma (pf1, pf2)
end | POW2bas () => begin
let prval POW2bas () = pf1 in () end
end
prfun bintree_size_height_lemma {t:bt} {s,h,n:nat} .<t>.
(pf1: btsz (t, s), pf2: btht (t, h), pf3: POW2 (h, n)): [s < n] void =
case+ pf1 of
| btsz_E () => let
prval btht_E () = pf2; prval POW2bas () = pf3 in ()
end | btsz_B {t1,t2} {s1,s2} (pf11, pf12) => let
prval btht_B {t1,t2} {h1,h2} (pf21, pf22) = pf2
prval POW2ind {h12_max} {n2} (pf30) = pf3 prval pf30_1 = pow2_total_lemma {h1} ()
prval () = pow2_monotone_lemma {h1,h12_max} (pf30_1, pf30) prval () = bintree_size_height_lemma (pf11, pf21, pf30_1) prval pf30_2 = pow2_total_lemma {h2} ()
prval () = pow2_monotone_lemma {h2,h12_max} (pf30_2, pf30) prval () = bintree_size_height_lemma (pf12, pf22, pf30_2) in
end