-- Copyright (C) 2003-2004 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.

{-# LANGUAGE ScopedTypeVariables #-}

module Darcs.Patch.Depends
    ( getUncovered
    , areUnrelatedRepos
    , findCommonAndUncommon
    , mergeThem
    , findCommonWithThem
    , countUsThem
    , removeFromPatchSet
    , slightlyOptimizePatchset
    , getPatchesBeyondTag
    , splitOnTag
    , patchSetUnion
    , patchSetIntersection
    , findUncommon
    , merge2FL
    , getDeps
    , SPatchAndDeps
    ) where

import Prelude ()
import Darcs.Prelude

import Prelude hiding ( pi )
import Data.List ( delete, intersect, (\\) )
import Data.Maybe ( fromMaybe )
import Control.Arrow ( (&&&) )

import Darcs.Patch ( RepoPatch )
import Darcs.Patch.Named ( Named (..), patch2patchinfo )
import Darcs.Patch.Named.Wrapped ( getdeps )
import Darcs.Patch.Choices ( Label, patchChoices, forceFirst
                           , PatchChoices, unLabel, getChoices
                           , LabelledPatch, label )
import Darcs.Patch.Commute ( Commute, commute, commuteFL, commuteRL )
import Darcs.Patch.Info ( PatchInfo, isTag, displayPatchInfo, piName )
import Darcs.Patch.Merge ( Merge, mergeFL )
import Darcs.Patch.Permutations ( partitionFL, partitionRL )
import Darcs.Patch.PatchInfoAnd( PatchInfoAnd, hopefully, hopefullyM, info )
import Darcs.Patch.Set ( PatchSet(..), Tagged(..), SealedPatchSet, patchSet2RL,
                         appendPSFL )
import Darcs.Patch.Progress ( progressRL )
import Darcs.Patch.Witnesses.Eq ( EqCheck(..), (=\/=), (=/\=) )
import Darcs.Patch.Witnesses.Unsafe ( unsafeCoerceP, unsafeCoercePStart )
import Darcs.Patch.Witnesses.Ordered
    ( (:\/:)(..), (:/\:)(..), (:>)(..), Fork(..),
    (+>>+), (+<<+), mapFL, RL(..), FL(..), isShorterThanRL,
    (+<+), reverseFL, reverseRL, mapRL, lengthFL, splitAtFL )
import Darcs.Patch.Witnesses.Sealed
    ( Sealed(..), FlippedSeal(..), flipSeal, seal, Sealed2(..), seal2 )

import Darcs.Util.Printer ( renderString, vcat )

{-
 - This module uses the following definitions:
 -
 - Explicit dependencies: the set of patches that a patch depends on "by name",
 - i.e. irrespective of (non-)commutation (non commuting patches are implicit
 - dependencies, or conflicts). In other words, the set of patch names in a tag
 - or patch recorded with --ask-deps.
 -
 - Covered: a patch p covers another, q, if p's explicit dependencies include
 - q. E.g. in a repo [a,b,t] where t is a tag and a,b have no explicit
 - dependencies, then t will cover a and b.
 -
 - "Clean" tag: a tag in a repository is clean if all patches prior to the tag
 - are (transitively-)covered by the tag. An obvious example of obtaining an
 - unclean tag is by pulling from one repo into another - the tag could have
 - been commuted past other patches. When patches are created, they are clean,
 - since they explicitly depend on all uncovered patches.
 -}

-- | S(ealed) Patch and his dependencies.
type SPatchAndDeps p = ( Sealed2 (LabelledPatch (Named p))
                       , Sealed2 (FL (LabelledPatch (Named p)))
                       )

-- | Searchs dependencies in @repoFL@ of the patches in @getDepsFL@.
getDeps :: (RepoPatch p) =>
            FL (Named p) wA wR -> FL (PatchInfoAnd rt p) wX wY -> [SPatchAndDeps p]
getDeps :: FL (Named p) wA wR
-> FL (PatchInfoAnd rt p) wX wY -> [SPatchAndDeps p]
getDeps repoFL :: FL (Named p) wA wR
repoFL getDepsFL :: FL (PatchInfoAnd rt p) wX wY
getDepsFL =
        let repoChoices :: PatchChoices (Named p) wA wR
repoChoices   = FL (Named p) wA wR -> PatchChoices (Named p) wA wR
forall (p :: * -> * -> *) wX wY. FL p wX wY -> PatchChoices p wX wY
patchChoices FL (Named p) wA wR
repoFL
            getDepsFL' :: [String]
getDepsFL'    = (forall wW wZ. PatchInfoAnd rt p wW wZ -> String)
-> FL (PatchInfoAnd rt p) wX wY -> [String]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> FL a wX wY -> [b]
mapFL (PatchInfo -> String
piName (PatchInfo -> String)
-> (PatchInfoAnd rt p wW wZ -> PatchInfo)
-> PatchInfoAnd rt p wW wZ
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info) FL (PatchInfoAnd rt p) wX wY
getDepsFL
            labelledDeps :: [(String, Label)]
labelledDeps  = [String] -> PatchChoices (Named p) wA wR -> [(String, Label)]
forall (p :: * -> * -> *) x y.
Commute p =>
[String] -> PatchChoices (Named p) x y -> [(String, Label)]
getLabelledDeps [String]
getDepsFL' PatchChoices (Named p) wA wR
repoChoices
        in
            ((String, Label) -> SPatchAndDeps p)
-> [(String, Label)] -> [SPatchAndDeps p]
forall a b. (a -> b) -> [a] -> [b]
map (PatchChoices (Named p) wA wR -> (String, Label) -> SPatchAndDeps p
forall (p :: * -> * -> *) wX wY.
Commute p =>
PatchChoices (Named p) wX wY -> (String, Label) -> SPatchAndDeps p
deps PatchChoices (Named p) wA wR
repoChoices) [(String, Label)]
labelledDeps
    where
        -- Search dependencies for the patch with label @l@ in @repoChoices@.
        deps :: (Commute p) => PatchChoices (Named p) wX wY ->
                (String,Label) -> SPatchAndDeps p
        deps :: PatchChoices (Named p) wX wY -> (String, Label) -> SPatchAndDeps p
deps repoChoices :: PatchChoices (Named p) wX wY
repoChoices (_,l :: Label
l) =
            case PatchChoices (Named p) wX wY
-> (:>)
     (FL (LabelledPatch (Named p)))
     (FL (LabelledPatch (Named p)) :> FL (LabelledPatch (Named p)))
     wX
     wY
forall (p :: * -> * -> *) wX wY.
Commute p =>
PatchChoices p wX wY
-> (:>)
     (FL (LabelledPatch p))
     (FL (LabelledPatch p) :> FL (LabelledPatch p))
     wX
     wY
getChoices (PatchChoices (Named p) wX wY
 -> (:>)
      (FL (LabelledPatch (Named p)))
      (FL (LabelledPatch (Named p)) :> FL (LabelledPatch (Named p)))
      wX
      wY)
-> PatchChoices (Named p) wX wY
-> (:>)
     (FL (LabelledPatch (Named p)))
     (FL (LabelledPatch (Named p)) :> FL (LabelledPatch (Named p)))
     wX
     wY
forall a b. (a -> b) -> a -> b
$ Label
-> PatchChoices (Named p) wX wY -> PatchChoices (Named p) wX wY
forall (p :: * -> * -> *) wA wB.
Commute p =>
Label -> PatchChoices p wA wB -> PatchChoices p wA wB
forceFirst Label
l PatchChoices (Named p) wX wY
repoChoices of
                (ds :: FL (LabelledPatch (Named p)) wX wZ
ds :> _) -> let i :: Int
i = FL (LabelledPatch (Named p)) wX wZ -> Int
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> Int
lengthFL FL (LabelledPatch (Named p)) wX wZ
ds
                             in case Int
-> FL (LabelledPatch (Named p)) wX wZ
-> (:>)
     (FL (LabelledPatch (Named p))) (FL (LabelledPatch (Named p))) wX wZ
forall (a :: * -> * -> *) wX wZ.
Int -> FL a wX wZ -> (:>) (FL a) (FL a) wX wZ
splitAtFL (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-1) FL (LabelledPatch (Named p)) wX wZ
ds of
                                    -- Separate last patch in list
                                    ds' :: FL (LabelledPatch (Named p)) wX wZ
ds' :> (r :: LabelledPatch (Named p) wZ wY
r :>: NilFL) -> (LabelledPatch (Named p) wZ wY -> Sealed2 (LabelledPatch (Named p))
forall (a :: * -> * -> *) wX wY. a wX wY -> Sealed2 a
seal2 LabelledPatch (Named p) wZ wY
r, FL (LabelledPatch (Named p)) wX wZ
-> Sealed2 (FL (LabelledPatch (Named p)))
forall (a :: * -> * -> *) wX wY. a wX wY -> Sealed2 a
seal2 FL (LabelledPatch (Named p)) wX wZ
ds')
                                    _ -> SPatchAndDeps p
forall a. a
impossible -- Because deps at least
                                                    -- has r, which is the patch
                                                    -- that we are looking at
                                                    -- dependencies.
        getLabelledDeps :: (Commute p) => [String] ->
                           PatchChoices (Named p) x y -> [(String, Label)]
        getLabelledDeps :: [String] -> PatchChoices (Named p) x y -> [(String, Label)]
getLabelledDeps patchnames :: [String]
patchnames repoChoices :: PatchChoices (Named p) x y
repoChoices =
            case PatchChoices (Named p) x y
-> (:>)
     (FL (LabelledPatch (Named p)))
     (FL (LabelledPatch (Named p)) :> FL (LabelledPatch (Named p)))
     x
     y
forall (p :: * -> * -> *) wX wY.
Commute p =>
PatchChoices p wX wY
-> (:>)
     (FL (LabelledPatch p))
     (FL (LabelledPatch p) :> FL (LabelledPatch p))
     wX
     wY
getChoices PatchChoices (Named p) x y
repoChoices of
                 a :: FL (LabelledPatch (Named p)) x wZ
a :> (b :: FL (LabelledPatch (Named p)) wZ wZ
b :> c :: FL (LabelledPatch (Named p)) wZ y
c) -> [String] -> FL (LabelledPatch (Named p)) x wZ -> [(String, Label)]
forall (p :: * -> * -> *) wX wY.
[String] -> FL (LabelledPatch (Named p)) wX wY -> [(String, Label)]
filterDepsFL [String]
patchnames FL (LabelledPatch (Named p)) x wZ
a [(String, Label)] -> [(String, Label)] -> [(String, Label)]
forall a. [a] -> [a] -> [a]
++
                                  [String] -> FL (LabelledPatch (Named p)) wZ wZ -> [(String, Label)]
forall (p :: * -> * -> *) wX wY.
[String] -> FL (LabelledPatch (Named p)) wX wY -> [(String, Label)]
filterDepsFL [String]
patchnames FL (LabelledPatch (Named p)) wZ wZ
b [(String, Label)] -> [(String, Label)] -> [(String, Label)]
forall a. [a] -> [a] -> [a]
++
                                  [String] -> FL (LabelledPatch (Named p)) wZ y -> [(String, Label)]
forall (p :: * -> * -> *) wX wY.
[String] -> FL (LabelledPatch (Named p)) wX wY -> [(String, Label)]
filterDepsFL [String]
patchnames FL (LabelledPatch (Named p)) wZ y
c
        filterDepsFL :: [String] -> FL (LabelledPatch (Named p)) wX wY ->
                        [(String, Label)]
        filterDepsFL :: [String] -> FL (LabelledPatch (Named p)) wX wY -> [(String, Label)]
filterDepsFL _ NilFL = []
        filterDepsFL patchnames :: [String]
patchnames (lp :: LabelledPatch (Named p) wX wY
lp :>: lps :: FL (LabelledPatch (Named p)) wY wY
lps) =
                                if (String, Label) -> String
forall a b. (a, b) -> a
fst (String, Label)
dep String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
patchnames
                                    then (String, Label)
dep (String, Label) -> [(String, Label)] -> [(String, Label)]
forall a. a -> [a] -> [a]
: [String] -> FL (LabelledPatch (Named p)) wY wY -> [(String, Label)]
forall (p :: * -> * -> *) wX wY.
[String] -> FL (LabelledPatch (Named p)) wX wY -> [(String, Label)]
filterDepsFL [String]
patchnames FL (LabelledPatch (Named p)) wY wY
lps
                                    else [String] -> FL (LabelledPatch (Named p)) wY wY -> [(String, Label)]
forall (p :: * -> * -> *) wX wY.
[String] -> FL (LabelledPatch (Named p)) wX wY -> [(String, Label)]
filterDepsFL [String]
patchnames FL (LabelledPatch (Named p)) wY wY
lps
            where
                lpTostring :: LabelledPatch (Named p) wA wB -> String
                lpTostring :: LabelledPatch (Named p) wA wB -> String
lpTostring = PatchInfo -> String
piName (PatchInfo -> String)
-> (LabelledPatch (Named p) wA wB -> PatchInfo)
-> LabelledPatch (Named p) wA wB
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Named p wA wB -> PatchInfo
forall (p :: * -> * -> *) wX wY. Named p wX wY -> PatchInfo
patch2patchinfo (Named p wA wB -> PatchInfo)
-> (LabelledPatch (Named p) wA wB -> Named p wA wB)
-> LabelledPatch (Named p) wA wB
-> PatchInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabelledPatch (Named p) wA wB -> Named p wA wB
forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> p wX wY
unLabel
                dep :: (String, Label)
                dep :: (String, Label)
dep = LabelledPatch (Named p) wX wY -> String
forall (p :: * -> * -> *) wA wB.
LabelledPatch (Named p) wA wB -> String
lpTostring (LabelledPatch (Named p) wX wY -> String)
-> (LabelledPatch (Named p) wX wY -> Label)
-> LabelledPatch (Named p) wX wY
-> (String, Label)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& LabelledPatch (Named p) wX wY -> Label
forall (p :: * -> * -> *) wX wY. LabelledPatch p wX wY -> Label
label (LabelledPatch (Named p) wX wY -> (String, Label))
-> LabelledPatch (Named p) wX wY -> (String, Label)
forall a b. (a -> b) -> a -> b
$ LabelledPatch (Named p) wX wY
lp

{-|
taggedIntersection takes two 'PatchSet's and splits them into a /common/
intersection portion and two sets of patches.  The intersection, however,
is only lazily determined, so there is no guarantee that all intersecting
patches will be included in the intersection 'PatchSet'.  This is a pretty
efficient function, because it makes use of the already-broken-up nature of
'PatchSet's.

Note that the first argument to taggedIntersection should be
the repository that is more cheaply accessed (i.e. local), as
taggedIntersection does its best to reduce the number of
inventories that are accessed from its rightmost argument.
-}
taggedIntersection :: forall rt p wStart wX wY . Commute p
                   => PatchSet rt p wStart wX -> PatchSet rt p wStart wY ->
                      Fork (RL (Tagged rt p))
                           (RL (PatchInfoAnd rt p))
                           (RL (PatchInfoAnd rt p)) wStart wX wY
taggedIntersection :: PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
taggedIntersection (PatchSet NilRL ps1 :: RL (PatchInfoAnd rt p) wX wX
ps1) s2 :: PatchSet rt p wStart wY
s2 = RL (Tagged rt p) wX wX
-> RL (PatchInfoAnd rt p) wX wX
-> RL (PatchInfoAnd rt p) wX wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wX
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) wX wX
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL RL (PatchInfoAnd rt p) wX wX
ps1 (PatchSet rt p wStart wY -> RL (PatchInfoAnd rt p) wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p wStart wY
s2)
taggedIntersection s1 :: PatchSet rt p wStart wX
s1 (PatchSet NilRL ps2 :: RL (PatchInfoAnd rt p) wX wY
ps2) = RL (Tagged rt p) wStart wStart
-> RL (PatchInfoAnd rt p) wStart wX
-> RL (PatchInfoAnd rt p) wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) wStart wStart
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL (PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p wStart wX
s1) RL (PatchInfoAnd rt p) wStart wY
RL (PatchInfoAnd rt p) wX wY
ps2
taggedIntersection s1 :: PatchSet rt p wStart wX
s1 (PatchSet (_ :<: Tagged t :: PatchInfoAnd rt p wY wX
t _ _) ps2 :: RL (PatchInfoAnd rt p) wX wY
ps2)
    | Just (PatchSet ts1 :: RL (Tagged rt p) wStart wX
ts1 ps1 :: RL (PatchInfoAnd rt p) wX wX
ps1) <- PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag (PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
t) PatchSet rt p wStart wX
s1 =
    RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wX
