diff options
Diffstat (limited to 'edit-lens/src/Control/FST.lhs')
-rw-r--r-- | edit-lens/src/Control/FST.lhs | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/edit-lens/src/Control/FST.lhs b/edit-lens/src/Control/FST.lhs index 4f1f364..9298e11 100644 --- a/edit-lens/src/Control/FST.lhs +++ b/edit-lens/src/Control/FST.lhs | |||
@@ -24,11 +24,11 @@ import qualified Data.Set as Set | |||
24 | import Data.Sequence (Seq) | 24 | import Data.Sequence (Seq) |
25 | import qualified Data.Sequence as Seq | 25 | import qualified Data.Sequence as Seq |
26 | 26 | ||
27 | import Data.Maybe (mapMaybe, fromMaybe) | 27 | import Data.Maybe (mapMaybe, fromMaybe, isJust, fromJust) |
28 | 28 | ||
29 | import Numeric.Natural | 29 | import Numeric.Natural |
30 | 30 | ||
31 | import Control.Lens.TH | 31 | import Control.Lens |
32 | 32 | ||
33 | import Control.Monad.State.Strict | 33 | import Control.Monad.State.Strict |
34 | 34 | ||
@@ -59,6 +59,55 @@ instance (Show state, Show input, Show output) => Pretty (FST state input output | |||
59 | list :: [PP.Doc] -> PP.Doc | 59 | list :: [PP.Doc] -> PP.Doc |
60 | list = PP.encloseSep (PP.lbracket PP.<> PP.space) (PP.space PP.<> PP.rbracket) (PP.comma PP.<> PP.space) | 60 | list = PP.encloseSep (PP.lbracket PP.<> PP.space) (PP.space PP.<> PP.rbracket) (PP.comma PP.<> PP.space) |
61 | 61 | ||
62 | runFST :: forall input output state. (Ord input, Ord output, Ord state) => FST state input output -> Seq input -> [Seq output] | ||
63 | runFST = fmap (map $ catMaybes . fmap (view _2) . view _2) . runFST' | ||
64 | where | ||
65 | catMaybes = fmap fromJust . Seq.filter isJust | ||
66 | |||
67 | runFST' :: forall input output state. (Ord input, Ord output, Ord state) | ||
68 | => FST state input output | ||
69 | -> Seq input | ||
70 | -> [(state, Seq (state, Maybe output))] -- ^ Tuples of initial state and chosen transitions; not neccessarily finite | ||
71 | -- ^ Compute all possible runs on the given input | ||
72 | runFST' fst Seq.Empty = guardAccept $ (\(_, st, _) -> (st, Seq.Empty)) <$> step fst Nothing Nothing | ||
73 | runFST' fst cs = guardAccept $ do | ||
74 | initial <- view _2 <$> step fst Nothing Nothing | ||
75 | go (initial, Seq.Empty) cs | ||
76 | where | ||
77 | guardAccept res = do | ||
78 | (initial, path) <- res | ||
79 | let | ||
80 | finalState | ||
81 | | (_ :> (st, _)) <- path = st | ||
82 | | otherwise = initial | ||
83 | guard $ finalState `Set.member` stAccept | ||
84 | return res | ||
85 | |||
86 | go :: (state, Seq (state, Maybe output)) -> Seq input-> [(state, Seq (state, Maybe output))] | ||
87 | go (initial, path) cs = do | ||
88 | let | ||
89 | current | ||
90 | | (_ :> (st, _)) <- path = st | ||
91 | | otherwise = initial | ||
92 | (head, next, out) <- step fst (Just current) (Seq.lookup 0 cs) | ||
93 | let | ||
94 | nPath = path :> (next, out) | ||
95 | ncs = maybe id (:<) head cs | ||
96 | go (initial, nPath) ncs | ||
97 | |||
98 | |||
99 | step :: forall input output state. (Ord input, Ord output, Ord state) | ||
100 | => FST state input output | ||
101 | -> Maybe state -- ^ Current state | ||
102 | -> Maybe input -- ^ Head of remaining input | ||
103 | -> [(Maybe input, state, Maybe output)] -- ^ Tuples of unconsumed input, next state, and produced output | ||
104 | step FST{..} Nothing inS = (\s -> (inS, s, Nothing)) <$> Set.toList stInitial | ||
105 | step FST{..} (Just c) inS = let | ||
106 | consuming = fromMaybe Set.empty $ Map.lookup (c, inS) stTransition | ||
107 | unconsuming = fromMaybe Set.empty $ Map.lookup (c, Nothing) stTransition | ||
108 | in Set.toList $ Set.map (\(n, mOut) -> (Nothing, n, mOut)) consuming `Set.union` Set.map (\(n, mOut) -> (inS, n, mOut)) unconsuming | ||
109 | |||
110 | |||
62 | wordFST :: forall input output. Seq output -> FST Natural input output | 111 | wordFST :: forall input output. Seq output -> FST Natural input output |
63 | -- ^ @wordFST str@ is the linear FST generating @str@ as output when given no input | 112 | -- ^ @wordFST str@ is the linear FST generating @str@ as output when given no input |
64 | wordFST outs = FST | 113 | wordFST outs = FST |