--  Copyright (C) 2011-2 Ganesh Sittampalam
--
--  BSD3

module Darcs.Patch.Rebase.Name
    ( RebaseName(..)
    , commuteNamePrim, commutePrimName
    , commuteNameNamed, commuteNamedName
    , canonizeNamePair
    ) where

import Prelude ()
import Darcs.Prelude

import Darcs.Patch.CommuteFn ( CommuteFn )
import Darcs.Patch.Effect ( Effect(..) )
import Darcs.Patch.Info ( PatchInfo, isInverted, showPatchInfo, readPatchInfo )
import Darcs.Patch.Inspect ( PatchInspect(..) )
import Darcs.Patch.Named ( Named(..) )
import Darcs.Patch.Apply ( Apply(..) )
import Darcs.Patch.Commute ( Commute(..) )
import Darcs.Patch.Invert ( Invert(..) )
import Darcs.Patch.Read ( ReadPatch(..) )
import Darcs.Patch.Show ( ShowPatch(..) )
import Darcs.Patch.Permutations ( inverseCommuter )
import Darcs.Patch.Prim ( PrimPatchBase(..) )
import Darcs.Patch.ReadMonads ( lexString )
import Darcs.Patch.Show ( ShowPatchBasic(..) )
import Darcs.Patch.Witnesses.Eq ( Eq2(..) )
import Darcs.Patch.Witnesses.Ordered ( (:>)(..), FL(..) )
import Darcs.Patch.Witnesses.Sealed ( Sealed(..) )
import Darcs.Patch.Witnesses.Show
    ( Show1(..), Show2(..)
    , ShowDict(ShowDictClass)
    )
import Darcs.Patch.Witnesses.Unsafe ( unsafeCoerceP )

import Darcs.Util.Printer ( empty, blueText, ($$) )

import Control.Applicative ( (<|>) )
import qualified Data.ByteString.Char8 as BC ( pack )

-- Note: in principle this is a general concept not limited to
-- rebase, and we might be able to generalise this type and
-- refactor named patches to use it too.
-- | A 'RebaseName' encapsulates the concept of the name of a patch,
-- without any contents. This allows us to track explicit dependencies
-- in the rebase state, changing them to follow uses of amend-record
-- or unsuspend on a depended-on patch, and warning the user if any
-- are lost entirely.
data RebaseName (p :: * -> * -> *) wX wY where
  AddName :: PatchInfo -> RebaseName p wX wY
  DelName :: PatchInfo -> RebaseName p wX wY
  Rename :: PatchInfo -> PatchInfo -> RebaseName p wX wY
    deriving Int -> RebaseName p wX wY -> ShowS
[RebaseName p wX wY] -> ShowS
RebaseName p wX wY -> String
(Int -> RebaseName p wX wY -> ShowS)
-> (RebaseName p wX wY -> String)
-> ([RebaseName p wX wY] -> ShowS)
-> Show (RebaseName p wX wY)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (p :: * -> * -> *) wX wY. Int -> RebaseName p wX wY -> ShowS
forall (p :: * -> * -> *) wX wY. [RebaseName p wX wY] -> ShowS
forall (p :: * -> * -> *) wX wY. RebaseName p wX wY -> String
showList :: [RebaseName p wX wY] -> ShowS
$cshowList :: forall (p :: * -> * -> *) wX wY. [RebaseName p wX wY] -> ShowS
show :: RebaseName p wX wY -> String
$cshow :: forall (p :: * -> * -> *) wX wY. RebaseName p wX wY -> String
showsPrec :: Int -> RebaseName p wX wY -> ShowS
$cshowsPrec :: forall (p :: * -> * -> *) wX wY. Int -> RebaseName p wX wY -> ShowS
Show

instance Show1 (RebaseName p wX) where
    showDict1 :: ShowDict (RebaseName p wX wX)
showDict1 = ShowDict (RebaseName p wX wX)
forall a. Show a => ShowDict a
ShowDictClass

instance Show2 (RebaseName p) where
    showDict2 :: ShowDict (RebaseName p wX wY)
showDict2 = ShowDict (RebaseName p wX wY)
forall a. Show a => ShowDict a
ShowDictClass

instance ShowPatchBasic (RebaseName p) where
   showPatch :: ShowPatchFor -> RebaseName p wX wY -> Doc
