| 
    
| 
    1module RadixTree2 
   2where 
   3 
   4import           Data.Char 
   5import           Data.Maybe 
   6 
   7import           Data.Map(Map) 
   8import qualified Data.Map as M 
   9 
  10import           Data.Set(Set) 
  11import qualified Data.Set as S 
  12 
  13-- ------------------------------------------------------------ 
  14-- 
  15 
  16type Key        = String 
  17type Attr       = Set Int 
  18 
  19data Table      = Entry Table  Attr 
  20                | Switch        ( Map Char Table ) 
  21                  deriving (Show) 
  22 
  23-- ------------------------------------------------------------ 
  24 
  25emptyTable      :: Table 
  26emptyTable      = Switch M.empty 
  27 
  28-- ------------------------------------------------------------ 
  29-- 
  30-- 5 cases      (completeness, correctness !!!) 
  31 
  32search          :: String -> Table -> Maybe Attr 
  33 
  34search "" (Entry table attr)    = Just attr 
  35 
  36search "" (Switch sw)           = Nothing 
  37 
  38search k  (Entry table attr)    = search k table 
  39 
  40search k  (Switch sw)           = switch (M.lookup (head k) sw) 
  41    where 
  42    switch Nothing      = Nothing 
  43    switch (Just tab)   = search (tail k) tab 
  44 
  45-- ------------------------------------------------------------ 
  46-- 
  47-- 4 cases, very fast 
  48 
  49searchPrefix    :: String -> Table -> Table 
  50 
  51searchPrefix "" tab                     = tab 
  52 
  53searchPrefix k (Entry tab' a')          = searchPrefix k tab' 
  54 
  55searchPrefix (c:rest) (Switch sw') 
  56    | M.member c sw'                    = searchPrefix rest 
  57                                          (fromJust $ M.lookup c sw') 
  58    | otherwise                         = emptyTable 
  59 
  60-- ------------------------------------------------------------ 
  61-- 
  62-- 5 cases      (completeness, correctness !!!) 
  63 
  64insert  :: String -> Attr -> Table -> Table 
  65 
  66 
  67insert ""       a (Entry tab' a')       = Entry tab' (a' `S.union` a) 
  68 
  69insert ""       a tab                   = Entry tab a 
  70 
  71insert k        a (Entry tab' a')       = Entry (insert k a tab') a' 
  72 
  73insert (c:rest) a (Switch sw') 
  74    | M.member c sw'                    = Switch (M.adjust (insert rest a) c sw') 
  75    | otherwise                         = Switch (M.insert c (insert rest a emptyTable) sw') 
  76 
  77-- ------------------------------------------------------------ 
  78 
  79keys    :: Table -> [String] 
  80 
  81keys (Entry tab a)      = "" : keys tab 
  82keys (Switch sw)        = [ c : w | c <- M.keys sw 
  83                                  , w <- keys (fromJust $ M.lookup c sw) 
  84                          ] 
  85 
  86-- ------------------------------------------------------------ 
  87-- 
  88-- invariant: 
  89-- 
  90-- no nested Entry constructors 
  91-- 
  92-- no subtable of a switch is empty 
  93 
  94invTable        :: Table -> Bool 
  95invTable (Entry tab attr) 
  96    = case tab of 
  97      Entry _ _  -> False 
  98      Switch _   -> invTable tab 
  99 
 100invTable (Switch sw) 
 101    = all invTable' (M.elems sw) 
 102      where 
 103      invTable' t'              = not (isEmptyTable t') 
 104                                && 
 105                                invTable t' 
 106 
 107      isEmptyTable (Entry _ _)  = False 
 108      isEmptyTable (Switch sw)  = M.null sw 
 109 
 110-- ------------------------------------------------------------ 
 111 
 112tableSpace              :: Table -> Int 
 113tableSpace (Entry t a) 
 114    = 2 + tableSpace t          -- 1 (constructor) + 1 (Table) + 0 (Attr not counted) 
 115 
 116tableSpace (Switch m) 
 117    = 2 + 2 * M.size m          -- 1 (constructor) + 1 (Map) +  per Entry (Char, Table) 
 118      + (sum . map tableSpace . M.elems) m 
 119 
 120tableSize               :: Table -> (Int, Int) 
 121tableSize t 
 122    = (length ks, sum . map length $ ks) 
 123    where 
 124    ks = keys t 
 125 
 126-- ------------------------------------------------------------ 
 | 
    
| Letzte Änderung: 11.07.2012 | © Prof. Dr. Uwe Schmidt |