module Language.Fixpoint.Utils.Trie
(
Trie (..)
, Branch (..)
, empty
, insert
, fromList
, fold
, foldM
)
where
import qualified Data.List as L
import Language.Fixpoint.Types.PrettyPrint
import qualified Language.Fixpoint.Misc as Misc
type Key = Int
type Path = [Key]
data Trie a
= Node ![Branch a]
deriving (Eq, Show)
data Branch a
= Bind !Key !(Trie a)
| Val a
deriving (Eq, Show)
empty :: Trie a
empty = Node []
insert :: Path -> a -> Trie a -> Trie a
insert [] v (Node ts) = Node ((Val v) : ts)
insert (i:is) v (Node ts) = Node (insertKey i is v ts)
fromList :: [(Path, a)] -> Trie a
fromList = L.foldl' (\t (k, v) -> insert k v t) empty
insertKey :: Key -> Path -> a -> [Branch a] -> [Branch a]
insertKey i is v bs@((Bind j tj) : bs')
| i == j = Bind i (insert is v tj) : bs'
| i < j = Bind i (pathTrie is v) : bs
insertKey i is v (b:bs) = b : insertKey i is v bs
insertKey i is v [] = [ Bind i (pathTrie is v) ]
pathTrie :: Path -> a -> Trie a
pathTrie [] v = Node [Val v]
pathTrie (i:is) v = Node [Bind i (pathTrie is v)]
fold :: (acc -> Path -> a -> acc) -> acc -> Trie a -> acc
fold = undefined
foldM :: (Monad m) => (acc -> Path -> a -> m acc) -> acc -> Trie a -> m acc
foldM = undefined
instance Show a => PPrint (Trie a) where
pprintTidy _ = Misc.tshow
_example0 :: Trie Char
_example0 = Node [Bind 1 n1]
where
n1 = Node [Bind 2 n2, Bind 6 n6]
n2 = Node [Val 'A' , Bind 3 n3]
n3 = Node [Bind 4 n4, Bind 5 n5]
n4 = Node [Val 'B']
n5 = Node [Val 'C']
n6 = Node [Val 'D']
_example1 :: Trie Char
_example1 = insert [1, 2] 'A'
. insert [1,2,3,4] 'B'
. insert [1,2,3,5] 'C'
. insert [1,6] 'D'
$ empty