diff options
Diffstat (limited to 'edit-lens/src')
| -rw-r--r-- | edit-lens/src/Control/DFST/Lens.lhs | 77 |
1 files changed, 55 insertions, 22 deletions
diff --git a/edit-lens/src/Control/DFST/Lens.lhs b/edit-lens/src/Control/DFST/Lens.lhs index 3959b39..95be34e 100644 --- a/edit-lens/src/Control/DFST/Lens.lhs +++ b/edit-lens/src/Control/DFST/Lens.lhs | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | module Control.DFST.Lens | 7 | module Control.DFST.Lens |
| 8 | ( StringEdit(..) | 8 | ( StringEdit(..) |
| 9 | , StringEdits(..) | 9 | , StringEdits(..) |
| 10 | , insert, delete | 10 | , insert, delete, replace |
| 11 | , DFSTAction(..), DFSTComplement | 11 | , DFSTAction(..), DFSTComplement |
| 12 | , dfstLens | 12 | , dfstLens |
| 13 | , module Control.DFST | 13 | , module Control.DFST |
| @@ -32,8 +32,8 @@ import Data.Sequence (Seq((:<|), (:|>))) | |||
| 32 | import qualified Data.Sequence as Seq | 32 | import qualified Data.Sequence as Seq |
| 33 | import Data.Set (Set) | 33 | import Data.Set (Set) |
| 34 | import qualified Data.Set as Set | 34 | import qualified Data.Set as Set |
| 35 | import Data.Map (Map) | 35 | import Data.Map.Strict (Map) |
| 36 | import qualified Data.Map as Map | 36 | import qualified Data.Map.Strict as Map |
| 37 | 37 | ||
| 38 | import Data.Compositions.Snoc (Compositions) | 38 | import Data.Compositions.Snoc (Compositions) |
| 39 | import qualified Data.Compositions.Snoc as Comp | 39 | import qualified Data.Compositions.Snoc as Comp |
| @@ -43,7 +43,7 @@ import qualified Data.Algorithm.Diff as Diff | |||
| 43 | 43 | ||
| 44 | import Data.Monoid | 44 | import Data.Monoid |
| 45 | import Data.Bool (bool) | 45 | import Data.Bool (bool) |
| 46 | import Data.Maybe (fromMaybe, maybeToList, listToMaybe, catMaybes) | 46 | import Data.Maybe (fromMaybe, maybeToList, listToMaybe, catMaybes, isNothing, isJust) |
| 47 | import Data.Function (on) | 47 | import Data.Function (on) |
| 48 | import Data.Foldable (toList) | 48 | import Data.Foldable (toList) |
| 49 | import Data.List (partition) | 49 | import Data.List (partition) |
| @@ -107,6 +107,9 @@ insert n c = StringEdits . Seq.singleton $ Insert n c | |||
| 107 | delete :: Natural -> StringEdits char | 107 | delete :: Natural -> StringEdits char |
| 108 | delete n = StringEdits . Seq.singleton $ Delete n | 108 | delete n = StringEdits . Seq.singleton $ Delete n |
| 109 | 109 | ||
| 110 | replace :: Natural -> char -> StringEdits char | ||
| 111 | replace n c = insert n c <> delete n | ||
| 112 | |||
| 110 | instance Monoid (StringEdits char) where | 113 | instance Monoid (StringEdits char) where |
| 111 | mempty = StringEdits Seq.empty | 114 | mempty = StringEdits Seq.empty |
| 112 | SEFail `mappend` _ = SEFail | 115 | SEFail `mappend` _ = SEFail |
| @@ -198,6 +201,9 @@ runDFSTAction' = runDFSTAction . Comp.composed | |||
| 198 | dfstaConsumes' :: DFSTComplement state input output -> Seq input | 201 | dfstaConsumes' :: DFSTComplement state input output -> Seq input |
| 199 | dfstaConsumes' = dfstaConsumes . Comp.composed | 202 | dfstaConsumes' = dfstaConsumes . Comp.composed |
| 200 | 203 | ||
| 204 | dfstaProduces :: DFST state input output -> DFSTComplement state input output -> Seq output | ||
| 205 | dfstaProduces DFST{..} = snd . flip runDFSTAction' stInitial | ||
| 206 | |||
| 201 | type Debug state input output = (Show state, Show input, Show output) | 207 | type Debug state input output = (Show state, Show input, Show output) |
| 202 | 208 | ||
| 203 | type LState state input output = (Natural, (state, Maybe (input, Natural))) | 209 | type LState state input output = (Natural, (state, Maybe (input, Natural))) |
| @@ -245,19 +251,22 @@ dfstLens dfst@DFST{..} = EditLens ground propR propL | |||
| 245 | max = fromIntegral $ Seq.length newOut | 251 | max = fromIntegral $ Seq.length newOut |
| 246 | all = 0 Int.... max | 252 | all = 0 Int.... max |
| 247 | runCandidates :: Interval Natural -- ^ Departure from complement-run only permitted within interval (to guarantee locality) | 253 | runCandidates :: Interval Natural -- ^ Departure from complement-run only permitted within interval (to guarantee locality) |
| 248 | -> [(Seq ((Natural, (state, Maybe (input, Natural))), Maybe output), StringEdits input)] | 254 | -> [ ( Seq (LState state input output, Maybe output) -- ^ Computed run |
| 249 | runCandidates focus = continueRun (Seq.empty, mempty) c 0 | 255 | , StringEdits input |
| 256 | , DFSTComplement state input output | ||
| 257 | ) | ||
| 258 | ] | ||
| 259 | runCandidates focus = continueRun (Seq.empty, mempty) (c, mempty) 0 | ||
| 250 | where | 260 | where |
| 251 | -- TODO: generate new complement | ||
| 252 | continueRun :: (Seq (LState state input output, Maybe output), StringEdits input) | 261 | continueRun :: (Seq (LState state input output, Maybe output), StringEdits input) |
| 253 | -> DFSTComplement state input output | 262 | -> (DFSTComplement state input output, DFSTComplement state input output) -- ^ Zipper into complement |
| 254 | -> Natural -- ^ Input position | 263 | -> Natural -- ^ Input position |
| 255 | -> [(Seq (LState state input output, Maybe output), StringEdits input)] | 264 | -> [(Seq (LState state input output, Maybe output), StringEdits input, DFSTComplement state input output)] |
| 256 | continueRun (run, inEdits) c' inP = do | 265 | continueRun (run, inEdits) (c', remC) inP = do |
| 257 | let | 266 | let |
| 258 | pos :: Natural | 267 | pos :: Natural |
| 259 | pos = fromIntegral $ Comp.length c - Comp.length c' | 268 | pos = fromIntegral $ Comp.length c - Comp.length c' |
| 260 | (c'', step) = Comp.splitAt (pred $ Comp.length c') c' -- TODO: unsafe | 269 | (c'', step) = Comp.splitAt (pred $ Comp.length c') c' -- TODO: unsafe? |
| 261 | current :: LState state input output | 270 | current :: LState state input output |
| 262 | current | 271 | current |
| 263 | | Seq.Empty <- run = (0, (stInitial, Nothing)) | 272 | | Seq.Empty <- run = (0, (stInitial, Nothing)) |
| @@ -276,26 +285,50 @@ dfstLens dfst@DFST{..} = EditLens ground propR propL | |||
| 276 | in Map.foldrWithKey go [] $ FST.stTransition outFST | 285 | in Map.foldrWithKey go [] $ FST.stTransition outFST |
| 277 | isPreferred :: (LState state input output, Maybe input, Maybe output) -> Bool | 286 | isPreferred :: (LState state input output, Maybe input, Maybe output) -> Bool |
| 278 | isPreferred ((_, (st, Nothing)), inS, _) = st == next' && (fromMaybe True $ (==) <$> oldIn <*> inS) | 287 | isPreferred ((_, (st, Nothing)), inS, _) = st == next' && (fromMaybe True $ (==) <$> oldIn <*> inS) |
| 279 | isPreferred (st, _, _) = any isPreferred $ outgoing st | 288 | isPreferred (st, _, _) = any isPreferred $ outgoing st -- By construction of `outFST`, `outgoing st` is a singleton |
| 280 | (preferred, alternate) = partition isPreferred $ outgoing current | 289 | (preferred, alternate) = partition isPreferred $ outgoing current |
| 281 | assocEdit :: (LState state input output, Maybe input, Maybe output) -> [(DFSTComplement state input output, StringEdits input, Natural)] | 290 | assocEdit :: (LState state input output, Maybe input, Maybe output) -- ^ Transition |
| 291 | -> [ ( (DFSTComplement state input output, DFSTComplement state input output) -- ^ new `(c', remC)`, i.e. complement-zipper `(c', remC)` but with edit applied | ||
| 292 | , StringEdits input | ||
| 293 | , Natural | ||
| 294 | ) | ||
| 295 | ] | ||
| 282 | assocEdit (_, Just inS, _) | 296 | assocEdit (_, Just inS, _) |
| 283 | | oldIn == Just inS = [(c'', mempty, succ inP)] | 297 | | oldIn == Just inS = [((c'', step <> remC), mempty, succ inP)] |
| 284 | | otherwise = [(c', insert inP inS, succ inP), (c'', insert inP inS <> delete inP, succ inP)] | 298 | | isJust oldIn = [((c'', altStep inS <> remC), replace inP inS, succ inP), ((c', altStep inS <> remC), insert inP inS, succ inP)] |
| 285 | assocEdit (_, Nothing, _) = [(c', mempty, inP)] | 299 | | otherwise = [((c', altStep inS <> remC), insert inP inS, succ inP)] |
| 300 | assocEdit (_, Nothing, _) = [((c', remC), mempty, inP)] -- TODO: is this correct? | ||
| 301 | altStep :: input -> DFSTComplement state input output | ||
| 302 | altStep inS = Comp.singleton DFSTAction{..} | ||
| 303 | where | ||
| 304 | dfstaConsumes = Seq.singleton inS | ||
| 305 | runDFSTAction x = runDFST' dfst x (pure inS) Seq.empty | ||
| 286 | options | 306 | options |
| 287 | | pos `Int.member` focus = preferred ++ alternate | 307 | | pos `Int.member` focus = preferred ++ alternate |
| 288 | | otherwise = preferred | 308 | | otherwise = preferred |
| 289 | choice@(next, inS, outS) <- options | 309 | choice@(next, inS, outS) <- options |
| 290 | (c', inEdits', inP') <- assocEdit choice | 310 | ((c3, remC'), inEdits', inP') <- assocEdit choice |
| 291 | let acc = (run :> (next, outS), inEdits' <> inEdits) | 311 | -- let |
| 292 | bool id (acc :) (next `Set.member` FST.stAccept outFST) $ continueRun acc c' inP' | 312 | -- -- | Replace prefix of old complement to reflect current candidate |
| 293 | 313 | -- -- TODO: smarter? | |
| 314 | -- (_, ((c3 <>) -> newComplement')) = Comp.splitAt (Comp.length c') c -- TODO: unsafe? | ||
| 315 | -- acc = (run :> (next, outS), inEdits' <> inEdits, newComplement') | ||
| 316 | -- dropSuffix = mconcat (replicate (Seq.length $ dfstaConsumes' c3) $ delete inP') | ||
| 317 | -- fin | ||
| 318 | -- | (trans, inEs, newComplement) <- acc = (trans, dropSuffix <> inEs, newComplement) | ||
| 319 | let | ||
| 320 | acc = (run :> (next, outS), inEdits' <> inEdits) | ||
| 321 | dropSuffix = mconcat (replicate (Seq.length $ dfstaConsumes' c3) $ delete inP') | ||
| 322 | fin | ||
| 323 | | (trans, inEs) <- acc = (trans, dropSuffix <> inEs, remC') | ||
| 324 | bool id (fin :) (next `Set.member` FST.stAccept outFST) $ continueRun acc (c3, remC') inP' | ||
| 294 | 325 | ||
| 295 | -- Properties of the edits computed are determined mostly by the order candidates are generated below | 326 | -- Properties of the edits computed are determined mostly by the order candidates are generated below |
| 296 | chosenRun <- (\xs -> foldr (\x f -> x `seq` f) listToMaybe xs $ xs) $ traceShowId fragmentIntervals >>= (\x -> traceShowId <$> runCandidates x) | 327 | -- (_, inEs, c') <- (\xs -> foldr (\x f -> x `seq` f) listToMaybe xs $ xs) $ traceShowId fragmentIntervals >>= (\x -> (\y@(y1, y2, _) -> traceShow (y1, y2) y) <$> runCandidates x) |
| 328 | |||
| 329 | (_, inEs, c') <- listToMaybe $ runCandidates =<< fragmentIntervals | ||
| 297 | 330 | ||
| 298 | return $ traceShow chosenRun undefined | 331 | return (c', inEs) |
| 299 | where | 332 | where |
| 300 | (_, prevOut) = runDFSTAction' c stInitial | 333 | (_, prevOut) = runDFSTAction' c stInitial |
| 301 | 334 | ||
