module Data.Tree.AVL.Size
(
size,addSize,clipSize,
#ifdef __GLASGOW_HASKELL__
addSize#,size#,
#endif
) where
import Data.Tree.AVL.Types(AVL(..))
import Data.Tree.AVL.Height(addHeight)
#ifdef __GLASGOW_HASKELL__
import GHC.Base
#include "ghcdefs.h"
#else
#include "h98defs.h"
#endif
#ifdef __GLASGOW_HASKELL__
import GHC.Base
#include "ghcdefs.h"
size :: AVL e -> Int
size t = ASINT(addSize# L(0) t)
size# :: AVL e -> UINT
size# t = addSize# L(0) t
addSize :: Int -> AVL e -> Int
addSize ASINT(n) t = ASINT(addSize# n t)
#define AddSize addSize#
#else
#include "h98defs.h"
size :: AVL e -> Int
size t = addSize 0 t
#define AddSize addSize
#endif
AddSize :: UINT -> AVL e -> UINT
AddSize n E = n
AddSize n (N l _ r) = case addHeight L(2) l of
L(2) -> INCINT2(n)
L(3) -> fas2 INCINT2(n) r
h -> fasNP n h l r
AddSize n (Z l _ r) = case addHeight L(1) l of
L(1) -> INCINT1(n)
L(2) -> INCINT3(n)
L(3) -> fas2 (fas2 INCINT1(n) l) r
h -> fasZ n h l r
AddSize n (P l _ r) = case addHeight L(2) r of
L(2) -> INCINT2(n)
L(3) -> fas2 INCINT2(n) l
h -> fasNP n h r l
fasNP,fasZ :: UINT -> UINT -> AVL e -> AVL e -> UINT
fasNP n h l r = fasG3 (fasG2 INCINT1(n) DECINT2(h) l) DECINT1(h) r
fasZ n h l r = fasG3 (fasG3 INCINT1(n) DECINT1(h) l) DECINT1(h) r
fasG2 :: UINT -> UINT -> AVL e -> UINT
fasG2 n L(2) t = fas2 n t
fasG2 n h t = fasG3 n h t
fasG3 :: UINT -> UINT -> AVL e -> UINT
fasG3 n L(3) (N _ _ r) = fas2 INCINT2(n) r
fasG3 n L(3) (Z l _ r) = fas2 (fas2 INCINT1(n) l) r
fasG3 n L(3) (P l _ _) = fas2 INCINT2(n) l
fasG3 n h (N l _ r) = fasNP n h l r
fasG3 n h (Z l _ r) = fasZ n h l r
fasG3 n h (P l _ r) = fasNP n h r l
fasG3 _ _ E = error "AddSize: Bad Tree."
fas2 :: UINT -> AVL e -> UINT
fas2 n (N _ _ _) = INCINT2(n)
fas2 n (Z _ _ _) = INCINT3(n)
fas2 n (P _ _ _) = INCINT2(n)
fas2 _ E = error "AddSize: Bad Tree."
clipSize :: Int -> AVL e -> Maybe Int
clipSize ASINT(c) t = let c_ = cSzh c t in if c_ LTN L(0)
then Nothing
else Just ASINT(SUBINT(c,c_))
cSzh :: UINT -> AVL e -> UINT
cSzh c E = c
cSzh c (N l _ r) = case addHeight L(2) l of
L(2) -> DECINT2(c)
L(3) -> cSzNP3 c r
h -> cSzNP c h l r
cSzh c (Z l _ r) = case addHeight L(1) l of
L(1) -> DECINT1(c)
L(2) -> DECINT3(c)
L(3) -> cSzZ3 c l r
h -> cSzZ c h l r
cSzh c (P l _ r) = case addHeight L(2) r of
L(2) -> DECINT2(c)
L(3) -> cSzNP3 c l
h -> cSzNP c h r l
cSzNP3 :: UINT -> AVL e -> UINT
cSzNP3 c t = if c LTN L(4) then L(1) else cSz2 DECINT2(c) t
cSzZ3 :: UINT -> AVL e -> AVL e -> UINT
cSzZ3 c l r = if c LTN L(5) then L(1)
else let c_ = cSz2 DECINT1(c) l
in if c_ LTN L(2) then L(1)
else cSz2 c_ r
cSzNP,cSzZ :: UINT -> UINT -> AVL e -> AVL e -> UINT
cSzNP c h l r = if c LTN L(7) then L(1)
else let c_ = cSzG2 DECINT1(c) DECINT2(h) l
in if c_ LTN L(4) then L(1)
else cSzG3 c_ DECINT1(h) r
cSzZ c h l r = if c LTN L(9) then L(1)
else let c_ = cSzG3 DECINT1(c) DECINT1(h) l
in if c_ LTN L(4) then L(1)
else cSzG3 c_ DECINT1(h) r
cSzG2 :: UINT -> UINT -> AVL e -> UINT
cSzG2 c L(2) t = cSz2 c t
cSzG2 c h t = cSzG3 c h t
cSzG3 :: UINT -> UINT -> AVL e -> UINT
cSzG3 c L(3) (N _ _ r) = cSzNP3 c r
cSzG3 c L(3) (Z l _ r) = cSzZ3 c l r
cSzG3 c L(3) (P l _ _) = cSzNP3 c l
cSzG3 c h (N l _ r) = cSzNP c h l r
cSzG3 c h (Z l _ r) = cSzZ c h l r
cSzG3 c h (P l _ r) = cSzNP c h r l
cSzG3 _ _ E = error "clipSize: Bad Tree."
cSz2 :: UINT -> AVL e -> UINT
cSz2 c (N _ _ _) = DECINT2(c)
cSz2 c (Z _ _ _) = DECINT3(c)
cSz2 c (P _ _ _) = DECINT2(c)
cSz2 _ E = error "clipSize: Bad Tree."