packages feed

bk-tree (empty) → 0.1

raw patch · 3 files changed

+98/−0 lines, 3 filesdep +basedep +containerssetup-changed

Dependencies added: base, containers

Files

+ Data/BKTree.hs view
@@ -0,0 +1,69 @@+-- | Implementation of a BK-tree: <https://en.wikipedia.org/wiki/Bk-tree>+module Data.BKTree+    ( -- * Types+      Distance+    , BKTree+      -- * Operations+    , empty+    , insert+    , query+    ) where++import           Data.IntMap (IntMap)+import qualified Data.IntMap as IntMap++type Distance s = s -> s -> Int++data BKTree s =+    BKTree !(BK s) (Distance s)++data BK s+    = EmptyBK+    | BK !s !(IntMap (BK s))++narrow :: Int -> Int -> IntMap a -> IntMap a+narrow n m im | n == m    = IntMap.fromList (maybe [] (\v -> [(n, v)]) (IntMap.lookup n im))+narrow n m im | otherwise = insMaybe m res pr+  where+    (_, pl, res0)  = IntMap.splitLookup n im+    (res, pr, _)   = IntMap.splitLookup m (insMaybe n res0 pl)+    insMaybe k im' = maybe im' (\v -> IntMap.insert k v im')++empty :: Distance s -- ^ The distance function \"d\" must be a metric on \"s\"+                    --   (<https://en.wikipedia.org/wiki/Metric_space#Definition>):+                    --+                    --   * d x y >= 0+                    --+                    --   * d x y == 0 iff x == y+                    --+                    --   * d x y == d y x+                    --+                    --   * d x z <= d x y + d y z+      -> BKTree s+empty = BKTree EmptyBK++insert :: s -> BKTree s -> BKTree s+insert s (BKTree bk f) = BKTree (insert' s f bk) f++insert' :: s -> Distance s -> BK s -> BK s+insert' s _ EmptyBK = BK s IntMap.empty+insert' s f bk@(BK s' bks)+    | dist == 0 = bk+    | otherwise = BK s' $ flip (IntMap.insert dist) bks $+                  maybe (insert' s f EmptyBK) (insert' s f) (IntMap.lookup dist bks)+  where dist = f s s'++query :: Int                    -- ^ The maximum distance to search for.+      -> s -> BKTree s+      -> [(s, Int)]             -- ^ All the words with a distance less than the+                                -- one specified, and their respective+                                -- distances.+query maxd s (BKTree bk f) = query' maxd s f bk++query' :: Int -> s -> Distance s -> BK s -> [(s, Int)]+query' _    _ _  EmptyBK    = []+query' maxd s f (BK s' bks) = match ++ concatMap (query' maxd s f) children+  where+    dist     = f s s'+    match    = if (dist <= maxd) then [(s', dist)] else []+    children = IntMap.elems $ narrow (max (dist - maxd) 0) (dist + maxd) bks
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ bk-tree.cabal view
@@ -0,0 +1,27 @@+Cabal-Version:      >= 1.8+Name:               bk-tree+Version:            0.1+Author:             Francesco Mazzoli (f@mazzo.li)+Maintainer:         Francesco Mazzoli (f@mazzo.li)+Build-Type:         Simple+License:            PublicDomain+Build-Type:         Simple+Category:           Data Structures+Synopsis:           BK-tree implementation+Tested-With:        GHC==7.4.1+Homepage:           https://github.com/bitonic/language-spelling+Bug-Reports:        https://github.com/bitonic/language-spelling/issues+Description:+    BK-tree implementation.++source-repository head+    type:     git+    location: git://github.com/bitonic/language-spelling.git++Library+    Build-Depends:    base >= 3 && < 5,+                      containers++    GHC-Options:      -Werror -O2++    Exposed-Modules:  Data.BKTree