diff options
| author | Gregor Kleen <gkleen@yggdrasil.li> | 2018-02-05 17:02:55 +0100 |
|---|---|---|
| committer | Gregor Kleen <gkleen@yggdrasil.li> | 2018-02-05 17:02:55 +0100 |
| commit | 6d1f39826963890e9612b39f92843f134b6973f3 (patch) | |
| tree | a613a5ff0b0b61a021a22cda7523e1d9aef9c9d9 /edit-lens/src | |
| parent | 529d127667a366f306f975b3ed34e8a118f3cefc (diff) | |
| download | incremental-dfsts-6d1f39826963890e9612b39f92843f134b6973f3.tar incremental-dfsts-6d1f39826963890e9612b39f92843f134b6973f3.tar.gz incremental-dfsts-6d1f39826963890e9612b39f92843f134b6973f3.tar.bz2 incremental-dfsts-6d1f39826963890e9612b39f92843f134b6973f3.tar.xz incremental-dfsts-6d1f39826963890e9612b39f92843f134b6973f3.zip | |
Framework for DFST edit lens
Diffstat (limited to 'edit-lens/src')
| -rw-r--r-- | edit-lens/src/Control/Edit.lhs | 8 | ||||
| -rw-r--r-- | edit-lens/src/Data/String/DFST.hs | 25 | ||||
| -rw-r--r-- | edit-lens/src/Data/String/DFST/Lens.lhs | 82 |
3 files changed, 102 insertions, 13 deletions
diff --git a/edit-lens/src/Control/Edit.lhs b/edit-lens/src/Control/Edit.lhs index 7be8db4..19fe336 100644 --- a/edit-lens/src/Control/Edit.lhs +++ b/edit-lens/src/Control/Edit.lhs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | \begin{comment} | 1 | \begin{comment} |
| 2 | \begin{code} | 2 | \begin{code} |
| 3 | module Control.Edit | 3 | module Control.Edit |
| 4 | ( Module(..) | 4 | ( Module(..), apply' |
| 5 | ) where | 5 | ) where |
| 6 | \end{code} | 6 | \end{code} |
| 7 | \end{comment} | 7 | \end{comment} |
| @@ -24,6 +24,8 @@ In Haskell charakterisieren wir Moduln über ihren Monoid, d.h. die Wahl des Mon | |||
| 24 | Eine Repräsentierung als Typklasse bietet sich an: | 24 | Eine Repräsentierung als Typklasse bietet sich an: |
| 25 | 25 | ||
| 26 | \begin{code} | 26 | \begin{code} |
| 27 | infix 5 `apply` | ||
| 28 | |||
| 27 | class Monoid m => Module m where | 29 | class Monoid m => Module m where |
| 28 | type Domain m :: * | 30 | type Domain m :: * |
| 29 | apply :: Domain m -> m -> Maybe (Domain m) | 31 | apply :: Domain m -> m -> Maybe (Domain m) |
| @@ -37,6 +39,10 @@ class Monoid m => Module m where | |||
| 37 | -- ^ Calculate a representation of an element of 'Domain m' in 'Del m' | 39 | -- ^ Calculate a representation of an element of 'Domain m' in 'Del m' |
| 38 | -- | 40 | -- |
| 39 | -- prop> init `apply` divInit m = m | 41 | -- prop> init `apply` divInit m = m |
| 42 | |||
| 43 | infixl 5 `apply'` | ||
| 44 | apply' :: Module m => Maybe (Domain m) -> m -> Maybe (Domain m) | ||
| 45 | apply' md e = flip apply e =<< md | ||
| 40 | \end{code} | 46 | \end{code} |
| 41 | \end{defn} | 47 | \end{defn} |
| 42 | 48 | ||
diff --git a/edit-lens/src/Data/String/DFST.hs b/edit-lens/src/Data/String/DFST.hs index 8a22dd3..75ca1cd 100644 --- a/edit-lens/src/Data/String/DFST.hs +++ b/edit-lens/src/Data/String/DFST.hs | |||
| @@ -8,7 +8,7 @@ Description: Deterministic finite state transducers | |||
| 8 | -} | 8 | -} |
| 9 | module Data.String.DFST | 9 | module Data.String.DFST |
| 10 | ( DFST(..) | 10 | ( DFST(..) |
| 11 | , runDFST | 11 | , runDFST, runDFST' |
| 12 | ) where | 12 | ) where |
| 13 | 13 | ||
| 14 | import Data.Map.Strict (Map, (!?)) | 14 | import Data.Map.Strict (Map, (!?)) |
| @@ -17,6 +17,8 @@ import qualified Data.Map.Strict as Map | |||
| 17 | import Data.Set (Set) | 17 | import Data.Set (Set) |
| 18 | import qualified Data.Set as Set | 18 | import qualified Data.Set as Set |
| 19 | 19 | ||
| 20 | import Control.Monad | ||
| 21 | |||
| 20 | data DFST state = DFST | 22 | data DFST state = DFST |
| 21 | { stInitial :: state | 23 | { stInitial :: state |
| 22 | , stTransition :: Map (state, Char) (state, Maybe Char) | 24 | , stTransition :: Map (state, Char) (state, Maybe Char) |
| @@ -25,14 +27,13 @@ data DFST state = DFST | |||
| 25 | } | 27 | } |
| 26 | 28 | ||
| 27 | runDFST :: forall state. Ord state => DFST state -> String -> Maybe String | 29 | runDFST :: forall state. Ord state => DFST state -> String -> Maybe String |
| 28 | runDFST DFST{..} str = ($ []) <$> go stInitial str id | 30 | runDFST dfst@DFST{..} str = let (finalState, str') = runDFST' dfst stInitial str id |
| 29 | where | 31 | in str' "" <$ guard (finalState `Set.member` stAccept) |
| 30 | go :: state -> String -> (String -> String) -> Maybe (String -> String) | 32 | |
| 31 | go st [] acc | 33 | runDFST' :: forall state. Ord state => DFST state -> state -> String -> (String -> String) -> (state, (String -> String)) |
| 32 | | st `Set.member` stAccept = Just acc | 34 | runDFST' _ st [] acc = (st, acc) |
| 33 | | otherwise = Nothing | 35 | runDFST' dfst@DFST{..} st (c:cs) acc |
| 34 | go st (c:cs) acc | 36 | | Just (st', mc') <- stTransition !? (st, c) |
| 35 | | Just (st', mc') <- stTransition !? (st, c) | 37 | = runDFST' dfst st' cs $ acc . maybe id (:) mc' |
| 36 | = go st' cs $ acc . maybe id (:) mc' | 38 | | otherwise |
| 37 | | otherwise | 39 | = runDFST' dfst st cs acc |
| 38 | = go st cs acc | ||
diff --git a/edit-lens/src/Data/String/DFST/Lens.lhs b/edit-lens/src/Data/String/DFST/Lens.lhs new file mode 100644 index 0000000..52c80d0 --- /dev/null +++ b/edit-lens/src/Data/String/DFST/Lens.lhs | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | \begin{code} | ||
| 2 | {-# LANGUAGE TupleSections | ||
| 3 | #-} | ||
| 4 | |||
| 5 | module Data.String.DFST.Lens | ||
| 6 | ( | ||
| 7 | ) where | ||
| 8 | |||
| 9 | import Data.String.DFST | ||
| 10 | import Control.Lens.Edit | ||
| 11 | import Control.Edit | ||
| 12 | |||
| 13 | import Numeric.Natural | ||
| 14 | import Data.Sequence (Seq((:<|), (:|>))) | ||
| 15 | import qualified Data.Sequence as Seq | ||
| 16 | |||
| 17 | data StringEdit = Insert Natural Char | ||
| 18 | | Delete Natural | ||
| 19 | deriving (Eq, Ord, Show, Read) | ||
| 20 | |||
| 21 | data StringEdits = StringEdits (Seq StringEdit) | ||
| 22 | | SEFail | ||
| 23 | deriving (Eq, Ord, Show, Read) | ||
| 24 | |||
| 25 | insert :: Natural -> Char -> StringEdits | ||
| 26 | insert n c = StringEdits . Seq.singleton $ Insert n c | ||
| 27 | |||
| 28 | delete :: Natural -> StringEdits | ||
| 29 | delete n = StringEdits . Seq.singleton $ Delete n | ||
| 30 | |||
| 31 | instance Monoid StringEdits where | ||
| 32 | mempty = StringEdits Seq.empty | ||
| 33 | SEFail `mappend` _ = SEFail | ||
| 34 | _ `mappend` SEFail = SEFail | ||
| 35 | (StringEdits Seq.Empty) `mappend` x = x | ||
| 36 | x `mappend` (StringEdits Seq.Empty) = x | ||
| 37 | (StringEdits x@(bs :|> b)) `mappend` (StringEdits y@(a :<| as)) | ||
| 38 | | (Insert n _) <- a | ||
| 39 | , (Delete n') <- b | ||
| 40 | , n == n' | ||
| 41 | = StringEdits bs `mappend` StringEdits as | ||
| 42 | | otherwise = StringEdits $ x `mappend` y | ||
| 43 | |||
| 44 | instance Module StringEdits where | ||
| 45 | type Domain StringEdits = String | ||
| 46 | apply str SEFail = Nothing | ||
| 47 | apply str (StringEdits Seq.Empty) = Just str | ||
| 48 | apply str (StringEdits (es :|> Insert n c)) = (flip apply) (StringEdits es) =<< go str n c | ||
| 49 | where | ||
| 50 | go [] n c | ||
| 51 | | n == 0 = Just [c] | ||
| 52 | | otherwise = Nothing | ||
| 53 | go str@(x:xs) n c | ||
| 54 | | n == 0 = Just $ c : str | ||
| 55 | | otherwise = (x:) <$> go xs (pred n) c | ||
| 56 | apply str (StringEdits (es :|> Delete n)) = (flip apply) (StringEdits es) =<< go str n | ||
| 57 | where | ||
| 58 | go [] _ = Nothing | ||
| 59 | go (x:xs) n | ||
| 60 | | n == 0 = Just xs | ||
| 61 | | otherwise = (x:) <$> go xs (pred n) | ||
| 62 | |||
| 63 | init = "" | ||
| 64 | divInit = StringEdits . Seq.unfoldl go . (0,) | ||
| 65 | where | ||
| 66 | go (_, []) = Nothing | ||
| 67 | go (n, (c:cs)) = Just ((succ n, cs), Insert n c) | ||
| 68 | |||
| 69 | data DFSTAction state = DFSTBranch (Map state (state, String)) (DFSTAction state) (DFSTAction state) | ||
| 70 | | DFSTLeaf | ||
| 71 | |||
| 72 | dfstLens :: forall state. Ord state => DFST state -> EditLens (DFSTAction state) StringEdits StringEdits | ||
| 73 | dfstLens DFST{..} = EditLens ground propR propL | ||
| 74 | where | ||
| 75 | ground :: DFSTAction state | ||
| 76 | ground = DFSTLeaf | ||
| 77 | |||
| 78 | propR :: (DFSTAction state, StringEdits) -> (DFSTAction state, StringEdits) | ||
| 79 | propR = undefined | ||
| 80 | propL :: (DFSTAction state, StringEdits) -> (DFSTAction state, StringEdits) | ||
| 81 | propL = undefined | ||
| 82 | \end{code} | ||
