--  Copyright (C) 2002-2003 David Roundy
--
--  This program is free software; you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation; either version 2, or (at your option)
--  any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with this program; see the file COPYING.  If not, write to
--  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
--  Boston, MA 02110-1301, USA.

{-# OPTIONS_GHC -fno-warn-orphans #-}

module Darcs.Patch.V1.Commute
    (
      merge,
      merger, unravel,
      publicUnravel,
    )
       where

import Darcs.Prelude

import Control.Monad ( MonadPlus, mplus, msum, mzero, guard )
import Control.Applicative ( Alternative(..) )
import Data.Maybe ( fromMaybe )

import Darcs.Patch.Commute ( selfCommuter )
import Darcs.Patch.CommuteFn ( commuterIdFL, commuterFLId )
import Darcs.Util.Path ( AnchoredPath )
import Darcs.Patch.Invert ( invertRL )
import Darcs.Patch.Merge ( CleanMerge(..), Merge(..) )
import Darcs.Patch.Commute ( Commute(..) )
import Darcs.Patch.Invert ( Invert(..) )
import Darcs.Patch.Inspect ( PatchInspect(..) )
import Darcs.Patch.V1.Core ( RepoPatchV1(..),
                             isMerger,
                             mergerUndo )
import Darcs.Patch.CommuteNoConflicts
    ( CommuteNoConflicts(..)
    , mergeNoConflicts
    )
import Darcs.Patch.Conflict
  ( Conflict(..), combineConflicts, mangleOrFail
  )
import Darcs.Patch.Unwind ( Unwind(..), Unwound(..), mkUnwound )
import Darcs.Patch.Effect ( Effect(..) )
import Darcs.Patch.FileHunk ( IsHunk(..) )
import Darcs.Patch.Prim ( PrimPatch, is_filepatch )
import Darcs.Patch.Permutations
    ( headPermutationsRL
    , simpleHeadPermutationsFL
    , removeFL
    )
import Darcs.Util.Printer ( renderString, text, vcat, ($$) )
import Darcs.Patch.V1.Show ( showPatch_ )
import Data.List ( nub )
import Data.List.Ordered ( nubSort )
import Darcs.Patch.Summary
    ( Summary(..)
    , ConflictState(..)
    , IsConflictedPrim(..)
    )
import Darcs.Patch.Witnesses.Sealed
    ( Sealed(..) , mapSeal, unseal
    , FlippedSeal(..), mapFlipped, unsealFlipped
    )
import Darcs.Patch.Witnesses.Eq ( EqCheck(..), Eq2(..) )
import Darcs.Patch.Witnesses.Unsafe
    ( unsafeCoerceP, unsafeCoercePStart
    , unsafeCoercePEnd )
import Darcs.Patch.Witnesses.Ordered
    ( mapFL_FL, mapFL,
    FL(..), RL(..), (+>+),
    (:/\:)(..), (:\/:)(..), (:>)(..),
    lengthFL, mapRL,
    reverseFL, reverseRL, concatFL
    )

data Perhaps a = Unknown | Failed | Succeeded a

instance Functor Perhaps where
    fmap :: forall a b. (a -> b) -> Perhaps a -> Perhaps b
fmap a -> b
_ Perhaps a
Unknown = forall a. Perhaps a
Unknown
    fmap a -> b
_ Perhaps a
Failed = forall a. Perhaps a
Failed
    fmap a -> b
f (Succeeded a
x) = forall a. a -> Perhaps a
Succeeded (a -> b
f a
x)

instance Applicative Perhaps where
    pure :: forall a. a -> Perhaps a
pure = forall a. a -> Perhaps a
Succeeded
    Perhaps (a -> b)
_ <*> :: forall a b. Perhaps (a -> b) -> Perhaps a -> Perhaps b
<*> Perhaps a
Failed = forall a. Perhaps a
Failed
    Perhaps (a -> b)
_ <*> Perhaps a
Unknown = forall a. Perhaps a
Unknown
    Perhaps (a -> b)
Failed <*> Perhaps a
_ = forall a. Perhaps a
Failed
    Perhaps (a -> b)
Unknown <*> Perhaps a
_ = forall a. Perhaps a
Unknown
    Succeeded a -> b
f <*> Succeeded a
x = forall a. a -> Perhaps a
Succeeded (a -> b
f a
x)

instance  Monad Perhaps where
    (Succeeded a
x) >>= :: forall a b. Perhaps a -> (a -> Perhaps b) -> Perhaps b
>>= a -> Perhaps b
k =  a -> Perhaps b
k a
x
    Perhaps a
Failed   >>= a -> Perhaps b
_      =  forall a. Perhaps a
Failed
    Perhaps a
Unknown  >>= a -> Perhaps b
_      =  forall a. Perhaps a
Unknown
    return :: forall a. a -> Perhaps a
return              =  forall a. a -> Perhaps a
Succeeded

instance Alternative Perhaps where
    empty :: forall a. Perhaps a
empty = forall a. Perhaps a
Unknown
    Perhaps a
Unknown <|> :: forall a. Perhaps a -> Perhaps a -> Perhaps a
<|> Perhaps a
ys    = Perhaps a
ys
    Perhaps a
Failed  <|> Perhaps a
_     = forall a. Perhaps a
Failed
    (Succeeded a
x) <|> Perhaps a
_ = forall a. a -> Perhaps a
Succeeded a
x

instance  MonadPlus Perhaps where
    mzero :: forall a. Perhaps a
mzero = forall a. Perhaps a
Unknown
    mplus :: forall a. Perhaps a -> Perhaps a -> Perhaps a
mplus = forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>)

toMaybe :: Perhaps a -> Maybe a
toMaybe :: forall a. Perhaps a -> Maybe a
toMaybe (Succeeded a
x) = forall a. a -> Maybe a
Just a
x
toMaybe Perhaps a
_ = forall a. Maybe a
Nothing

toPerhaps :: Maybe a -> Perhaps a
toPerhaps :: forall a. Maybe a -> Perhaps a
toPerhaps (Just a
x) = forall a. a -> Perhaps a
Succeeded a
x
toPerhaps Maybe a
Nothing = forall a. Perhaps a
Failed

