packages feed

polimorf (empty) → 0.1.0

raw patch · 4 files changed

+211/−0 lines, 4 filesdep +basedep +binarydep +containerssetup-changed

Dependencies added: base, binary, containers, text

Files

+ Data/PoliMorf.hs view
@@ -0,0 +1,149 @@+{-# LANGUAGE PatternGuards #-}+{-# LANGUAGE BangPatterns #-}++-- | The module provides functionality for manipulating PoliMorf, the+-- morphological dictionary for Polish. Apart from IO utilities there+-- is a 'merge' function which can be used to merge the PoliMorf with+-- another dictionary resources.++module Data.PoliMorf+( +-- * Types+  Form+, Base+, Tag+, Entry (..)++-- * Parsing+, readPoliMorf+, parsePoliMorf++-- * Merging+, BaseMap+, mkBaseMap+, RelCode (..)+, merge+) where++import Control.Applicative ((<$>), (<*>))+import Data.Monoid (Monoid, mappend)+import Data.List (foldl')+import Data.Maybe (maybeToList)+import Data.Binary (Binary, get, put)+import qualified Data.Map as M+import qualified Data.Set as S+import qualified Data.Text as T+import qualified Data.Text.Lazy as L+import qualified Data.Text.Lazy.IO as L++-- | A form.+type Form = T.Text++-- | A base form.+type Base = T.Text++-- | A morphosyntactic tag.+type Tag  = T.Text++-- | An entry from the PoliMorf dictionary.+data Entry = Entry+    { form :: !Form+    , base :: !Base+    , tag  :: !Tag }++-- | Read the PoliMorf from the file.+readPoliMorf :: FilePath -> IO [Entry]+readPoliMorf path = parsePoliMorf <$> L.readFile path++-- | Parse the PoliMorf into a list of entries.+parsePoliMorf :: L.Text -> [Entry]+parsePoliMorf = map parsePoliRow . L.lines ++-- | Get an entry pair from a PoliMorf row.+parsePoliRow :: L.Text -> Entry+parsePoliRow row = case map L.toStrict (L.split (=='\t') row) of+    [_form, _base, _tag] -> Entry _form _base _tag+    _   -> error $ "parsePoliRow: invalid row \"" ++ L.unpack row ++ "\""++-- | A map from forms to their possible base forms (there may be many since+-- the form may be a member of multiple lexemes).+type BaseMap = M.Map Form [Base]++-- | Make the base map from the list of entries.+mkBaseMap :: [Entry] -> BaseMap+mkBaseMap = M.fromListWith (++) . map ((,) <$> form <*> (:[]) . base)++-- | Reliability information: how did we assign a particular label to+-- a particular word form.+data RelCode+    = Exact     -- ^ Label assigned in a direct manner+    | ByBase    -- ^ Label assigned based on a lemma label  +    | ByForm    -- ^ Based on labels of other forms within the same lexeme+    deriving (Eq, Ord, Show, Read)++instance Binary RelCode where+    put Exact   = put '1'+    put ByBase = put '2'+    put ByForm  = put '3'+    get = get >>= \x -> return $ case x of+        '1' -> Exact+        '2' -> ByBase+        '3' -> ByForm+        c   -> error $ "get: invalid RelCode code '" ++ [c] ++ "'"++-- | Merge the 'BaseMap' with the dictionary resource which maps forms to+-- monoidal labels.  Depending on the inference technique there are three+-- kinds of labels in the resultant dictionary:+-- 'Exact' labels assigned in a direct manner, 'ByBase' labels assigned+-- to all forms which have a base form with a label in the input dictionary,+-- and 'ByForm' labels assigned to all forms which have a related form from the+-- same lexeme with a label in the input dictionary.+--+-- For a particular form in the output dictionary there are labels extracted+-- with at most one of the methods described above, with 'Exact' labels+-- having a precedence over 'ByBase' labels and 'ByBase' labels having+-- a precedence over 'ByForm' labels.+--+-- This function is far from being memory efficient right now.  If you plan to+-- run it with respect to the entire PoliMorf dictionary you should do it+-- on a machine with an abundance of available memory.+merge :: Monoid m => BaseMap -> M.Map Form m -> M.Map Form (Maybe (m, RelCode))+merge poli dict0 =+    M.fromList [(x, combine x) | x <- keys]+  where+    -- Keys in the output dictionary.+    keys = S.toList (M.keysSet poli `S.union` M.keysSet dict0)++    -- Combining function.+    combine x+        | Just y <- M.lookup x dict0 = Just (y, Exact)+        | Just y <- M.lookup x dict1 = Just (y, ByBase)+        | Just y <- M.lookup x dict2 = Just (y, ByForm)+        | otherwise = Nothing++    -- Extended to all base forms of dict0 keys.+    dict1 = fromListWith mappend+        [ (lemma, x)+        | (_form, x) <- M.assocs dict0+        , lemmas <- maybeToList (_form `M.lookup` poli)+        , lemma <- lemmas ]++    -- Extended to all forms of dict0 keys.+    dict2 = fromListWith mappend+        [ (form', x)+        | (_form, x) <- M.assocs dict0+        , lemmas <- maybeToList (_form `M.lookup` poli)+        , lemma  <- lemmas+        , forms' <- maybeToList (lemma `M.lookup` ilop)+        , form'  <- forms' ]++    -- Inverse poli dictionary.+    ilop = fmap S.toList $ fromListWith mappend+        [ (lemma, S.singleton _form)+        | (_form, lemmas) <- M.assocs poli+        , lemma <- lemmas ]++fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> M.Map k a+fromListWith f xs =+    let update m (!k, !x) = M.insertWith' f k x m+    in  foldl' update M.empty xs
+ LICENSE view
@@ -0,0 +1,26 @@+Copyright (c) 2012, IPI PAN+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ polimorf.cabal view
@@ -0,0 +1,34 @@+name:               polimorf+version:            0.1.0+synopsis:           Working with the PoliMorf dictionary+description:+    The library provides functionality for manipulating PoliMorf, the+    morphological dictionary for Polish.+    In particular, the library exports functions which can be used to+    merge the PoliMorf with another dictionary resources.+license:            BSD3+license-file:       LICENSE+cabal-version:      >= 1.6+copyright:          Copyright (c) 2012 IPI PAN+author:             Jakub Waszczuk+maintainer:         waszczuk.kuba@gmail.com+stability:          experimental+category:           Natural Language Processing+homepage:           https://github.com/kawu/polimorf+build-type:         Simple++library+    build-depends:+        base >= 4 && < 5+      , containers+      , text+      , binary++    exposed-modules:+        Data.PoliMorf++    ghc-options: -Wall++source-repository head+    type: git+    location: git://github.com/kawu/polimorf.git