module Darcs.Patch.CommuteFn
( CommuteFn,
commuterIdFL, commuterFLId,
commuterIdRL, commuterRLId,
MergeFn,
mergerIdFL,
TotalCommuteFn,
totalCommuterIdFL, totalCommuterFLId, totalCommuterFLFL
) where
import Prelude ()
import Darcs.Prelude
import Darcs.Patch.Witnesses.Ordered
( (:>)(..)
, (:\/:)(..)
, (:/\:)(..)
, FL(..)
, RL(..)
)
type CommuteFn p1 p2 = forall wX wY . (p1 :> p2) wX wY -> Maybe ((p2 :> p1) wX wY)
type TotalCommuteFn p1 p2 = forall wX wY . (p1 :> p2) wX wY -> (p2 :> p1) wX wY
type MergeFn p1 p2 = forall wX wY . (p1 :\/: p2) wX wY -> (p2 :/\: p1) wX wY
commuterIdRL :: CommuteFn p1 p2 -> CommuteFn p1 (RL p2)
commuterIdRL _ (x :> NilRL) = return (NilRL :> x)
commuterIdRL commuter (x :> (ys :<: y))
= do ys' :> x' <- commuterIdRL commuter (x :> ys)
y' :> x'' <- commuter (x' :> y)
return ((ys' :<: y') :> x'')
commuterIdFL :: CommuteFn p1 p2 -> CommuteFn p1 (FL p2)
commuterIdFL _ (x :> NilFL) = return (NilFL :> x)
commuterIdFL commuter (x :> (y :>: ys))
= do y' :> x' <- commuter (x :> y)
ys' :> x'' <- commuterIdFL commuter (x' :> ys)
return ((y' :>: ys') :> x'')
mergerIdFL :: MergeFn p1 p2 -> MergeFn p1 (FL p2)
mergerIdFL _ (x :\/: NilFL) = NilFL :/\: x
mergerIdFL merger (x :\/: (y :>: ys))
= case merger (x :\/: y) of
y' :/\: x' -> case mergerIdFL merger (x' :\/: ys) of
ys' :/\: x'' -> (y' :>: ys') :/\: x''
totalCommuterIdFL :: TotalCommuteFn p1 p2 -> TotalCommuteFn p1 (FL p2)
totalCommuterIdFL _ (x :> NilFL) = NilFL :> x
totalCommuterIdFL commuter (x :> (y :>: ys)) =
case commuter (x :> y) of
y' :> x' -> case totalCommuterIdFL commuter (x' :> ys) of
ys' :> x'' -> (y' :>: ys') :> x''
commuterFLId :: CommuteFn p1 p2 -> CommuteFn (FL p1) p2
commuterFLId _ (NilFL :> y) = return (y :> NilFL)
commuterFLId commuter ((x :>: xs) :> y)
= do y' :> xs' <- commuterFLId commuter (xs :> y)
y'' :> x' <- commuter (x :> y')
return (y'' :> (x' :>: xs'))
commuterRLId :: CommuteFn p1 p2 -> CommuteFn (RL p1) p2
commuterRLId _ (NilRL :> y) = return (y :> NilRL)
commuterRLId commuter ((xs :<: x) :> y)
= do y' :> x' <- commuter (x :> y)
y'' :> xs' <- commuterRLId commuter (xs :> y')
return (y'' :> (xs' :<: x'))
totalCommuterFLId :: TotalCommuteFn p1 p2 -> TotalCommuteFn (FL p1) p2
totalCommuterFLId _ (NilFL :> y) = y :> NilFL
totalCommuterFLId commuter ((x :>: xs) :> y) =
case totalCommuterFLId commuter (xs :> y) of
y' :> xs' -> case commuter (x :> y') of
y'' :> x' -> y'' :> (x' :>: xs')
totalCommuterFLFL :: TotalCommuteFn p1 p2 -> TotalCommuteFn (FL p1) (FL p2)
totalCommuterFLFL commuter = totalCommuterFLId (totalCommuterIdFL commuter)