-- | 'cleverCommute' attempts to commute two patches @p1@ and @p2@, in their
-- original order, with the given commute function. If the commute function
-- doesn't know how to handle the patches (i.e. it returns Unknown as a
-- result), then we try again with @invert p2@ and @invert p1@ (inverting the
-- results, if succesful).
--
-- TODO: when can the first attempt fail, but the second not? What's so clever
-- in this function?
cleverCommute :: Invert prim => CommuteFunction prim -> CommuteFunction prim
cleverCommute :: forall (prim :: * -> * -> *).
Invert prim =>
CommuteFunction prim -> CommuteFunction prim
cleverCommute CommuteFunction prim
c (RepoPatchV1 prim wX wZ
p1 :> RepoPatchV1 prim wZ wY
p2) = case CommuteFunction prim
c (RepoPatchV1 prim wX wZ
p1 forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wZ wY
p2) of
    Succeeded (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
x -> forall a. a -> Perhaps a
Succeeded (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
x
    Perhaps ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
Failed -> forall a. Perhaps a
Failed
    Perhaps ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
Unknown -> case CommuteFunction prim
c (forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wZ wY
p2 forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wX wZ
p1) of
                 Succeeded (RepoPatchV1 prim wY wZ
ip1' :> RepoPatchV1 prim wZ wX
ip2') -> forall a. a -> Perhaps a
Succeeded (forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wZ wX
ip2' forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wY wZ
ip1')
                 Perhaps ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wY wX)
Failed -> forall a. Perhaps a
Failed
                 Perhaps ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wY wX)
Unknown -> forall a. Perhaps a
Unknown

-- | If we have two Filepatches which modify different files, we can return a
-- result early, since the patches trivially commute.
speedyCommute :: PrimPatch prim => CommuteFunction prim
speedyCommute :: forall (prim :: * -> * -> *).
PrimPatch prim =>
CommuteFunction prim
speedyCommute (RepoPatchV1 prim wX wZ
p1 :> RepoPatchV1 prim wZ wY
p2)
    | Just AnchoredPath
m1 <- forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
RepoPatchV1 prim wX wY -> Maybe AnchoredPath
isFilepatchMerger RepoPatchV1 prim wX wZ
p1
    , Just AnchoredPath
m2 <- forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
RepoPatchV1 prim wX wY -> Maybe AnchoredPath
isFilepatchMerger RepoPatchV1 prim wZ wY
p2
    , AnchoredPath
m1 forall a. Eq a => a -> a -> Bool
/= AnchoredPath
m2 = forall a. a -> Perhaps a
Succeeded (forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP RepoPatchV1 prim wZ wY
p2 forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP RepoPatchV1 prim wX wZ
p1)
    | Bool
otherwise = forall a. Perhaps a
Unknown

everythingElseCommute :: forall prim . PrimPatch prim => CommuteFunction prim
everythingElseCommute :: forall (prim :: * -> * -> *).
PrimPatch prim =>
CommuteFunction prim
everythingElseCommute (PP prim wX wZ
p1 :> PP prim wZ wY
p2) = forall a. Maybe a -> Perhaps a
toPerhaps forall a b. (a -> b) -> a -> b
$ do
    prim wX wZ
p2' :> prim wZ wY
p1' <- forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (prim wX wZ
p1 forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> prim wZ wY
p2)
    forall (m :: * -> *) a. Monad m => a -> m a
return (forall (prim :: * -> * -> *) wX wY.
prim wX wY -> RepoPatchV1 prim wX wY
PP prim wX wZ
p2' forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (prim :: * -> * -> *) wX wY.
prim wX wY -> RepoPatchV1 prim wX wY
PP prim wZ wY
p1')
everythingElseCommute (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
ps =
    forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum [ forall (prim :: * -> * -> *).
Invert prim =>
CommuteFunction prim -> CommuteFunction prim
cleverCommute forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
(:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
-> Perhaps ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
commuteRecursiveMerger      (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
ps
         , forall (prim :: * -> * -> *).
Invert prim =>
CommuteFunction prim -> CommuteFunction prim
cleverCommute forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
(:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
-> Perhaps ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
otherCommuteRecursiveMerger (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
ps
         ]

{-
Note that it must be true that

commutex (A^-1 A, P) = Just (P, A'^-1 A')

and

if commutex (A, B) == Just (B', A')
then commutex (B^-1, A^-1) == Just (A'^-1, B'^-1)
-}

unsafeMerger :: PrimPatch prim => String -> RepoPatchV1 prim wX wY -> RepoPatchV1 prim wX wZ -> RepoPatchV1 prim wA wB
unsafeMerger :: forall (prim :: * -> * -> *) wX wY wZ wA wB.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> RepoPatchV1 prim wA wB
unsafeMerger String
x RepoPatchV1 prim wX wY
p1 RepoPatchV1 prim wX wZ
p2 = forall (a :: * -> *) b. (forall wX. a wX -> b) -> Sealed a -> b
unseal forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP forall a b. (a -> b) -> a -> b
$ forall (prim :: * -> * -> *) wX wY wZ.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> Sealed (RepoPatchV1 prim wY)
merger String
x RepoPatchV1 prim wX wY
p1 RepoPatchV1 prim wX wZ
p2

-- | Attempt to commute two patches, the first of which is a Merger patch.
mergerCommute :: PrimPatch prim
              => (RepoPatchV1 prim :> RepoPatchV1 prim) wX wY -> Perhaps ((RepoPatchV1 prim :> RepoPatchV1 prim) wX wY)
mergerCommute :: forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
(:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
-> Perhaps ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
mergerCommute (RepoPatchV1 prim wX wZ
pA :> Merger FL (RepoPatchV1 prim) wZ wY
_ RL (RepoPatchV1 prim) wZ wB
_ RepoPatchV1 prim wC wZ
p1 RepoPatchV1 prim wC wD
p2)
    | forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
unsafeCompare RepoPatchV1 prim wX wZ
pA RepoPatchV1 prim wC wZ
p1 = forall a. a -> Perhaps a
Succeeded (forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart RepoPatchV1 prim wC wD
p2 forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (prim :: * -> * -> *) wX wY wZ wA wB.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> RepoPatchV1 prim wA wB
unsafeMerger String
"0.0" RepoPatchV1 prim wC wD
p2 RepoPatchV1 prim wC wZ
p1)
    | forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
unsafeCompare RepoPatchV1 prim wX wZ
pA (forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert (forall (prim :: * -> * -> *) wX wY wZ wA wB.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> RepoPatchV1 prim wA wB
unsafeMerger String
"0.0" RepoPatchV1 prim wC wD
p2 RepoPatchV1 prim wC wZ
p1)) = forall a. Perhaps a
Failed
mergerCommute (Merger FL (RepoPatchV1 prim) wX wZ
_ RL (RepoPatchV1 prim) wX wB
_ RepoPatchV1 prim wC wX
b' RepoPatchV1 prim wC wD
c'' :> Merger FL (RepoPatchV1 prim) wZ wY
_ RL (RepoPatchV1 prim) wZ wB
_ (Merger FL (RepoPatchV1 prim) wC wZ
_ RL (RepoPatchV1 prim) wC wB
_ RepoPatchV1 prim wC wC
c RepoPatchV1 prim wC wD
b) (Merger FL (RepoPatchV1 prim) wC wD
_ RL (RepoPatchV1 prim) wC wB
_ RepoPatchV1 prim wC wC
c' RepoPatchV1 prim wC wD
a))
    | forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
unsafeCompare RepoPatchV1 prim wC wX
b' RepoPatchV1 prim wC wD
b Bool -> Bool -> Bool
&& forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
unsafeCompare RepoPatchV1 prim wC wC
c RepoPatchV1 prim wC wC
c' Bool -> Bool -> Bool
&& forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
unsafeCompare RepoPatchV1 prim wC wC
c RepoPatchV1 prim wC wD
c'' =
        forall a. a -> Perhaps a
Succeeded ( forall (prim :: * -> * -> *) wX wY wZ wA wB.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> RepoPatchV1 prim wA wB
unsafeMerger String
"0.0" RepoPatchV1 prim wC wD
b (forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart RepoPatchV1 prim wC wD
a) forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:>
                    forall (prim :: * -> * -> *) wX wY wZ wA wB.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> RepoPatchV1 prim wA wB
unsafeMerger String
"0.0" (forall (prim :: * -> * -> *) wX wY wZ wA wB.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> RepoPatchV1 prim wA wB
unsafeMerger String
"0.0" RepoPatchV1 prim wC wD
b (forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart RepoPatchV1 prim wC wD
a)) (forall (prim :: * -> * -> *) wX wY wZ wA wB.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> RepoPatchV1 prim wA wB
unsafeMerger String
"0.0" RepoPatchV1 prim wC wD
b RepoPatchV1 prim wC wC
c)
                  )
mergerCommute (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
_ = forall a. Perhaps a
Unknown

instance PrimPatch prim => CleanMerge (RepoPatchV1 prim) where
    cleanMerge :: forall wX wY.
(:\/:) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
-> Maybe ((:/\:) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
cleanMerge = forall (p :: * -> * -> *) wX wY.
(Invert p, CommuteNoConflicts p) =>
(:\/:) p p wX wY -> Maybe ((:/\:) p p wX wY)
mergeNoConflicts

instance PrimPatch prim => Merge (RepoPatchV1 prim) where
    merge :: forall wX wY.
(:\/:) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
-> (:/\:) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
merge (RepoPatchV1 prim wZ wX
p1 :\/: RepoPatchV1 prim wZ wY
p2) =
        case forall (p :: * -> * -> *) wX wY.
(Invert p, CommuteNoConflicts p) =>
(:\/:) p p wX wY -> Maybe ((:/\:) p p wX wY)
mergeNoConflicts (RepoPatchV1 prim wZ wX
p1 forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wZ wX -> a2 wZ wY -> (:\/:) a1 a2 wX wY
:\/: RepoPatchV1 prim wZ wY
p2) of
            Just (:/\:) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
r -> (:/\:) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
r
            Maybe ((:/\:) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
Nothing ->
                case forall (prim :: * -> * -> *) wX wY wZ.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> Sealed (RepoPatchV1 prim wY)
merger String
"0.0" RepoPatchV1 prim wZ wX
p1 RepoPatchV1 prim wZ wY
p2 of
                    Sealed RepoPatchV1 prim wX wX
p2' ->
                        case forall (prim :: * -> * -> *) wX wY wZ.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> Sealed (RepoPatchV1 prim wY)
merger String
"0.0" RepoPatchV1 prim wZ wY
p2 RepoPatchV1 prim wZ wX
p1 of
                            Sealed RepoPatchV1 prim wY wX
p1' -> forall (a :: * -> * -> *) wX wY1 wY2. a wX wY1 -> a wX wY2
unsafeCoercePEnd RepoPatchV1 prim wX wX
p2' forall (a3 :: * -> * -> *) (a4 :: * -> * -> *) wX wY wZ.
a3 wX wZ -> a4 wY wZ -> (:/\:) a3 a4 wX wY
:/\: forall (a :: * -> * -> *) wX wY1 wY2. a wX wY1 -> a wX wY2
unsafeCoercePEnd RepoPatchV1 prim wY wX
p1'

instance PrimPatch prim => Commute (RepoPatchV1 prim) where
    commute :: forall wX wY.
(:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
-> Maybe ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
commute (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
x = forall a. Perhaps a -> Maybe a
toMaybe forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
                  [forall (prim :: * -> * -> *).
PrimPatch prim =>
CommuteFunction prim
speedyCommute (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
x,
                   (forall (prim :: * -> * -> *).
Invert prim =>
CommuteFunction prim -> CommuteFunction prim
cleverCommute forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
(:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
-> Perhaps ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
mergerCommute) (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
x,
                   forall (prim :: * -> * -> *).
PrimPatch prim =>
CommuteFunction prim
everythingElseCommute (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
x
                  ]

instance PrimPatch prim => PatchInspect (RepoPatchV1 prim) where
    -- Recurse on everything, these are potentially spoofed patches
    listTouchedFiles :: forall wX wY. RepoPatchV1 prim wX wY -> [AnchoredPath]
listTouchedFiles (Merger FL (RepoPatchV1 prim) wX wY
_ RL (RepoPatchV1 prim) wX wB
_ RepoPatchV1 prim wC wX
p1 RepoPatchV1 prim wC wD
p2) = forall a. Ord a => [a] -> [a]
nubSort forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
p wX wY -> [AnchoredPath]
listTouchedFiles RepoPatchV1 prim wC wX
p1
                                            forall a. [a] -> [a] -> [a]
++ forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
p wX wY -> [AnchoredPath]
listTouchedFiles RepoPatchV1 prim wC wD
p2
    listTouchedFiles c :: RepoPatchV1 prim wX wY
c@(Regrem{}) = forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
p wX wY -> [AnchoredPath]
listTouchedFiles forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wX wY
c
    listTouchedFiles (PP prim wX wY
p) = forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
p wX wY -> [AnchoredPath]
listTouchedFiles prim wX wY
p

    hunkMatches :: forall wX wY.
(ByteString -> Bool) -> RepoPatchV1 prim wX wY -> Bool
hunkMatches ByteString -> Bool
f (Merger FL (RepoPatchV1 prim) wX wY
_ RL (RepoPatchV1 prim) wX wB
_ RepoPatchV1 prim wC wX
p1 RepoPatchV1 prim wC wD
p2) = forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
(ByteString -> Bool) -> p wX wY -> Bool
hunkMatches ByteString -> Bool
f RepoPatchV1 prim wC wX
p1 Bool -> Bool -> Bool
|| forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
(ByteString -> Bool) -> p wX wY -> Bool
hunkMatches ByteString -> Bool
f RepoPatchV1 prim wC wD
p2
    hunkMatches ByteString -> Bool
f c :: RepoPatchV1 prim wX wY
c@(Regrem{}) = forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
(ByteString -> Bool) -> p wX wY -> Bool
hunkMatches ByteString -> Bool
f forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wX wY
c
    hunkMatches ByteString -> Bool
f (PP prim wX wY
p) = forall (p :: * -> * -> *) wX wY.
PatchInspect p =>
(ByteString -> Bool) -> p wX wY -> Bool
hunkMatches ByteString -> Bool
f prim wX wY
p

isFilepatchMerger :: PrimPatch prim => RepoPatchV1 prim wX wY -> Maybe AnchoredPath
isFilepatchMerger :: forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
RepoPatchV1 prim wX wY -> Maybe AnchoredPath
isFilepatchMerger (PP prim wX wY
p) = forall (prim :: * -> * -> *) wX wY.
PrimClassify prim =>
prim wX wY -> Maybe AnchoredPath
is_filepatch prim wX wY
p
isFilepatchMerger (Merger FL (RepoPatchV1 prim) wX wY
_ RL (RepoPatchV1 prim) wX wB
_ RepoPatchV1 prim wC wX
p1 RepoPatchV1 prim wC wD
p2) = do
     AnchoredPath
f1 <- forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
RepoPatchV1 prim wX wY -> Maybe AnchoredPath
isFilepatchMerger RepoPatchV1 prim wC wX
p1
     AnchoredPath
f2 <- forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
RepoPatchV1 prim wX wY -> Maybe AnchoredPath
isFilepatchMerger RepoPatchV1 prim wC wD
p2
     if AnchoredPath
f1 forall a. Eq a => a -> a -> Bool
== AnchoredPath
f2 then forall (m :: * -> *) a. Monad m => a -> m a
return AnchoredPath
f1 else forall a. Maybe a
Nothing
isFilepatchMerger (Regrem FL (RepoPatchV1 prim) wY wX
und RL (RepoPatchV1 prim) wY wB
unw RepoPatchV1 prim wC wY
p1 RepoPatchV1 prim wC wD
p2)
    = forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
RepoPatchV1 prim wX wY -> Maybe AnchoredPath
isFilepatchMerger (forall (prim :: * -> * -> *) wX wY wB wC wD.
FL (RepoPatchV1 prim) wX wY
-> RL (RepoPatchV1 prim) wX wB
-> RepoPatchV1 prim wC wX
-> RepoPatchV1 prim wC wD
-> RepoPatchV1 prim wX wY
Merger FL (RepoPatchV1 prim) wY wX
und RL (RepoPatchV1 prim) wY wB
unw RepoPatchV1 prim wC wY
p1 RepoPatchV1 prim wC wD
p2)

commuteRecursiveMerger :: PrimPatch prim
    => (RepoPatchV1 prim :> RepoPatchV1 prim) wX wY -> Perhaps ((RepoPatchV1 prim :> RepoPatchV1 prim) wX wY)
commuteRecursiveMerger :: forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
(:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
-> Perhaps ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
commuteRecursiveMerger (RepoPatchV1 prim wX wZ
pA :> p :: RepoPatchV1 prim wZ wY
p@(Merger FL (RepoPatchV1 prim) wZ wY
_ RL (RepoPatchV1 prim) wZ wB
_ RepoPatchV1 prim wC wZ
p1 RepoPatchV1 prim wC wD
p2)) = forall a. Maybe a -> Perhaps a
toPerhaps forall a b. (a -> b) -> a -> b
$
  do (FL (RepoPatchV1 prim) wX wZ
_ :> RepoPatchV1 prim wZ wY
pA') <- forall (p1 :: * -> * -> *) (p2 :: * -> * -> *).
CommuteFn p1 p2 -> CommuteFn p1 (FL p2)
commuterIdFL forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
selfCommuter (RepoPatchV1 prim wX wZ
pA forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> FL (RepoPatchV1 prim) wZ wY
undo)
     (:>) (FL (RepoPatchV1 prim)) (RepoPatchV1 prim) wZ wZ
_ <- forall (p1 :: * -> * -> *) (p2 :: * -> * -> *).
CommuteFn p1 p2 -> CommuteFn p1 (FL p2)
commuterIdFL forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
selfCommuter (RepoPatchV1 prim wZ wY
pA' forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert FL (RepoPatchV1 prim) wZ wY
undo)
     (RepoPatchV1 prim wX wZ
_ :> RepoPatchV1 prim wZ wC
pAmid) <- forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (RepoPatchV1 prim wX wZ
pA forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart (forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wC wZ
p1))
     (RepoPatchV1 prim wZ wZ
p1' :> RepoPatchV1 prim wZ wZ
pAx) <- forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (RepoPatchV1 prim wZ wC
pAmid forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wC wZ
p1)
     forall (f :: * -> *). Alternative f => Bool -> f ()
guard (RepoPatchV1 prim wZ wZ
pAx forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` RepoPatchV1 prim wX wZ
pA)
     (RepoPatchV1 prim wZ wZ
p2' :> RepoPatchV1 prim wZ wD
_) <- forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (RepoPatchV1 prim wZ wC
pAmid forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wC wD
p2)
     (RepoPatchV1 prim wC wZ
p2o :> RepoPatchV1 prim wZ wZ
_) <- forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wZ wC
pAmid forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wZ wZ
p2')
     forall (f :: * -> *). Alternative f => Bool -> f ()
guard (RepoPatchV1 prim wC wZ
p2o forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` RepoPatchV1 prim wC wD
p2)
     let p' :: RepoPatchV1 prim wB wC
p' = if forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
unsafeCompare RepoPatchV1 prim wZ wZ
p1' RepoPatchV1 prim wC wZ
p1 Bool -> Bool -> Bool
&& forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
unsafeCompare RepoPatchV1 prim wZ wZ
p2' RepoPatchV1 prim wC wD
p2
              then forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP RepoPatchV1 prim wZ wY
p
              else forall (prim :: * -> * -> *) wX wY wZ wA wB.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> RepoPatchV1 prim wA wB
unsafeMerger String
"0.0" RepoPatchV1 prim wZ wZ
p1' RepoPatchV1 prim wZ wZ
p2'
         undo' :: FL (RepoPatchV1 prim) wX wY
undo' = forall (prim :: * -> * -> *) wX wY.
RepoPatchV1 prim wX wY -> FL (RepoPatchV1 prim) wX wY
mergerUndo forall {wB} {wC}. RepoPatchV1 prim wB wC
p'
     (RepoPatchV1 prim Any wZ
pAo :> FL (RepoPatchV1 prim) wZ wY
_) <- forall (p1 :: * -> * -> *) (p2 :: * -> * -> *).
CommuteFn p1 p2 -> CommuteFn (FL p1) p2
commuterFLId forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
selfCommuter (forall {wX} {wY}. FL (RepoPatchV1 prim) wX wY
undo' forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wZ wY
pA')
     forall (f :: * -> *). Alternative f => Bool -> f ()
guard (RepoPatchV1 prim Any wZ
pAo forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` RepoPatchV1 prim wX wZ
pA)
     forall (m :: * -> *) a. Monad m => a -> m a
return (forall {wB} {wC}. RepoPatchV1 prim wB wC
p' forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wZ wY
pA')
    where undo :: FL (RepoPatchV1 prim) wZ wY
undo = forall (prim :: * -> * -> *) wX wY.
RepoPatchV1 prim wX wY -> FL (RepoPatchV1 prim) wX wY
mergerUndo RepoPatchV1 prim wZ wY
p
commuteRecursiveMerger (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
_ = forall a. Perhaps a
Unknown

otherCommuteRecursiveMerger :: PrimPatch prim
    => (RepoPatchV1 prim :> RepoPatchV1 prim) wX wY -> Perhaps ((RepoPatchV1 prim :> RepoPatchV1 prim) wX wY)
otherCommuteRecursiveMerger :: forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
(:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
-> Perhaps ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
otherCommuteRecursiveMerger (p_old :: RepoPatchV1 prim wX wZ
p_old@(Merger FL (RepoPatchV1 prim) wX wZ
_ RL (RepoPatchV1 prim) wX wB
_ RepoPatchV1 prim wC wX
p1' RepoPatchV1 prim wC wD
p2') :> RepoPatchV1 prim wZ wY
pA') = forall a. Maybe a -> Perhaps a
toPerhaps forall a b. (a -> b) -> a -> b
$
  do (RepoPatchV1 prim wX wZ
pA :> FL (RepoPatchV1 prim) wZ wY
_) <- forall (p1 :: * -> * -> *) (p2 :: * -> * -> *).
CommuteFn p1 p2 -> CommuteFn (FL p1) p2
commuterFLId forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
selfCommuter (forall (prim :: * -> * -> *) wX wY.
RepoPatchV1 prim wX wY -> FL (RepoPatchV1 prim) wX wY
mergerUndo RepoPatchV1 prim wX wZ
p_old forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wZ wY
pA')
     (RepoPatchV1 prim wC wZ
pAmid :> RepoPatchV1 prim wZ wZ
p1) <- forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (forall (a :: * -> * -> *) wX wY1 wY2. a wX wY1 -> a wX wY2
unsafeCoercePEnd RepoPatchV1 prim wC wX
p1' forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wX wZ
pA)
     (RepoPatchV1 prim wX wZ
_ :> RepoPatchV1 prim wZ wZ
pAmido) <- forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (RepoPatchV1 prim wX wZ
pA forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wZ wZ
p1)
     forall (f :: * -> *). Alternative f => Bool -> f ()
guard (RepoPatchV1 prim wZ wZ
pAmido forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` RepoPatchV1 prim wC wZ
pAmid)
     (RepoPatchV1 prim wZ wZ
p2 :> RepoPatchV1 prim wZ wD
_) <- forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wC wZ
pAmid forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wC wD
p2')
     (RepoPatchV1 prim wC wZ
p2o' :> RepoPatchV1 prim wZ wZ
_) <- forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (RepoPatchV1 prim wC wZ
pAmid forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wZ wZ
p2)
     forall (f :: * -> *). Alternative f => Bool -> f ()
guard (RepoPatchV1 prim wC wZ
p2o' forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` RepoPatchV1 prim wC wD
p2')
     let p :: RepoPatchV1 prim wB wC
p = if RepoPatchV1 prim wZ wZ
p1 forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` RepoPatchV1 prim wC wX
p1' Bool -> Bool -> Bool
&& RepoPatchV1 prim wZ wZ
p2 forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` RepoPatchV1 prim wC wD
p2'
             then forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP RepoPatchV1 prim wX wZ
p_old
             else forall (prim :: * -> * -> *) wX wY wZ wA wB.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> RepoPatchV1 prim wA wB
unsafeMerger String
"0.0" RepoPatchV1 prim wZ wZ
p1 RepoPatchV1 prim wZ wZ
p2
         undo :: FL (RepoPatchV1 prim) wX wY
undo = forall (prim :: * -> * -> *) wX wY.
RepoPatchV1 prim wX wY -> FL (RepoPatchV1 prim) wX wY
mergerUndo forall {wB} {wC}. RepoPatchV1 prim wB wC
p
     forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ RepoPatchV1 prim wX wZ
pA forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` RepoPatchV1 prim wZ wZ
p1) -- special case here...
     (FL (RepoPatchV1 prim) wX wZ
_ :> RepoPatchV1 prim wZ Any
pAo') <- forall (p1 :: * -> * -> *) (p2 :: * -> * -> *).
CommuteFn p1 p2 -> CommuteFn p1 (FL p2)
commuterIdFL forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
selfCommuter (RepoPatchV1 prim wX wZ
pA forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall {wX} {wY}. FL (RepoPatchV1 prim) wX wY
undo)
     forall (f :: * -> *). Alternative f => Bool -> f ()
guard (RepoPatchV1 prim wZ Any
pAo' forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` RepoPatchV1 prim wZ wY
pA')
     forall (m :: * -> *) a. Monad m => a -> m a
return (RepoPatchV1 prim wX wZ
pA forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall {wB} {wC}. RepoPatchV1 prim wB wC
p)
otherCommuteRecursiveMerger (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
_ = forall a. Perhaps a
Unknown

type CommuteFunction prim = forall wX wY . (RepoPatchV1 prim :> RepoPatchV1 prim) wX wY -> Perhaps ((RepoPatchV1 prim :> RepoPatchV1 prim) wX wY)

{-
A note about mergers and type witnesses
---------------------------------------

The merger code predates the introduction of type witnesses, and because
of its complexity has proved the hardest part of the codebase to retrofit.
Attempting to do this has exposed various places where the code behaves
oddly (e.g. 'putBefore' below); these are likely to be bugs but fixing
them would be potentially disruptive and dangerous as it might change
the existing merge behaviour and thus break existing repositories.

As a result the addition of witnesses to this code has required the
liberal use of unsafe operators. In effect, witnesses bring no safety
in this area; the sole purpose of adding them here was to allow this
code to run as part of a codebase that uses witnesses everywhere else.

A key problem point is the type of the 'Merger' and 'Regrem' constructors
of Patch, where the witnesses seem odd. It is likely that some or many
of the unsafe operations could be removed by finding a better type for
these constructors.
-}


-- Recreates a patch history in reverse.
unwind :: RepoPatchV1 prim wX wY -> Sealed (RL (RepoPatchV1 prim) wX)
unwind :: forall (prim :: * -> * -> *) wX wY.
RepoPatchV1 prim wX wY -> Sealed (RL (RepoPatchV1 prim) wX)
unwind (Merger FL (RepoPatchV1 prim) wX wY
_ RL (RepoPatchV1 prim) wX wB
unwindings RepoPatchV1 prim wC wX
_ RepoPatchV1 prim wC wD
_) = forall (a :: * -> *) wB. a wB -> Sealed a
Sealed RL (RepoPatchV1 prim) wX wB
unwindings
unwind RepoPatchV1 prim wX wY
p = forall (a :: * -> *) wB. a wB -> Sealed a
Sealed (forall (a :: * -> * -> *) wX. RL a wX wX
NilRL forall (a :: * -> * -> *) wX wB wZ.
RL a wX wB -> a wB wZ -> RL a wX wZ
:<: RepoPatchV1 prim wX wY
p)

-- Recreates a patch history in reverse. The patch being unwound is always at
-- the start of the list of patches.
trueUnwind :: PrimPatch prim
    => RepoPatchV1 prim wC wX -> RepoPatchV1 prim wC wD -> Sealed ((RL (RepoPatchV1 prim) :> RepoPatchV1 prim) wX)
trueUnwind :: forall (prim :: * -> * -> *) wC wX wD.
PrimPatch prim =>
RepoPatchV1 prim wC wX
-> RepoPatchV1 prim wC wD
-> Sealed ((:>) (RL (RepoPatchV1 prim)) (RepoPatchV1 prim) wX)
trueUnwind RepoPatchV1 prim wC wX
p1 RepoPatchV1 prim wC wD
p2 =
  let fake_p :: RepoPatchV1 prim wX wX
fake_p = forall (prim :: * -> * -> *) wX wY wB wC wD.
FL (RepoPatchV1 prim) wX wY
-> RL (RepoPatchV1 prim) wX wB
-> RepoPatchV1 prim wC wX
-> RepoPatchV1 prim wC wD
-> RepoPatchV1 prim wX wY
Merger forall (a :: * -> * -> *) wX. FL a wX wX
NilFL forall (a :: * -> * -> *) wX. RL a wX wX
NilRL RepoPatchV1 prim wC wX
p1 RepoPatchV1 prim wC wD
p2
  in
  case (forall (prim :: * -> * -> *) wX wY.
RepoPatchV1 prim wX wY -> Sealed (RL (RepoPatchV1 prim) wX)
unwind RepoPatchV1 prim wC wX
p1, forall (prim :: * -> * -> *) wX wY.
RepoPatchV1 prim wX wY -> Sealed (RL (RepoPatchV1 prim) wX)
unwind RepoPatchV1 prim wC wD
p2) of
    (Sealed (RL (RepoPatchV1 prim) wC wY
p1s:<:RepoPatchV1 prim wY wX
_),Sealed (RL (RepoPatchV1 prim) wC wY
p2s:<:RepoPatchV1 prim wY wX
_)) ->
         forall (a :: * -> *) wB. a wB -> Sealed a
Sealed (forall (a :: * -> * -> *) b wZ.
(forall wX wY. a wX wY -> b) -> FlippedSeal a wZ -> b
unsealFlipped forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP (forall (prim :: * -> * -> *) wA wB wX wZ wY.
PrimPatch prim =>
RepoPatchV1 prim wA wB
-> RL (RepoPatchV1 prim) wX wZ
-> RL (RepoPatchV1 prim) wY wZ
-> FlippedSeal (RL (RepoPatchV1 prim)) wZ
reconcileUnwindings RepoPatchV1 prim wX wX
fake_p RL (RepoPatchV1 prim) wC wY
p1s (forall (a :: * -> * -> *) wX wY1 wY2. a wX wY1 -> a wX wY2
unsafeCoercePEnd RL (RepoPatchV1 prim) wC wY
p2s)) forall (a :: * -> * -> *) wX wB wZ.
RL a wX wB -> a wB wZ -> RL a wX wZ
:<: forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP RepoPatchV1 prim wC wX
p1 forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wX wX
fake_p)
    (Sealed (RL (RepoPatchV1 prim) wC),
 Sealed (RL (RepoPatchV1 prim) wC))
_ -> forall a. HasCallStack => String -> a
error String
"impossible case"

reconcileUnwindings :: PrimPatch prim
    => RepoPatchV1 prim wA wB -> RL (RepoPatchV1 prim) wX wZ -> RL (RepoPatchV1 prim) wY wZ -> FlippedSeal (RL (RepoPatchV1 prim)) wZ
reconcileUnwindings :: forall (prim :: * -> * -> *) wA wB wX wZ wY.
PrimPatch prim =>
RepoPatchV1 prim wA wB
-> RL (RepoPatchV1 prim) wX wZ
-> RL (RepoPatchV1 prim) wY wZ
-> FlippedSeal (RL (RepoPatchV1 prim)) wZ
reconcileUnwindings RepoPatchV1 prim wA wB
_ RL (RepoPatchV1 prim) wX wZ
NilRL RL (RepoPatchV1 prim) wY wZ
p2s = forall (a :: * -> * -> *) wB wY. a wB wY -> FlippedSeal a wY
FlippedSeal RL (RepoPatchV1 prim) wY wZ
p2s
reconcileUnwindings RepoPatchV1 prim wA wB
_ RL (RepoPatchV1 prim) wX wZ
p1s RL (RepoPatchV1 prim) wY wZ
NilRL = forall (a :: * -> * -> *) wB wY. a wB wY -> FlippedSeal a wY
FlippedSeal RL (RepoPatchV1 prim) wX wZ
p1s
reconcileUnwindings RepoPatchV1 prim wA wB
p (RL (RepoPatchV1 prim) wX wY
p1s:<:RepoPatchV1 prim wY wZ
p1) p2s :: RL (RepoPatchV1 prim) wY wZ
p2s@(RL (RepoPatchV1 prim) wY wY
tp2s:<:RepoPatchV1 prim wY wZ
p2) =
    case [(RL (RepoPatchV1 prim) wX wZ
p1s', RL (RepoPatchV1 prim) wY wZ
p2s')|
          p1s' :: RL (RepoPatchV1 prim) wX wZ
p1s'@(RL (RepoPatchV1 prim) wX wY
_:<:RepoPatchV1 prim wY wZ
hp1s') <- forall (p :: * -> * -> *) wX wY.
Commute p =>
RL p wX wY -> [RL p wX wY]
headPermutationsRL (RL (RepoPatchV1 prim) wX wY
p1sforall (a :: * -> * -> *) wX wB wZ.
RL a wX wB -> a wB wZ -> RL a wX wZ
:<:RepoPatchV1 prim wY wZ
p1),
          p2s' :: RL (RepoPatchV1 prim) wY wZ
p2s'@(RL (RepoPatchV1 prim) wY wY
_:<:RepoPatchV1 prim wY wZ
hp2s') <- forall (p :: * -> * -> *) wX wY.
Commute p =>
RL p wX wY -> [RL p wX wY]
headPermutationsRL RL (RepoPatchV1 prim) wY wZ
p2s,
          RepoPatchV1 prim wY wZ
hp1s' forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` RepoPatchV1 prim wY wZ
hp2s'] of
    ((RL (RepoPatchV1 prim) wX wY
p1s':<:RepoPatchV1 prim wY wZ
p1', RL (RepoPatchV1 prim) wY wY
p2s':<:RepoPatchV1 prim wY wZ
_):[(RL (RepoPatchV1 prim) wX wZ, RL (RepoPatchV1 prim) wY wZ)]
_) ->
        forall (a :: * -> * -> *) wY (b :: * -> * -> *) wZ.
(forall wX. a wX wY -> b wX wZ)
-> FlippedSeal a wY -> FlippedSeal b wZ
mapFlipped (forall (a :: * -> * -> *) wX wB wZ.
RL a wX wB -> a wB wZ -> RL a wX wZ
:<:RepoPatchV1 prim wY wZ
p1') forall a b. (a -> b) -> a -> b
$ forall (prim :: * -> * -> *) wA wB wX wZ wY.
PrimPatch prim =>
RepoPatchV1 prim wA wB
-> RL (RepoPatchV1 prim) wX wZ
-> RL (RepoPatchV1 prim) wY wZ
-> FlippedSeal (RL (RepoPatchV1 prim)) wZ
reconcileUnwindings RepoPatchV1 prim wA wB
p RL (RepoPatchV1 prim) wX wY
p1s' (forall (a :: * -> * -> *) wX wY1 wY2. a wX wY1 -> a wX wY2
unsafeCoercePEnd RL (RepoPatchV1 prim) wY wY
p2s')
    [] -> case forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall (prim :: * -> * -> *) wY wZ wX wW.
PrimPatch prim =>
RepoPatchV1 prim wY wZ
-> FL (RepoPatchV1 prim) wX wZ
-> Maybe (FL (RepoPatchV1 prim) wY wW)
putBefore RepoPatchV1 prim wY wZ
p1 (forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (RepoPatchV1 prim) wY wZ
p2s) of
          Just RL (RepoPatchV1 prim) wY wY
p2s' -> forall (a :: * -> * -> *) wY (b :: * -> * -> *) wZ.
(forall wX. a wX wY -> b wX wZ)
-> FlippedSeal a wY -> FlippedSeal b wZ
mapFlipped (forall (a :: * -> * -> *) wX wB wZ.
RL a wX wB -> a wB wZ -> RL a wX wZ
:<:RepoPatchV1 prim wY wZ
p1) forall a b. (a -> b) -> a -> b
$ forall (prim :: * -> * -> *) wA wB wX wZ wY.
PrimPatch prim =>
RepoPatchV1 prim wA wB
-> RL (RepoPatchV1 prim) wX wZ
-> RL (RepoPatchV1 prim) wY wZ
-> FlippedSeal (RL (RepoPatchV1 prim)) wZ
reconcileUnwindings RepoPatchV1 prim wA wB
p RL (RepoPatchV1 prim) wX wY
p1s RL (RepoPatchV1 prim) wY wY
p2s'
          Maybe (RL (RepoPatchV1 prim) wY wY)
Nothing ->
              case forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL forall a b. (a -> b) -> a -> b
$ forall (prim :: * -> * -> *) wY wZ wX wW.
PrimPatch prim =>
RepoPatchV1 prim wY wZ
-> FL (RepoPatchV1 prim) wX wZ
-> Maybe (FL (RepoPatchV1 prim) wY wW)
putBefore RepoPatchV1 prim wY wZ
p2 forall a b. (a -> b) -> a -> b
$
                   forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL (RL (RepoPatchV1 prim) wX wY
p1sforall (a :: * -> * -> *) wX wB wZ.
RL a wX wB -> a wB wZ -> RL a wX wZ
:<:RepoPatchV1 prim wY wZ
p1) of
              Just RL (RepoPatchV1 prim) wY wY
p1s' -> forall (a :: * -> * -> *) wY (b :: * -> * -> *) wZ.
(forall wX. a wX wY -> b wX wZ)
-> FlippedSeal a wY -> FlippedSeal b wZ
mapFlipped (forall (a :: * -> * -> *) wX wB wZ.
RL a wX wB -> a wB wZ -> RL a wX wZ
:<:RepoPatchV1 prim wY wZ
p2) forall a b. (a -> b) -> a -> b
$
                           forall (prim :: * -> * -> *) wA wB wX wZ wY.
PrimPatch prim =>
RepoPatchV1 prim wA wB
-> RL (RepoPatchV1 prim) wX wZ
-> RL (RepoPatchV1 prim) wY wZ
-> FlippedSeal (RL (RepoPatchV1 prim)) wZ
reconcileUnwindings RepoPatchV1 prim wA wB
p RL (RepoPatchV1 prim) wY wY
p1s' RL (RepoPatchV1 prim) wY wY
tp2s
              Maybe (RL (RepoPatchV1 prim) wY wY)
Nothing ->
                forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ Doc -> String
renderString
                  forall a b. (a -> b) -> a -> b
$ String -> Doc
text String
"in function reconcileUnwindings"
                  Doc -> Doc -> Doc
$$ String -> Doc
text String
"Original patch:"
                  Doc -> Doc -> Doc
$$ forall (prim :: * -> * -> *) wX wY.
ShowPatchBasic prim =>
prim wX wY -> Doc
showPatch_ RepoPatchV1 prim wA wB
p
    [(RL (RepoPatchV1 prim) wX wZ, RL (RepoPatchV1 prim) wY wZ)]
_ -> forall a. HasCallStack => String -> a
error String
"in reconcileUnwindings"

-- This code seems wrong, shouldn't the commute be invert p1 :> p2 ? And why isn't p1' re-inverted?
-- it seems to have been this way forever:
-- Fri May 23 10:27:04 BST 2003  droundy@abridgegame.org
--    * fix bug in unwind and add docs on unwind algorithm.
putBefore :: PrimPatch prim
    => RepoPatchV1 prim wY wZ -> FL (RepoPatchV1 prim) wX wZ -> Maybe (FL (RepoPatchV1 prim) wY wW)
putBefore :: forall (prim :: * -> * -> *) wY wZ wX wW.
PrimPatch prim =>
RepoPatchV1 prim wY wZ
-> FL (RepoPatchV1 prim) wX wZ
-> Maybe (FL (RepoPatchV1 prim) wY wW)
putBefore RepoPatchV1 prim wY wZ
p1 (RepoPatchV1 prim wX wY
p2:>:FL (RepoPatchV1 prim) wY wZ
p2s) =
    do RepoPatchV1 prim Any wZ
p1' :> RepoPatchV1 prim wZ wY
p2' <- forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP RepoPatchV1 prim wX wY
p2 forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wY wZ
p1)
       (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wZ wZ
_ <- forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (RepoPatchV1 prim wZ wY
p2' forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RepoPatchV1 prim wY wZ
p1)
       (forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP RepoPatchV1 prim wZ wY
p2' forall (a :: * -> * -> *) wX wB wZ.
a wX wB -> FL a wB wZ -> FL a wX wZ
:>:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall (prim :: * -> * -> *) wY wZ wX wW.
PrimPatch prim =>
RepoPatchV1 prim wY wZ
-> FL (RepoPatchV1 prim) wX wZ
-> Maybe (FL (RepoPatchV1 prim) wY wW)
putBefore RepoPatchV1 prim Any wZ
p1' (forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP FL (RepoPatchV1 prim) wY wZ
p2s)
putBefore RepoPatchV1 prim wY wZ
_ FL (RepoPatchV1 prim) wX wZ
NilFL = forall a. a -> Maybe a
Just (forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP forall (a :: * -> * -> *) wX. FL a wX wX
NilFL)

instance PrimPatch prim => CommuteNoConflicts (RepoPatchV1 prim) where
  commuteNoConflicts :: forall wX wY.
(:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
-> Maybe ((:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY)
commuteNoConflicts (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
x =
    forall a. Perhaps a -> Maybe a
toMaybe forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum [ forall (prim :: * -> * -> *).
PrimPatch prim =>
CommuteFunction prim
speedyCommute (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
x
                   , forall (prim :: * -> * -> *).
PrimPatch prim =>
CommuteFunction prim
everythingElseCommute (:>) (RepoPatchV1 prim) (RepoPatchV1 prim) wX wY
x
                   ]

instance PrimPatch prim => Conflict (RepoPatchV1 prim) where
  resolveConflicts :: forall wO wX wY.
RL (RepoPatchV1 prim) wO wX
-> RL (RepoPatchV1 prim) wX wY
-> [ConflictDetails (PrimOf (RepoPatchV1 prim)) wY]
resolveConflicts RL (RepoPatchV1 prim) wO wX
_ = forall a b. (a -> b) -> [a] -> [b]
map forall (prim :: * -> * -> *) wX.
PrimMangleUnravelled prim =>
Unravelled prim wX -> ConflictDetails prim wX
mangleOrFail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) wX wY.
CommuteNoConflicts p =>
(forall wA wB. p wA wB -> [Unravelled (PrimOf p) wB])
-> RL p wX wY -> [Unravelled (PrimOf p) wY]
combineConflicts forall {prim :: * -> * -> *} {wX} {wY}.
(CleanMerge prim, Commute prim, Invert prim, Eq2 prim, IsHunk prim,
 PatchInspect prim, RepairToFL prim, Show2 prim, PrimConstruct prim,
 PrimCanonize prim, PrimClassify prim, PrimDetails prim,
 PrimApply prim, PrimSift prim, PrimMangleUnravelled prim,
 ReadPatch prim, ShowPatch prim, ShowContextPatch prim,
 PatchListFormat prim) =>
RepoPatchV1 prim wX wY -> [[Sealed (FL prim wY)]]
resolveOne
    where
      resolveOne :: RepoPatchV1 prim wX wY -> [[Sealed (FL prim wY)]]
resolveOne RepoPatchV1 prim wX wY
p | forall (prim :: * -> * -> *) wA wB. RepoPatchV1 prim wA wB -> Bool
isMerger RepoPatchV1 prim wX wY
p = [forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
RepoPatchV1 prim wX wY -> [Sealed (FL prim wY)]
publicUnravel RepoPatchV1 prim wX wY
p]
      resolveOne RepoPatchV1 prim wX wY
_ = []

instance PrimPatch prim => Unwind (RepoPatchV1 prim) where
  fullUnwind :: forall wX wY.
RepoPatchV1 prim wX wY -> Unwound (PrimOf (RepoPatchV1 prim)) wX wY
fullUnwind (PP prim wX wY
prim) = forall (prim :: * -> * -> *) wA wB wC wD.
(Commute prim, Invert prim, Eq2 prim) =>
FL prim wA wB
-> FL prim wB wC -> FL prim wC wD -> Unwound prim wA wD
mkUnwound forall (a :: * -> * -> *) wX. FL a wX wX
NilFL (prim wX wY
prim forall (a :: * -> * -> *) wX wB wZ.
a wX wB -> FL a wB wZ -> FL a wX wZ
:>: forall (a :: * -> * -> *) wX. FL a wX wX
NilFL) forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
  fullUnwind (Merger FL (RepoPatchV1 prim) wX wY
a RL (RepoPatchV1 prim) wX wB
_ RepoPatchV1 prim wC wX
c RepoPatchV1 prim wC wD
d) =
    case forall (p :: * -> * -> *) wX wY.
Unwind p =>
p wX wY -> Unwound (PrimOf p) wX wY
fullUnwind RepoPatchV1 prim wC wD
d of
      Unwound FL (PrimOf (RepoPatchV1 prim)) wC wB
before FL (PrimOf (RepoPatchV1 prim)) wB wC
prim RL (PrimOf (RepoPatchV1 prim)) wC wD
_after ->
        forall (prim :: * -> * -> *) wA wB wC wD.
(Commute prim, Invert prim, Eq2 prim) =>
FL prim wA wB
-> FL prim wB wC -> FL prim wC wD -> Unwound prim wA wD
mkUnwound
          (forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert (forall (p :: * -> * -> *) wX wY.
Effect p =>
p wX wY -> FL (PrimOf p) wX wY
effect RepoPatchV1 prim wC wX
c) forall (a :: * -> * -> *) wX wY wZ.
FL a wX wY -> FL a wY wZ -> FL a wX wZ
+>+ FL (PrimOf (RepoPatchV1 prim)) wC wB
before)
          FL (PrimOf (RepoPatchV1 prim)) wB wC
prim
          (forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert FL (PrimOf (RepoPatchV1 prim)) wB wC
prim forall (a :: * -> * -> *) wX wY wZ.
FL a wX wY -> FL a wY wZ -> FL a wX wZ
+>+ forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert FL (PrimOf (RepoPatchV1 prim)) wC wB
before forall (a :: * -> * -> *) wX wY wZ.
FL a wX wY -> FL a wY wZ -> FL a wX wZ
+>+ forall (p :: * -> * -> *) wX wY.
Effect p =>
p wX wY -> FL (PrimOf p) wX wY
effect RepoPatchV1 prim wC wX
c forall (a :: * -> * -> *) wX wY wZ.
FL a wX wY -> FL a wY wZ -> FL a wX wZ
+>+ forall (p :: * -> * -> *) wX wY.
Effect p =>
p wX wY -> FL (PrimOf p) wX wY
effect FL (RepoPatchV1 prim) wX wY
a)
  fullUnwind (Regrem FL (RepoPatchV1 prim) wY wX
a RL (RepoPatchV1 prim) wY wB
b RepoPatchV1 prim wC wY
c RepoPatchV1 prim wC wD
d) = forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert (forall (p :: * -> * -> *) wX wY.
Unwind p =>
p wX wY -> Unwound (PrimOf p) wX wY
fullUnwind (forall (prim :: * -> * -> *) wX wY wB wC wD.
FL (RepoPatchV1 prim) wX wY
-> RL (RepoPatchV1 prim) wX wB
-> RepoPatchV1 prim wC wX
-> RepoPatchV1 prim wC wD
-> RepoPatchV1 prim wX wY
Merger FL (RepoPatchV1 prim) wY wX
a RL (RepoPatchV1 prim) wY wB
b RepoPatchV1 prim wC wY
c RepoPatchV1 prim wC wD
d))

instance PrimPatch prim => Summary (RepoPatchV1 prim) where
  conflictedEffect :: forall wX wY.
RepoPatchV1 prim wX wY
-> [IsConflictedPrim (PrimOf (RepoPatchV1 prim))]
conflictedEffect RepoPatchV1 prim wX wY
x
    | forall (prim :: * -> * -> *) wA wB. RepoPatchV1 prim wA wB -> Bool
isMerger RepoPatchV1 prim wX wY
x = forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> FL a wX wY -> [b]
mapFL (forall (prim :: * -> * -> *) wB wC.
ConflictState -> prim wB wC -> IsConflictedPrim prim
IsC ConflictState
Conflicted) forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
Effect p =>
p wX wY -> FL (PrimOf p) wX wY
effect RepoPatchV1 prim wX wY
x
    | Bool
otherwise = forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> FL a wX wY -> [b]
mapFL (forall (prim :: * -> * -> *) wB wC.
ConflictState -> prim wB wC -> IsConflictedPrim prim
IsC ConflictState
Okay) forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
Effect p =>
p wX wY -> FL (PrimOf p) wX wY
effect RepoPatchV1 prim wX wY
x

-- This type seems wrong - the most natural type for the result would seem to be
-- [Sealed (FL prim wX)], given the type of unwind.
-- However downstream code in darcs convert assumes the wY type, and I was unable
-- to figure out whether this could/should reasonably be changed -- Ganesh 13/4/10
--
-- bf says: the type here is correct, those of unwind and unravel are wrong,
-- because conflict resolution applies to the end of the repo.
publicUnravel :: PrimPatch prim => RepoPatchV1 prim wX wY -> [Sealed (FL prim wY)]
publicUnravel :: forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
RepoPatchV1 prim wX wY -> [Sealed (FL prim wY)]
publicUnravel = forall a b. (a -> b) -> [a] -> [b]
map (forall (a :: * -> *) (b :: * -> *).
(forall wX. a wX -> b wX) -> Sealed a -> Sealed b
mapSeal forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
RepoPatchV1 prim wX wY -> [Sealed (FL prim wX)]
unravel

dropAllInverses :: (Commute p, Invert p, Eq2 p) => FL p wX wY -> FL p wX wY
dropAllInverses :: forall (p :: * -> * -> *) wX wY.
(Commute p, Invert p, Eq2 p) =>
FL p wX wY -> FL p wX wY
dropAllInverses FL p wX wY
NilFL = forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
dropAllInverses (p wX wY
p :>: FL p wY wY
ps) =
  let ps' :: FL p wY wY
ps' = forall (p :: * -> * -> *) wX wY.
(Commute p, Invert p, Eq2 p) =>
FL p wX wY -> FL p wX wY
dropAllInverses FL p wY wY
ps in
  forall a. a -> Maybe a -> a
fromMaybe (p wX wY
p forall (a :: * -> * -> *) wX wB wZ.
a wX wB -> FL a wB wZ -> FL a wX wZ
:>: FL p wY wY
ps') forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY wZ.
(Eq2 p, Commute p) =>
p wX wY -> FL p wX wZ -> Maybe (FL p wY wZ)
removeFL (forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert p wX wY
p) FL p wY wY
ps'

unravel :: PrimPatch prim => RepoPatchV1 prim wX wY -> [Sealed (FL prim wX)]
unravel :: forall (prim :: * -> * -> *) wX wY.
PrimPatch prim =>
RepoPatchV1 prim wX wY -> [Sealed (FL prim wX)]
unravel RepoPatchV1 prim wX wY
p = forall a. Eq a => [a] -> [a]
nub forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall (a :: * -> *) (b :: * -> *).
(forall wX. a wX -> b wX) -> Sealed a -> Sealed b
mapSeal (forall (p :: * -> * -> *) wX wY.
(Commute p, Invert p, Eq2 p) =>
FL p wX wY -> FL p wX wY
dropAllInverses forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: * -> * -> *) wX wZ. FL (FL a) wX wZ -> FL a wX wZ
concatFL forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: * -> * -> *) (b :: * -> * -> *) wX wZ.
(forall wW wY. a wW wY -> b wW wY) -> FL a wX wZ -> FL b wX wZ
mapFL_FL forall (p :: * -> * -> *) wX wY.
Effect p =>
p wX wY -> FL (PrimOf p) wX wY
effect)) forall a b. (a -> b) -> a -> b
$
            forall (prim :: * -> * -> *) wX.
PrimPatch prim =>
[Sealed (FL (RepoPatchV1 prim) wX)]
-> [Sealed (FL (RepoPatchV1 prim) wX)]
getSupers forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall (a :: * -> *) (b :: * -> *).
(forall wX. a wX -> b wX) -> Sealed a -> Sealed b
mapSeal forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL) forall a b. (a -> b) -> a -> b
$ forall (a :: * -> *) b. (forall wX. a wX -> b) -> Sealed a -> b
unseal (forall (prim :: * -> * -> *) wA wB wX wY.
PrimPatch prim =>
RepoPatchV1 prim wA wB
-> RL (RepoPatchV1 prim) wX wY
-> [Sealed (RL (RepoPatchV1 prim) wX)]
newUr RepoPatchV1 prim wX wY
p) forall a b. (a -> b) -> a -> b
$ forall (prim :: * -> * -> *) wX wY.
RepoPatchV1 prim wX wY -> Sealed (RL (RepoPatchV1 prim) wX)
unwind RepoPatchV1 prim wX wY
p

getSupers :: PrimPatch prim
    => [Sealed (FL (RepoPatchV1 prim) wX)] -> [Sealed (FL (RepoPatchV1 prim) wX)]
getSupers :: forall (prim :: * -> * -> *) wX.
PrimPatch prim =>
[Sealed (FL (RepoPatchV1 prim) wX)]
-> [Sealed (FL (RepoPatchV1 prim) wX)]
getSupers (Sealed (FL (RepoPatchV1 prim) wX)
x:[Sealed (FL (RepoPatchV1 prim) wX)]
xs) =
    case forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
notforall b c a. (b -> c) -> (a -> b) -> a -> c
.(Sealed (FL (RepoPatchV1 prim) wX)
x forall (prim :: * -> * -> *) wX.
PrimPatch prim =>
Sealed (FL (RepoPatchV1 prim) wX)
-> Sealed (FL (RepoPatchV1 prim) wX) -> Bool
`isSuperpatchOf`)) [Sealed (FL (RepoPatchV1 prim) wX)]
xs of
    [Sealed (FL (RepoPatchV1 prim) wX)]
xs' -> if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (forall (prim :: * -> * -> *) wX.
PrimPatch prim =>
Sealed (FL (RepoPatchV1 prim) wX)
-> Sealed (FL (RepoPatchV1 prim) wX) -> Bool
`isSuperpatchOf` Sealed (FL (RepoPatchV1 prim) wX)
x) [Sealed (FL (RepoPatchV1 prim) wX)]
xs'
           then forall (prim :: * -> * -> *) wX.
PrimPatch prim =>
[Sealed (FL (RepoPatchV1 prim) wX)]
-> [Sealed (FL (RepoPatchV1 prim) wX)]
getSupers [Sealed (FL (RepoPatchV1 prim) wX)]
xs'
           else Sealed (FL (RepoPatchV1 prim) wX)
x forall a. a -> [a] -> [a]
: forall (prim :: * -> * -> *) wX.
PrimPatch prim =>
[Sealed (FL (RepoPatchV1 prim) wX)]
-> [Sealed (FL (RepoPatchV1 prim) wX)]
getSupers [Sealed (FL (RepoPatchV1 prim) wX)]
xs'
getSupers [] = []

isSuperpatchOf :: PrimPatch prim
    => Sealed (FL (RepoPatchV1 prim) wX) -> Sealed (FL (RepoPatchV1 prim) wX) -> Bool
Sealed FL (RepoPatchV1 prim) wX wX
x isSuperpatchOf :: forall (prim :: * -> * -> *) wX.
PrimPatch prim =>
Sealed (FL (RepoPatchV1 prim) wX)
-> Sealed (FL (RepoPatchV1 prim) wX) -> Bool
`isSuperpatchOf` Sealed FL (RepoPatchV1 prim) wX wX
y | forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> Int
lengthFL FL (RepoPatchV1 prim) wX wX
y forall a. Ord a => a -> a -> Bool
> forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> Int
lengthFL FL (RepoPatchV1 prim) wX wX
x = Bool
False -- should be just an optimisation
Sealed FL (RepoPatchV1 prim) wX wX
x `isSuperpatchOf` Sealed FL (RepoPatchV1 prim) wX wX
y = FL (RepoPatchV1 prim) wX wX
x forall (prim :: * -> * -> *) wX wY wZ.
PrimPatch prim =>
FL (RepoPatchV1 prim) wX wY -> FL (RepoPatchV1 prim) wX wZ -> Bool
`iso` FL (RepoPatchV1 prim) wX wX
y
    where iso :: PrimPatch prim => FL (RepoPatchV1 prim) wX wY -> FL (RepoPatchV1 prim) wX wZ -> Bool
          FL (RepoPatchV1 prim) wX wY
_ iso :: forall (prim :: * -> * -> *) wX wY wZ.
PrimPatch prim =>
FL (RepoPatchV1 prim) wX wY -> FL (RepoPatchV1 prim) wX wZ -> Bool
`iso` FL (RepoPatchV1 prim) wX wZ
NilFL = Bool
True
          FL (RepoPatchV1 prim) wX wY
NilFL `iso` FL (RepoPatchV1 prim) wX wZ
_ = Bool
False
          FL (RepoPatchV1 prim) wX wY
a `iso` (RepoPatchV1 prim wX wY
b:>:FL (RepoPatchV1 prim) wY wZ
bs) =
              forall a. [a] -> a
head forall a b. (a -> b) -> a -> b
$ ([FL (RepoPatchV1 prim) wY wY
as forall (prim :: * -> * -> *) wX wY wZ.
PrimPatch prim =>
FL (RepoPatchV1 prim) wX wY -> FL (RepoPatchV1 prim) wX wZ -> Bool
`iso` FL (RepoPatchV1 prim) wY wZ
bs | (RepoPatchV1 prim wX wY
ah :>: FL (RepoPatchV1 prim) wY wY
as) <- forall (p :: * -> * -> *) wX wY.
Commute p =>
FL p wX wY -> [FL p wX wY]
simpleHeadPermutationsFL FL (RepoPatchV1 prim) wX wY
a, EqCheck wY wY
IsEq <- [RepoPatchV1 prim wX wY
ah forall (p :: * -> * -> *) wA wB wC.
Eq2 p =>
p wA wB -> p wA wC -> EqCheck wB wC
=\/= RepoPatchV1 prim wX wY
b]] :: [Bool]) forall a. [a] -> [a] -> [a]
++ [Bool
False]

-- | merger takes two patches, (which have been determined to conflict) and
-- constructs a Merger patch to represent the conflict. @p1@ is considered to
-- be conflicting with @p2@ (@p1@ is the "first" patch in the repo ordering),
-- the resulting Merger is therefore a representation of @p2@.
merger :: PrimPatch prim
    => String -> RepoPatchV1 prim wX wY -> RepoPatchV1 prim wX wZ -> Sealed (RepoPatchV1 prim wY)
merger :: forall (prim :: * -> * -> *) wX wY wZ.
PrimPatch prim =>
String
-> RepoPatchV1 prim wX wY
-> RepoPatchV1 prim wX wZ
-> Sealed (RepoPatchV1 prim wY)
merger String
"0.0" RepoPatchV1 prim wX wY
p1 RepoPatchV1 prim wX wZ
p2 = Sealed (RepoPatchV1 prim wY)
final_p
    where
          sealed_unwindings :: Sealed ((:>) (RL (RepoPatchV1 prim)) (RepoPatchV1 prim) wY)
sealed_unwindings = forall (prim :: * -> * -> *) wC wX wD.
PrimPatch prim =>
RepoPatchV1 prim wC wX
-> RepoPatchV1 prim wC wD
-> Sealed ((:>) (RL (RepoPatchV1 prim)) (RepoPatchV1 prim) wX)
trueUnwind RepoPatchV1 prim wX wY
p1 RepoPatchV1 prim wX wZ
p2
          final_p :: Sealed (RepoPatchV1 prim wY)
final_p =
            case (Sealed (FL (RepoPatchV1 prim) wY)
sealed_undoit, Sealed ((:>) (RL (RepoPatchV1 prim)) (RepoPatchV1 prim) wY)
sealed_unwindings) of
              (Sealed FL (RepoPatchV1 prim) wY wX
undoit, Sealed (:>) (RL (RepoPatchV1 prim)) (RepoPatchV1 prim) wY wX
unwindings)
                -> forall (a :: * -> *) wB. a wB -> Sealed a
Sealed forall a b. (a -> b) -> a -> b
$ forall (prim :: * -> * -> *) wX wY wB wC wD.
FL (RepoPatchV1 prim) wX wY
-> RL (RepoPatchV1 prim) wX wB
-> RepoPatchV1 prim wC wX
-> RepoPatchV1 prim wC wD
-> RepoPatchV1 prim wX wY
Merger FL (RepoPatchV1 prim) wY wX
undoit ((\(RL (RepoPatchV1 prim) wY wZ
a :> RepoPatchV1 prim wZ wX
b) -> (RL (RepoPatchV1 prim) wY wZ
a forall (a :: * -> * -> *) wX wB wZ.
RL a wX wB -> a wB wZ -> RL a wX wZ
:<: RepoPatchV1 prim wZ wX
b)) (:>) (RL (RepoPatchV1 prim)) (RepoPatchV1 prim) wY wX
unwindings) RepoPatchV1 prim wX wY
p1 RepoPatchV1 prim wX wZ
p2
          sealed_undoit :: Sealed (FL (RepoPatchV1 prim) wY)
sealed_undoit =
              case (forall (prim :: * -> * -> *) wA wB. RepoPatchV1 prim wA wB -> Bool
isMerger RepoPatchV1 prim wX wY
p1, forall (prim :: * -> * -> *) wA wB. RepoPatchV1 prim wA wB -> Bool
isMerger RepoPatchV1 prim wX wZ
p2) of
              (Bool
True ,Bool
True ) -> case Sealed ((:>) (RL (RepoPatchV1 prim)) (RepoPatchV1 prim) wY)
sealed_unwindings of
                                 Sealed (RL (RepoPatchV1 prim) wY wZ
t :> RepoPatchV1 prim wZ wX
_) -> forall (a :: * -> *) wB. a wB -> Sealed a
Sealed forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
Invert p =>
RL p wX wY -> FL p wY wX
invertRL RL (RepoPatchV1 prim) wY wZ
t
              (Bool
False,Bool
False) -> forall (a :: * -> *) wB. a wB -> Sealed a
Sealed forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wX wY
p1 forall (a :: * -> * -> *) wX wB wZ.
a wX wB -> FL a wB wZ -> FL a wX wZ
:>: forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
              (Bool
True ,Bool
False) -> forall (a :: * -> *) wB. a wB -> Sealed a
Sealed forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
              (Bool
False,Bool
True ) -> forall (a :: * -> *) wB. a wB -> Sealed a
Sealed forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wX wY
p1 forall (a :: * -> * -> *) wX wB wZ.
a wX wB -> FL a wB wZ -> FL a wX wZ
:>: forall (prim :: * -> * -> *) wX wY.
RepoPatchV1 prim wX wY -> FL (RepoPatchV1 prim) wX wY
mergerUndo RepoPatchV1 prim wX wZ
p2
merger String
g RepoPatchV1 prim wX wY
_ RepoPatchV1 prim wX wZ
_ =
    forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"Cannot handle mergers other than version 0.0\n"forall a. [a] -> [a] -> [a]
++String
g
    forall a. [a] -> [a] -> [a]
++ String
"\nPlease use darcs optimize --modernize with an older darcs."

instance PrimPatch prim => Effect (RepoPatchV1 prim) where
    effect :: forall wX wY.
RepoPatchV1 prim wX wY -> FL (PrimOf (RepoPatchV1 prim)) wX wY
effect p :: RepoPatchV1 prim wX wY
p@(Merger{}) = forall (p :: * -> * -> *) wX wY.
(Commute p, Invert p, Eq2 p) =>
FL p wX wY -> FL p wX wY
dropAllInverses forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
Effect p =>
p wX wY -> FL (PrimOf p) wX wY
effect forall a b. (a -> b) -> a -> b
$ forall (prim :: * -> * -> *) wX wY.
RepoPatchV1 prim wX wY -> FL (RepoPatchV1 prim) wX wY
mergerUndo RepoPatchV1 prim wX wY
p
    effect p :: RepoPatchV1 prim wX wY
p@(Regrem{}) = forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
Effect p =>
p wX wY -> FL (PrimOf p) wX wY
effect forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert RepoPatchV1 prim wX wY
p
    effect (PP prim wX wY
p) = prim wX wY
p forall (a :: * -> * -> *) wX wB wZ.
a wX wB -> FL a wB wZ -> FL a wX wZ
:>: forall (a :: * -> * -> *) wX. FL a wX wX
NilFL

instance IsHunk prim => IsHunk (RepoPatchV1 prim) where
    isHunk :: forall wX wY. RepoPatchV1 prim wX wY -> Maybe (FileHunk wX wY)
isHunk RepoPatchV1 prim wX wY
p = do PP prim wX wY
p' <- forall (m :: * -> *) a. Monad m => a -> m a
return RepoPatchV1 prim wX wY
p
                  forall (p :: * -> * -> *) wX wY.
IsHunk p =>
p wX wY -> Maybe (FileHunk wX wY)
isHunk prim wX wY
p'

newUr :: PrimPatch prim
    => RepoPatchV1 prim wA wB -> RL (RepoPatchV1 prim) wX wY -> [Sealed (RL (RepoPatchV1 prim) wX)]
newUr :: forall (prim :: * -> * -> *) wA wB wX wY.
PrimPatch prim =>
RepoPatchV1 prim wA wB
-> RL (RepoPatchV1 prim) wX wY
-> [Sealed (RL (RepoPatchV1 prim) wX)]
newUr RepoPatchV1 prim wA wB
p (RL (RepoPatchV1 prim) wX wY
ps :<: Merger FL (RepoPatchV1 prim) wY wY
_ RL (RepoPatchV1 prim) wY wB
_ RepoPatchV1 prim wC wY
p1 RepoPatchV1 prim wC wD
p2) =
   case forall a. (a -> Bool) -> [a] -> [a]
filter (\(RL (RepoPatchV1 prim) wX wY
_:<:RepoPatchV1 prim wY wY
pp) -> RepoPatchV1 prim wY wY
pp forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
`unsafeCompare` RepoPatchV1 prim wC wY
p1) forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
Commute p =>
RL p wX wY -> [RL p wX wY]
headPermutationsRL RL (RepoPatchV1 prim) wX wY
ps of
   ((RL (RepoPatchV1 prim) wX wY
ps':<:RepoPatchV1 prim wY wY
_):[RL (RepoPatchV1 prim) wX wY]
_) -> forall (prim :: * -> * -> *) wA wB wX wY.
PrimPatch prim =>
RepoPatchV1 prim wA wB
-> RL (RepoPatchV1 prim) wX wY
-> [Sealed (RL (RepoPatchV1 prim) wX)]
newUr RepoPatchV1 prim wA wB
p (RL (RepoPatchV1 prim) wX wY
ps'forall (a :: * -> * -> *) wX wB wZ.
RL a wX wB -> a wB wZ -> RL a wX wZ
:<:forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart RepoPatchV1 prim wC wY
p1) forall a. [a] -> [a] -> [a]
++ forall (prim :: * -> * -> *) wA wB wX wY.
PrimPatch prim =>
RepoPatchV1 prim wA wB
-> RL (RepoPatchV1 prim) wX wY
-> [Sealed (RL (RepoPatchV1 prim) wX)]
newUr RepoPatchV1 prim wA wB
p (RL (RepoPatchV1 prim) wX wY
ps'forall (a :: * -> * -> *) wX wB wZ.
RL a wX wB -> a wB wZ -> RL a wX wZ
:<:forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart RepoPatchV1 prim wC wD
p2)
   [RL (RepoPatchV1 prim) wX wY]
_ -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ Doc -> String
renderString forall a b. (a -> b) -> a -> b
$ String -> Doc
text String
"in function newUr"
                 Doc -> Doc -> Doc
$$ String -> Doc
text String
"Original patch:"
                 Doc -> Doc -> Doc
$$ forall (prim :: * -> * -> *) wX wY.
ShowPatchBasic prim =>
prim wX wY -> Doc
showPatch_ RepoPatchV1 prim wA wB
p
                 Doc -> Doc -> Doc
$$ String -> Doc
text String
"Unwound:"
                 Doc -> Doc -> Doc
$$ [Doc] -> Doc
vcat (forall (a :: * -> *) b. (forall wX. a wX -> b) -> Sealed a -> b
unseal (forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (prim :: * -> * -> *) wX wY.
ShowPatchBasic prim =>
prim wX wY -> Doc
showPatch_) forall a b. (a -> b) -> a -> b
$ forall (prim :: * -> * -> *) wX wY.
RepoPatchV1 prim wX wY -> Sealed (RL (RepoPatchV1 prim) wX)
unwind RepoPatchV1 prim wA wB
p)

newUr RepoPatchV1 prim wA wB
op RL (RepoPatchV1 prim) wX wY
ps =
    case forall a. (a -> Bool) -> [a] -> [a]
filter (\(RL (RepoPatchV1 prim) wX wY
_:<:RepoPatchV1 prim wY wY
p) -> forall (prim :: * -> * -> *) wA wB. RepoPatchV1 prim wA wB -> Bool
isMerger RepoPatchV1 prim wY wY
p) forall a b. (a -> b) -> a -> b
$ forall (p :: * -> * -> *) wX wY.
Commute p =>
RL p wX wY -> [RL p wX wY]
headPermutationsRL RL (RepoPatchV1 prim) wX wY
ps of
    [] -> [forall (a :: * -> *) wB. a wB -> Sealed a
Sealed RL (RepoPatchV1 prim) wX wY
ps]
    (RL (RepoPatchV1 prim) wX wY
ps':[RL (RepoPatchV1 prim) wX wY]
_) -> forall (prim :: * -> * -> *) wA wB wX wY.
PrimPatch prim =>
RepoPatchV1 prim wA wB
-> RL (RepoPatchV1 prim) wX wY
-> [Sealed (RL (RepoPatchV1 prim) wX)]
newUr RepoPatchV1 prim wA wB
op RL (RepoPatchV1 prim) wX wY
ps'

instance Invert prim => Invert (RepoPatchV1 prim) where
    invert :: forall wX wY. RepoPatchV1 prim wX wY -> RepoPatchV1 prim wY wX
invert (Merger FL (RepoPatchV1 prim) wX wY
undo RL (RepoPatchV1 prim) wX wB
unwindings RepoPatchV1 prim wC wX
p1 RepoPatchV1 prim wC wD
p2)
        = forall (prim :: * -> * -> *) wX wY wB wC wD.
FL (RepoPatchV1 prim) wX wY
-> RL (RepoPatchV1 prim) wX wB
-> RepoPatchV1 prim wC wX
-> RepoPatchV1 prim wC wD
-> RepoPatchV1 prim wY wX
Regrem FL (RepoPatchV1 prim) wX wY
undo RL (RepoPatchV1 prim) wX wB
unwindings RepoPatchV1 prim wC wX
p1 RepoPatchV1 prim wC wD
p2
    invert (Regrem FL (RepoPatchV1 prim) wY wX
undo RL (RepoPatchV1 prim) wY wB
unwindings RepoPatchV1 prim wC wY
p1 RepoPatchV1 prim wC wD
p2)
        = forall (prim :: * -> * -> *) wX wY wB wC wD.
FL (RepoPatchV1 prim) wX wY
-> RL (RepoPatchV1 prim) wX wB
-> RepoPatchV1 prim wC wX
-> RepoPatchV1 prim wC wD
-> RepoPatchV1 prim wX wY
Merger FL (RepoPatchV1 prim) wY wX
undo RL (RepoPatchV1 prim) wY wB
unwindings RepoPatchV1 prim wC wY
p1 RepoPatchV1 prim wC wD
p2
    invert (PP prim wX wY
p) = forall (prim :: * -> * -> *) wX wY.
prim wX wY -> RepoPatchV1 prim wX wY
PP (forall (p :: * -> * -> *) wX wY. Invert p => p wX wY -> p wY wX
invert prim wX wY
p)

instance Eq2 prim => Eq2 (RepoPatchV1 prim) where
    unsafeCompare :: forall wA wB wC wD.
RepoPatchV1 prim wA wB -> RepoPatchV1 prim wC wD -> Bool
unsafeCompare = forall (prim :: * -> * -> *) wX wY wW wZ.
Eq2 prim =>
RepoPatchV1 prim wX wY -> RepoPatchV1 prim wW wZ -> Bool
eqPatches

instance Eq2 prim => Eq (RepoPatchV1 prim wX wY) where
    == :: RepoPatchV1 prim wX wY -> RepoPatchV1 prim wX wY -> Bool
(==) = forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
unsafeCompare

eqPatches :: Eq2 prim => RepoPatchV1 prim wX wY -> RepoPatchV1 prim wW wZ -> Bool
eqPatches :: forall (prim :: * -> * -> *) wX wY wW wZ.
Eq2 prim =>
RepoPatchV1 prim wX wY -> RepoPatchV1 prim wW wZ -> Bool
eqPatches (PP prim wX wY
p1) (PP prim wW wZ
p2) = forall (p :: * -> * -> *) wA wB wC wD.
Eq2 p =>
p wA wB -> p wC wD -> Bool
unsafeCompare prim wX wY
p1 prim wW wZ
p2
eqPatches (Merger FL (RepoPatchV1 prim) wX wY
_ RL (RepoPatchV1 prim) wX wB
_ RepoPatchV1 prim wC wX
p1a RepoPatchV1 prim wC wD
p1b) (Merger FL (RepoPatchV1 prim) wW wZ
_ RL (RepoPatchV1 prim) wW wB
_ RepoPatchV1 prim wC wW
p2a RepoPatchV1 prim wC wD
p2b)
 = forall (prim :: * -> * -> *) wX wY wW wZ.
Eq2 prim =>
RepoPatchV1 prim wX wY -> RepoPatchV1 prim wW wZ -> Bool
eqPatches RepoPatchV1 prim wC wX
p1a RepoPatchV1 prim wC wW
p2a Bool -> Bool -> Bool
&&
   forall (prim :: * -> * -> *) wX wY wW wZ.
Eq2 prim =>
RepoPatchV1 prim wX wY -> RepoPatchV1 prim wW wZ -> Bool
eqPatches RepoPatchV1 prim wC wD
p1b RepoPatchV1 prim wC wD
p2b
eqPatches (Regrem FL (RepoPatchV1 prim) wY wX
_ RL (RepoPatchV1 prim) wY wB
_ RepoPatchV1 prim wC wY
p1a RepoPatchV1 prim wC wD
p1b) (Regrem FL (RepoPatchV1 prim) wZ wW
_ RL (RepoPatchV1 prim) wZ wB
_ RepoPatchV1 prim wC wZ
p2a RepoPatchV1 prim wC wD
p2b)
 = forall (prim :: * -> * -> *) wX wY wW wZ.
Eq2 prim =>
RepoPatchV1 prim wX wY -> RepoPatchV1 prim wW wZ -> Bool
eqPatches RepoPatchV1 prim wC wY
p1a RepoPatchV1 prim wC wZ
p2a Bool -> Bool -> Bool
&&
   forall (prim :: * -> * -> *) wX wY wW wZ.
Eq2 prim =>
RepoPatchV1 prim wX wY -> RepoPatchV1 prim wW wZ -> Bool
eqPatches RepoPatchV1 prim wC wD
p1b RepoPatchV1 prim wC wD
p2b
eqPatches RepoPatchV1 prim wX wY
_ RepoPatchV1 prim wW wZ
_ = Bool
False