showPatch f :: ShowPatchFor
f (AddName n :: PatchInfo
n) = String -> Doc
blueText "addname" Doc -> Doc -> Doc
$$ ShowPatchFor -> PatchInfo -> Doc
showPatchInfo ShowPatchFor
f PatchInfo
n
   showPatch f :: ShowPatchFor
f (DelName n :: PatchInfo
n) = String -> Doc
blueText "delname" Doc -> Doc -> Doc
$$ ShowPatchFor -> PatchInfo -> Doc
showPatchInfo ShowPatchFor
f PatchInfo
n
   showPatch f :: ShowPatchFor
f (Rename old :: PatchInfo
old new :: PatchInfo
new) = String -> Doc
blueText "rename" Doc -> Doc -> Doc
$$ ShowPatchFor -> PatchInfo -> Doc
showPatchInfo ShowPatchFor
f PatchInfo
old Doc -> Doc -> Doc
$$ ShowPatchFor -> PatchInfo -> Doc
showPatchInfo ShowPatchFor
f PatchInfo
new

instance ShowPatch (RebaseName p) where
   summary :: RebaseName p wX wY -> Doc
summary _ = Doc
empty -- TODO improve this?
   summaryFL :: FL (RebaseName p) wX wY -> Doc
summaryFL _ = Doc
empty

instance ReadPatch (RebaseName p) where
   readPatch' :: m (Sealed (RebaseName p wX))
readPatch' = m (Sealed (RebaseName p wX))
forall (p :: * -> * -> *) wX. m (Sealed (RebaseName p wX))
readAddName m (Sealed (RebaseName p wX))
-> m (Sealed (RebaseName p wX)) -> m (Sealed (RebaseName p wX))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> m (Sealed (RebaseName p wX))
forall (p :: * -> * -> *) wX. m (Sealed (RebaseName p wX))
readDelName m (Sealed (RebaseName p wX))
-> m (Sealed (RebaseName p wX)) -> m (Sealed (RebaseName p wX))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> m (Sealed (RebaseName p wX))
forall (p :: * -> * -> *) wX. m (Sealed (RebaseName p wX))
readRename
     where
       readAddName :: m (Sealed (RebaseName p wX))
readAddName = do ByteString -> m ()
forall (m :: * -> *). ParserM m => ByteString -> m ()
lexString (String -> ByteString
BC.pack "addname")
                        PatchInfo
n <- m PatchInfo
forall (m :: * -> *). ParserM m => m PatchInfo
readPatchInfo
                        Sealed (RebaseName p wX) -> m (Sealed (RebaseName p wX))
forall (m :: * -> *) a. Monad m => a -> m a
return (RebaseName p wX Any -> Sealed (RebaseName p wX)
forall (a :: * -> *) wX. a wX -> Sealed a
Sealed (PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
AddName PatchInfo
n))
       readDelName :: m (Sealed (RebaseName p wX))
readDelName = do ByteString -> m ()
forall (m :: * -> *). ParserM m => ByteString -> m ()
lexString (String -> ByteString
BC.pack "delname")
                        PatchInfo
n <- m PatchInfo
forall (m :: * -> *). ParserM m => m PatchInfo
readPatchInfo
                        Sealed (RebaseName p wX) -> m (Sealed (RebaseName p wX))
forall (m :: * -> *) a. Monad m => a -> m a
return (RebaseName p wX Any -> Sealed (RebaseName p wX)
forall (a :: * -> *) wX. a wX -> Sealed a
Sealed (PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
DelName PatchInfo
n))
       readRename :: m (Sealed (RebaseName p wX))
readRename  = do ByteString -> m ()
forall (m :: * -> *). ParserM m => ByteString -> m ()
lexString (String -> ByteString
BC.pack "rename")
                        PatchInfo
old <- m PatchInfo
forall (m :: * -> *). ParserM m => m PatchInfo
readPatchInfo
                        PatchInfo
new <- m PatchInfo
forall (m :: * -> *). ParserM m => m PatchInfo
readPatchInfo
                        Sealed (RebaseName p wX) -> m (Sealed (RebaseName p wX))