-> RL (PatchInfoAnd rt p) wX wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) wStart wX
ts1 RL (PatchInfoAnd rt p) wX wX
ps1 (RL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wX wY
forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart RL (PatchInfoAnd rt p) wX wY
ps2)
taggedIntersection s1 :: PatchSet rt p wStart wX
s1 s2 :: PatchSet rt p wStart wY
s2@(PatchSet (ts2 :: RL (Tagged rt p) wStart wY
ts2 :<: Tagged t :: PatchInfoAnd rt p wY wX
t _ p :: RL (PatchInfoAnd rt p) wY wY
p) ps2 :: RL (PatchInfoAnd rt p) wX wY
ps2) =
    case PatchInfoAnd rt p wY wX -> Maybe (WrappedNamed rt p wY wX)
forall (m :: * -> *) (rt :: RepoType) (p :: * -> * -> *) wA wB.
MonadFail m =>
PatchInfoAnd rt p wA wB -> m (WrappedNamed rt p wA wB)
hopefullyM PatchInfoAnd rt p wY wX
t of
        Just _ -> PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
Commute p =>
PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
taggedIntersection PatchSet rt p wStart wX
s1 (RL (Tagged rt p) wStart wY
-> RL (PatchInfoAnd rt p) wY wY -> PatchSet rt p wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wY
ts2 (RL (PatchInfoAnd rt p) wY wY
p RL (PatchInfoAnd rt p) wY wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t RL (PatchInfoAnd rt p) wY wX
-> RL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wY
ps2))
        Nothing -> case PatchInfo
-> PatchSet rt p wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
splitOnTag (PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
t) PatchSet rt p wStart wX
s1 of
                       Just (PatchSet com :: RL (Tagged rt p) wStart wX
com NilRL :> us :: RL (PatchInfoAnd rt p) wZ wX
us) ->
                           RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wX
-> RL (PatchInfoAnd rt p) wX wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) wStart wX
com RL (PatchInfoAnd rt p) wZ wX
RL (PatchInfoAnd rt p) wX wX
us (RL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wX wY
forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart RL (PatchInfoAnd rt p) wX wY
ps2)
                       Just _ -> Fork
  (RL (Tagged rt p))
  (RL (PatchInfoAnd rt p))
  (RL (PatchInfoAnd rt p))
  wStart
  wX
  wY
forall a. a
impossible
                       Nothing -> RL (Tagged rt p) wStart wStart
-> RL (PatchInfoAnd rt p) wStart wX
-> RL (PatchInfoAnd rt p) wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) wStart wStart
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL (PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p wStart wX
s1) (PatchSet rt p wStart wY -> RL (PatchInfoAnd rt p) wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p wStart wY
s2)

-- |'maybeSplitSetOnTag' takes a tag's 'PatchInfo', @t0@, and a 'PatchSet' and
-- attempts to find @t0@ in one of the 'Tagged's in the PatchSet. If the tag is
-- found, the PatchSet is split up, on that tag, such that all later patches
-- are in the "since last tag" patch list. If the tag is not found, 'Nothing'
-- is returned.
maybeSplitSetOnTag :: PatchInfo -> PatchSet rt p wStart wX
                   -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag :: PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag t0 :: PatchInfo
t0 origSet :: PatchSet rt p wStart wX
origSet@(PatchSet (ts :: RL (Tagged rt p) wStart wY
ts :<: Tagged t :: PatchInfoAnd rt p wY wX
t _ pst :: RL (PatchInfoAnd rt p) wY wY
pst) ps :: RL (PatchInfoAnd rt p) wX wX
ps)
    | PatchInfo
t0 PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
t = PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
forall a. a -> Maybe a
Just PatchSet rt p wStart wX
origSet
    | Bool
otherwise = do
        PatchSet ts' :: RL (Tagged rt p) wStart wX
ts' ps' :: RL (PatchInfoAnd rt p) wX wX
ps' <- PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag PatchInfo
t0 (RL (Tagged rt p) wStart wY
-> RL (PatchInfoAnd rt p) wY wX -> PatchSet rt p wStart wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wY
ts (RL (PatchInfoAnd rt p) wY wY
pst RL (PatchInfoAnd rt p) wY wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t))
        PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
forall a. a -> Maybe a
Just (PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX))
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p wStart wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wX
ts' (RL (PatchInfoAnd rt p) wX wX
ps' RL (PatchInfoAnd rt p) wX wX
-> RL (PatchInfoAnd rt p) wX wX -> RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wX
ps)
maybeSplitSetOnTag _ _ = Maybe (PatchSet rt p wStart wX)
forall a. Maybe a
Nothing

getPatchesBeyondTag :: Commute p => PatchInfo -> PatchSet rt p wStart wX
                    -> FlippedSeal (RL (PatchInfoAnd rt p)) wX
getPatchesBeyondTag :: PatchInfo
-> PatchSet rt p wStart wX
-> FlippedSeal (RL (PatchInfoAnd rt p)) wX
getPatchesBeyondTag t :: PatchInfo
t (PatchSet (_ :<: Tagged hp :: PatchInfoAnd rt p wY wX
hp _ _) ps :: RL (PatchInfoAnd rt p) wX wX
ps) | PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
hp PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
t =
    RL (PatchInfoAnd rt p) wX wX
-> FlippedSeal (RL (PatchInfoAnd rt p)) wX
forall (a :: * -> * -> *) wX wY. a wX wY -> FlippedSeal a wY
flipSeal RL (PatchInfoAnd rt p) wX wX
ps
getPatchesBeyondTag t :: PatchInfo
t patchset :: PatchSet rt p wStart wX
patchset@(PatchSet ts :: RL (Tagged rt p) wStart wX
ts (ps :: RL (PatchInfoAnd rt p) wX wY
ps :<: hp :: PatchInfoAnd rt p wY wX
hp)) =
    if PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
hp PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
t
        then if PatchSet rt p wStart wX -> [PatchInfo]
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> [PatchInfo]
getUncovered PatchSet rt p wStart wX
patchset [PatchInfo] -> [PatchInfo] -> Bool
forall a. Eq a => a -> a -> Bool
== [PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
hp]
                 -- special case to avoid looking at redundant patches
                 then RL (PatchInfoAnd rt p) wX wX
-> FlippedSeal (RL (PatchInfoAnd rt p)) wX
forall (a :: * -> * -> *) wX wY. a wX wY -> FlippedSeal a wY
flipSeal RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
                 else case PatchInfo
-> PatchSet rt p wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
splitOnTag PatchInfo
t PatchSet rt p wStart wX
patchset of
                     Just (_ :> e :: RL (PatchInfoAnd rt p) wZ wX
e) -> RL (PatchInfoAnd rt p) wZ wX
-> FlippedSeal (RL (PatchInfoAnd rt p)) wX
forall (a :: * -> * -> *) wX wY. a wX wY -> FlippedSeal a wY
flipSeal RL (PatchInfoAnd rt p) wZ wX
e
                     _ -> FlippedSeal (RL (PatchInfoAnd rt p)) wX
forall a. a
impossible
        else case PatchInfo
-> PatchSet rt p wStart wY
-> FlippedSeal (RL (PatchInfoAnd rt p)) wY
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX
-> FlippedSeal (RL (PatchInfoAnd rt p)) wX
getPatchesBeyondTag PatchInfo
t (RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wX
ts RL (PatchInfoAnd rt p) wX wY
ps) of
                 FlippedSeal xxs :: RL (PatchInfoAnd rt p) wX wY
xxs -> RL (PatchInfoAnd rt p) wX wX
-> FlippedSeal (RL (PatchInfoAnd rt p)) wX
forall (a :: * -> * -> *) wX wY. a wX wY -> FlippedSeal a wY
FlippedSeal (RL (PatchInfoAnd rt p) wX wY
xxs RL (PatchInfoAnd rt p) wX wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
hp)
getPatchesBeyondTag t :: PatchInfo
t (PatchSet NilRL NilRL) =
    String -> FlippedSeal (RL (PatchInfoAnd rt p)) wX
forall a. String -> a
bug (String -> FlippedSeal (RL (PatchInfoAnd rt p)) wX)
-> String -> FlippedSeal (RL (PatchInfoAnd rt p)) wX
forall a b. (a -> b) -> a -> b
$ "tag\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Doc -> String
renderString (PatchInfo -> Doc
displayPatchInfo PatchInfo
t)
          String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\nis not in the patchset in getPatchesBeyondTag."
