datasort bt = btcons of (bt, bt) | btnil of ()
dataprop SZ (bt, int) =
| SZnil (btnil, 0)
| {t1,t2:bt} {s1,s2:nat}
SZcons (btcons (t1, t2), 1+s1+s2) of (SZ (t1, s1), SZ (t2, s2))
dataprop HT (bt, int) =
| HTnil (btnil, 0)
| {t1,t2:bt} {h1,h2:nat}
HTcons (btcons (t1, t2), 1+max(h1,h2)) of (HT (t1, h1), HT (t2, h2))
dataprop POW2 (int, int) =
| POW2bas (0, 1)
| {n:nat} {p:nat} POW2ind (n+1, 2*p) of POW2 (n, p)
prfun pow2_istot {n:nat} .<n>. (): [p:nat] POW2 (n, p) =
sif n > 0 then POW2ind (pow2_istot {n-1} ()) else POW2bas ()
prfun pow2_isfun {n:nat} {p1,p2:int} .<n>.
(pf1: POW2 (n, p1), pf2: POW2 (n, p2)): [p1==p2] void =
case+ (pf1, pf2) of
| (POW2ind pf1, POW2ind pf2) => pow2_isfun (pf1, pf2)
| (POW2bas (), POW2bas ()) => ()
prfun pow2_isinc {n1,n2:nat | n1 <= n2}
{p1,p2:int} .<n2>. (pf1: POW2 (n1, p1), pf2: POW2 (n2, p2)): [p1 <= p2] void =
sif n1 < n2 then let
prval POW2ind pf20 = pf2
prval () = pow2_isinc (pf1, pf20)
in
end else let
prval () = pow2_isfun (pf1, pf2)
in
end
prfun lemma_SZ_HT {t:bt} {s,h,p:int} .<t>.
(pf1: SZ (t, s), pf2: HT (t, h), pf3: POW2 (h, p)): [s < p] void =
case+ pf1 of
| SZnil () => let
prval HTnil () = pf2
prval POW2bas () = pf3
in
end | SZcons (pf11, pf12) => let
prval HTcons {t1,t2} {h1,h2} (pf21, pf22) = pf2 prval POW2ind (pf30) = pf3
prval [p1:int] pf31 = pow2_istot {h1} () prval () = lemma_SZ_HT (pf11, pf21, pf31)
prval [p2:int] pf32 = pow2_istot {h2} () prval () = lemma_SZ_HT (pf12, pf22, pf32)
prval () = pow2_isinc (pf31, pf30)
prval () = pow2_isinc (pf32, pf30)
in
end