atree itemType depthType ::= ALeaf | ABranch (atree itemType depthType) itemType (atree itemType depthType) depthType; list a ::= Nil | Cons a (list a); ;; error = error; { add :: Ord a => ATree a -> a -> ATree a add ALeaf x = ABranch ALeaf x ALeaf 1 add (ABranch l y r hy) x | y > x = let (ABranch l1 z l2 _) = add l x in combine l1 (f l1) l2 (f l2) r (f r) z y | x > y = let (ABranch r1 z r2 _) = add r x in combine l (f l) r1 (f r1) r2 (f r2) y z where f ALeaf = 0 f (ABranch _ _ _ d) = d } add tree x = let f = \ft -> case ft of ALeaf -> 0; ABranch fl fm fr fd -> fd end in case tree of ALeaf -> ABranch ALeaf x ALeaf 1; ABranch l y r hy -> case y > x of True -> case add l x of ALeaf -> error; ABranch l1 z l2 dontCare -> combine l1 (f l1) l2 (f l2) r (f r) z y end; False -> case add r x of ALeaf -> error; ABranch r1 z r2 dontCare -> combine l (f l) r1 (f r1) r2 (f r2) y z end end end; { combine :: ATree a -> Int -> ATree a -> Int -> ATree a -> Int -> a -> a -> ATree a combine t1 h1 t2 h2 t3 h3 a c | h2 > h1 && h2 > h3 = ABranch (ABranch t1 a t21 (h1+1)) b (ABranch t22 c t3 (h3+1)) (h1+2) | h1 >= h2 && h1 >= h3 = ABranch t1 a (ABranch t2 c t3 (max1 h2 h3)) (max1 h1 (max1 h2 h3)) | h3 >= h2 && h3 >= h1 = ABranch (ABranch t1 a t2 (max1 h1 h2)) c t3 (max1 (max1 h1 h2) h3) where (ABranch t21 b t22 _) = t2 max1 a b = 1 + (if a > b then a else b) } combine t1 h1 t2 h2 t3 h3 a c = let max1 = \pp qq -> 1 + (case pp > qq of True -> pp; False -> qq end) in case h2 > h1 & h2 > h3 of True -> case t2 of ABranch t21 b t22 dontCare -> ABranch (ABranch t1 a t21 (h1+1)) b (ABranch t22 c t3 (h3+1)) (h1+2); ALeaf -> error end; False -> case h1 >= h2 & h1 >= h3 of True -> ABranch t1 a (ABranch t2 c t3 (max1 h1 h2)) (max1 h1 (max1 h2 h3)); False -> ABranch (ABranch t1 a t2 (max1 h1 h2)) c t3 (max1 (max1 h1 h2) h3) end end; { toAVL :: Ord a => [a] -> ATree a toAVL [] = ALeaf toAVL (x:xs) = add (toAVL xs) x } toAVL l = case l of Nil -> ALeaf; Cons x xs -> add (toAVL xs) x end; { maxd :: ATree a -> Int maxd ALeaf = 0 maxd (ABranch l _ r _) = let dl = maxd l; dr = maxd r in 1 + (if dl > dr then dl else dr) }