forall (m :: * -> *) a. Monad m => a -> m a
return (RebaseName p wX Any -> Sealed (RebaseName p wX)
forall (a :: * -> *) wX. a wX -> Sealed a
Sealed (PatchInfo -> PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY.
PatchInfo -> PatchInfo -> RebaseName p wX wY
Rename PatchInfo
old PatchInfo
new))

instance Commute (RebaseName p) where
   commute :: (:>) (RebaseName p) (RebaseName p) wX wY
-> Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
commute (AddName n1 :: PatchInfo
n1 :> AddName n2 :: PatchInfo
n2)
      | PatchInfo
n1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
n2 = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a
impossible
      | Bool
otherwise = (:>) (RebaseName p) (RebaseName p) wX wY
-> Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
AddName PatchInfo
n2 RebaseName p wX Any
-> RebaseName p Any wY -> (:>) (RebaseName p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
AddName PatchInfo
n1)
   commute (DelName n1 :: PatchInfo
n1 :> DelName n2 :: PatchInfo
n2)
      | PatchInfo
n1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
n2 = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a
impossible
      | Bool
otherwise = (:>) (RebaseName p) (RebaseName p) wX wY
-> Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
DelName PatchInfo
n2 RebaseName p wX Any
-> RebaseName p Any wY -> (:>) (RebaseName p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
DelName PatchInfo
n1)
   commute (AddName n1 :: PatchInfo
n1 :> DelName n2 :: PatchInfo
n2)
      | PatchInfo
n1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
/= PatchInfo
n2 = (:>) (RebaseName p) (RebaseName p) wX wY
-> Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
DelName PatchInfo
n2 RebaseName p wX Any
-> RebaseName p Any wY -> (:>) (RebaseName p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
AddName PatchInfo
n1)
      | Bool
otherwise = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. Maybe a
Nothing
   commute (DelName n1 :: PatchInfo
n1 :> AddName n2 :: PatchInfo
n2)
      | PatchInfo
n1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
/= PatchInfo
n2 = (:>) (RebaseName p) (RebaseName p) wX wY
-> Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
AddName PatchInfo
n2 RebaseName p wX Any
-> RebaseName p Any wY -> (:>) (RebaseName p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
DelName PatchInfo
n1)
      | Bool
otherwise = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. Maybe a
Nothing
   commute (Rename old :: PatchInfo
old new :: PatchInfo
new :> AddName n :: PatchInfo
n)
      | PatchInfo
n PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
old = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. Maybe a
Nothing
      | PatchInfo
n PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
new = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a
impossible -- precondition of Add is that n doesn't exist
      | Bool
otherwise = (:>) (RebaseName p) (RebaseName p) wX wY
-> Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
AddName PatchInfo
n RebaseName p wX Any
-> RebaseName p Any wY -> (:>) (RebaseName p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY.
PatchInfo -> PatchInfo -> RebaseName p wX wY
Rename PatchInfo
old PatchInfo
new)
   commute (AddName n :: PatchInfo
n :> Rename old :: PatchInfo
old new :: PatchInfo
new)
      | PatchInfo
n PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
old = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. Maybe a
Nothing
      | PatchInfo
n PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
new = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a
impossible -- precondition of Rename is that new doesn't exist
      | Bool
otherwise = (:>) (RebaseName p) (RebaseName p) wX wY
-> Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY.
PatchInfo -> PatchInfo -> RebaseName p wX wY
Rename PatchInfo
old PatchInfo
new RebaseName p wX Any
-> RebaseName p Any wY -> (:>) (RebaseName p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
AddName PatchInfo
n)
   commute (Rename old :: PatchInfo
old new :: PatchInfo
new :> DelName n :: PatchInfo
n)
      | PatchInfo
n PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
old = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a
impossible -- precondition of Del is that n does exist
      | PatchInfo
n PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
new = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. Maybe a
Nothing
      | Bool
otherwise = (:>) (RebaseName p) (RebaseName p) wX wY
-> Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
DelName PatchInfo
n RebaseName p wX Any
-> RebaseName p Any wY -> (:>) (RebaseName p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY.
PatchInfo -> PatchInfo -> RebaseName p wX wY
Rename PatchInfo
old PatchInfo
new)
   commute (DelName n :: PatchInfo
n :> Rename old :: PatchInfo
old new :: PatchInfo
new)
      | PatchInfo
n PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
old = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a
impossible -- precondition of Rename is that old does exist
      | PatchInfo
n PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
new = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. Maybe a
Nothing
      | Bool
