module Data.Tree.AVL.Internals.HeightUtils
(height,addHeight,compareHeight,
fastAddSize,
) where
import Data.Tree.AVL.Types(AVL(..))
#ifdef __GLASGOW_HASKELL__
import GHC.Base
#include "ghcdefs.h"
#else
#include "h98defs.h"
#endif
height :: AVL e -> UINT
height t = addHeight L(0) t
addHeight :: UINT -> AVL e -> UINT
addHeight h E = h
addHeight h (N l _ _) = addHeight INCINT2(h) l
addHeight h (Z l _ _) = addHeight INCINT1(h) l
addHeight h (P _ _ r) = addHeight INCINT2(h) r
compareHeight :: AVL a -> AVL b -> Ordering
compareHeight = ch L(0) where
ch :: UINT -> AVL a -> AVL b -> Ordering
ch d E E = COMPAREUINT d L(0)
ch d E (N l1 _ _ ) = chA DECINT2(d) l1
ch d E (Z l1 _ _ ) = chA DECINT1(d) l1
ch d E (P _ _ r1) = chA DECINT2(d) r1
ch d (N l0 _ _ ) E = chB INCINT2(d) l0
ch d (N l0 _ _ ) (N l1 _ _ ) = ch d l0 l1
ch d (N l0 _ _ ) (Z l1 _ _ ) = ch INCINT1(d) l0 l1
ch d (N l0 _ _ ) (P _ _ r1) = ch d l0 r1
ch d (Z l0 _ _ ) E = chB INCINT1(d) l0
ch d (Z l0 _ _ ) (N l1 _ _ ) = ch DECINT1(d) l0 l1
ch d (Z l0 _ _ ) (Z l1 _ _ ) = ch d l0 l1
ch d (Z l0 _ _ ) (P _ _ r1) = ch DECINT1(d) l0 r1
ch d (P _ _ r0) E = chB INCINT2(d) r0
ch d (P _ _ r0) (N l1 _ _ ) = ch d r0 l1
ch d (P _ _ r0) (Z l1 _ _ ) = ch INCINT1(d) r0 l1
ch d (P _ _ r0) (P _ _ r1) = ch d r0 r1
chA d tB = case COMPAREUINT d L(0) of
LT -> LT
EQ -> case tB of
E -> EQ
_ -> LT
GT -> case tB of
E -> GT
N l _ _ -> chA DECINT2(d) l
Z l _ _ -> chA DECINT1(d) l
P _ _ r -> chA DECINT2(d) r
chB d tA = case COMPAREUINT d L(0) of
GT -> GT
EQ -> case tA of
E -> EQ
_ -> GT
LT -> case tA of
E -> LT
N l _ _ -> chB INCINT2(d) l
Z l _ _ -> chB INCINT1(d) l
P _ _ r -> chB INCINT2(d) r
fastAddSize :: UINT -> AVL e -> UINT
fastAddSize n E = n
fastAddSize n (N l _ r) = case addHeight L(2) l of
L(2) -> INCINT2(n)
h -> fasN n h l r
fastAddSize n (Z l _ r) = case addHeight L(1) l of
L(1) -> INCINT1(n)
L(2) -> INCINT3(n)
h -> fasZ n h l r
fastAddSize n (P l _ r) = case addHeight L(2) r of
L(2) -> INCINT2(n)
h -> fasP n h l r
fasN,fasZ,fasP :: UINT -> UINT -> AVL e -> AVL e -> UINT
fasN n L(3) _ r = fas INCINT2(n) L(2) r
fasN n h l r = fas (fas INCINT1(n) DECINT2(h) l) DECINT1(h) r
fasZ n h l r = fas (fas INCINT1(n) DECINT1(h) l) DECINT1(h) r
fasP n L(3) l _ = fas INCINT2(n) L(2) l
fasP n h l r = fas (fas INCINT1(n) DECINT2(h) r) DECINT1(h) l
fas :: UINT -> UINT -> AVL e -> UINT
fas _ L(2) E = error "fas: Bug0"
fas n L(2) (N _ _ _) = INCINT2(n)
fas n L(2) (Z _ _ _) = INCINT3(n)
fas n L(2) (P _ _ _) = INCINT2(n)
fas n h (N l _ r) = fasN n h l r
fas n h (Z l _ r) = fasZ n h l r
fas n h (P l _ r) = fasP n h l r