getPatchesBeyondTag t0 :: PatchInfo
t0 (PatchSet (ts :: RL (Tagged rt p) wStart wY
ts :<: Tagged t :: PatchInfoAnd rt p wY wX
t _ ps :: RL (PatchInfoAnd rt p) wY wY
ps) NilRL) =
    PatchInfo
-> PatchSet rt p wStart wX
-> FlippedSeal (RL (PatchInfoAnd rt p)) wX
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX
-> FlippedSeal (RL (PatchInfoAnd rt p)) wX
getPatchesBeyondTag PatchInfo
t0 (RL (Tagged rt p) wStart wY
-> RL (PatchInfoAnd rt p) wY wX -> PatchSet rt p wStart wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wY
ts (RL (PatchInfoAnd rt p) wY wY
ps RL (PatchInfoAnd rt p) wY wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t))

-- |splitOnTag takes a tag's 'PatchInfo', and a 'PatchSet', and attempts to
-- find the tag in the PatchSet, returning a pair: the clean PatchSet "up to"
-- the tag, and a RL of patches after the tag; If the tag is not in the
-- PatchSet, we return Nothing.
splitOnTag :: Commute p => PatchInfo -> PatchSet rt p wStart wX
           -> Maybe ((PatchSet rt p :> RL (PatchInfoAnd rt p)) wStart wX)
-- If the tag we are looking for is the first Tagged tag of the patchset, just
-- separate out the patchset's patches.
splitOnTag :: PatchInfo
-> PatchSet rt p wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
splitOnTag t :: PatchInfo
t (PatchSet ts :: RL (Tagged rt p) wStart wX
ts@(_ :<: Tagged hp :: PatchInfoAnd rt p wY wX
hp _ _) ps :: RL (PatchInfoAnd rt p) wX wX
ps) | PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
hp PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
t =
    (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall a. a -> Maybe a
Just ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
 -> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX))
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p wStart wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wX
ts RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL PatchSet rt p wStart wX
-> RL (PatchInfoAnd rt p) wX wX
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RL (PatchInfoAnd rt p) wX wX
ps
-- If the tag is the most recent patch in the set, we check if the patch is the
-- only non-depended-on patch in the set (i.e. it is a clean tag); creating a
-- new Tagged out of the patches and tag, and adding it to the patchset, if
-- this is the case. Otherwise, we try to make the tag clean.
splitOnTag t :: PatchInfo
t patchset :: PatchSet rt p wStart wX
patchset@(PatchSet ts :: RL (Tagged rt p) wStart wX
ts hps :: RL (PatchInfoAnd rt p) wX wX
hps@(ps :: RL (PatchInfoAnd rt p) wX wY
ps :<: hp :: PatchInfoAnd rt p wY wX
hp)) | PatchInfoAnd rt p wY wX -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
hp PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
t =
    if PatchSet rt p wStart wX -> [PatchInfo]
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> [PatchInfo]
getUncovered PatchSet rt p wStart wX
patchset [PatchInfo] -> [PatchInfo] -> Bool
forall a. Eq a => a -> a -> Bool
== [PatchInfo
t]
        then (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall a. a -> Maybe a
Just ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
 -> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX))
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p wStart wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet (RL (Tagged rt p) wStart wX
ts RL (Tagged rt p) wStart wX
-> Tagged rt p wX wX -> RL (Tagged rt p) wStart wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wX
forall (rt :: RepoType) (p :: * -> * -> *) wY wZ wX.
PatchInfoAnd rt p wY wZ
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wZ
Tagged PatchInfoAnd rt p wY wX
hp Maybe String
forall a. Maybe a
Nothing RL (PatchInfoAnd rt p) wX wY
ps) RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL PatchSet rt p wStart wX
-> RL (PatchInfoAnd rt p) wX wX
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
        else case (forall wU wV. PatchInfoAnd rt p wU wV -> Bool)
