module Dynforkmerge(DynMsg(..), DynSPMsg(..), dynforkmerge) where
import SP
import Utils(part)

data DynMsg a b = DynCreate b |
                  DynDestroy |
                  DynMsg a 
                  deriving (DynMsg a b -> DynMsg a b -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall a b. (Eq b, Eq a) => DynMsg a b -> DynMsg a b -> Bool
/= :: DynMsg a b -> DynMsg a b -> Bool
$c/= :: forall a b. (Eq b, Eq a) => DynMsg a b -> DynMsg a b -> Bool
== :: DynMsg a b -> DynMsg a b -> Bool
$c== :: forall a b. (Eq b, Eq a) => DynMsg a b -> DynMsg a b -> Bool
Eq, DynMsg a b -> DynMsg a b -> Bool
DynMsg a b -> DynMsg a b -> Ordering
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a} {b}. (Ord b, Ord a) => Eq (DynMsg a b)
forall a b. (Ord b, Ord a) => DynMsg a b -> DynMsg a b -> Bool
forall a b. (Ord b, Ord a) => DynMsg a b -> DynMsg a b -> Ordering
forall a b.
(Ord b, Ord a) =>
DynMsg a b -> DynMsg a b -> DynMsg a b
min :: DynMsg a b -> DynMsg a b -> DynMsg a b
$cmin :: forall a b.
(Ord b, Ord a) =>
DynMsg a b -> DynMsg a b -> DynMsg a b
max :: DynMsg a b -> DynMsg a b -> DynMsg a b
$cmax :: forall a b.
(Ord b, Ord a) =>
DynMsg a b -> DynMsg a b -> DynMsg a b
>= :: DynMsg a b -> DynMsg a b -> Bool
$c>= :: forall a b. (Ord b, Ord a) => DynMsg a b -> DynMsg a b -> Bool
> :: DynMsg a b -> DynMsg a b -> Bool
$c> :: forall a b. (Ord b, Ord a) => DynMsg a b -> DynMsg a b -> Bool
<= :: DynMsg a b -> DynMsg a b -> Bool
$c<= :: forall a b. (Ord b, Ord a) => DynMsg a b -> DynMsg a b -> Bool
< :: DynMsg a b -> DynMsg a b -> Bool
$c< :: forall a b. (Ord b, Ord a) => DynMsg a b -> DynMsg a b -> Bool
compare :: DynMsg a b -> DynMsg a b -> Ordering
$ccompare :: forall a b. (Ord b, Ord a) => DynMsg a b -> DynMsg a b -> Ordering
Ord)

type DynSPMsg a b = DynMsg a (SP a b)

dynforkmerge :: Eq a => SP (a, DynSPMsg b c) (a, c)
dynforkmerge :: forall a b c. Eq a => SP (a, DynSPMsg b c) (a, c)
dynforkmerge = forall {b} {a} {b}.
Eq b =>
[(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfm []

dfm :: [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfm [(b, a -> SP a b)]
dynxsps =
    forall a b. (a -> SP a b) -> SP a b
GetSP (\(b, DynMsg a (SP a b))
msg ->
           case (b, DynMsg a (SP a b))
msg of
             (b
t, DynCreate SP a b
dynsp) -> b
-> SP a b -> [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfmout b
t SP a b
dynsp [(b, a -> SP a b)]
dynxsps
             (b
t, DynMsg a
msg') -> b -> a -> [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfmin b
t a
msg' [(b, a -> SP a b)]
dynxsps
             (b
t, DynMsg a (SP a b)
DynDestroy) -> b -> [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfmrm b
t [(b, a -> SP a b)]
dynxsps)

dfmout :: b
-> SP a b -> [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfmout b
t SP a b
dynsp [(b, a -> SP a b)]
dynxsps =
    case SP a b
dynsp of
      PutSP b
y SP a b
sp' -> forall a b. b -> SP a b -> SP a b
PutSP (b
t, b
y) (b
-> SP a b -> [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfmout b
t SP a b
sp' [(b, a -> SP a b)]
dynxsps)
      GetSP a -> SP a b
xsp -> [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfm ((b
t, a -> SP a b
xsp) forall a. a -> [a] -> [a]
: [(b, a -> SP a b)]
dynxsps)
      SP a b
NullSP -> [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfm [(b, a -> SP a b)]
dynxsps

dfmin :: b -> a -> [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfmin b
t a
msg [(b, a -> SP a b)]
dynxsps =
    case forall {a}. (a -> Bool) -> [a] -> ([a], [a])
part ((forall a. Eq a => a -> a -> Bool
== b
t) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(b, a -> SP a b)]
dynxsps of
      ([], [(b, a -> SP a b)]
_) -> [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfm [(b, a -> SP a b)]
dynxsps
      ([(b
_, a -> SP a b
xsp)], [(b, a -> SP a b)]
dynxsps') -> b
-> SP a b -> [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfmout b
t (a -> SP a b
xsp a
msg) [(b, a -> SP a b)]
dynxsps'
      ([(b, a -> SP a b)], [(b, a -> SP a b)])
_ -> forall a. HasCallStack => [Char] -> a
error [Char]
"Same tag used twice in dynforkmerge (or dynListF)."

dfmrm :: b -> [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfmrm b
t [(b, a -> SP a b)]
dynxsps = [(b, a -> SP a b)] -> SP (b, DynMsg a (SP a b)) (b, b)
dfm (forall a. (a -> Bool) -> [a] -> [a]
filter ((b
t forall a. Eq a => a -> a -> Bool
/=) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(b, a -> SP a b)]
dynxsps)