1
1
mirror of https://github.com/github/semantic.git synced 2024-12-22 14:21:31 +03:00

Compute reverse d-paths in the same manner as forward ones.

This commit is contained in:
Rob Rix 2017-03-10 16:15:50 -05:00
parent 781a525f87
commit f1ad91a346

View File

@ -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