packages feed

pred-trie 0.5.0 → 0.5.1

raw patch · 6 files changed

+416/−7 lines, 6 filesdep +containersdep +hashtablesdep +pred-setPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: containers, hashtables, pred-set

API changes (from Hackage documentation)

- Data.Trie.Pred.Interface.Types: instance (GHC.Classes.Eq k, Data.Hashable.Class.Hashable k) => Data.Trie.Pred.Interface.Types.Extend (Data.Trie.Pred.Interface.Types.PathChunk k ('GHC.Base.Just r)) (Data.Trie.Pred.Base.RootedPredTrie k (r -> a)) (Data.Trie.Pred.Base.RootedPredTrie k a)
+ Data.Trie.Pred.Interface.Types: instance (GHC.Classes.Eq k, Data.Hashable.Class.Hashable k, Data.Typeable.Internal.Typeable r) => Data.Trie.Pred.Interface.Types.Extend (Data.Trie.Pred.Interface.Types.PathChunk k ('GHC.Base.Just r)) (Data.Trie.Pred.Base.RootedPredTrie k (r -> a)) (Data.Trie.Pred.Base.RootedPredTrie k a)
+ Data.Trie.Pred.Mutable: HashTableTrie :: {-# UNPACK #-} !(HashTable s k (RawValue s k a)) -> [PredStep s k a] -> HashTableTrie s k a
+ Data.Trie.Pred.Mutable: PredStep :: {-# UNPACK #-} !(PredKey s k a) -> !(Maybe (a -> r)) -> !(HashTableTrie s k (a -> r)) -> PredStep s k r
+ Data.Trie.Pred.Mutable: RawValue :: !(Maybe a) -> !(HashTableTrie s k a) -> RawValue s k a
+ Data.Trie.Pred.Mutable: RootedHashTableTrie :: !(Maybe a) -> !(HashTableTrie s k a) -> {-# UNPACK #-} !(PredSet s k) -> RootedHashTableTrie s k a
+ Data.Trie.Pred.Mutable: [predData] :: PredStep s k r -> !(Maybe (a -> r))
+ Data.Trie.Pred.Mutable: [predPred] :: PredStep s k r -> {-# UNPACK #-} !(PredKey s k a)
+ Data.Trie.Pred.Mutable: [predPreds] :: HashTableTrie s k a -> [PredStep s k a]
+ Data.Trie.Pred.Mutable: [predSub] :: PredStep s k r -> !(HashTableTrie s k (a -> r))
+ Data.Trie.Pred.Mutable: [rawChildren] :: RawValue s k a -> !(HashTableTrie s k a)
+ Data.Trie.Pred.Mutable: [rawValue] :: RawValue s k a -> !(Maybe a)
+ Data.Trie.Pred.Mutable: [rawValues] :: HashTableTrie s k a -> {-# UNPACK #-} !(HashTable s k (RawValue s k a))
+ Data.Trie.Pred.Mutable: [rootedBase] :: RootedHashTableTrie s k a -> !(Maybe a)
+ Data.Trie.Pred.Mutable: [rootedPredSet] :: RootedHashTableTrie s k a -> {-# UNPACK #-} !(PredSet s k)
+ Data.Trie.Pred.Mutable: [rootedSub] :: RootedHashTableTrie s k a -> !(HashTableTrie s k a)
+ Data.Trie.Pred.Mutable: data HashTableTrie s k a
+ Data.Trie.Pred.Mutable: data PredStep s k r
+ Data.Trie.Pred.Mutable: data RawValue s k a
+ Data.Trie.Pred.Mutable: data RootedHashTableTrie s k a
+ Data.Trie.Pred.Mutable: insert :: (Eq k, Hashable k) => NonEmpty k -> a -> HashTableTrie s k a -> ST s (HashTableTrie s k a)
+ Data.Trie.Pred.Mutable: lookup :: (Eq k, Hashable k, Typeable s, Typeable k) => PredSet s k -> NonEmpty k -> HashTableTrie s k a -> ST s (Maybe a)
+ Data.Trie.Pred.Mutable: lookupR :: (Eq k, Hashable k, Typeable s, Typeable k, Typeable a) => [k] -> RootedHashTableTrie s k a -> ST s (Maybe a)
+ Data.Trie.Pred.Mutable: match :: (Eq k, Hashable k, Typeable s, Typeable k) => PredSet s k -> NonEmpty k -> HashTableTrie s k a -> ST s (Maybe (NonEmpty k, a, [k]))
+ Data.Trie.Pred.Mutable: matchR :: (Eq k, Hashable k, Typeable s, Typeable k, Typeable a) => [k] -> RootedHashTableTrie s k a -> ST s (Maybe ([k], a, [k]))
+ Data.Trie.Pred.Mutable: matches :: (Eq k, Hashable k, Typeable s, Typeable k) => PredSet s k -> NonEmpty k -> HashTableTrie s k a -> ST s [(NonEmpty k, a, [k])]
+ Data.Trie.Pred.Mutable: matchesR :: (Eq k, Hashable k, Typeable s, Typeable k, Typeable a) => [k] -> RootedHashTableTrie s k a -> ST s [([k], a, [k])]
+ Data.Trie.Pred.Mutable: new :: ST s (HashTableTrie s k a)
+ Data.Trie.Pred.Mutable: newR :: ST s (RootedHashTableTrie s k a)
+ Data.Trie.Pred.Mutable.Morph: insertPredKey :: (Ord k', Typeable s, Typeable k, Typeable a) => k' -> PredKey s k a -> HMap k' -> HMap k'
+ Data.Trie.Pred.Mutable.Morph: lookupPredKey :: (Ord k', Typeable s, Typeable k, Typeable a) => k' -> ST s (k -> Maybe a) -> HMap k' -> ST s (Maybe (PredKey s k a))
+ Data.Trie.Pred.Mutable.Morph: toHashTable :: (Eq k, Hashable k) => HashMap k a -> ST s (HashTable s k a)
+ Data.Trie.Pred.Mutable.Morph: toHashTableTrie :: (Eq k, Hashable k, Ord k, Typeable s, Typeable k, Typeable a) => STRef s (HMap k) -> PredSet s k -> PredTrie k a -> ST s (HashTableTrie s k a)
+ Data.Trie.Pred.Mutable.Morph: toMutable :: (Eq k, Hashable k, Ord k, Typeable s, Typeable k, Typeable a) => PredSet s k -> PredTrie k a -> ST s (HashTableTrie s k a)
+ Data.Trie.Pred.Mutable.Morph: toMutablePredStep :: (Ord k, Eq k, Hashable k, Typeable s, Typeable k, Typeable a) => STRef s (HMap k) -> PredSet s k -> PredStep k PredTrie k a -> ST s (PredStep s k a)
+ Data.Trie.Pred.Mutable.Morph: toMutableRooted :: (Eq k, Hashable k, Ord k, Typeable s, Typeable k, Typeable a) => RootedPredTrie k a -> ST s (RootedHashTableTrie s k a)
+ Data.Trie.Pred.Mutable.Morph: toRawValue :: (Eq k, Hashable k, Ord k, Typeable s, Typeable k, Typeable a) => STRef s (HMap k) -> PredSet s k -> HashMapChildren PredTrie k a -> ST s (RawValue s k a)
+ Data.Trie.Pred.Mutable.Morph: type HMap k = Map k Dynamic
- Data.Trie.Pred.Base.Step: singletonPred :: Monoid (c s (r -> a)) => k -> (s -> Maybe r) -> (r -> a) -> PredStep k c s a
+ Data.Trie.Pred.Base.Step: singletonPred :: (Monoid (c s (r -> a)), Typeable r) => k -> (s -> Maybe r) -> (r -> a) -> PredStep k c s a

Files

pred-trie.cabal view
@@ -1,5 +1,5 @@ Name:                   pred-trie-Version:                0.5.0+Version:                0.5.1 Author:                 Athan Clark <athan.clark@gmail.com> Maintainer:             Athan Clark <athan.clark@gmail.com> License:                BSD3@@ -19,11 +19,16 @@                         Data.Trie.Pred.Base.Step                         Data.Trie.Pred.Interface                         Data.Trie.Pred.Interface.Types+                        Data.Trie.Pred.Mutable+                        Data.Trie.Pred.Mutable.Morph   Build-Depends:        base >= 4.8 && < 5                       , composition-extra >= 2.0.0+                      , containers                       , hashable+                      , hashtables                       , mtl                       , poly-arity >= 0.0.7+                      , pred-set                       , semigroups                       , tries >= 0.0.4                       , unordered-containers
src/Data/Trie/Pred/Base/Step.hs view
@@ -31,11 +31,11 @@  -- * Single Predicated Step -data PredStep k c s a = forall r. PredStep+data PredStep k c s a = forall r. Typeable r => PredStep   { -- | Unique identifier for the predicate - used for combination     predTag  :: !k   , -- | The predicate, existentially quantified in the successful result @r@-    predPred :: !(s -> Maybe r) +    predPred :: !(s -> Maybe r)   , -- | The result function, capturing the quantified result @r@ and turning     --   it into a top-level variable @a@.     predData :: !(Maybe (r -> a))@@ -65,7 +65,9 @@                else PredStep i p mx $! delete (NE.fromList ts) xs)       (p t) -singletonPred :: Monoid (c s (r -> a)) => k -> (s -> Maybe r) -> (r -> a) -> PredStep k c s a+singletonPred :: ( Monoid (c s (r -> a))+                 , Typeable r+                 ) => k -> (s -> Maybe r) -> (r -> a) -> PredStep k c s a singletonPred i p x = PredStep i p (Just x) mempty  
src/Data/Trie/Pred/Interface.hs view
@@ -90,7 +90,8 @@  newtype PTBuilderT k v m a = PTBuilderT   { runPTBuilderT :: StateT (RootedPredTrie k v) m a-  } deriving (Functor, Applicative, Monad, MonadTrans, MonadState (RootedPredTrie k v))+  } deriving ( Functor, Applicative, Monad, MonadTrans+             , MonadState (RootedPredTrie k v))  instance ( Monad m          , Eq k@@ -128,7 +129,7 @@             -> childContent             -> PTBuilderT k resultContent m () insert !ts !vl =-  modify' ((singleton ts vl) <>)+  modify' (singleton ts vl <>)   insertHere :: ( Monad m@@ -149,7 +150,7 @@             -> PTBuilderT k resultContent m () prefix !ts cs = do   trie <- lift (execPTBuilderT cs)-  modify' ((extrude ts trie) <>)+  modify' (extrude ts trie <>)   lookup :: ( Eq k
src/Data/Trie/Pred/Interface/Types.hs view
@@ -51,6 +51,7 @@ import qualified Data.HashMap.Lazy as HM import Data.Hashable import Data.Function.Poly+import Data.Typeable  import Data.String (IsString (..)) @@ -92,6 +93,7 @@ -- | Existentially quantified case instance ( Eq k          , Hashable k+         , Typeable r          ) => Extend (PathChunk k ('Just r)) (RootedPredTrie k (r -> a)) (RootedPredTrie k a) where   extend (Pred i q) (RootedPredTrie mx xs) = RootedPredTrie Nothing $     PredTrie mempty (PredSteps [PredStep i q mx xs])
+ src/Data/Trie/Pred/Mutable.hs view
@@ -0,0 +1,262 @@+{-# LANGUAGE+    ExistentialQuantification+  #-}++module Data.Trie.Pred.Mutable where++import Prelude hiding (lookup)+import Data.Monoid+import Data.Maybe (fromMaybe)+import Data.Foldable (foldlM)+import Data.Typeable++import Data.List.NonEmpty hiding (insert)++import           Data.HashTable.ST.Basic (HashTable)+import qualified Data.HashTable.ST.Basic as HT+import           Data.PredSet.Mutable (PredSet, PredKey)+import qualified Data.PredSet.Mutable as HS+import Control.Monad.ST+import Data.Hashable+++-- * Tail++data PredStep s k r = forall a. Typeable a => PredStep+  { predPred :: {-# UNPACK #-} !(PredKey s k a)+  , predData :: !(Maybe (a -> r))+  , predSub  :: !(HashTableTrie s k (a -> r))+  }++data RawValue s k a = RawValue+  { rawValue    :: !(Maybe a)+  , rawChildren :: !(HashTableTrie s k a)+  }++data HashTableTrie s k a = HashTableTrie+  { rawValues :: {-# UNPACK #-} !(HashTable s k (RawValue s k a))+  , predPreds :: [PredStep s k a]+  }+++new :: ST s (HashTableTrie s k a)+new = flip HashTableTrie [] <$> HT.new++insert :: ( Eq k+          , Hashable k+          ) => NonEmpty k+            -> a+            -> HashTableTrie s k a+            -> ST s (HashTableTrie s k a)+insert (k:|ks) x ref@(HashTableTrie raw _) =+  case ks of+    [] -> do+      mx' <- HT.lookup raw k+      case mx' of+        Nothing -> do+          children <- new+          HT.insert raw k $! RawValue (Just x) children+          pure ref+        Just (RawValue _ children) -> do+          HT.insert raw k $! RawValue (Just x) children+          pure ref+    (k':ks') -> do+      mx' <- HT.lookup raw k+      case mx' of+        Nothing -> do+          children <- new+          children' <- insert (k':|ks') x children+          HT.insert raw k $! RawValue Nothing children'+          pure ref+        Just (RawValue mx children) -> do+          children' <- insert (k':|ks') x children+          HT.insert raw k $! RawValue mx children'+          pure ref+++lookup :: ( Eq k+          , Hashable k+          , Typeable s+          , Typeable k+          ) => PredSet s k+            -> NonEmpty k+            -> HashTableTrie s k a+            -> ST s (Maybe a)+lookup predSet (k:|ks) (HashTableTrie raw preds) = do+  mx <- HT.lookup raw k+  case mx of+    Just (RawValue mx' children) ->+      case ks of+        []       -> pure mx'+        (k':ks') -> lookup predSet (k':|ks') children+    Nothing ->+      let -- go :: Typeable t => Maybe t -> PredStep s k t -> ST s (Maybe t)+          go solution@(Just _) _                          = pure solution+          go Nothing (PredStep predKey mHandler children) = do+            mx' <- HS.lookup predKey k predSet+            case mx' of+              Nothing -> pure Nothing+              Just x  ->+                case ks of+                  [] ->+                    pure $! ($ x) <$> mHandler+                  (k':ks') -> do+                    mf <- lookup predSet (k':|ks') children+                    pure $! ($ x) <$> mf+      in  foldlM go Nothing preds+++match :: ( Eq k+         , Hashable k+         , Typeable s+         , Typeable k+         ) => PredSet s k+           -> NonEmpty k+           -> HashTableTrie s k a+           -> ST s (Maybe (NonEmpty k, a, [k]))+match predSet (k:|ks) (HashTableTrie raw preds) = do+  mLit <- goLit raw+  case mLit of+    Just _  -> pure mLit+    Nothing ->+      let go solution@(Just _) _ = pure solution+          go Nothing pred        = goPred pred+      in  foldlM go Nothing preds+  where+    goLit xs = do+      mx' <- HT.lookup raw k+      case mx' of+        Nothing -> pure Nothing+        Just (RawValue mx children) ->+          let mFoundHere = (\x -> (k:|[], x, ks)) <$> mx+              prependAncestry (pre,x,suff) = (k:|toList pre,x,suff)+          in case ks of+            [] -> pure mFoundHere+            (k':ks') -> do+              mFoundThere <- match predSet (k':|ks') children+              pure $! getFirst $+                   First (prependAncestry <$> mFoundThere)+                <> First mFoundHere++    goPred (PredStep predKey mx children) = do+      mr' <- HS.lookup predKey k predSet+      case mr' of+        Nothing -> pure Nothing+        Just r  ->+          let mFoundHere = (\x -> (k:|[], x r, ks)) <$> mx+              prependAncestryAndApply (pre,f,suff) =+                (k:|toList pre,f r,suff)+          in case ks of+            [] -> pure mFoundHere+            (k':ks') -> do+              mFoundThere <- match predSet (k':|ks') children+              pure $! getFirst $+                   First (prependAncestryAndApply <$> mFoundThere)+                <> First mFoundHere++matches :: ( Eq k+           , Hashable k+           , Typeable s+           , Typeable k+           ) => PredSet s k+             -> NonEmpty k+             -> HashTableTrie s k a+             -> ST s [(NonEmpty k, a, [k])]+matches predSet (k:|ks) (HashTableTrie raw preds) = do+  mLit <- goLit raw+  case mLit of+    Just lit -> pure lit+    Nothing ->+      let go solution@(Just _) _ = pure solution+          go Nothing pred        = goPred pred+      in  fromMaybe [] <$> foldlM go Nothing preds+  where+    goLit xs = do+      mx' <- HT.lookup raw k+      case mx' of+        Nothing -> pure Nothing+        Just (RawValue mx children) ->+          let mFoundHere = (\x -> [(k:|[], x, ks)]) <$> mx+              prependAncestry (pre,x,suff) = (k:|toList pre, x, suff)+          in case ks of+            [] -> pure mFoundHere+            (k':ks') ->+              case mFoundHere of+                Nothing -> pure Nothing+                Just foundHere -> do+                  foundThere <- matches predSet (k':|ks') children+                  pure . Just $! foundHere ++ (prependAncestry <$> foundThere)++    goPred (PredStep predKey mx children) = do+      mr <- HS.lookup predKey k predSet+      case mr of+        Nothing -> pure Nothing+        Just r  ->+          let mFoundHere = (\f -> [(k:|[],f r,ks)]) <$> mx+              prependAncestryAndApply (pre,f,suff) =+                (k:|toList pre,f r,suff)+          in case ks of+            [] -> pure mFoundHere+            (k':ks') ->+              case mFoundHere of+                Nothing -> pure Nothing+                Just foundHere -> do+                  foundThere <- matches predSet (k':|ks') children+                  pure . Just $! foundHere ++ (prependAncestryAndApply <$> foundThere)+++-- * Rooted++data RootedHashTableTrie s k a = RootedHashTableTrie+  { rootedBase    :: !(Maybe a)+  , rootedSub     :: !(HashTableTrie s k a)+  , rootedPredSet :: {-# UNPACK #-} !(PredSet s k)+  }++newR :: ST s (RootedHashTableTrie s k a)+newR = RootedHashTableTrie Nothing <$> new <*> HS.new++lookupR :: ( Eq k+           , Hashable k+           , Typeable s+           , Typeable k+           , Typeable a+           ) => [k]+             -> RootedHashTableTrie s k a+             -> ST s (Maybe a)+lookupR [] (RootedHashTableTrie mx _ _) = pure mx+lookupR (k:ks) (RootedHashTableTrie _ xs predSet) = lookup predSet (k:|ks) xs++matchR :: ( Eq k+          , Hashable k+          , Typeable s+          , Typeable k+          , Typeable a+          ) => [k]+            -> RootedHashTableTrie s k a+            -> ST s (Maybe ([k],a,[k]))+matchR [] (RootedHashTableTrie mx _ _) =+  pure $! (\x -> ([],x,[])) <$> mx+matchR (k:ks) (RootedHashTableTrie mx xs predSet) = do+  mFoundThere <- match predSet (k:|ks) xs+  pure $! getFirst $+      First ((\(pre,x,suff) -> (toList pre,x,suff)) <$> mFoundThere)+   <> First ((\x -> ([],x,k:ks)) <$> mx)+++matchesR :: ( Eq k+            , Hashable k+            , Typeable s+            , Typeable k+            , Typeable a+            ) => [k]+              -> RootedHashTableTrie s k a+              -> ST s [([k],a,[k])]+matchesR [] (RootedHashTableTrie mx _ _) =+  pure $! fromMaybe [] $ (\x -> [([],x,[])]) <$> mx+matchesR (k:ks) (RootedHashTableTrie mx xs predSet) = do+  foundThere <- matches predSet (k:|ks) xs+  pure $! foundHere ++ (allowRoot <$> foundThere)+  where+    foundHere = fromMaybe [] $ (\x -> [([],x,k:ks)]) <$> mx+    allowRoot (pre,x,suff) = (toList pre,x,suff)
+ src/Data/Trie/Pred/Mutable/Morph.hs view
@@ -0,0 +1,137 @@+module Data.Trie.Pred.Mutable.Morph where++import Data.Trie.Pred.Mutable as M+import Data.Trie.Pred.Base as B+import Data.Trie.Pred.Base.Step as B++import Data.PredSet.Mutable as HS+import Data.Trie.HashMap as HMT+import           Data.HashMap.Lazy (HashMap)+import qualified Data.HashMap.Lazy as HM+import           Data.HashTable.ST.Basic (HashTable)+import qualified Data.HashTable.ST.Basic as HT+import qualified Data.Map.Strict as Map++import Control.Monad.ST+import Data.Foldable (foldlM)+import Data.Typeable+import Data.Dynamic+import Data.Hashable+import Data.Proxy+import Data.STRef+++toMutableRooted :: ( Eq k+                   , Hashable k+                   , Ord k+                   , Typeable s+                   , Typeable k+                   , Typeable a+                   ) => RootedPredTrie k a+                     -> ST s (RootedHashTableTrie s k a)+toMutableRooted (RootedPredTrie mx xs) = do+  predSet <- HS.new+  xs' <- toMutable predSet xs+  pure $! RootedHashTableTrie mx xs' predSet++toMutable :: ( Eq k+             , Hashable k+             , Ord k+             , Typeable s+             , Typeable k+             , Typeable a+             ) => PredSet s k+               -> PredTrie k a+               -> ST s (HashTableTrie s k a)+toMutable predSet xs = do+  predRefs <- newSTRef Map.empty+  toHashTableTrie predRefs predSet xs+++toHashTableTrie :: ( Eq k+                   , Hashable k+                   , Ord k+                   , Typeable s+                   , Typeable k+                   , Typeable a+                   ) => STRef s (HMap k)+                     -> PredSet s k+                     -> PredTrie k a+                     -> ST s (HashTableTrie s k a)+toHashTableTrie predRefs predSet (PredTrie (HashMapStep raw) (PredSteps preds)) = do+  raw' <- toHashTable =<< traverse (toRawValue predRefs predSet) raw+  preds' <- mapM (toMutablePredStep predRefs predSet) preds+  pure (HashTableTrie raw' preds')++toRawValue :: ( Eq k+              , Hashable k+              , Ord k+              , Typeable s+              , Typeable k+              , Typeable a+              ) => STRef s (HMap k)+                -> PredSet s k+                -> HashMapChildren PredTrie k a+                -> ST s (RawValue s k a)+toRawValue predRefs predSet (HashMapChildren mx mchildren) = do+  children <- case mchildren of+                Nothing -> M.new+                Just xs -> toHashTableTrie predRefs predSet xs+  pure (RawValue mx children)++toHashTable :: ( Eq k+               , Hashable k+               ) => HM.HashMap k a+                 -> ST s (HashTable s k a)+toHashTable xs = do+  fresh <- HT.new+  foldlM (\() (k,v) -> HT.insert fresh k v) () (HM.toList xs)+  pure fresh++toMutablePredStep :: ( Ord k+                     , Eq k+                     , Hashable k+                     , Typeable s+                     , Typeable k+                     , Typeable a+                     ) => STRef s (HMap k)+                       -> PredSet s k+                       -> B.PredStep k PredTrie k a+                       -> ST s (M.PredStep s k a)+toMutablePredStep predRefs predSet (B.PredStep tag pred mx children) = do+  predRefs' <- readSTRef predRefs+  mPredKey <- lookupPredKey tag (pure pred) predRefs'+  predKey  <- case mPredKey of+                Nothing -> do predKey' <- HS.insert pred predSet+                              writeSTRef predRefs (insertPredKey tag predKey' predRefs')+                              pure predKey'+                Just x  -> pure x+  children' <- toHashTableTrie predRefs predSet children+  pure (M.PredStep predKey mx children')+++-- Wiiiked abuse of the type system++type HMap k = Map.Map k Dynamic++insertPredKey :: ( Ord k'+                 , Typeable s+                 , Typeable k+                 , Typeable a+                 ) => k'+                   -> PredKey s k a+                   -> HMap k'+                   -> HMap k'+insertPredKey k pred = Map.insert k (toDyn pred)++lookupPredKey :: ( Ord k'+                 , Typeable s+                 , Typeable k+                 , Typeable a+                 ) => k'+                   -> ST s (k -> Maybe a)+                   -> HMap k'+                   -> ST s (Maybe (PredKey s k a))+lookupPredKey k pred xs = do+  pred' <- pred+  pure $! fromDynamic =<< Map.lookup k xs