moduleDarcs.Patch.Conflict(Conflict(..),CommuteNoConflicts(..),IsConflictedPrim(..),ConflictState(..))whereimportDarcs.Patch.Effect(Effect(..))importDarcs.Patch.Inspect(PatchInspect(..))importDarcs.Patch.Permutations()importDarcs.Patch.Prim.Class(PrimOf)importDarcs.Witnesses.Ordered(FL(..),RL(..),(:>)(..),mapFL,reverseFL,mapRL,reverseRL)importDarcs.Witnesses.Sealed(Sealed,unseal)importDarcs.Utils(nubsort)#include "gadts.h"class(Effectp,PatchInspect(PrimOfp))=>ConflictpwherelistConflictedFiles::pC(xy)->[FilePath]listConflictedFilesp=nubsort$concatMap(unseallistTouchedFiles)$concat$resolveConflictspresolveConflicts::pC(xy)->[[Sealed(FL(PrimOfp)C(y))]]conflictedEffect::pC(xy)->[IsConflictedPrim(PrimOfp)]conflictedEffectx=caselistConflictedFilesxof[]->mapFL(IsCOkay)$effectx_->mapFL(IsCConflicted)$effectxclassCommuteNoConflictspwhere-- | If 'commuteNoConflicts' @x :> y@ succeeds, we know that that @x@ commutes-- past @y@ without any conflicts. This function is useful for patch types-- for which 'commute' is defined to always succeed; so we need some way to-- pick out the specific cases where commutation succeeds without any conflicts.commuteNoConflicts::(p:>p)C(xy)->Maybe((p:>p)C(xy))instance(CommuteNoConflictsp,Conflictp)=>Conflict(FLp)wherelistConflictedFiles=nubsort.concat.mapFLlistConflictedFilesresolveConflictsNilFL=[]resolveConflictsx=resolveConflicts$reverseFLxconflictedEffect=concat.mapFLconflictedEffectinstanceCommuteNoConflictsp=>CommuteNoConflicts(FLp)wherecommuteNoConflicts(NilFL:>x)=Just(x:>NilFL)commuteNoConflicts(x:>NilFL)=Just(NilFL:>x)commuteNoConflicts(xs:>ys)=doys':>rxs'<-commuteNoConflictsRLFL(reverseFLxs:>ys)return$ys':>reverseRLrxs'instance(CommuteNoConflictsp,Conflictp)=>Conflict(RLp)wherelistConflictedFiles=nubsort.concat.mapRLlistConflictedFilesresolveConflictsx=rcsxNilFLwherercs::RLpC(xy)->FLpC(yw)->[[Sealed(FL(PrimOfp)C(w))]]rcsNilRL_=[]rcs(p:<:ps)passedby|(_:_)<-resolveConflictsp=casecommuteNoConflictsFL(p:>passedby)ofJust(_:>p')->resolveConflictsp'++rcsps(p:>:passedby)Nothing->rcsps(p:>:passedby)rcs(p:<:ps)passedby=seqpassedby$rcsps(p:>:passedby)conflictedEffect=concat.reverse.mapRLconflictedEffectinstanceCommuteNoConflictsp=>CommuteNoConflicts(RLp)wherecommuteNoConflicts(NilRL:>x)=Just(x:>NilRL)commuteNoConflicts(x:>NilRL)=Just(NilRL:>x)commuteNoConflicts(xs:>ys)=doys':>rxs'<-commuteNoConflictsRLFL(xs:>reverseRLys)return$reverseFLys':>rxs'dataIsConflictedPrimprimwhereIsC::!ConflictState->!(primC(xy))->IsConflictedPrimprimdataConflictState=Okay|Conflicted|Duplicatedderiving(Eq,Ord,Show,Read)commuteNoConflictsFL::CommuteNoConflictsp=>(p:>FLp)C(xy)->Maybe((FLp:>p)C(xy))commuteNoConflictsFL(p:>NilFL)=Just(NilFL:>p)commuteNoConflictsFL(q:>p:>:ps)=dop':>q'<-commuteNoConflicts(q:>p)ps':>q''<-commuteNoConflictsFL(q':>ps)return(p':>:ps':>q'')commuteNoConflictsRL::CommuteNoConflictsp=>(RLp:>p)C(xy)->Maybe((p:>RLp)C(xy))commuteNoConflictsRL(NilRL:>p)=Just(p:>NilRL)commuteNoConflictsRL(p:<:ps:>q)=doq':>p'<-commuteNoConflicts(p:>q)q'':>ps'<-commuteNoConflictsRL(ps:>q')return(q'':>p':<:ps')commuteNoConflictsRLFL::CommuteNoConflictsp=>(RLp:>FLp)C(xy)->Maybe((FLp:>RLp)C(xy))commuteNoConflictsRLFL(NilRL:>ys)=Just(ys:>NilRL)commuteNoConflictsRLFL(xs:>NilFL)=Just(NilFL:>xs)commuteNoConflictsRLFL(xs:>y:>:ys)=doy':>xs'<-commuteNoConflictsRL(xs:>y)ys':>xs''<-commuteNoConflictsRLFL(xs':>ys)return(y':>:ys':>xs'')