-> RL (PatchInfoAnd rt p) wX wX
-> (:>) (RL (PatchInfoAnd rt p)) (RL (PatchInfoAnd rt p)) wX wX
forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> RL p wX wY -> (:>) (RL p) (RL p) wX wY
partitionRL ((PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` (PatchInfo
t PatchInfo -> [PatchInfo] -> [PatchInfo]
forall a. a -> [a] -> [a]
: [PatchInfo]
ds)) (PatchInfo -> Bool)
-> (PatchInfoAnd rt p wU wV -> PatchInfo)
-> PatchInfoAnd rt p wU wV
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAnd rt p wU wV -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info) RL (PatchInfoAnd rt p) wX wX
hps of
            -- Partition hps by those that are the tag and its explicit deps.
            tagAndDeps :: RL (PatchInfoAnd rt p) wX wZ
tagAndDeps@(ds' :: RL (PatchInfoAnd rt p) wX wY
ds' :<: hp' :: PatchInfoAnd rt p wY wZ
hp') :> nonDeps :: RL (PatchInfoAnd rt p) wZ wX
nonDeps ->
                -- If @ds@ doesn't contain the tag of the first Tagged, that
                -- tag will also be returned by the call to getUncovered - so
                -- we need to unwrap the next Tagged in order to expose it to
                -- being partitioned out in the recursive call to splitOnTag.
                if PatchSet rt p wStart wZ -> [PatchInfo]
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> [PatchInfo]
getUncovered (RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wZ -> PatchSet rt p wStart wZ
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wX
ts RL (PatchInfoAnd rt p) wX wZ
tagAndDeps) [PatchInfo] -> [PatchInfo] -> Bool
forall a. Eq a => a -> a -> Bool
== [PatchInfo
t]
                    then let tagged :: Tagged rt p wX wZ
tagged = PatchInfoAnd rt p wY wZ
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wZ
forall (rt :: RepoType) (p :: * -> * -> *) wY wZ wX.
PatchInfoAnd rt p wY wZ
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wZ
Tagged PatchInfoAnd rt p wY wZ
hp' Maybe String
forall a. Maybe a
Nothing RL (PatchInfoAnd rt p) wX wY
ds' in
                         (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall (m :: * -> *) a. Monad m => a -> m a
return ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
 -> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX))
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wStart wZ
-> RL (PatchInfoAnd rt p) wZ wZ -> PatchSet rt p wStart wZ
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet (RL (Tagged rt p) wStart wX
ts RL (Tagged rt p) wStart wX
-> Tagged rt p wX wZ -> RL (Tagged rt p) wStart wZ
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: Tagged rt p wX wZ
tagged) RL (PatchInfoAnd rt p) wZ wZ
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL PatchSet rt p wStart wZ
-> RL (PatchInfoAnd rt p) wZ wX
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RL (PatchInfoAnd rt p) wZ wX
nonDeps
                    else do
                        PatchSet rt p wStart wZ
unfolded <- PatchSet rt p wStart wZ -> Maybe (PatchSet rt p wStart wZ)
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged (PatchSet rt p wStart wZ -> Maybe (PatchSet rt p wStart wZ))
-> PatchSet rt p wStart wZ -> Maybe (PatchSet rt p wStart wZ)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wZ -> PatchSet rt p wStart wZ
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wX
ts RL (PatchInfoAnd rt p) wX wZ
tagAndDeps
                        xx :: PatchSet rt p wStart wZ
xx :> yy :: RL (PatchInfoAnd rt p) wZ wZ
yy <- PatchInfo
-> PatchSet rt p wStart wZ
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wZ)
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
splitOnTag PatchInfo
t PatchSet rt p wStart wZ
unfolded
                        (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall (m :: * -> *) a. Monad m => a -> m a
return ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
 -> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX))
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall a b. (a -> b) -> a -> b
$ PatchSet rt p wStart wZ
xx PatchSet rt p wStart wZ
-> RL (PatchInfoAnd rt p) wZ wX
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> (RL (PatchInfoAnd rt p) wZ wZ
yy RL (PatchInfoAnd rt p) wZ wZ
-> RL (PatchInfoAnd rt p) wZ wX -> RL (PatchInfoAnd rt p) wZ wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wZ wX
nonDeps)
            _ -> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall a. a
impossible
  where
    ds :: [PatchInfo]
ds = WrappedNamed rt p wY wX -> [PatchInfo]
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
WrappedNamed rt p wX wY -> [PatchInfo]
getdeps (PatchInfoAnd rt p wY wX -> WrappedNamed rt p wY wX
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> WrappedNamed rt p wA wB
hopefully PatchInfoAnd rt p wY wX
hp)
-- We drop the leading patch, to try and find a non-Tagged tag.
splitOnTag t :: PatchInfo
t (PatchSet ts :: RL (Tagged rt p) wStart wX
ts (ps :: RL (PatchInfoAnd rt p) wX wY
ps :<: p :: PatchInfoAnd rt p wY wX
p)) = do
    ns :: PatchSet rt p wStart wZ
ns :> x :: RL (PatchInfoAnd rt p) wZ wY
x <- PatchInfo
-> PatchSet rt p wStart wY
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wY)
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
splitOnTag PatchInfo
t (RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wX
ts RL (PatchInfoAnd rt p) wX wY
ps)
    (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall (m :: * -> *) a. Monad m => a -> m a
return ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
 -> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX))
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall a b. (a -> b) -> a -> b
$ PatchSet rt p wStart wZ
ns PatchSet rt p wStart wZ
-> RL (PatchInfoAnd rt p) wZ wX
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> (RL (PatchInfoAnd rt p) wZ wY
x RL (PatchInfoAnd rt p) wZ wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wZ wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
p)
-- If there are no patches left, we "unfold" the next Tagged, and try again.
splitOnTag t0 :: PatchInfo
t0 patchset :: PatchSet rt p wStart wX
patchset@(PatchSet (_ :<: Tagged _ _ _s :: RL (PatchInfoAnd rt p) wY wY
_s) NilRL) =
    PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged PatchSet rt p wStart wX
patchset Maybe (PatchSet rt p wStart wX)
-> (PatchSet rt p wStart wX
    -> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX))
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= PatchInfo
-> PatchSet rt p wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX
-> Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
splitOnTag PatchInfo
t0
-- If we've checked all the patches, but haven't found the tag, return Nothing.
splitOnTag _ (PatchSet NilRL NilRL) = Maybe ((:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wStart wX)
forall a. Maybe a
Nothing

-- |'unwrapOneTagged' unfolds a single Tagged object in a PatchSet, adding the
-- tag and patches to the PatchSet's patch list.
unwrapOneTagged :: PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged :: PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged (PatchSet (ts :: RL (Tagged rt p) wX wY
ts :<: Tagged t :: PatchInfoAnd rt p wY wX
t _ tps :: RL (PatchInfoAnd rt p) wY wY
tps) ps :: RL (PatchInfoAnd rt p) wX wY
ps) =
    PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
forall a. a -> Maybe a
Just (PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY))
-> PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wX wY
-> RL (PatchInfoAnd rt p) wY wY -> PatchSet rt p wX wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wX wY
ts (RL (PatchInfoAnd rt p) wY wY
tps RL (PatchInfoAnd rt p) wY wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t RL (PatchInfoAnd rt p) wY wX
-> RL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wY
ps)
unwrapOneTagged _ = Maybe (PatchSet rt p wX wY)
forall a. Maybe a
Nothing

-- | @getUncovered ps@ returns the 'PatchInfo' for all the patches in
--   @ps@ that are not depended on by anything else *through explicit
--   dependencies*. Tags are a likely candidate, although we may also
--   find some non-tag patches in this list.
--
--   Keep in mind that in a typical repository with a lot of tags, only a small
--   fraction of tags would be returned as they would be at least indirectly
--   depended on by the topmost ones.
getUncovered :: PatchSet rt p wStart wX -> [PatchInfo]
getUncovered :: PatchSet rt p wStart wX -> [PatchInfo]
getUncovered patchset :: PatchSet rt p wStart wX
patchset = case PatchSet rt p wStart wX
patchset of
    (PatchSet NilRL ps :: RL (PatchInfoAnd rt p) wX wX
ps) -> [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered ((forall wW wZ.
 PatchInfoAnd rt p wW wZ -> (PatchInfo, Maybe [PatchInfo]))
-> RL (PatchInfoAnd rt p) wX wX -> [(PatchInfo, Maybe [PatchInfo])]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ.
PatchInfoAnd rt p wW wZ -> (PatchInfo, Maybe [PatchInfo])
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchInfoAnd rt p wX wY -> (PatchInfo, Maybe [PatchInfo])
infoAndExplicitDeps RL (PatchInfoAnd rt p) wX wX
ps)
    (PatchSet (_ :<: Tagged t :: PatchInfoAnd rt p wY wX
t _ _) ps :: RL (PatchInfoAnd rt p) wX wX
ps) ->
        [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered ((forall wW wZ.
 PatchInfoAnd rt p wW wZ -> (PatchInfo, Maybe [PatchInfo]))
-> RL (PatchInfoAnd rt p) wY wX -> [(PatchInfo, Maybe [PatchInfo])]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ.
PatchInfoAnd rt p wW wZ -> (PatchInfo, Maybe [PatchInfo])
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchInfoAnd rt p wX wY -> (PatchInfo, Maybe [PatchInfo])
infoAndExplicitDeps (RL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL RL (PatchInfoAnd rt p) wY wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t RL (PatchInfoAnd rt p) wY wX
-> RL (PatchInfoAnd rt p) wX wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wX
ps))
  where
    findUncovered :: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
    findUncovered :: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered [] = []
    findUncovered ((pi :: PatchInfo
pi, Nothing) : rest :: [(PatchInfo, Maybe [PatchInfo])]
rest) = PatchInfo
pi PatchInfo -> [PatchInfo] -> [PatchInfo]
forall a. a -> [a] -> [a]
: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered [(PatchInfo, Maybe [PatchInfo])]
rest
    findUncovered ((pi :: PatchInfo
pi, Just deps :: [PatchInfo]
deps) : rest :: [(PatchInfo, Maybe [PatchInfo])]
rest) =
        PatchInfo
pi PatchInfo -> [PatchInfo] -> [PatchInfo]
forall a. a -> [a] -> [a]
: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered ([PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn [PatchInfo]
deps [(PatchInfo, Maybe [PatchInfo])]
rest)

    -- |dropDepsIn traverses the list of patches, dropping any patches that
    -- occur in the dependency list; when a patch is dropped, its dependencies
    -- are added to the dependency list used for later patches.
    dropDepsIn :: [PatchInfo] -> [(PatchInfo, Maybe [PatchInfo])]
               -> [(PatchInfo, Maybe [PatchInfo])]
    dropDepsIn :: [PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn [] pps :: [(PatchInfo, Maybe [PatchInfo])]
pps = [(PatchInfo, Maybe [PatchInfo])]
pps
    dropDepsIn _  []  = []
    dropDepsIn ds :: [PatchInfo]
ds (hp :: (PatchInfo, Maybe [PatchInfo])
hp : pps :: [(PatchInfo, Maybe [PatchInfo])]
pps)
        | (PatchInfo, Maybe [PatchInfo]) -> PatchInfo
forall a b. (a, b) -> a
fst (PatchInfo, Maybe [PatchInfo])
hp PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PatchInfo]
ds =
            let extraDeps :: [PatchInfo]
extraDeps = [PatchInfo] -> Maybe [PatchInfo] -> [PatchInfo]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [PatchInfo] -> [PatchInfo])
-> Maybe [PatchInfo] -> [PatchInfo]
forall a b. (a -> b) -> a -> b
$ (PatchInfo, Maybe [PatchInfo]) -> Maybe [PatchInfo]
forall a b. (a, b) -> b
snd (PatchInfo, Maybe [PatchInfo])
hp in
            [PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn ([PatchInfo]
extraDeps [PatchInfo] -> [PatchInfo] -> [PatchInfo]
forall a. [a] -> [a] -> [a]
++ PatchInfo -> [PatchInfo] -> [PatchInfo]
forall a. Eq a => a -> [a] -> [a]
delete ((PatchInfo, Maybe [PatchInfo]) -> PatchInfo
forall a b. (a, b) -> a
fst (PatchInfo, Maybe [PatchInfo])
hp) [PatchInfo]
ds) [(PatchInfo, Maybe [PatchInfo])]
pps
        | Bool
otherwise = (PatchInfo, Maybe [PatchInfo])
hp (PatchInfo, Maybe [PatchInfo])
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
forall a. a -> [a] -> [a]
: [PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn [PatchInfo]
ds [(PatchInfo, Maybe [PatchInfo])]
pps

    -- |infoAndExplicitDeps returns the patch info and (for tags only) the list
    -- of explicit dependencies of a patch.
    infoAndExplicitDeps :: PatchInfoAnd rt p wX wY
                        -> (PatchInfo, Maybe [PatchInfo])
    infoAndExplicitDeps :: PatchInfoAnd rt p wX wY -> (PatchInfo, Maybe [PatchInfo])
infoAndExplicitDeps p :: PatchInfoAnd rt p wX wY
p
        | PatchInfo -> Bool
isTag (PatchInfoAnd rt p wX wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wX wY
p) = (PatchInfoAnd rt p wX wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wX wY
p, WrappedNamed rt p wX wY -> [PatchInfo]
forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
WrappedNamed rt p wX wY -> [PatchInfo]
getdeps (WrappedNamed rt p wX wY -> [PatchInfo])
-> Maybe (WrappedNamed rt p wX wY) -> Maybe [PatchInfo]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` PatchInfoAnd rt p wX wY -> Maybe (WrappedNamed rt p wX wY)
forall (m :: * -> *) (rt :: RepoType) (p :: * -> * -> *) wA wB.
MonadFail m =>
PatchInfoAnd rt p wA wB -> m (WrappedNamed rt p wA wB)
hopefullyM PatchInfoAnd rt p wX wY
p)
        | Bool
otherwise = (PatchInfoAnd rt p wX wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wX wY
p, Maybe [PatchInfo]
forall a. Maybe a
Nothing)

-- | @slightlyOptimizePatchset@ only works on the surface inventory
--   (see 'optimizePatchset') and only optimises at most one tag in
--   there, going for the most recent tag which has no non-depended
--   patch after it. Older tags won't be 'clean', which means the
--   PatchSet will not be in 'clean :> unclean' state.
slightlyOptimizePatchset :: PatchSet rt p wStart wX -> PatchSet rt p wStart wX
slightlyOptimizePatchset :: PatchSet rt p wStart wX -> PatchSet rt p wStart wX
slightlyOptimizePatchset (PatchSet ps0 :: RL (Tagged rt p) wStart wX
ps0 ts0 :: RL (PatchInfoAnd rt p) wX wX
ts0) =
    PatchSet rt p wStart wX -> PatchSet rt p wStart wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wY.
PatchSet rt p wStart wY -> PatchSet rt p wStart wY
sops (PatchSet rt p wStart wX -> PatchSet rt p wStart wX)
-> PatchSet rt p wStart wX -> PatchSet rt p wStart wX
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p wStart wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet (RL (Tagged rt p) wStart wX -> RL (Tagged rt p) wStart wX
forall (a :: * -> * -> *) wX wY. RL a wX wY -> RL a wX wY
prog RL (Tagged rt p) wStart wX
ps0) RL (PatchInfoAnd rt p) wX wX
ts0
  where
    prog :: RL a wX wY -> RL a wX wY
prog = String -> RL a wX wY -> RL a wX wY
forall (a :: * -> * -> *) wX wY. String -> RL a wX wY -> RL a wX wY
progressRL "Optimizing inventory"
    sops :: PatchSet rt p wStart wY -> PatchSet rt p wStart wY
    sops :: PatchSet rt p wStart wY -> PatchSet rt p wStart wY
sops patchset :: PatchSet rt p wStart wY
patchset@(PatchSet _ NilRL) = PatchSet rt p wStart wY
patchset
    sops patchset :: PatchSet rt p wStart wY
patchset@(PatchSet ts :: RL (Tagged rt p) wStart wX
ts (ps :: RL (PatchInfoAnd rt p) wX wY
ps :<: hp :: PatchInfoAnd rt p wY wY
hp))
        | PatchInfo -> Bool
isTag (PatchInfoAnd rt p wY wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wY
hp) =
            if PatchSet rt p wStart wY -> [PatchInfo]
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> [PatchInfo]
getUncovered PatchSet rt p wStart wY
patchset [PatchInfo] -> [PatchInfo] -> Bool
forall a. Eq a => a -> a -> Bool
== [PatchInfoAnd rt p wY wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wY
hp]
                -- exactly one tag and it depends on everything not already
                -- archived
                then RL (Tagged rt p) wStart wY
-> RL (PatchInfoAnd rt p) wY wY -> PatchSet rt p wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet (RL (Tagged rt p) wStart wX
ts RL (Tagged rt p) wStart wX
-> Tagged rt p wX wY -> RL (Tagged rt p) wStart wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wY
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wY
forall (rt :: RepoType) (p :: * -> * -> *) wY wZ wX.
PatchInfoAnd rt p wY wZ
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wY
-> Tagged rt p wX wZ
Tagged PatchInfoAnd rt p wY wY
hp Maybe String
forall a. Maybe a
Nothing RL (PatchInfoAnd rt p) wX wY
ps) RL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
                -- other tags or other top-level patches too (so move past hp)
                else let ps' :: PatchSet rt p wStart wY
ps' = PatchSet rt p wStart wY -> PatchSet rt p wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wY.
PatchSet rt p wStart wY -> PatchSet rt p wStart wY
sops (PatchSet rt p wStart wY -> PatchSet rt p wStart wY)
-> PatchSet rt p wStart wY -> PatchSet rt p wStart wY
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wX
ts (RL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wX wY
forall (a :: * -> * -> *) wX wY. RL a wX wY -> RL a wX wY
prog RL (PatchInfoAnd rt p) wX wY
ps) in
                     PatchSet rt p wStart wY
-> FL (PatchInfoAnd rt p) wY wY -> PatchSet rt p wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
PatchSet rt p wStart wX
-> FL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
appendPSFL PatchSet rt p wStart wY
ps' (PatchInfoAnd rt p wY wY
hp PatchInfoAnd rt p wY wY
-> FL (PatchInfoAnd rt p) wY wY -> FL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL)
        | Bool
otherwise = PatchSet rt p wStart wY
-> FL (PatchInfoAnd rt p) wY wY -> PatchSet rt p wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
PatchSet rt p wStart wX
-> FL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
appendPSFL (PatchSet rt p wStart wY -> PatchSet rt p wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wY.
PatchSet rt p wStart wY -> PatchSet rt p wStart wY
sops (PatchSet rt p wStart wY -> PatchSet rt p wStart wY)
-> PatchSet rt p wStart wY -> PatchSet rt p wStart wY
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wX
ts RL (PatchInfoAnd rt p) wX wY
ps) (PatchInfoAnd rt p wY wY
hp PatchInfoAnd rt p wY wY
-> FL (PatchInfoAnd rt p) wY wY -> FL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL)

removeFromPatchSet :: Commute p => FL (PatchInfoAnd rt p) wX wY
                   -> PatchSet rt p wStart wY -> Maybe (PatchSet rt p wStart wX)
removeFromPatchSet :: FL (PatchInfoAnd rt p) wX wY
-> PatchSet rt p wStart wY -> Maybe (PatchSet rt p wStart wX)
removeFromPatchSet bad :: FL (PatchInfoAnd rt p) wX wY
bad (PatchSet ts :: RL (Tagged rt p) wStart wX
ts ps :: RL (PatchInfoAnd rt p) wX wY
ps) | (PatchInfo -> Bool) -> [PatchInfo] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wX wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wX wY
ps) ((forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> FL (PatchInfoAnd rt p) wX wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> FL a wX wY -> [b]
mapFL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info FL (PatchInfoAnd rt p) wX wY
bad) = do
    RL (PatchInfoAnd rt p) wX wX
ps' <- RL (PatchInfoAnd rt p) wX wY
-> RL (PatchInfoAnd rt p) wX wY
-> Maybe (RL (PatchInfoAnd rt p) wX wX)
forall (p :: * -> * -> *) (rt :: RepoType) wY wZ wX.
Commute p =>
RL (PatchInfoAnd rt p) wY wZ
-> RL (PatchInfoAnd rt p) wX wZ
-> Maybe (RL (PatchInfoAnd rt p) wX wY)
fastRemoveSubsequenceRL (FL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wX wY
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wX wY
bad) RL (PatchInfoAnd rt p) wX wY
ps
    PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
forall (m :: * -> *) a. Monad m => a -> m a
return (RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p wStart wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wX
ts RL (PatchInfoAnd rt p) wX wX
ps')
removeFromPatchSet _ (PatchSet NilRL _) = Maybe (PatchSet rt p wStart wX)
forall a. Maybe a
Nothing
removeFromPatchSet bad :: FL (PatchInfoAnd rt p) wX wY
bad (PatchSet (ts :: RL (Tagged rt p) wStart wY
ts :<: Tagged t :: PatchInfoAnd rt p wY wX
t _ tps :: RL (PatchInfoAnd rt p) wY wY
tps) ps :: RL (PatchInfoAnd rt p) wX wY
ps) =
    FL (PatchInfoAnd rt p) wX wY
-> PatchSet rt p wStart wY -> Maybe (PatchSet rt p wStart wX)
forall (p :: * -> * -> *) (rt :: RepoType) wX wY wStart.
Commute p =>
FL (PatchInfoAnd rt p) wX wY
-> PatchSet rt p wStart wY -> Maybe (PatchSet rt p wStart wX)
removeFromPatchSet FL (PatchInfoAnd rt p) wX wY
bad (RL (Tagged rt p) wStart wY
-> RL (PatchInfoAnd rt p) wY wY -> PatchSet rt p wStart wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wY
ts (RL (PatchInfoAnd rt p) wY wY
tps RL (PatchInfoAnd rt p) wY wY
-> PatchInfoAnd rt p wY wX -> RL (PatchInfoAnd rt p) wY wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t RL (PatchInfoAnd rt p) wY wX
-> RL (PatchInfoAnd rt p) wX wY -> RL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wY
ps))

fastRemoveSubsequenceRL :: Commute p
                        => RL (PatchInfoAnd rt p) wY wZ
                        -> RL (PatchInfoAnd rt p) wX wZ
                        -> Maybe (RL (PatchInfoAnd rt p) wX wY)
fastRemoveSubsequenceRL :: RL (PatchInfoAnd rt p) wY wZ
-> RL (PatchInfoAnd rt p) wX wZ
-> Maybe (RL (PatchInfoAnd rt p) wX wY)
fastRemoveSubsequenceRL NilRL ys :: RL (PatchInfoAnd rt p) wX wZ
ys = RL (PatchInfoAnd rt p) wX wZ
-> Maybe (RL (PatchInfoAnd rt p) wX wZ)
forall a. a -> Maybe a
Just RL (PatchInfoAnd rt p) wX wZ
ys
fastRemoveSubsequenceRL (xs :: RL (PatchInfoAnd rt p) wY wY
xs:<:x :: PatchInfoAnd rt p wY wZ
x) ys :: RL (PatchInfoAnd rt p) wX wZ
ys = PatchInfoAnd rt p wY wZ
-> RL (PatchInfoAnd rt p) wX wZ
-> Maybe (RL (PatchInfoAnd rt p) wX wY)
forall (p :: * -> * -> *) (rt :: RepoType) wY wZ wX.
Commute p =>
PatchInfoAnd rt p wY wZ
-> RL (PatchInfoAnd rt p) wX wZ
-> Maybe (RL (PatchInfoAnd rt p) wX wY)
fastRemoveRL PatchInfoAnd rt p wY wZ
x RL (PatchInfoAnd rt p) wX wZ
ys Maybe (RL (PatchInfoAnd rt p) wX wY)
-> (RL (PatchInfoAnd rt p) wX wY
    -> Maybe (RL (PatchInfoAnd rt p) wX wY))
-> Maybe (RL (PatchInfoAnd rt p) wX wY)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= RL (PatchInfoAnd rt p) wY wY
-> RL (PatchInfoAnd rt p) wX wY
-> Maybe (RL (PatchInfoAnd rt p) wX wY)
forall (p :: * -> * -> *) (rt :: RepoType) wY wZ wX.
Commute p =>
RL (PatchInfoAnd rt p) wY wZ
-> RL (PatchInfoAnd rt p) wX wZ
-> Maybe (RL (PatchInfoAnd rt p) wX wY)
fastRemoveSubsequenceRL RL (PatchInfoAnd rt p) wY wY
xs

findCommonAndUncommon :: forall rt p wStart wX wY . Commute p
                      => PatchSet rt p wStart wX -> PatchSet rt p wStart wY
                      -> Fork (PatchSet rt p)
                              (FL (PatchInfoAnd rt p))
                              (FL (PatchInfoAnd rt p)) wStart wX wY
findCommonAndUncommon :: PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     wStart
     wX
     wY
findCommonAndUncommon us :: PatchSet rt p wStart wX
us them :: PatchSet rt p wStart wY
them = case PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
Commute p =>
PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
taggedIntersection PatchSet rt p wStart wX
us PatchSet rt p wStart wY
them of
    Fork common :: RL (Tagged rt p) wStart wU
common us' :: RL (PatchInfoAnd rt p) wU wX
us' them' :: RL (PatchInfoAnd rt p) wU wY
them' ->
        case (forall wU wV. PatchInfoAnd rt p wU wV -> Bool)
-> FL (PatchInfoAnd rt p) wU wX
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wX
forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> FL p wX wY -> (:>) (FL p) (FL p :> FL p) wX wY
partitionFL (RL (PatchInfoAnd rt p) wU wY -> PatchInfoAnd rt p wU wV -> Bool
forall (rt :: RepoType) (p :: * -> * -> *) wX wY (rt :: RepoType)
       (p :: * -> * -> *) wA wB.
RL (PatchInfoAnd rt p) wX wY -> PatchInfoAnd rt p wA wB -> Bool
infoIn RL (PatchInfoAnd rt p) wU wY
them') (FL (PatchInfoAnd rt p) wU wX
 -> (:>)
      (FL (PatchInfoAnd rt p))
      (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
      wU
      wX)
-> FL (PatchInfoAnd rt p) wU wX
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wX
forall a b. (a -> b) -> a -> b
$ RL (PatchInfoAnd rt p) wU wX -> FL (PatchInfoAnd rt p) wU wX
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wX
us' of
            _ :> bad :: FL (PatchInfoAnd rt p) wZ wZ
bad@(_ :>: _) :> _ ->
                String
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall a. String -> a
bug (String
 -> Fork
      (PatchSet rt p)
      (FL (PatchInfoAnd rt p))
      (FL (PatchInfoAnd rt p))
      wStart
      wX
      wY)
-> String
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall a b. (a -> b) -> a -> b
$ "Failed to commute common patches:\n"
                      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Doc -> String
renderString
                          ([Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (forall wW wZ. PatchInfoAnd rt p wW wZ -> Doc)
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL (PatchInfo -> Doc
displayPatchInfo (PatchInfo -> Doc)
-> (PatchInfoAnd rt p wW wZ -> PatchInfo)
-> PatchInfoAnd rt p wW wZ
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info) (RL (PatchInfoAnd rt p) wZ wZ -> [Doc])
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall a b. (a -> b) -> a -> b
$ FL (PatchInfoAnd rt p) wZ wZ -> RL (PatchInfoAnd rt p) wZ wZ
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wZ wZ
bad)
            (common2 :: FL (PatchInfoAnd rt p) wU wZ
common2 :> NilFL :> only_ours :: FL (PatchInfoAnd rt p) wZ wX
only_ours) ->
                case (forall wU wV. PatchInfoAnd rt p wU wV -> Bool)
-> FL (PatchInfoAnd rt p) wU wY
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wY
forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> FL p wX wY -> (:>) (FL p) (FL p :> FL p) wX wY
partitionFL (RL (PatchInfoAnd rt p) wU wX -> PatchInfoAnd rt p wU wV -> Bool
forall (rt :: RepoType) (p :: * -> * -> *) wX wY (rt :: RepoType)
       (p :: * -> * -> *) wA wB.
RL (PatchInfoAnd rt p) wX wY -> PatchInfoAnd rt p wA wB -> Bool
infoIn RL (PatchInfoAnd rt p) wU wX
us') (FL (PatchInfoAnd rt p) wU wY
 -> (:>)
      (FL (PatchInfoAnd rt p))
      (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
      wU
      wY)
-> FL (PatchInfoAnd rt p) wU wY
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wY
forall a b. (a -> b) -> a -> b
$ RL (PatchInfoAnd rt p) wU wY -> FL (PatchInfoAnd rt p) wU wY
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wY
them' of
                    _ :> bad :: FL (PatchInfoAnd rt p) wZ wZ
bad@(_ :>: _) :> _ ->
                        String
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall a. String -> a
bug (String
 -> Fork
      (PatchSet rt p)
      (FL (PatchInfoAnd rt p))
      (FL (PatchInfoAnd rt p))
      wStart
      wX
      wY)
-> String
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall a b. (a -> b) -> a -> b
$ "Failed to commute common patches:\n"
                            String -> String -> String
forall a. [a] -> [a] -> [a]
++ Doc -> String
renderString ([Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
                                (forall wW wZ. PatchInfoAnd rt p wW wZ -> Doc)
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL (PatchInfo -> Doc
displayPatchInfo (PatchInfo -> Doc)
-> (PatchInfoAnd rt p wW wZ -> PatchInfo)
-> PatchInfoAnd rt p wW wZ
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info) (RL (PatchInfoAnd rt p) wZ wZ -> [Doc])
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall a b. (a -> b) -> a -> b
$ FL (PatchInfoAnd rt p) wZ wZ -> RL (PatchInfoAnd rt p) wZ wZ
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wZ wZ
bad)
                    _ :> NilFL :> only_theirs :: FL (PatchInfoAnd rt p) wZ wY
only_theirs ->
                        PatchSet rt p wStart wZ
-> FL (PatchInfoAnd rt p) wZ wX
-> FL (PatchInfoAnd rt p) wZ wY
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork (RL (Tagged rt p) wStart wU
-> RL (PatchInfoAnd rt p) wU wZ -> PatchSet rt p wStart wZ
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wU
common (FL (PatchInfoAnd rt p) wU wZ -> RL (PatchInfoAnd rt p) wU wZ
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wU wZ
common2))
                            FL (PatchInfoAnd rt p) wZ wX
FL (PatchInfoAnd rt p) wZ wX
only_ours (FL (PatchInfoAnd rt p) wZ wY -> FL (PatchInfoAnd rt p) wZ wY
forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart FL (PatchInfoAnd rt p) wZ wY
only_theirs)
  where
    infoIn :: RL (PatchInfoAnd rt p) wX wY -> PatchInfoAnd rt p wA wB -> Bool
infoIn inWhat :: RL (PatchInfoAnd rt p) wX wY
inWhat = (PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wX wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wX wY
inWhat) (PatchInfo -> Bool)
-> (PatchInfoAnd rt p wA wB -> PatchInfo)
-> PatchInfoAnd rt p wA wB
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAnd rt p wA wB -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info

findCommonWithThem :: Commute p
                   => PatchSet rt p wStart wX
                   -> PatchSet rt p wStart wY
                   -> (PatchSet rt p :> FL (PatchInfoAnd rt p)) wStart wX
findCommonWithThem :: PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) wStart wX
findCommonWithThem us :: PatchSet rt p wStart wX
us them :: PatchSet rt p wStart wY
them = case PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
Commute p =>
PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
taggedIntersection PatchSet rt p wStart wX
us PatchSet rt p wStart wY
them of
    Fork common :: RL (Tagged rt p) wStart wU
common us' :: RL (PatchInfoAnd rt p) wU wX
us' them' :: RL (PatchInfoAnd rt p) wU wY
them' ->
        case (forall wU wV. PatchInfoAnd rt p wU wV -> Bool)
-> FL (PatchInfoAnd rt p) wU wX
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wX
forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> FL p wX wY -> (:>) (FL p) (FL p :> FL p) wX wY
partitionFL ((PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wU wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wY
them') (PatchInfo -> Bool)
-> (PatchInfoAnd rt p wU wV -> PatchInfo)
-> PatchInfoAnd rt p wU wV
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAnd rt p wU wV -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info) (FL (PatchInfoAnd rt p) wU wX
 -> (:>)
      (FL (PatchInfoAnd rt p))
      (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
      wU
      wX)
-> FL (PatchInfoAnd rt p) wU wX
-> (:>)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p) :> FL (PatchInfoAnd rt p))
     wU
     wX
forall a b. (a -> b) -> a -> b
$ RL (PatchInfoAnd rt p) wU wX -> FL (PatchInfoAnd rt p) wU wX
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wX
us' of
            _ :> bad :: FL (PatchInfoAnd rt p) wZ wZ
bad@(_ :>: _) :> _ ->
                String -> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) wStart wX
forall a. String -> a
bug (String -> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) wStart wX)
-> String
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) wStart wX
forall a b. (a -> b) -> a -> b
$ "Failed to commute common patches:\n"
                      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Doc -> String
renderString
                          ([Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (forall wW wZ. PatchInfoAnd rt p wW wZ -> Doc)
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL (PatchInfo -> Doc
displayPatchInfo (PatchInfo -> Doc)
-> (PatchInfoAnd rt p wW wZ -> PatchInfo)
-> PatchInfoAnd rt p wW wZ
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info) (RL (PatchInfoAnd rt p) wZ wZ -> [Doc])
-> RL (PatchInfoAnd rt p) wZ wZ -> [Doc]
forall a b. (a -> b) -> a -> b
$ FL (PatchInfoAnd rt p) wZ wZ -> RL (PatchInfoAnd rt p) wZ wZ
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wZ wZ
bad)
            common2 :: FL (PatchInfoAnd rt p) wU wZ
common2 :> _nilfl :: FL (PatchInfoAnd rt p) wZ wZ
_nilfl :> only_ours :: FL (PatchInfoAnd rt p) wZ wX
only_ours ->
                RL (Tagged rt p) wStart wU
-> RL (PatchInfoAnd rt p) wU wZ -> PatchSet rt p wStart wZ
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wU
common (FL (PatchInfoAnd rt p) wU wZ -> RL (PatchInfoAnd rt p) wU wZ
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wU wZ
common2) PatchSet rt p wStart wZ
-> FL (PatchInfoAnd rt p) wZ wX
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) wStart wX
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> FL (PatchInfoAnd rt p) wZ wX -> FL (PatchInfoAnd rt p) wZ wX
forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP FL (PatchInfoAnd rt p) wZ wX
only_ours

findUncommon :: Commute p
             => PatchSet rt p wStart wX -> PatchSet rt p wStart wY
             -> (FL (PatchInfoAnd rt p) :\/: FL (PatchInfoAnd rt p)) wX wY
findUncommon :: PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> (:\/:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wX wY
findUncommon us :: PatchSet rt p wStart wX
us them :: PatchSet rt p wStart wY
them =
    case PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) wStart wX
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX wY.
Commute p =>
PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) wStart wX
findCommonWithThem PatchSet rt p wStart wX
us PatchSet rt p wStart wY
them of
        _common :: PatchSet rt p wStart wZ
_common :> us' :: FL (PatchInfoAnd rt p) wZ wX
us' -> case PatchSet rt p wStart wY
-> PatchSet rt p wStart wX
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) wStart wY
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX wY.
Commute p =>
PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) wStart wX
findCommonWithThem PatchSet rt p wStart wY
them PatchSet rt p wStart wX
us of
            _ :> them' :: FL (PatchInfoAnd rt p) wZ wY
them' -> FL (PatchInfoAnd rt p) wZ wX -> FL (PatchInfoAnd rt p) wZ wX
forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart FL (PatchInfoAnd rt p) wZ wX
us' FL (PatchInfoAnd rt p) wZ wX
-> FL (PatchInfoAnd rt p) wZ wY
-> (:\/:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wX wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wZ wX -> a2 wZ wY -> (:\/:) a1 a2 wX wY
:\/: FL (PatchInfoAnd rt p) wZ wY
them'

countUsThem :: Commute p
            => PatchSet rt p wStart wX
            -> PatchSet rt p wStart wY
            -> (Int, Int)
countUsThem :: PatchSet rt p wStart wX -> PatchSet rt p wStart wY -> (Int, Int)
countUsThem us :: PatchSet rt p wStart wX
us them :: PatchSet rt p wStart wY
them =
    case PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
Commute p =>
PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
taggedIntersection PatchSet rt p wStart wX
us PatchSet rt p wStart wY
them of
        Fork _ us' :: RL (PatchInfoAnd rt p) wU wX
us' them' :: RL (PatchInfoAnd rt p) wU wY
them' -> let uu :: [PatchInfo]
uu = (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wU wX -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wX
us'
                                tt :: [PatchInfo]
tt = (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wU wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wY
them' in
                            ([PatchInfo] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([PatchInfo] -> Int) -> [PatchInfo] -> Int
forall a b. (a -> b) -> a -> b
$ [PatchInfo]
uu [PatchInfo] -> [PatchInfo] -> [PatchInfo]
forall a. Eq a => [a] -> [a] -> [a]
\\ [PatchInfo]
tt, [PatchInfo] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([PatchInfo] -> Int) -> [PatchInfo] -> Int
forall a b. (a -> b) -> a -> b
$ [PatchInfo]
tt [PatchInfo] -> [PatchInfo] -> [PatchInfo]
forall a. Eq a => [a] -> [a] -> [a]
\\ [PatchInfo]
uu)

mergeThem :: (Merge p)
          => PatchSet rt p wStart wX -> PatchSet rt p wStart wY
          -> Sealed (FL (PatchInfoAnd rt p) wX)
mergeThem :: PatchSet rt p wStart wX
-> PatchSet rt p wStart wY -> Sealed (FL (PatchInfoAnd rt p) wX)
mergeThem us :: PatchSet rt p wStart wX
us them :: PatchSet rt p wStart wY
them =
    case PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
Commute p =>
PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
taggedIntersection PatchSet rt p wStart wX
us PatchSet rt p wStart wY
them of
        Fork _ us' :: RL (PatchInfoAnd rt p) wU wX
us' them' :: RL (PatchInfoAnd rt p) wU wY
them' ->
            case FL (PatchInfoAnd rt p) wU wX
-> FL (PatchInfoAnd rt p) wU wY
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wX wY
forall (p :: * -> * -> *) (rt :: RepoType) wX wY wZ.
Merge p =>
FL (PatchInfoAnd rt p) wX wY
-> FL (PatchInfoAnd rt p) wX wZ
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wY wZ
merge2FL (RL (PatchInfoAnd rt p) wU wX -> FL (PatchInfoAnd rt p) wU wX
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wX
us') (RL (PatchInfoAnd rt p) wU wY -> FL (PatchInfoAnd rt p) wU wY
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wY
them') of
               them'' :: FL (PatchInfoAnd rt p) wX wZ
them'' :/\: _ -> FL (PatchInfoAnd rt p) wX wZ -> Sealed (FL (PatchInfoAnd rt p) wX)
forall (a :: * -> *) wX. a wX -> Sealed a
Sealed FL (PatchInfoAnd rt p) wX wZ
them''

patchSetIntersection :: Commute p
                   => [SealedPatchSet rt p wStart]
                   -> SealedPatchSet rt p wStart
patchSetIntersection :: [SealedPatchSet rt p wStart] -> SealedPatchSet rt p wStart
patchSetIntersection [] = PatchSet rt p wStart wStart -> SealedPatchSet rt p wStart
forall (a :: * -> *) wX. a wX -> Sealed a
seal (PatchSet rt p wStart wStart -> SealedPatchSet rt p wStart)
-> PatchSet rt p wStart wStart -> SealedPatchSet rt p wStart
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wStart wStart
-> RL (PatchInfoAnd rt p) wStart wStart
-> PatchSet rt p wStart wStart
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wStart
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL RL (PatchInfoAnd rt p) wStart wStart
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
patchSetIntersection [x :: SealedPatchSet rt p wStart
x] = SealedPatchSet rt p wStart
x
patchSetIntersection (Sealed y :: PatchSet rt p wStart wX
y : ys :: [SealedPatchSet rt p wStart]
ys) =
    case [SealedPatchSet rt p wStart] -> SealedPatchSet rt p wStart
forall (p :: * -> * -> *) (rt :: RepoType) wStart.
Commute p =>
[SealedPatchSet rt p wStart] -> SealedPatchSet rt p wStart
patchSetIntersection [SealedPatchSet rt p wStart]
ys of
        Sealed z :: PatchSet rt p wStart wX
z -> case PatchSet rt p wStart wX
-> PatchSet rt p wStart wX
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
Commute p =>
PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
taggedIntersection PatchSet rt p wStart wX
y PatchSet rt p wStart wX
z of
            Fork common :: RL (Tagged rt p) wStart wU
common a :: RL (PatchInfoAnd rt p) wU wX
a b :: RL (PatchInfoAnd rt p) wU wX
b -> case (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wU wX -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wX
a [PatchInfo] -> [PatchInfo] -> [PatchInfo]
forall a. Eq a => [a] -> [a] -> [a]
`intersect` (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wU wX -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wX
b of
                morecommon :: [PatchInfo]
morecommon ->
                    case (forall wU wV. PatchInfoAnd rt p wU wV -> Bool)
-> RL (PatchInfoAnd rt p) wU wX
-> (:>) (RL (PatchInfoAnd rt p)) (RL (PatchInfoAnd rt p)) wU wX
forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> RL p wX wY -> (:>) (RL p) (RL p) wX wY
partitionRL (\e :: PatchInfoAnd rt p wU wV
e -> PatchInfoAnd rt p wU wV -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wU wV
e PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [PatchInfo]
morecommon) RL (PatchInfoAnd rt p) wU wX
a of
                        commonps :: RL (PatchInfoAnd rt p) wU wZ
commonps :> _ -> PatchSet rt p wStart wZ -> SealedPatchSet rt p wStart
forall (a :: * -> *) wX. a wX -> Sealed a
seal (PatchSet rt p wStart wZ -> SealedPatchSet rt p wStart)
-> PatchSet rt p wStart wZ -> SealedPatchSet rt p wStart
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wStart wU
-> RL (PatchInfoAnd rt p) wU wZ -> PatchSet rt p wStart wZ
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wU
common RL (PatchInfoAnd rt p) wU wZ
commonps

patchSetUnion :: (Merge p)
            => [SealedPatchSet rt p wStart]
            -> SealedPatchSet rt p wStart
patchSetUnion :: [SealedPatchSet rt p wStart] -> SealedPatchSet rt p wStart
patchSetUnion [] = PatchSet rt p wStart wStart -> SealedPatchSet rt p wStart
forall (a :: * -> *) wX. a wX -> Sealed a
seal (PatchSet rt p wStart wStart -> SealedPatchSet rt p wStart)
-> PatchSet rt p wStart wStart -> SealedPatchSet rt p wStart
forall a b. (a -> b) -> a -> b
$ RL (Tagged rt p) wStart wStart
-> RL (PatchInfoAnd rt p) wStart wStart
-> PatchSet rt p wStart wStart
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wStart
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL RL (PatchInfoAnd rt p) wStart wStart
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
patchSetUnion [x :: SealedPatchSet rt p wStart
x] = SealedPatchSet rt p wStart
x
patchSetUnion (Sealed y :: PatchSet rt p wStart wX
y@(PatchSet tsy :: RL (Tagged rt p) wStart wX
tsy psy :: RL (PatchInfoAnd rt p) wX wX
psy) : Sealed y2 :: PatchSet rt p wStart wX
y2 : ys :: [SealedPatchSet rt p wStart]
ys) =
    case PatchSet rt p wStart wX
-> PatchSet rt p wStart wX -> Sealed (FL (PatchInfoAnd rt p) wX)
forall (p :: * -> * -> *) (rt :: RepoType) wStart wX wY.
Merge p =>
PatchSet rt p wStart wX
-> PatchSet rt p wStart wY -> Sealed (FL (PatchInfoAnd rt p) wX)
mergeThem PatchSet rt p wStart wX
y PatchSet rt p wStart wX
y2 of
        Sealed p2 :: FL (PatchInfoAnd rt p) wX wX
p2 ->
            [SealedPatchSet rt p wStart] -> SealedPatchSet rt p wStart
forall (p :: * -> * -> *) (rt :: RepoType) wStart.
Merge p =>
[SealedPatchSet rt p wStart] -> SealedPatchSet rt p wStart
patchSetUnion ([SealedPatchSet rt p wStart] -> SealedPatchSet rt p wStart)
-> [SealedPatchSet rt p wStart] -> SealedPatchSet rt p wStart
forall a b. (a -> b) -> a -> b
$ PatchSet rt p wStart wX -> SealedPatchSet rt p wStart
forall (a :: * -> *) wX. a wX -> Sealed a
seal (RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wX -> PatchSet rt p wStart wX
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
RL (Tagged rt p) wStart wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
PatchSet RL (Tagged rt p) wStart wX
tsy (RL (PatchInfoAnd rt p) wX wX
psy RL (PatchInfoAnd rt p) wX wX
-> RL (PatchInfoAnd rt p) wX wX -> RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ FL (PatchInfoAnd rt p) wX wX -> RL (PatchInfoAnd rt p) wX wX
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wX wX
p2)) SealedPatchSet rt p wStart
-> [SealedPatchSet rt p wStart] -> [SealedPatchSet rt p wStart]
forall a. a -> [a] -> [a]
: [SealedPatchSet rt p wStart]
ys

-- | Merge two FLs (say L and R), starting in a common context. The result is a
-- FL starting in the original end context of L, going to a new context that is
-- the result of applying all patches from R on top of patches from L.
--
-- While this function is similar to 'mergeFL', there are some important
-- differences to keep in mind:
--
-- * 'mergeFL' does not correctly deal with duplicate patches whereas this one
--   does
--   (Question from Eric Kow: in what sense? Why not fix 'mergeFL'?)
--   (bf: I guess what was meant here is that 'merge2FL' works in the
--    the way it does because it considers patch meta data whereas
--    'mergeFL' cannot since it must work for primitive patches, too.
merge2FL :: (Merge p)
         => FL (PatchInfoAnd rt p) wX wY
         -> FL (PatchInfoAnd rt p) wX wZ
         -> (FL (PatchInfoAnd rt p) :/\: FL (PatchInfoAnd rt p)) wY wZ
merge2FL :: FL (PatchInfoAnd rt p) wX wY
-> FL (PatchInfoAnd rt p) wX wZ
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wY wZ
merge2FL xs :: FL (PatchInfoAnd rt p) wX wY
xs NilFL = FL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL FL (PatchInfoAnd rt p) wY wY
-> FL (PatchInfoAnd rt p) wX wY
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wY wX
forall (a3 :: * -> * -> *) (a4 :: * -> * -> *) wX wY wZ.
a3 wX wZ -> a4 wY wZ -> (:/\:) a3 a4 wX wY
:/\: FL (PatchInfoAnd rt p) wX wY
xs
merge2FL NilFL ys :: FL (PatchInfoAnd rt p) wX wZ
ys = FL (PatchInfoAnd rt p) wX wZ
ys FL (PatchInfoAnd rt p) wX wZ
-> FL (PatchInfoAnd rt p) wZ wZ
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wX wZ
forall (a3 :: * -> * -> *) (a4 :: * -> * -> *) wX wY wZ.
a3 wX wZ -> a4 wY wZ -> (:/\:) a3 a4 wX wY
:/\: FL (PatchInfoAnd rt p) wZ wZ
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
merge2FL xs :: FL (PatchInfoAnd rt p) wX wY
xs (y :: PatchInfoAnd rt p wX wY
y :>: ys :: FL (PatchInfoAnd rt p) wY wZ
ys) | Just xs' :: FL (PatchInfoAnd rt p) wY wY
xs' <- PatchInfoAnd rt p wX wY
-> FL (PatchInfoAnd rt p) wX wY
-> Maybe (FL (PatchInfoAnd rt p) wY wY)
forall (p :: * -> * -> *) (rt :: RepoType) wX wY wZ.
Commute p =>
PatchInfoAnd rt p wX wY
-> FL (PatchInfoAnd rt p) wX wZ
-> Maybe (FL (PatchInfoAnd rt p) wY wZ)
fastRemoveFL PatchInfoAnd rt p wX wY
y FL (PatchInfoAnd rt p) wX wY
xs = FL (PatchInfoAnd rt p) wY wY
-> FL (PatchInfoAnd rt p) wY wZ
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wY wZ
forall (p :: * -> * -> *) (rt :: RepoType) wX wY wZ.
Merge p =>
FL (PatchInfoAnd rt p) wX wY
-> FL (PatchInfoAnd rt p) wX wZ
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wY wZ
merge2FL FL (PatchInfoAnd rt p) wY wY
xs' FL (PatchInfoAnd rt p) wY wZ
ys
merge2FL (x :: PatchInfoAnd rt p wX wY
x :>: xs :: FL (PatchInfoAnd rt p) wY wY
xs) ys :: FL (PatchInfoAnd rt p) wX wZ
ys | Just ys' :: FL (PatchInfoAnd rt p) wY wZ
ys' <- PatchInfoAnd rt p wX wY
-> FL (PatchInfoAnd rt p) wX wZ
-> Maybe (FL (PatchInfoAnd rt p) wY wZ)
forall (p :: * -> * -> *) (rt :: RepoType) wX wY wZ.
Commute p =>
PatchInfoAnd rt p wX wY
-> FL (PatchInfoAnd rt p) wX wZ
-> Maybe (FL (PatchInfoAnd rt p) wY wZ)
fastRemoveFL PatchInfoAnd rt p wX wY
x FL (PatchInfoAnd rt p) wX wZ
ys = FL (PatchInfoAnd rt p) wY wY
-> FL (PatchInfoAnd rt p) wY wZ
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wY wZ
forall (p :: * -> * -> *) (rt :: RepoType) wX wY wZ.
Merge p =>
FL (PatchInfoAnd rt p) wX wY
-> FL (PatchInfoAnd rt p) wX wZ
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wY wZ
merge2FL FL (PatchInfoAnd rt p) wY wY
xs FL (PatchInfoAnd rt p) wY wZ
ys'
                       | Bool
otherwise = case (:\/:) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wY wZ
-> (:/\:) (FL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wY wZ
forall (p :: * -> * -> *) wX wY.
Merge p =>
(:\/:) p (FL p) wX wY -> (:/\:) (FL p) p wX wY
mergeFL (PatchInfoAnd rt p wX wY
x PatchInfoAnd rt p wX wY
-> FL (PatchInfoAnd rt p) wX wZ
-> (:\/:) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wY wZ
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wZ wX -> a2 wZ wY -> (:\/:) a1 a2 wX wY
:\/: FL (PatchInfoAnd rt p) wX wZ
ys) of
                                         ys' :: FL (PatchInfoAnd rt p) wY wZ
ys' :/\: x' :: PatchInfoAnd rt p wZ wZ
x' ->
                                            case FL (PatchInfoAnd rt p) wY wY
-> FL (PatchInfoAnd rt p) wY wZ
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wY wZ
forall (p :: * -> * -> *) (rt :: RepoType) wX wY wZ.
Merge p =>
FL (PatchInfoAnd rt p) wX wY
-> FL (PatchInfoAnd rt p) wX wZ
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wY wZ
merge2FL FL (PatchInfoAnd rt p) wY wY
xs FL (PatchInfoAnd rt p) wY wZ
ys' of
                                                ys'' :: FL (PatchInfoAnd rt p) wY wZ
ys'' :/\: xs' :: FL (PatchInfoAnd rt p) wZ wZ
xs' ->
                                                   FL (PatchInfoAnd rt p) wY wZ
ys'' FL (PatchInfoAnd rt p) wY wZ
-> FL (PatchInfoAnd rt p) wZ wZ
-> (:/\:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wY wZ
forall (a3 :: * -> * -> *) (a4 :: * -> * -> *) wX wY wZ.
a3 wX wZ -> a4 wY wZ -> (:/\:) a3 a4 wX wY
:/\: (PatchInfoAnd rt p wZ wZ
x' PatchInfoAnd rt p wZ wZ
-> FL (PatchInfoAnd rt p) wZ wZ -> FL (PatchInfoAnd rt p) wZ wZ
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (PatchInfoAnd rt p) wZ wZ
xs')

areUnrelatedRepos :: Commute p
                  => PatchSet rt p wStart wX
                  -> PatchSet rt p wStart wY -> Bool
areUnrelatedRepos :: PatchSet rt p wStart wX -> PatchSet rt p wStart wY -> Bool
areUnrelatedRepos us :: PatchSet rt p wStart wX
us them :: PatchSet rt p wStart wY
them =
    case PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
Commute p =>
PatchSet rt p wStart wX
-> PatchSet rt p wStart wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     wStart
     wX
     wY
taggedIntersection PatchSet rt p wStart wX
us PatchSet rt p wStart wY
them of
        Fork c :: RL (Tagged rt p) wStart wU
c u :: RL (PatchInfoAnd rt p) wU wX
u t :: RL (PatchInfoAnd rt p) wU wY
t -> RL (Tagged rt p) wStart wU
-> RL (PatchInfoAnd rt p) wU wX
-> RL (PatchInfoAnd rt p) wU wY
-> Bool
forall (rt :: RepoType) (p :: * -> * -> *) wX wZ (rt :: RepoType)
       (p :: * -> * -> *) wX wY (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) wX wZ
-> RL (PatchInfoAnd rt p) wX wY
-> RL (PatchInfoAnd rt p) wX wY
-> Bool
checkit RL (Tagged rt p) wStart wU
c RL (PatchInfoAnd rt p) wU wX
u RL (PatchInfoAnd rt p) wU wY
t
  where
    checkit :: RL (Tagged rt p) wX wZ
-> RL (PatchInfoAnd rt p) wX wY
-> RL (PatchInfoAnd rt p) wX wY
-> Bool
checkit (_ :<: Tagged{}) _ _ = Bool
False
    checkit _ u :: RL (PatchInfoAnd rt p) wX wY
u t :: RL (PatchInfoAnd rt p) wX wY
t | RL (PatchInfoAnd rt p) wX wY
t RL (PatchInfoAnd rt p) wX wY -> Int -> Bool
forall (a :: * -> * -> *) wX wY. RL a wX wY -> Int -> Bool
`isShorterThanRL` 5 = Bool
False
                  | RL (PatchInfoAnd rt p) wX wY
u RL (PatchInfoAnd rt p) wX wY -> Int -> Bool
forall (a :: * -> * -> *) wX wY. RL a wX wY -> Int -> Bool
`isShorterThanRL` 5 = Bool
False
                  | Bool
otherwise = [PatchInfo] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([PatchInfo] -> Bool) -> [PatchInfo] -> Bool
forall a b. (a -> b) -> a -> b
$ [PatchInfo] -> [PatchInfo] -> [PatchInfo]
forall a. Eq a => [a] -> [a] -> [a]
intersect ((forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wX wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wX wY
u) ((forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wX wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wX wY
t)

-- | Remove a patch from FL, using PatchInfo equality. The result is Just
-- whenever the patch has been found and removed. If the patch is not present
-- in the sequence at all or any commutation fails, we get Nothing. First two
-- cases are optimisations for the common cases where the head of the list is
-- the patch to remove, or the patch is not there at all.
--
-- A note on the witness types: the patch to be removed is typed as if it had
-- to be the first in the list, since it has the same pre-context as the list.
-- The types fit together (internally, in this module) because we commute the
-- patch to the front before removing it and commutation inside a sequence does
-- not change the sequence's contexts.
fastRemoveFL :: Commute p
             => PatchInfoAnd rt p wX wY -- this type assumes element is at the front
             -> FL (PatchInfoAnd rt p) wX wZ
             -> Maybe (FL (PatchInfoAnd rt p) wY wZ)
fastRemoveFL :: PatchInfoAnd rt p wX wY
-> FL (PatchInfoAnd rt p) wX wZ
-> Maybe (FL (PatchInfoAnd rt p) wY wZ)
fastRemoveFL _ NilFL = Maybe (FL (PatchInfoAnd rt p) wY wZ)
forall a. Maybe a
Nothing
fastRemoveFL a :: PatchInfoAnd rt p wX wY
a (b :: PatchInfoAnd rt p wX wY
b :>: bs :: FL (PatchInfoAnd rt p) wY wZ
bs) | EqCheck wY wY
IsEq <- PatchInfoAnd rt p wX wY
a PatchInfoAnd rt p wX wY -> PatchInfoAnd rt p wX wY -> EqCheck wY wY
forall (p :: * -> * -> *) wA wB wC.
Eq2 p =>
p wA wB -> p wA wC -> EqCheck wB wC
=\/= PatchInfoAnd rt p wX wY
b = FL (PatchInfoAnd rt p) wY wZ
-> Maybe (FL (PatchInfoAnd rt p) wY wZ)
forall a. a -> Maybe a
Just FL (PatchInfoAnd rt p) wY wZ
bs
                          | PatchInfoAnd rt p wX wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wX wY
a PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> FL (PatchInfoAnd rt p) wY wZ -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> FL a wX wY -> [b]
mapFL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info FL (PatchInfoAnd rt p) wY wZ
bs = Maybe (FL (PatchInfoAnd rt p) wY wZ)
forall a. Maybe a
Nothing
fastRemoveFL a :: PatchInfoAnd rt p wX wY
a (b :: PatchInfoAnd rt p wX wY
b :>: bs :: FL (PatchInfoAnd rt p) wY wZ
bs) = do
    a' :: PatchInfoAnd rt p wY wZ
a' :> bs' :: FL (PatchInfoAnd rt p) wZ wZ
bs' <- RL (PatchInfoAnd rt p) wY wY
-> FL (PatchInfoAnd rt p) wY wZ
-> Maybe ((:>) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wY wZ)
forall (p :: * -> * -> *) (rt :: RepoType) wA wB wC.
Commute p =>
RL (PatchInfoAnd rt p) wA wB
-> FL (PatchInfoAnd rt p) wB wC
-> Maybe ((:>) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wA wC)
pullout RL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL FL (PatchInfoAnd rt p) wY wZ
bs
    a'' :: PatchInfoAnd rt p wX wZ
a'' :> b' :: PatchInfoAnd rt p wZ wZ
b' <- (:>) (PatchInfoAnd rt p) (PatchInfoAnd rt p) wX wZ
-> Maybe ((:>) (PatchInfoAnd rt p) (PatchInfoAnd rt p) wX wZ)
forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (PatchInfoAnd rt p wX wY
b PatchInfoAnd rt p wX wY
-> PatchInfoAnd rt p wY wZ
-> (:>) (PatchInfoAnd rt p) (PatchInfoAnd rt p) wX wZ
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfoAnd rt p wY wZ
a')
    EqCheck wZ wY
IsEq <- EqCheck wZ wY -> Maybe (EqCheck wZ wY)
forall (m :: * -> *) a. Monad m => a -> m a
return (PatchInfoAnd rt p wX wZ
a'' PatchInfoAnd rt p wX wZ -> PatchInfoAnd rt p wX wY -> EqCheck wZ wY
forall (p :: * -> * -> *) wA wB wC.
Eq2 p =>
p wA wB -> p wA wC -> EqCheck wB wC
=\/= PatchInfoAnd rt p wX wY
a)
    FL (PatchInfoAnd rt p) wZ wZ
-> Maybe (FL (PatchInfoAnd rt p) wZ wZ)
forall a. a -> Maybe a
Just (PatchInfoAnd rt p wZ wZ
b' PatchInfoAnd rt p wZ wZ
-> FL (PatchInfoAnd rt p) wZ wZ -> FL (PatchInfoAnd rt p) wZ wZ
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (PatchInfoAnd rt p) wZ wZ
bs')
  where
    i :: PatchInfo
i = PatchInfoAnd rt p wX wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wX wY
a
    pullout :: Commute p
            => RL (PatchInfoAnd rt p) wA wB
            -> FL (PatchInfoAnd rt p) wB wC
            -> Maybe ((PatchInfoAnd rt p :> FL (PatchInfoAnd rt p)) wA wC)
    pullout :: RL (PatchInfoAnd rt p) wA wB
-> FL (PatchInfoAnd rt p) wB wC
-> Maybe ((:>) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wA wC)
pullout _ NilFL = Maybe ((:>) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wA wC)
forall a. Maybe a
Nothing
    pullout acc :: RL (PatchInfoAnd rt p) wA wB
acc (x :: PatchInfoAnd rt p wB wY
x :>: xs :: FL (PatchInfoAnd rt p) wY wC
xs)
        | PatchInfoAnd rt p wB wY -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wB wY
x PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
i = do x' :: PatchInfoAnd rt p wA wZ
x' :> acc' :: RL (PatchInfoAnd rt p) wZ wY
acc' <- (:>) (RL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wA wY
-> Maybe ((:>) (PatchInfoAnd rt p) (RL (PatchInfoAnd rt p)) wA wY)
forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) (RL p) p wX wY -> Maybe ((:>) p (RL p) wX wY)
commuteRL (RL (PatchInfoAnd rt p) wA wB
acc RL (PatchInfoAnd rt p) wA wB
-> PatchInfoAnd rt p wB wY
-> (:>) (RL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wA wY
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfoAnd rt p wB wY
x)
                           (:>) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wA wC
-> Maybe ((:>) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wA wC)
forall a. a -> Maybe a
Just (PatchInfoAnd rt p wA wZ
x' PatchInfoAnd rt p wA wZ
-> FL (PatchInfoAnd rt p) wZ wC
-> (:>) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wA wC
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> RL (PatchInfoAnd rt p) wZ wY
acc' RL (PatchInfoAnd rt p) wZ wY
-> FL (PatchInfoAnd rt p) wY wC -> FL (PatchInfoAnd rt p) wZ wC
forall (p :: * -> * -> *) wX wY wZ.
RL p wX wY -> FL p wY wZ -> FL p wX wZ
+>>+ FL (PatchInfoAnd rt p) wY wC
xs)
        | Bool
otherwise = RL (PatchInfoAnd rt p) wA wY
-> FL (PatchInfoAnd rt p) wY wC
-> Maybe ((:>) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wA wC)
forall (p :: * -> * -> *) (rt :: RepoType) wA wB wC.
Commute p =>
RL (PatchInfoAnd rt p) wA wB
-> FL (PatchInfoAnd rt p) wB wC
-> Maybe ((:>) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wA wC)
pullout (RL (PatchInfoAnd rt p) wA wB
acc RL (PatchInfoAnd rt p) wA wB
-> PatchInfoAnd rt p wB wY -> RL (PatchInfoAnd rt p) wA wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wB wY
x) FL (PatchInfoAnd rt p) wY wC
xs

-- | Same as 'fastRemoveFL' only for 'RL'.
fastRemoveRL :: Commute p
             => PatchInfoAnd rt p wY wZ -- this type assumes element is at the back
             -> RL (PatchInfoAnd rt p) wX wZ
             -> Maybe (RL (PatchInfoAnd rt p) wX wY)
fastRemoveRL :: PatchInfoAnd rt p wY wZ
-> RL (PatchInfoAnd rt p) wX wZ
-> Maybe (RL (PatchInfoAnd rt p) wX wY)
fastRemoveRL _ NilRL = Maybe (RL (PatchInfoAnd rt p) wX wY)
forall a. Maybe a
Nothing
fastRemoveRL a :: PatchInfoAnd rt p wY wZ
a (bs :: RL (PatchInfoAnd rt p) wX wY
bs :<: b :: PatchInfoAnd rt p wY wZ
b) | EqCheck wY wY
IsEq <- PatchInfoAnd rt p wY wZ
b PatchInfoAnd rt p wY wZ -> PatchInfoAnd rt p wY wZ -> EqCheck wY wY
forall (p :: * -> * -> *) wA wC wB.
Eq2 p =>
p wA wC -> p wB wC -> EqCheck wA wB
=/\= PatchInfoAnd rt p wY wZ
a = RL (PatchInfoAnd rt p) wX wY
-> Maybe (RL (PatchInfoAnd rt p) wX wY)
forall a. a -> Maybe a
Just RL (PatchInfoAnd rt p) wX wY
bs
                          | PatchInfoAnd rt p wY wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wZ
a PatchInfo -> [PatchInfo] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` (forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo)
-> RL (PatchInfoAnd rt p) wX wY -> [PatchInfo]
forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall wW wZ. PatchInfoAnd rt p wW wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wX wY
bs = Maybe (RL (PatchInfoAnd rt p) wX wY)
forall a. Maybe a
Nothing
fastRemoveRL a :: PatchInfoAnd rt p wY wZ
a (bs :: RL (PatchInfoAnd rt p) wX wY
bs :<: b :: PatchInfoAnd rt p wY wZ
b) = do
    bs' :: RL (PatchInfoAnd rt p) wX wZ
bs' :> a' :: PatchInfoAnd rt p wZ wY
a' <- RL (PatchInfoAnd rt p) wX wY
-> FL (PatchInfoAnd rt p) wY wY
-> Maybe ((:>) (RL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wX wY)
forall (p :: * -> * -> *) (rt :: RepoType) wA wB wC.
Commute p =>
RL (PatchInfoAnd rt p) wA wB
-> FL (PatchInfoAnd rt p) wB wC
-> Maybe ((:>) (RL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wA wC)
pullout RL (PatchInfoAnd rt p) wX wY
bs FL (PatchInfoAnd rt p) wY wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
    b' :: PatchInfoAnd rt p wZ wZ
b' :> a'' :: PatchInfoAnd rt p wZ wZ
a'' <- (:>) (PatchInfoAnd rt p) (PatchInfoAnd rt p) wZ wZ
-> Maybe ((:>) (PatchInfoAnd rt p) (PatchInfoAnd rt p) wZ wZ)
forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p p wX wY -> Maybe ((:>) p p wX wY)
commute (PatchInfoAnd rt p wZ wY
a' PatchInfoAnd rt p wZ wY
-> PatchInfoAnd rt p wY wZ
-> (:>) (PatchInfoAnd rt p) (PatchInfoAnd rt p) wZ wZ
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfoAnd rt p wY wZ
b)
    EqCheck wZ wY
IsEq <- EqCheck wZ wY -> Maybe (EqCheck wZ wY)
forall (m :: * -> *) a. Monad m => a -> m a
return (PatchInfoAnd rt p wZ wZ
a'' PatchInfoAnd rt p wZ wZ -> PatchInfoAnd rt p wY wZ -> EqCheck wZ wY
forall (p :: * -> * -> *) wA wC wB.
Eq2 p =>
p wA wC -> p wB wC -> EqCheck wA wB
=/\= PatchInfoAnd rt p wY wZ
a)
    RL (PatchInfoAnd rt p) wX wZ
-> Maybe (RL (PatchInfoAnd rt p) wX wZ)
forall a. a -> Maybe a
Just (RL (PatchInfoAnd rt p) wX wZ
bs' RL (PatchInfoAnd rt p) wX wZ
-> PatchInfoAnd rt p wZ wZ -> RL (PatchInfoAnd rt p) wX wZ
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wZ wZ
b')
  where
    i :: PatchInfo
i = PatchInfoAnd rt p wY wZ -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wZ
a
    pullout :: Commute p
            => RL (PatchInfoAnd rt p) wA wB
            -> FL (PatchInfoAnd rt p) wB wC
            -> Maybe ((RL (PatchInfoAnd rt p) :> PatchInfoAnd rt p) wA wC)
    pullout :: RL (PatchInfoAnd rt p) wA wB
-> FL (PatchInfoAnd rt p) wB wC
-> Maybe ((:>) (RL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wA wC)
pullout NilRL _ = Maybe ((:>) (RL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wA wC)
forall a. Maybe a
Nothing
    pullout (xs :: RL (PatchInfoAnd rt p) wA wY
xs :<: x :: PatchInfoAnd rt p wY wB
x) acc :: FL (PatchInfoAnd rt p) wB wC
acc
        | PatchInfoAnd rt p wY wB -> PatchInfo
forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAnd rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wB
x PatchInfo -> PatchInfo -> Bool
forall a. Eq a => a -> a -> Bool
== PatchInfo
i = do acc' :: FL (PatchInfoAnd rt p) wY wZ
acc' :> x' :: PatchInfoAnd rt p wZ wC
x' <- (:>) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wY wC
-> Maybe ((:>) (FL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wY wC)
forall (p :: * -> * -> *) wX wY.
Commute p =>
(:>) p (FL p) wX wY -> Maybe ((:>) (FL p) p wX wY)
commuteFL (PatchInfoAnd rt p wY wB
x PatchInfoAnd rt p wY wB
-> FL (PatchInfoAnd rt p) wB wC
-> (:>) (PatchInfoAnd rt p) (FL (PatchInfoAnd rt p)) wY wC
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> FL (PatchInfoAnd rt p) wB wC
acc)
                           (:>) (RL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wA wC
-> Maybe ((:>) (RL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wA wC)
forall a. a -> Maybe a
Just (RL (PatchInfoAnd rt p) wA wY
xs RL (PatchInfoAnd rt p) wA wY
-> FL (PatchInfoAnd rt p) wY wZ -> RL (PatchInfoAnd rt p) wA wZ
forall (p :: * -> * -> *) wX wY wZ.
RL p wX wY -> FL p wY wZ -> RL p wX wZ
+<<+ FL (PatchInfoAnd rt p) wY wZ
acc' RL (PatchInfoAnd rt p) wA wZ
-> PatchInfoAnd rt p wZ wC
-> (:>) (RL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wA wC
forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> PatchInfoAnd rt p wZ wC
x')
        | Bool
otherwise = RL (PatchInfoAnd rt p) wA wY
-> FL (PatchInfoAnd rt p) wY wC
-> Maybe ((:>) (RL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wA wC)
forall (p :: * -> * -> *) (rt :: RepoType) wA wB wC.
Commute p =>
RL (PatchInfoAnd rt p) wA wB
-> FL (PatchInfoAnd rt p) wB wC
-> Maybe ((:>) (RL (PatchInfoAnd rt p)) (PatchInfoAnd rt p) wA wC)
pullout RL (PatchInfoAnd rt p) wA wY
xs (PatchInfoAnd rt p wY wB
x PatchInfoAnd rt p wY wB
-> FL (PatchInfoAnd rt p) wB wC -> FL (PatchInfoAnd rt p) wY wC
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL (PatchInfoAnd rt p) wB wC
acc)