packages feed

AvlTree 2.4 → 3.0

raw patch · 14 files changed

+164/−129 lines, 14 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Tree.AVL: instance (Eq e) => Eq (AVL e)
- Data.Tree.AVL: instance (Ord e) => Ord (AVL e)
+ Data.Tree.AVL: addHeight :: Int# -> AVL e -> Int#
+ Data.Tree.AVL: compareHeight :: AVL a -> AVL b -> Ordering
+ Data.Tree.AVL: height :: AVL e -> Int#

Files

AvlTree.cabal view
@@ -1,5 +1,5 @@ Name:               AvlTree-Version:            2.4+Version:            3.0 Cabal-Version:      >= 1.2 Build-Type:         Simple License:            BSD3@@ -10,16 +10,16 @@ Stability:          Stable Homepage:           http://www.haskell.org/haskellwiki/AvlTree Package-Url:-Synopsis:           Balanced binary trees using AVL algorithm.+Synopsis:           Balanced binary trees using the AVL algorithm. Description:        A comprehensive library and efficient implementation of AVL trees. The raw AVL-                    API has been designed with efficiency and generality in mind, not elagance. It-                    contains all the stuff you really don't want to write yourself if you can avoid-                    it. This library may be useful for rolling your own Sets, Maps, Sequences, Queues-                    (for example).+                    API has been designed with efficiency and generality in mind, not elagance or+                    safety. It contains all the stuff you really don't want to write yourself if you+                    can avoid it. This library may be useful for rolling your own Sets, Maps, Sequences,+                    Queues (for example). Category:           Data Structures Tested-With:        GHC == 6.8.2, GHC == 6.8.1 Data-Files:-Extra-Source-Files: AUTHORS, CHANGELOG, Test/Test.hs, include/ghcdefs.h, include/h98defs.h+Extra-Source-Files: AUTHORS, CHANGELOG, MasterTable.txt, Test/Test.hs, include/ghcdefs.h, include/h98defs.h Extra-Tmp-Files: Author:             Adrian Hey @@ -37,6 +37,7 @@                      Data.Tree.AVL.Read,                      Data.Tree.AVL.Set,                      Data.Tree.AVL.Size,+                     Data.Tree.AVL.Height,                      Data.Tree.AVL.Split,                      Data.Tree.AVL.Types,                      Data.Tree.AVL.Write,@@ -47,12 +48,11 @@                      Data.Tree.AVL.Internals.HAVL,                      Data.Tree.AVL.Internals.HJoin,                      Data.Tree.AVL.Internals.HPush,-                     Data.Tree.AVL.Internals.HSet,-                     Data.Tree.AVL.Internals.HeightUtils+                     Data.Tree.AVL.Internals.HSet  Extensions:         CPP  Hs-Source-Dirs:     .  Build-Tools:- Ghc-Options:        -O -Wall -split-objs+ Ghc-Options:        -Wall  Ghc-Prof-Options:  Ghc-Shared-Options:  Hugs-Options:
CHANGELOG view
@@ -2,3 +2,13 @@ ---
 * Initial Hackage/Cabal release.
   Version set to 2.4 to distinguish from the 2.3 (non-cabal) release on my home page.