otherwise = (:>) (RebaseName p) (RebaseName p) wX wY
-> Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY.
PatchInfo -> PatchInfo -> RebaseName p wX wY
Rename PatchInfo
old PatchInfo
new RebaseName p wX Any
-> RebaseName p Any wY -> (:>) (RebaseName p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
DelName PatchInfo
n)
   commute (Rename old1 :: PatchInfo
old1 new1 :: PatchInfo
new1 :> Rename old2 :: PatchInfo
old2 new2 :: PatchInfo
new2)
      | PatchInfo
old1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
old2 = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a
impossible
      | PatchInfo
new1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
new2 = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a
impossible
      | PatchInfo
old1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
new2 = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. Maybe a
Nothing
      | PatchInfo
new1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
old2 = Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. Maybe a
Nothing
      | Bool
otherwise = (:>) (RebaseName p) (RebaseName p) wX wY
-> Maybe ((:>) (RebaseName p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY.
PatchInfo -> PatchInfo -> RebaseName p wX wY
Rename PatchInfo
old2 PatchInfo
new2 RebaseName p wX Any
-> RebaseName p Any wY -> (:>) (RebaseName p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY.
PatchInfo -> PatchInfo -> RebaseName p wX wY
Rename PatchInfo
old1 PatchInfo
new1)

instance Invert (RebaseName p) where
   invert :: RebaseName p wX wY -> RebaseName p wY wX
invert (AddName n :: PatchInfo
n) = PatchInfo -> RebaseName p wY wX
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
DelName PatchInfo
n
   invert (DelName n :: PatchInfo
n) = PatchInfo -> RebaseName p wY wX
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
AddName PatchInfo
n
   invert (Rename old :: PatchInfo
old new :: PatchInfo
new) = PatchInfo -> PatchInfo -> RebaseName p wY wX
forall (p :: * -> * -> *) wX wY.
PatchInfo -> PatchInfo -> RebaseName p wX wY
Rename PatchInfo
new PatchInfo
old

instance PatchInspect (RebaseName p) where
    listTouchedFiles :: RebaseName p wX wY -> [String]
listTouchedFiles _ = []
    hunkMatches :: (ByteString -> Bool) -> RebaseName p wX wY -> Bool
hunkMatches _ _ = Bool
False

instance Apply (RebaseName p) where
   type ApplyState (RebaseName p) = ApplyState p
   apply :: RebaseName p wX wY -> m ()
apply _ = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

instance PrimPatchBase p => PrimPatchBase (RebaseName p) where
   type PrimOf (RebaseName p) = PrimOf p

instance Effect (RebaseName p) where
   effect :: RebaseName p wX wY -> FL (PrimOf (RebaseName p)) wX wY
effect _ = FL (PrimOf p) Any Any -> FL (PrimOf p) wX wY
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP FL (PrimOf p) Any Any
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL

instance Eq2 (RebaseName p) where
   AddName n1 :: PatchInfo
n1 unsafeCompare :: RebaseName p wA wB -> RebaseName p wC wD -> Bool
`unsafeCompare` AddName n2 :: PatchInfo
n2 = PatchInfo
n1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
n2
   AddName _ `unsafeCompare` _ = Bool
False
   _ `unsafeCompare` AddName _ = Bool
False

   DelName n1 :: PatchInfo
n1 `unsafeCompare` DelName n2 :: PatchInfo
n2 = PatchInfo
n1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
n2
   DelName _ `unsafeCompare` _ = Bool
False
   _ `unsafeCompare` DelName _ = Bool
False

   Rename old1 :: PatchInfo
old1 new1 :: PatchInfo
new1 `unsafeCompare` Rename old2 :: PatchInfo
old2 new2 :: PatchInfo
new2 = PatchInfo
old1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
old2 Bool -> Bool -> Bool
&& PatchInfo
new1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
new2
   -- Rename _ _  `unsafeCompare` _ = False
   -- _ `unsafeCompare` Rename _ _  = False


-- |Commute a name patch and a primitive patch. They trivially
-- commute so this just involves changing the witnesses.
commuteNamePrim :: (RebaseName p :> PrimOf p) wX wY -> (PrimOf p :> RebaseName p) wX wY
commuteNamePrim :: (:>) (RebaseName p) (PrimOf p) wX wY
-> (:>) (PrimOf p) (RebaseName p) wX wY
commuteNamePrim (n :: RebaseName p wX wZ
n :> f :: PrimOf p wZ wY
f) = PrimOf p wZ wY -> PrimOf p wX Any
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP PrimOf p wZ wY
f PrimOf p wX Any
-> RebaseName p Any wY -> (:>) (PrimOf p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RebaseName p wX wZ -> RebaseName p Any wY
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP RebaseName p wX wZ
n

-- |Commute a primitive patch and a name patch. They trivially
-- commute so this just involves changing the witnesses.
commutePrimName :: (PrimOf p :> RebaseName p) wX wY -> (RebaseName p :> PrimOf p) wX wY
commutePrimName :: (:>) (PrimOf p) (RebaseName p) wX wY
-> (:>) (RebaseName p) (PrimOf p) wX wY
commutePrimName (f :: PrimOf p wX wZ
f :> n :: RebaseName p wZ wY
n) = RebaseName p wZ wY -> RebaseName p wX Any
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP RebaseName p wZ wY
n RebaseName p wX Any
-> PrimOf p Any wY -> (:>) (RebaseName p) (PrimOf p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PrimOf p wX wZ -> PrimOf p Any wY
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP PrimOf p wX wZ
f

-- |Commute a name patch and a named patch. In most cases this is
-- trivial but we do need to check explicit dependencies.
commuteNameNamed :: Invert p => CommuteFn (RebaseName p) (Named p)
commuteNameNamed :: CommuteFn (RebaseName p) (Named p)
commuteNameNamed pair :: (:>) (RebaseName p) (Named p) wX wY
pair@(_ :> NamedP pn :: PatchInfo
pn _ _)
  | PatchInfo -> Bool
isInverted PatchInfo
pn = CommuteFn (Named p) (RebaseName p)
-> (:>) (RebaseName p) (Named p) wX wY
-> Maybe ((:>) (Named p) (RebaseName p) wX wY)
forall (p :: * -> * -> *) (q :: * -> * -> *).
(Invert p, Invert q) =>
CommuteFn p q -> CommuteFn q p
inverseCommuter CommuteFn (Named p) (RebaseName p)
forall (p :: * -> * -> *).
Invert p =>
CommuteFn (Named p) (RebaseName p)
commuteNamedName (:>) (RebaseName p) (Named p) wX wY
pair
commuteNameNamed (AddName an :: PatchInfo
an :> p :: Named p wZ wY
p@(NamedP pn :: PatchInfo
pn deps :: [PatchInfo]
deps _))
  | PatchInfo
an PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
pn = Maybe ((:>) (Named p) (RebaseName p) wX wY)
forall a. a
impossible
  | PatchInfo
an PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PatchInfo]
deps = Maybe ((:>) (Named p) (RebaseName p) wX wY)
forall a. Maybe a
Nothing
  | Bool
otherwise = (:>) (Named p) (RebaseName p) wX wY
-> Maybe ((:>) (Named p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (Named p wZ wY -> Named p wX Any
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP Named p wZ wY
p Named p wX Any
-> RebaseName p Any wY -> (:>) (Named p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
AddName PatchInfo
an)
commuteNameNamed (DelName dn :: PatchInfo
dn :> p :: Named p wZ wY
p@(NamedP pn :: PatchInfo
pn deps :: [PatchInfo]
deps _))
  | PatchInfo
dn PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
pn = Maybe ((:>) (Named p) (RebaseName p) wX wY)
forall a. a
impossible
  | PatchInfo
dn PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PatchInfo]
deps = Maybe ((:>) (Named p) (RebaseName p) wX wY)
forall a. a
impossible
  | Bool
otherwise = (:>) (Named p) (RebaseName p) wX wY
-> Maybe ((:>) (Named p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (Named p wZ wY -> Named p wX Any
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP Named p wZ wY
p Named p wX Any
-> RebaseName p Any wY -> (:>) (Named p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
DelName PatchInfo
dn)
commuteNameNamed (Rename old :: PatchInfo
old new :: PatchInfo
new :> NamedP pn :: PatchInfo
pn deps :: [PatchInfo]
deps body :: FL p wZ wY
body)
  | PatchInfo
old PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
pn = Maybe ((:>) (Named p) (RebaseName p) wX wY)
forall a. a
impossible
  | PatchInfo
new PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
pn = Maybe ((:>) (Named p) (RebaseName p) wX wY)
forall a. a
impossible
  | PatchInfo
old PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PatchInfo]
deps = Maybe ((:>) (Named p) (RebaseName p) wX wY)
forall a. a
impossible
  | Bool
otherwise =
      let newdeps :: [PatchInfo]
newdeps = (PatchInfo -> PatchInfo) -> [PatchInfo] -> [PatchInfo]
forall a b. (a -> b) -> [a] -> [b]
map (\dep :: PatchInfo
dep -> if PatchInfo
new PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
dep then PatchInfo
old else PatchInfo
dep) [PatchInfo]
deps
      in (:>) (Named p) (RebaseName p) wX wY
-> Maybe ((:>) (Named p) (RebaseName p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> [PatchInfo] -> FL p wX Any -> Named p wX Any
forall (p :: * -> * -> *) wX wY.
PatchInfo -> [PatchInfo] -> FL p wX wY -> Named p wX wY
NamedP PatchInfo
pn [PatchInfo]
newdeps (FL p wZ wY -> FL p wX Any
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP FL p wZ wY
body) Named p wX Any
-> RebaseName p Any wY -> (:>) (Named p) (RebaseName p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> PatchInfo -> RebaseName p Any wY
forall (p :: * -> * -> *) wX wY.
PatchInfo -> PatchInfo -> RebaseName p wX wY
Rename PatchInfo
old PatchInfo
new)

-- |Commute a named patch and a name patch. In most cases this is
-- trivial but we do need to check explicit dependencies.
commuteNamedName :: Invert p => CommuteFn (Named p) (RebaseName p)
commuteNamedName :: CommuteFn (Named p) (RebaseName p)
commuteNamedName pair :: (:>) (Named p) (RebaseName p) wX wY
pair@(NamedP pn :: PatchInfo
pn _ _ :> _)
  | PatchInfo -> Bool
isInverted PatchInfo
pn = CommuteFn (RebaseName p) (Named p)
-> (:>) (Named p) (RebaseName p) wX wY
-> Maybe ((:>) (RebaseName p) (Named p) wX wY)
forall (p :: * -> * -> *) (q :: * -> * -> *).
(Invert p, Invert q) =>
CommuteFn p q -> CommuteFn q p
inverseCommuter CommuteFn (RebaseName p) (Named p)
forall (p :: * -> * -> *).
Invert p =>
CommuteFn (RebaseName p) (Named p)
commuteNameNamed (:>) (Named p) (RebaseName p) wX wY
pair
commuteNamedName (p :: Named p wX wZ
p@(NamedP pn :: PatchInfo
pn deps :: [PatchInfo]
deps _) :> AddName an :: PatchInfo
an)
  | PatchInfo
an PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
pn = Maybe ((:>) (RebaseName p) (Named p) wX wY)
forall a. a
impossible  -- the NamedP introduces pn, then AddName introduces it again
  | PatchInfo
an PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PatchInfo]
deps = Maybe ((:>) (RebaseName p) (Named p) wX wY)
forall a. a
impossible -- the NamedP depends on an before it is introduced
  | Bool
otherwise = (:>) (RebaseName p) (Named p) wX wY
-> Maybe ((:>) (RebaseName p) (Named p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
AddName PatchInfo
an RebaseName p wX Any
-> Named p Any wY -> (:>) (RebaseName p) (Named p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> Named p wX wZ -> Named p Any wY
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP Named p wX wZ
p)
commuteNamedName (p :: Named p wX wZ
p@(NamedP pn :: PatchInfo
pn deps :: [PatchInfo]
deps _) :> DelName dn :: PatchInfo
dn)
  | PatchInfo
dn PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
pn = Maybe ((:>) (RebaseName p) (Named p) wX wY)
forall a. Maybe a
Nothing
  | PatchInfo
dn PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PatchInfo]
deps = Maybe ((:>) (RebaseName p) (Named p) wX wY)
forall a. Maybe a
Nothing
  | Bool
otherwise = (:>) (RebaseName p) (Named p) wX wY
-> Maybe ((:>) (RebaseName p) (Named p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
DelName PatchInfo
dn RebaseName p wX Any
-> Named p Any wY -> (:>) (RebaseName p) (Named p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> Named p wX wZ -> Named p Any wY
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP Named p wX wZ
p)
commuteNamedName (NamedP pn :: PatchInfo
pn deps :: [PatchInfo]
deps body :: FL p wX wZ
body :> Rename old :: PatchInfo
old new :: PatchInfo
new)
  | PatchInfo
old PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
pn = Maybe ((:>) (RebaseName p) (Named p) wX wY)
forall a. Maybe a
Nothing
  | PatchInfo
new PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
pn = Maybe ((:>) (RebaseName p) (Named p) wX wY)
forall a. a
impossible
  | PatchInfo
new PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PatchInfo]
deps = Maybe ((:>) (RebaseName p) (Named p) wX wY)
forall a. a
impossible
  | Bool
otherwise =
      let newdeps :: [PatchInfo]
newdeps = (PatchInfo -> PatchInfo) -> [PatchInfo] -> [PatchInfo]
forall a b. (a -> b) -> [a] -> [b]
map (\dep :: PatchInfo
dep -> if PatchInfo
old PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
dep then PatchInfo
new else PatchInfo
dep) [PatchInfo]
deps
      in (:>) (RebaseName p) (Named p) wX wY
-> Maybe ((:>) (RebaseName p) (Named p) wX wY)
forall a. a -> Maybe a
Just (PatchInfo -> PatchInfo -> RebaseName p wX Any
forall (p :: * -> * -> *) wX wY.
PatchInfo -> PatchInfo -> RebaseName p wX wY
Rename PatchInfo
old PatchInfo
new RebaseName p wX Any
-> Named p Any wY -> (:>) (RebaseName p) (Named p) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfo -> [PatchInfo] -> FL p Any wY -> Named p Any wY
forall (p :: * -> * -> *) wX wY.
PatchInfo -> [PatchInfo] -> FL p wX wY -> Named p wX wY
NamedP PatchInfo
pn [PatchInfo]
newdeps (FL p wX wZ -> FL p Any wY
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP FL p wX wZ
body))

canonizeNamePair :: (RebaseName p :> RebaseName p) wX wY -> FL (RebaseName p) wX wY
canonizeNamePair :: (:>) (RebaseName p) (RebaseName p) wX wY -> FL (RebaseName p) wX wY
canonizeNamePair (AddName n :: PatchInfo
n :> Rename old :: PatchInfo
old new :: PatchInfo
new) | PatchInfo
n PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
old = PatchInfo -> RebaseName p wX wY
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
AddName PatchInfo
new RebaseName p wX wY
-> FL (RebaseName p) wY wY -> FL (RebaseName p) wX wY
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (RebaseName p) wY wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
canonizeNamePair (Rename old :: PatchInfo
old new :: PatchInfo
new :> DelName n :: PatchInfo
n) | PatchInfo
n PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
new = PatchInfo -> RebaseName p wX wY
forall (p :: * -> * -> *) wX wY. PatchInfo -> RebaseName p wX wY
DelName PatchInfo
old RebaseName p wX wY
-> FL (RebaseName p) wY wY -> FL (RebaseName p) wX wY
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (RebaseName p) wY wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
canonizeNamePair (Rename old1 :: PatchInfo
old1 new1 :: PatchInfo
new1 :> Rename old2 :: PatchInfo
old2 new2 :: PatchInfo
new2) | PatchInfo
new1 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
old2 = PatchInfo -> PatchInfo -> RebaseName p wX wY
forall (p :: * -> * -> *) wX wY.
PatchInfo -> PatchInfo -> RebaseName p wX wY
Rename PatchInfo
old1 PatchInfo
new2 RebaseName p wX wY
-> FL (RebaseName p) wY wY -> FL (RebaseName p) wX wY
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (RebaseName p) wY wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
canonizeNamePair (n1 :: RebaseName p wX wZ
n1 :> n2 :: RebaseName p wZ wY
n2) = RebaseName p wX wZ
n1 RebaseName p wX wZ
-> FL (RebaseName p) wZ wY -> FL (RebaseName p) wX wY
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: RebaseName p wZ wY
n2 RebaseName p wZ wY
-> FL (RebaseName p) wY wY -> FL (RebaseName p) wZ wY
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (RebaseName p) wY wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL