From f1ad91a3467360f8f51854a6f5b775225c3bca51 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Fri, 10 Mar 2017 16:15:50 -0500 Subject: [PATCH] Compute reverse d-paths in the same manner as forward ones. --- src/SES/Myers.hs | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/SES/Myers.hs b/src/SES/Myers.hs index 4094cd50c..a98a9a187 100644 --- a/src/SES/Myers.hs +++ b/src/SES/Myers.hs @@ -106,16 +106,16 @@ decompose myers = let ?callStack = popCallStack callStack in case myers of <$> for [negate d, negate d + 2 .. d] (\ k -> do forwardEndpoint <- findDPath graph Forward (EditDistance d) (Diagonal k) backwardV <- gets backward - let reverseEndpoint = backwardV `at` k - if odd delta && k `inInterval` (delta - pred d, delta + pred d) && overlaps forwardEndpoint reverseEndpoint then + let reverseEndpoint = let x = backwardV `at` k in Endpoint x (x - k) + if odd delta && k `inInterval` (delta - pred d, delta + pred d) && overlaps graph forwardEndpoint reverseEndpoint then return (Just (Snake reverseEndpoint forwardEndpoint, EditDistance $ 2 * d - 1)) else continue) <*> for [negate d, negate d + 2 .. d] (\ k -> do reverseEndpoint <- findDPath graph Reverse (EditDistance d) (Diagonal (k + delta)) forwardV <- gets forward - let forwardEndpoint = forwardV `at` (k + delta) - if even delta && (k + delta) `inInterval` (negate d, d) && overlaps forwardEndpoint reverseEndpoint then + let forwardEndpoint = let x = forwardV `at` (k + delta) in Endpoint x (x - k) + if even delta && (k + delta) `inInterval` (negate d, d) && overlaps graph forwardEndpoint reverseEndpoint then return (Just (Snake reverseEndpoint forwardEndpoint, EditDistance $ 2 * d)) else continue) @@ -125,10 +125,10 @@ decompose myers = let ?callStack = popCallStack callStack in case myers of eq <- getEq let prev = v `at` pred k let next = v `at` succ k - let xy = if k == negate d || k /= d && x prev < x next + let x = if k == negate d || k /= d && prev < next then next - else let x' = succ (x prev) in Endpoint x' (x' - k) - let Endpoint x' y' = slide 1 eq xy + else succ prev + let Endpoint x' y' = slide Reverse eq (Endpoint x (x - k)) setForward (v Vector.// [(maxD + k, x')]) return (Endpoint x' y') @@ -137,10 +137,10 @@ decompose myers = let ?callStack = popCallStack callStack in case myers of eq <- getEq let prev = v `at` pred k let next = v `at` succ k - let xy = if k == negate d || k /= d && x prev < x next + let x = if k == negate d || k /= d && prev < next then next - else let x' = succ (x prev) in Endpoint x' (x' - k) - let Endpoint x' y' = slide (negate 1) eq xy + else succ prev + let Endpoint x' y' = slide Reverse eq (Endpoint x (x - k)) setBackward (v Vector.// [(maxD + k, x')]) return (Endpoint x' y') @@ -151,14 +151,17 @@ decompose myers = let ?callStack = popCallStack callStack in case myers of delta = n - m maxD = (m + n) `ceilDiv` 2 - at v k = let x = v ! maxD + k in Endpoint x (x - k) + at v k = v ! maxD + k - slide by eq (Endpoint x y) + slide dir eq (Endpoint x y) | x >= 0, x < length as , y >= 0, y < length bs - , (as ! x) `eq` (bs ! y) = slide by eq (Endpoint (x + by) (y + by)) + , nth dir as x `eq` nth dir bs y = slide dir eq (Endpoint (succ x) (succ y)) | otherwise = Endpoint x y + nth Forward v i = v ! i + nth Reverse v i = v ! (length v - 1 - i) + -- Smart constructors @@ -188,8 +191,8 @@ setForward v = modify (\ s -> s { forward = v }) setBackward :: Vector.Vector Int -> Myers a () setBackward v = modify (\ s -> s { backward = v }) -overlaps :: Endpoint -> Endpoint -> Bool -overlaps (Endpoint x y) (Endpoint u v) = x - y == u - v && x <= u +overlaps :: EditGraph a -> Endpoint -> Endpoint -> Bool +overlaps (EditGraph as _) (Endpoint x y) (Endpoint u v) = x - y == u - v && x <= length as - u inInterval :: Ord a => a -> (a, a) -> Bool inInterval k (lower, upper) = k >= lower && k <= upper