+
+3.0
+---
+* Included MasterTable.txt in the distro.
+* Eq and Ord Instances now based on strict structural equality (derived)
+* Exposed height related functions
+
+
+
+
Data/Tree/AVL.hs view
@@ -33,7 +33,6 @@ -- mySelector :: (key,val) -> COrdering val    Tree elements are (key,val) pairs -- @ ----- Please read the notes in the "Data.Tree.AVL.Types" module documentation too. ----------------------------------------------------------------------------- module Data.Tree.AVL (module Data.Tree.AVL.Types,@@ -47,6 +46,7 @@  map2AVL,avl2Map,   module Data.Tree.AVL.Size,+ module Data.Tree.AVL.Height,  module Data.Tree.AVL.Read,  module Data.Tree.AVL.Write,  module Data.Tree.AVL.Push,@@ -71,6 +71,7 @@  import Data.Tree.AVL.Types hiding (E,N,P,Z) import Data.Tree.AVL.Size+import Data.Tree.AVL.Height import Data.Tree.AVL.Read import Data.Tree.AVL.Write import Data.Tree.AVL.Push@@ -116,6 +117,7 @@ avl2Map :: AVL (key,val) -> BaseMap.Map key val avl2Map avl = BaseMap.fromDistinctAscList (asListL avl) +{- Not any more! -- | Eq is based on equality of the lists produced by 'asListL'. This definition has been placed here -- to avoid introducing cyclic dependency between Types.hs and List.hs instance Eq e => Eq (AVL e) where@@ -125,6 +127,8 @@ -- to avoid introducing cyclic dependency between Types.hs and List.hs instance Ord e => Ord (AVL e) where  x `compare` y =  asListL x `compare` asListL y+-}+  -- | Show is based on showing the list produced by 'asListL'. This definition has been placed here -- to avoid introducing cyclic dependency between Types.hs and List.hs
+ Data/Tree/AVL/Height.hs view
@@ -0,0 +1,99 @@+{-# OPTIONS_GHC -fglasgow-exts #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Data.Tree.AVL.Height+-- Copyright   :  (c) Adrian Hey 2004,2005+-- License     :  BSD3+--+-- Maintainer  :  http://homepages.nildram.co.uk/~ahey/em.png+-- Stability   :  stable+-- Portability :  portable+--+-- AVL tree height related utilities.+--+-- The functions defined here are not exported by the main Data.Tree.AVL module+-- because they violate the policy for AVL tree equality used elsewhere in this library.+-- You need to import this module explicitly if you want to use any of these functions.+-----------------------------------------------------------------------------+module Data.Tree.AVL.Height+        (-- * AVL tree height utilities.+         height,addHeight,compareHeight, -- heightInt,+        ) where++import Data.Tree.AVL.Types(AVL(..))++#ifdef __GLASGOW_HASKELL__+import GHC.Base+#include "ghcdefs.h"+#else+#include "h98defs.h"+#endif++-- {-# INLINE heightInt #-} -- Don't want this+-- heightInt :: AVL e -> Int+-- heightInt t = ASINT(addHeight L(0) t)++-- | Determine the height of an AVL tree.+--+-- Complexity: O(log n)+{-# INLINE height #-}+height :: AVL e -> UINT+height t = addHeight L(0) t++-- | Adds the height of a tree to the first argument.+--+-- Complexity: O(log n)+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++-- | A fast algorithm for comparing the heights of two trees. This algorithm avoids the need+-- to compute the heights of both trees and should offer better performance if the trees differ+-- significantly in height. But if you need the heights anyway it will be quicker to just evaluate+-- them both and compare the results.+--+-- Complexity: O(log n), where n is the size of the smaller of the two trees.+compareHeight :: AVL a -> AVL b -> Ordering+compareHeight = ch L(0) where                       -- d = hA-hB+ 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+ -- Tree A ended first, continue with Tree B until hA-hB<0, or Tree B ends+ 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+ -- Tree B ended first, continue with Tree A until hA-hB>0, or Tree A ends+ 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+
Data/Tree/AVL/Internals/HAVL.hs view
@@ -19,7 +19,7 @@         ) where  import Data.Tree.AVL.Types(AVL(..))-import Data.Tree.AVL.Internals.HeightUtils(addHeight)+import Data.Tree.AVL.Height(addHeight) import Data.Tree.AVL.Internals.HJoin(spliceH,joinH) import Data.Tree.AVL.Internals.HPush(pushHL,pushHR) 
− Data/Tree/AVL/Internals/HeightUtils.hs
@@ -1,98 +0,0 @@-{-# OPTIONS_GHC -fglasgow-exts #-}--------------------------------------------------------------------------------- |--- Module      :  Data.Tree.AVL.Internals.HeightUtils--- Copyright   :  (c) Adrian Hey 2004,2005--- License     :  BSD3------ Maintainer  :  http://homepages.nildram.co.uk/~ahey/em.png--- Stability   :  stable--- Portability :  portable------ AVL tree height related utilities.------ The functions defined here are not exported by the main Data.Tree.AVL module--- because they violate the policy for AVL tree equality used elsewhere in this library.--- You need to import this module explicitly if you want to use any of these functions.-------------------------------------------------------------------------------module Data.Tree.AVL.Internals.HeightUtils-        (height,addHeight,compareHeight, -- heightInt,-        ) where--import Data.Tree.AVL.Types(AVL(..))--#ifdef __GLASGOW_HASKELL__-import GHC.Base-#include "ghcdefs.h"-#else-#include "h98defs.h"-#endif---- {-# INLINE heightInt #-} -- Don't want this--- heightInt :: AVL e -> Int--- heightInt t = ASINT(addHeight L(0) t)---- | Determine the height of an AVL tree.------ Complexity: O(log n)-{-# INLINE height #-}-height :: AVL e -> UINT-height t = addHeight L(0) t---- | Adds the height of a tree to the first argument.------ Complexity: O(log n)-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---- | A fast algorithm for comparing the heights of two trees. This algorithm avoids the need--- to compute the heights of both trees and should offer better performance if the trees differ--- significantly in height. But if you need the heights anyway it will be quicker to just evaluate--- them both and compare the results.------ Complexity: O(log n), where n is the size of the smaller of the two trees.-compareHeight :: AVL a -> AVL b -> Ordering-compareHeight = ch L(0) where                       -- d = hA-hB- 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- -- Tree A ended first, continue with Tree B until hA-hB<0, or Tree B ends- 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- -- Tree B ended first, continue with Tree A until hA-hB>0, or Tree A ends- 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-
Data/Tree/AVL/Join.hs view
@@ -18,7 +18,7 @@ import Data.Tree.AVL.Size(addSize) import Data.Tree.AVL.List(asTreeLenL,toListL) import Data.Tree.AVL.Internals.DelUtils(popHLN,popHLZ,popHLP)-import Data.Tree.AVL.Internals.HeightUtils(height,addHeight)+import Data.Tree.AVL.Height(height,addHeight) import Data.Tree.AVL.Internals.HJoin(joinH',spliceH)  import Data.List(foldl')
Data/Tree/AVL/Set.hs view
@@ -46,7 +46,7 @@ import Prelude -- so haddock finds the symbols there  import Data.Tree.AVL.Types(AVL(..))-import Data.Tree.AVL.Internals.HeightUtils(addHeight)+import Data.Tree.AVL.Height(addHeight) import Data.Tree.AVL.Internals.HJoin(spliceH) import Data.Tree.AVL.Internals.HSet(unionH,unionMaybeH,                                     intersectionH,intersectionMaybeH,
Data/Tree/AVL/Size.hs view
@@ -17,7 +17,7 @@         ) where  import Data.Tree.AVL.Types(AVL(..))-import Data.Tree.AVL.Internals.HeightUtils(addHeight)+import Data.Tree.AVL.Height(addHeight)  #ifdef __GLASGOW_HASKELL__ import GHC.Base
Data/Tree/AVL/Test/AllTests.hs view
@@ -1042,7 +1042,7 @@                                                    mn = min (ls-1) (2*rs-1)                                                in isBalanced u  &&                                                   (asListL u == filter even [0..mn] ++ [mn+1..ls-1]) &&-                                                  isBalanced u_ && (u_ == l_)+                                                  isBalanced u_ && (asListL u_ == asListL l_)                              difference = genDifference compare  -- | Test the genDifferenceMaybe function@@ -1075,7 +1075,7 @@                                 mx = max (mn+1) 0                                 listfil = filter odd [0..mn]                                 listrem = [mx..ls-1]-                            in isBalanced u && isBalanced u_ && (u_ == l_) &&+                            in isBalanced u && isBalanced u_ && (asListL u_ == asListL l_) &&                                (asListL u == listfil ++ listrem)  -- | Test the genIsSubsetOf function
Data/Tree/AVL/Types.hs view
@@ -82,23 +82,19 @@ -- where appropriate), or using strict variants of the combinators defined in "Data.COrdering", -- or using 'seq' etc. in your own code (in any combining comparisons you define, for example). ----- A note about 'Eq' and 'Ord' class instances.+-- The Eq and Ord instances. ----- For 'AVL' trees the defined instances of 'Ord' and 'Eq' are based on the lists that are produced using--- the 'Data.Tree.AVL.List.asListL' function (it could just as well have been 'Data.Tree.AVL.List.asListR',--- the choice is arbitrary but I can only chose one). This means that two trees which contain the same elements--- in the same order are equal regardless of detailed tree structure. The same principle has been applied to--- the instances of 'Read' and 'Show'. Unfortunately, this has the undesirable and non-intuitive effect--- of making \"equal\" trees potentially distinguishable using some functions (such as height).--- All such functions have been placed in the Data.Tree.AVL.Internals modules, which are not--- included in the main "Data.Tree.AVL" wrapper. For all \"normal\" functions (f) exported by "Data.Tree.AVL"--- it is safe to assume that if a and b are 'AVL' trees then (a == b) implies (f a == f b), provided the same--- is true for the tree elements.+-- Begining with version 3.0 these are now derived, and hence are defined in terms of+-- strict structural equality, rather than observational equivalence. The reason for+-- this change is that the observational equivalence abstraction was technically breakable+-- with the exposed API. But since this change, some functions which were previously+-- considered unsafe have become safe to expose (those that measure tree height). -- data AVL e = E                      -- ^ Empty Tree            | N (AVL e) e (AVL e)    -- ^ BF=-1 (right height > left height)            | Z (AVL e) e (AVL e)    -- ^ BF= 0            | P (AVL e) e (AVL e)    -- ^ BF=+1 (left height > right height)+           deriving(Eq,Ord)  -- A name for the AVL type constructor, fully qualified avlTyConName :: String
Data/Tree/AVL/Zipper.hs view
@@ -111,8 +111,8 @@  import Data.Tree.AVL.Types(AVL(..)) import Data.Tree.AVL.Size(size,addSize)+import Data.Tree.AVL.Height(height,addHeight) import Data.Tree.AVL.Internals.DelUtils(deletePath,popRN,popRZ,popRP,popLN,popLZ,popLP)-import Data.Tree.AVL.Internals.HeightUtils(height,addHeight) import Data.Tree.AVL.Internals.HJoin(spliceH,joinH) import Data.Tree.AVL.Internals.HPush(pushHL,pushHR) import Data.Tree.AVL.Internals.BinPath(BinPath(..),genOpenPath,writePath,insertPath,sel,goL,goR)
Data/Tree/AVLX.hs view
@@ -14,7 +14,6 @@ module Data.Tree.AVLX (module Data.Tree.AVL -- The normal user AVL API -- + Normally Hidden Modules-,module Data.Tree.AVL.Internals.HeightUtils ,module Data.Tree.AVL.Internals.DelUtils ,module Data.Tree.AVL.Internals.HPush ,module Data.Tree.AVL.Internals.HSet@@ -30,7 +29,6 @@ import Data.Tree.AVL hiding (AVL) import Data.Tree.AVL.Types(AVL(..))        -- We want constructors exposed -import Data.Tree.AVL.Internals.HeightUtils import Data.Tree.AVL.Internals.DelUtils import Data.Tree.AVL.Internals.HPush import Data.Tree.AVL.Internals.HSet
+ MasterTable.txt view
@@ -0,0 +1,26 @@+Change in Height as a function of change in BF.+These figures are correct even if rebalancing has occurred.+Cases marked "--" are impossible.++Figures are given for insertion/deletion from left and+right sub-trees separately, and a combined figure for+where it's unknown which sub-tree was modified.++         InsL  InsR   Insert  |  DelL  DelR   Delete+ E->E      0     0       0    |    0     0       0+ E->N     --    --      --    |   --    --      --+ E->Z     +1    +1      +1    |   --    --      --+ E->P     --    --      --    |   --    --      --+ N->E     --    --      --    |   --    --      --+ N->N      0     0       0    |    0     0       0+ N->Z      0     0       0    |   -1    -1      -1+ N->P     --    --      --    |    0    --       0+ Z->E     --    --      --    |   -1    -1      -1+ Z->N     --    +1      +1    |    0    --       0+ Z->Z      0     0       0    |    0     0       0+ Z->P     +1    --      +1    |   --     0       0+ P->E     --    --      --    |   --    --      --+ P->N     --    --      --    |   --     0       0+ P->Z      0     0       0    |   -1    -1      -1+ P->P      0     0       0    |    0     0       0+