summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--edit-lens/src/Control/DFST/Lens.lhs77
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 @@
7module Control.DFST.Lens 7module 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((:<|), (:|>)))
32import qualified Data.Sequence as Seq 32import qualified Data.Sequence as Seq
33import Data.Set (Set) 33import Data.Set (Set)
34import qualified Data.Set as Set 34import qualified Data.Set as Set
35import Data.Map (Map) 35import Data.Map.Strict (Map)
36import qualified Data.Map as Map 36import qualified Data.Map.Strict as Map
37 37
38import Data.Compositions.Snoc (Compositions) 38import Data.Compositions.Snoc (Compositions)
39import qualified Data.Compositions.Snoc as Comp 39import qualified Data.Compositions.Snoc as Comp
@@ -43,7 +43,7 @@ import qualified Data.Algorithm.Diff as Diff
43 43
44import Data.Monoid 44import Data.Monoid
45import Data.Bool (bool) 45import Data.Bool (bool)
46import Data.Maybe (fromMaybe, maybeToList, listToMaybe, catMaybes) 46import Data.Maybe (fromMaybe, maybeToList, listToMaybe, catMaybes, isNothing, isJust)
47import Data.Function (on) 47import Data.Function (on)
48import Data.Foldable (toList) 48import Data.Foldable (toList)
49import Data.List (partition) 49import Data.List (partition)
@@ -107,6 +107,9 @@ insert n c = StringEdits . Seq.singleton $ Insert n c
107delete :: Natural -> StringEdits char 107delete :: Natural -> StringEdits char
108delete n = StringEdits . Seq.singleton $ Delete n 108delete n = StringEdits . Seq.singleton $ Delete n
109 109
110replace :: Natural -> char -> StringEdits char
111replace n c = insert n c <> delete n
112
110instance Monoid (StringEdits char) where 113instance 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
198dfstaConsumes' :: DFSTComplement state input output -> Seq input 201dfstaConsumes' :: DFSTComplement state input output -> Seq input
199dfstaConsumes' = dfstaConsumes . Comp.composed 202dfstaConsumes' = dfstaConsumes . Comp.composed
200 203
204dfstaProduces :: DFST state input output -> DFSTComplement state input output -> Seq output
205dfstaProduces DFST{..} = snd . flip runDFSTAction' stInitial
206
201type Debug state input output = (Show state, Show input, Show output) 207type Debug state input output = (Show state, Show input, Show output)
202 208
203type LState state input output = (Natural, (state, Maybe (input, Natural))) 209type 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