----------------------------------------------------------------------
-- |
-- Module      :  ForSyDe.Atom.MoC.SDF.BDF
-- Copyright   :  (c) George Ungureanu, KTH/EECS/ESY 2018-2020
-- License     :  BSD-style (see the file LICENSE)
-- 
-- Maintainer  :  ugeorge@kth.se
-- Stability   :  experimental
-- Portability :  portable
--
-- The @BDF@ library implements a DSL of atoms operating according to the Boolean,
-- respectively the integer dataflow model of computation, in terms of the atoms of
-- "ForSyDe.Atom.MoC.SDF". As such SADF patterns are operating on
-- 'ForSyDe.Atom.MoC.SDF.SDF' signals, i.e. they have the exact same time semantics,
-- hence there is no need for MoC interfaces between these two MoCs.
--
-- BDF/IDF are early attempts to increase SDF's expresivity by allowing the dynamic
-- redirecting of the data flow based on Boolean, respectively integer
-- conditions. These MoCs introduce two new types of processes:
--
-- * /switch/ is a process which takes one control signal (of a Boolean, respectively
--   integer type) and one data signal, and redirects it to /one of the outputs/ based
--   on the control token.
--
-- * /select/ is a process which takes one control signal (of Boolean, respectively
--   integer type), a number of input channels associated with every control
--   message. Each firing, a /select/ process consumes tokens from one of the
--   inputs based on the control token, and redirects them to the output.
--
-- While BDF/IDF languages have been shown to be Turing complete, their expressiveness
-- comes at the cost of analyzability: many of the static analyses for liveness and
-- boundness cannot be applied any longer for data-dependent dataflow. However, for
-- certain well-behaved compositions (e.g. fork-join patterns), there are methods to
-- derive equivalent SDF schedules. For more information of BDF/IDF please consult
-- <ForSyDe-Atom.html#buck93 [Buck93]>.
--
-- To implement this library we reused everything: the BDF/IDF actors are implemented
-- as specific "ForSyDe.Atom.MoC.SDF.SADF" patterns. We did not re-export anything
-- from "ForSyDe.Atom.MoC.SDF" as it is supposed to be working alongside it anyway.
--
-- Useful pointers:
--
-- * "ForSyDe.Atom" contains general guidelines for using the API
--
-- * "ForSyDe.Atom.MoC.SDF" defines the synchronous dataflow MoC.
--
-- * "ForSyDe.Atom.MoC.SDF.SADF" defines the scenario-aware dataflow MoC.
----------------------------------------------------------------------

module ForSyDe.Atom.MoC.SDF.BDF (

  -- * BDF Actors

  bSwitch, bSelect,

  -- * IDF Actors

  -- | Note that channels are indexed from 1 to /n/.
  iSwitch2, iSwitch3, iSwitch4,
  iSelect2, iSelect3, iSelect4
  ) where

import ForSyDe.Atom.MoC.SDF.SADF
import ForSyDe.Atom.MoC.SDF.Core

-- ---------------------------
-- -- BDF Actors 
-- ---------------------------

-- | Switch process with a Boolean control signal.
--
-- >>> let s1 = signal [1..10]
-- >>> let sb = signal [True,False,True,True,False]
-- >>> bSwitch 2 sb s1
-- ({3,4,9,10},{1,2,5,6,7,8})
--
-- <<fig/moc-ddf-bdf-switch.png>>
bSwitch :: Prod -> Signal Bool -> Signal a -> (Signal a, Signal a)
bSwitch :: Prod -> Signal Bool -> Signal a -> (Signal a, Signal a)
bSwitch p :: Prod
p sb :: Signal Bool
sb = Signal (Prod, (Prod, Prod), [a] -> ([a], [a]))
-> Signal a -> (Signal a, Signal a)
forall a1 b1 b2.
Signal (Prod, (Prod, Prod), [a1] -> ([b1], [b2]))
-> Signal a1 -> (Signal b1, Signal b2)
kernel12 Signal (Prod, (Prod, Prod), [a] -> ([a], [a]))
forall a. Signal (Prod, (Prod, Prod), [a] -> ([a], [a]))
cSw
  where cSw :: Signal (Prod, (Prod, Prod), [a] -> ([a], [a]))
cSw = Prod
-> (Bool -> [Bool] -> Bool)
-> (Bool -> (Prod, [(Prod, (Prod, Prod), [a] -> ([a], [a]))]))
-> Bool
-> Signal Bool
-> Signal (Prod, (Prod, Prod), [a] -> ([a], [a]))
forall s a1 y.
Prod
-> (s -> [a1] -> s)
-> (s -> (Prod, [y]))
-> s
-> Signal a1
-> Signal y
detector11 1 (\_ [s :: Bool
s] -> Bool
s) Bool -> (Prod, [(Prod, (Prod, Prod), [a] -> ([a], [a]))])
forall a a.
Num a =>
Bool -> (a, [(Prod, (Prod, Prod), [a] -> ([a], [a]))])
chSel Bool
False Signal Bool
sb
        chSel :: Bool -> (a, [(Prod, (Prod, Prod), [a] -> ([a], [a]))])
chSel False = (1, [(Prod
p, (Prod
p,0), \d :: [a]
d -> ([a]
d,[]))])
        chSel True  = (1, [(Prod
p, (0,Prod
p), \d :: [a]
d -> ([],[a]
d))])

-- | Select process with a Boolean control signal.
--
-- >>> let s1 = signal [1..10]
-- >>> let s2 = signal [11..20]
-- >>> let sb = signal [True,False,True,True,False]
-- >>> bSelect (3,2) sb s1 s2
-- {11,12,1,2,3,13,14,15,16,4,5,6}
--
-- <<fig/moc-ddf-bdf-select.png>>
bSelect :: (Cons,Cons) -> Signal Bool -> Signal a -> Signal a -> Signal a
bSelect :: (Prod, Prod) -> Signal Bool -> Signal a -> Signal a -> Signal a
bSelect (c1 :: Prod
c1,c2 :: Prod
c2) sb :: Signal Bool
sb = Signal ((Prod, Prod), Prod, [a] -> [a] -> [a])
-> Signal a -> Signal a -> Signal a
forall a1 a2 b1.
Signal ((Prod, Prod), Prod, [a1] -> [a2] -> [b1])
-> Signal a1 -> Signal a2 -> Signal b1
kernel21 Signal ((Prod, Prod), Prod, [a] -> [a] -> [a])
forall p. Signal ((Prod, Prod), Prod, p -> p -> p)
cSel 
  where cSel :: Signal ((Prod, Prod), Prod, p -> p -> p)
cSel = Prod
-> (Bool -> [Bool] -> Bool)
-> (Bool -> (Prod, [((Prod, Prod), Prod, p -> p -> p)]))
-> Bool
-> Signal Bool
-> Signal ((Prod, Prod), Prod, p -> p -> p)
forall s a1 y.
Prod
-> (s -> [a1] -> s)
-> (s -> (Prod, [y]))
-> s
-> Signal a1
-> Signal y
detector11 1 (\_ [s :: Bool
s] -> Bool
s) Bool -> (Prod, [((Prod, Prod), Prod, p -> p -> p)])
forall a p.
Num a =>
Bool -> (a, [((Prod, Prod), Prod, p -> p -> p)])
chSel Bool
False Signal Bool
sb
        chSel :: Bool -> (a, [((Prod, Prod), Prod, p -> p -> p)])
chSel False = (1, [((Prod
c1,0), Prod
c1, \d :: p
d _ -> p
d)])
        chSel True  = (1, [((0,Prod
c2), Prod
c2, \_ d :: p
d -> p
d)])

-- ---------------------------
-- -- IDF Actors 
-- ---------------------------

iSwitch2 :: Prod -> Signal Int -> Signal a -> (Signal a, Signal a)
iSwitch3 :: Prod -> Signal Int -> Signal a -> (Signal a, Signal a, Signal a)
iSwitch4 :: Prod -> Signal Int -> Signal a -> (Signal a, Signal a, Signal a, Signal a)
iSwitch2 :: Prod -> Signal Prod -> Signal a -> (Signal a, Signal a)
iSwitch2 p :: Prod
p sb :: Signal Prod
sb = Signal (Prod, (Prod, Prod), [a] -> ([a], [a]))
-> Signal a -> (Signal a, Signal a)
forall a1 b1 b2.
Signal (Prod, (Prod, Prod), [a1] -> ([b1], [b2]))
-> Signal a1 -> (Signal b1, Signal b2)
kernel12 Signal (Prod, (Prod, Prod), [a] -> ([a], [a]))
forall a. Signal (Prod, (Prod, Prod), [a] -> ([a], [a]))
cSw
  where cSw :: Signal (Prod, (Prod, Prod), [a] -> ([a], [a]))
cSw = Prod
-> (Prod -> [Prod] -> Prod)
-> (Prod -> (Prod, [(Prod, (Prod, Prod), [a] -> ([a], [a]))]))
-> Prod
-> Signal Prod
-> Signal (Prod, (Prod, Prod), [a] -> ([a], [a]))
forall s a1 y.
Prod
-> (s -> [a1] -> s)
-> (s -> (Prod, [y]))
-> s
-> Signal a1
-> Signal y
detector11 1 (\_ [s :: Prod
s] -> Prod
s) Prod -> (Prod, [(Prod, (Prod, Prod), [a] -> ([a], [a]))])
forall a a a.
(Eq a, Num a, Num a, Show a) =>
a -> (a, [(Prod, (Prod, Prod), [a] -> ([a], [a]))])
chSel 0 Signal Prod
sb
        chSel :: a -> (a, [(Prod, (Prod, Prod), [a] -> ([a], [a]))])
chSel 1 = (1, [(Prod
p, (Prod
p,0), \d :: [a]
d -> ([a]
d,[]))])
        chSel 2 = (1, [(Prod
p, (0,Prod
p), \d :: [a]
d -> ([],[a]
d))])
        chSel n :: a
n = [Char] -> (a, [(Prod, (Prod, Prod), [a] -> ([a], [a]))])
forall a. HasCallStack => [Char] -> a
error ([Char] -> (a, [(Prod, (Prod, Prod), [a] -> ([a], [a]))]))
-> [Char] -> (a, [(Prod, (Prod, Prod), [a] -> ([a], [a]))])
forall a b. (a -> b) -> a -> b
$ "iSwitch2: received control token " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ "!"
iSwitch3 :: Prod -> Signal Prod -> Signal a -> (Signal a, Signal a, Signal a)
iSwitch3 p :: Prod
p sb :: Signal Prod
sb = Signal (Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))
-> Signal a -> (Signal a, Signal a, Signal a)
forall a1 b1 b2 b3.
Signal (Prod, (Prod, Prod, Prod), [a1] -> ([b1], [b2], [b3]))
-> Signal a1 -> (Signal b1, Signal b2, Signal b3)
kernel13 Signal (Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))
forall a. Signal (Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))
cSw
  where cSw :: Signal (Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))
cSw = Prod
-> (Prod -> [Prod] -> Prod)
-> (Prod
    -> (Prod, [(Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))]))
-> Prod
-> Signal Prod
-> Signal (Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))
forall s a1 y.
Prod
-> (s -> [a1] -> s)
-> (s -> (Prod, [y]))
-> s
-> Signal a1
-> Signal y
detector11 1 (\_ [s :: Prod
s] -> Prod
s) Prod
-> (Prod, [(Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))])
forall a a a.
(Eq a, Num a, Num a, Show a) =>
a -> (a, [(Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))])
chSel 0 Signal Prod
sb
        chSel :: a -> (a, [(Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))])
chSel 1 = (1, [(Prod
p, (Prod
p,0,0), \d :: [a]
d -> ([a]
d,[],[]))])
        chSel 2 = (1, [(Prod
p, (0,Prod
p,0), \d :: [a]
d -> ([],[a]
d,[]))])
        chSel 3 = (1, [(Prod
p, (0,0,Prod
p), \d :: [a]
d -> ([],[],[a]
d))])
        chSel n :: a
n = [Char] -> (a, [(Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))])
forall a. HasCallStack => [Char] -> a
error ([Char]
 -> (a, [(Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))]))
-> [Char]
-> (a, [(Prod, (Prod, Prod, Prod), [a] -> ([a], [a], [a]))])
forall a b. (a -> b) -> a -> b
$ "iSwitch3: received control token " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ "!"
iSwitch4 :: Prod
-> Signal Prod
-> Signal a
-> (Signal a, Signal a, Signal a, Signal a)
iSwitch4 p :: Prod
p sb :: Signal Prod
sb = Signal
  (Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))
-> Signal a -> (Signal a, Signal a, Signal a, Signal a)
forall a1 b1 c d e.
Signal
  (Prod, (Prod, Prod, Prod, Prod), [a1] -> ([b1], [c], [d], [e]))
-> Signal a1 -> (Signal b1, Signal c, Signal d, Signal e)
kernel14 Signal
  (Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))
forall a.
Signal
  (Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))
cSw
  where cSw :: Signal
  (Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))
cSw = Prod
-> (Prod -> [Prod] -> Prod)
-> (Prod
    -> (Prod,
        [(Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))]))
-> Prod
-> Signal Prod
-> Signal
     (Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))
forall s a1 y.
Prod
-> (s -> [a1] -> s)
-> (s -> (Prod, [y]))
-> s
-> Signal a1
-> Signal y
detector11 1 (\_ [s :: Prod
s] -> Prod
s) Prod
-> (Prod,
    [(Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))])
forall a a a.
(Eq a, Num a, Num a, Show a) =>
a
-> (a,
    [(Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))])
chSel 0 Signal Prod
sb
        chSel :: a
-> (a,
    [(Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))])
chSel 1 = (1, [(Prod
p, (Prod
p,0,0,0), \d :: [a]
d -> ([a]
d,[],[],[]))])
        chSel 2 = (1, [(Prod
p, (0,Prod
p,0,0), \d :: [a]
d -> ([],[a]
d,[],[]))])
        chSel 3 = (1, [(Prod
p, (0,0,Prod
p,0), \d :: [a]
d -> ([],[],[a]
d,[]))])
        chSel 4 = (1, [(Prod
p, (0,0,0,Prod
p), \d :: [a]
d -> ([],[],[],[a]
d))])
        chSel n :: a
n = [Char]
-> (a,
    [(Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))])
forall a. HasCallStack => [Char] -> a
error ([Char]
 -> (a,
     [(Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))]))
-> [Char]
-> (a,
    [(Prod, (Prod, Prod, Prod, Prod), [a] -> ([a], [a], [a], [a]))])
forall a b. (a -> b) -> a -> b
$ "iSwitch4: received control token " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ "!"

iSelect2 :: (Cons,Cons) -> Signal Int
         -> Signal a -> Signal a -> Signal a
iSelect3 :: (Cons,Cons,Cons) -> Signal Int
         -> Signal a -> Signal a -> Signal a -> Signal a
iSelect4 :: (Cons,Cons,Cons,Cons) -> Signal Int
         -> Signal a -> Signal a -> Signal a -> Signal a -> Signal a
iSelect2 :: (Prod, Prod) -> Signal Prod -> Signal a -> Signal a -> Signal a
iSelect2 (c1 :: Prod
c1,c2 :: Prod
c2) sb :: Signal Prod
sb = Signal ((Prod, Prod), Prod, [a] -> [a] -> [a])
-> Signal a -> Signal a -> Signal a
forall a1 a2 b1.
Signal ((Prod, Prod), Prod, [a1] -> [a2] -> [b1])
-> Signal a1 -> Signal a2 -> Signal b1
kernel21 Signal ((Prod, Prod), Prod, [a] -> [a] -> [a])
forall p. Signal ((Prod, Prod), Prod, p -> p -> p)
cSel 
  where cSel :: Signal ((Prod, Prod), Prod, p -> p -> p)
cSel = Prod
-> (Prod -> [Prod] -> Prod)
-> (Prod -> (Prod, [((Prod, Prod), Prod, p -> p -> p)]))
-> Prod
-> Signal Prod
-> Signal ((Prod, Prod), Prod, p -> p -> p)
forall s a1 y.
Prod
-> (s -> [a1] -> s)
-> (s -> (Prod, [y]))
-> s
-> Signal a1
-> Signal y
detector11 1 (\_ [s :: Prod
s] -> Prod
s) Prod -> (Prod, [((Prod, Prod), Prod, p -> p -> p)])
forall a a p.
(Eq a, Num a, Num a, Show a) =>
a -> (a, [((Prod, Prod), Prod, p -> p -> p)])
chSel 0 Signal Prod
sb
        chSel :: a -> (a, [((Prod, Prod), Prod, p -> p -> p)])
chSel 1 = (1, [((Prod
c1,0), Prod
c1, \d :: p
d _ -> p
d)])
        chSel 2 = (1, [((0,Prod
c2), Prod
c2, \_ d :: p
d -> p
d)])
        chSel n :: a
n = [Char] -> (a, [((Prod, Prod), Prod, p -> p -> p)])
forall a. HasCallStack => [Char] -> a
error ([Char] -> (a, [((Prod, Prod), Prod, p -> p -> p)]))
-> [Char] -> (a, [((Prod, Prod), Prod, p -> p -> p)])
forall a b. (a -> b) -> a -> b
$ "iSelect2: received control token " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ "!"
iSelect3 :: (Prod, Prod, Prod)
-> Signal Prod -> Signal a -> Signal a -> Signal a -> Signal a
iSelect3 (c1 :: Prod
c1,c2 :: Prod
c2,c3 :: Prod
c3) sb :: Signal Prod
sb = Signal ((Prod, Prod, Prod), Prod, [a] -> [a] -> [a] -> [a])
-> Signal a -> Signal a -> Signal a -> Signal a
forall a1 a2 a3 b1.
Signal ((Prod, Prod, Prod), Prod, [a1] -> [a2] -> [a3] -> [b1])
-> Signal a1 -> Signal a2 -> Signal a3 -> Signal b1
kernel31 Signal ((Prod, Prod, Prod), Prod, [a] -> [a] -> [a] -> [a])
forall p. Signal ((Prod, Prod, Prod), Prod, p -> p -> p -> p)
cSel 
  where cSel :: Signal ((Prod, Prod, Prod), Prod, p -> p -> p -> p)
cSel = Prod
-> (Prod -> [Prod] -> Prod)
-> (Prod -> (Prod, [((Prod, Prod, Prod), Prod, p -> p -> p -> p)]))
-> Prod
-> Signal Prod
-> Signal ((Prod, Prod, Prod), Prod, p -> p -> p -> p)
forall s a1 y.
Prod
-> (s -> [a1] -> s)
-> (s -> (Prod, [y]))
-> s
-> Signal a1
-> Signal y
detector11 1 (\_ [s :: Prod
s] -> Prod
s) Prod -> (Prod, [((Prod, Prod, Prod), Prod, p -> p -> p -> p)])
forall a a p.
(Eq a, Num a, Num a, Show a) =>
a -> (a, [((Prod, Prod, Prod), Prod, p -> p -> p -> p)])
chSel 0 Signal Prod
sb
        chSel :: a -> (a, [((Prod, Prod, Prod), Prod, p -> p -> p -> p)])
chSel 1 = (1, [((Prod
c1,0,0), Prod
c1, \d :: p
d _ _ -> p
d)])
        chSel 2 = (1, [((0,Prod
c2,0), Prod
c2, \_ d :: p
d _ -> p
d)])
        chSel 3 = (1, [((0,0,Prod
c3), Prod
c3, \_ _ d :: p
d -> p
d)])
        chSel n :: a
n = [Char] -> (a, [((Prod, Prod, Prod), Prod, p -> p -> p -> p)])
forall a. HasCallStack => [Char] -> a
error ([Char] -> (a, [((Prod, Prod, Prod), Prod, p -> p -> p -> p)]))
-> [Char] -> (a, [((Prod, Prod, Prod), Prod, p -> p -> p -> p)])
forall a b. (a -> b) -> a -> b
$ "iSelect3: received control token " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ "!"
iSelect4 :: (Prod, Prod, Prod, Prod)
-> Signal Prod
-> Signal a
-> Signal a
-> Signal a
-> Signal a
-> Signal a
iSelect4 (c1 :: Prod
c1,c2 :: Prod
c2,c3 :: Prod
c3,c4 :: Prod
c4) sb :: Signal Prod
sb = Signal
  ((Prod, Prod, Prod, Prod), Prod, [a] -> [a] -> [a] -> [a] -> [a])
-> Signal a -> Signal a -> Signal a -> Signal a -> Signal a
forall a1 a2 a3 a4 b1.
Signal
  ((Prod, Prod, Prod, Prod), Prod,
   [a1] -> [a2] -> [a3] -> [a4] -> [b1])
-> Signal a1 -> Signal a2 -> Signal a3 -> Signal a4 -> Signal b1
kernel41 Signal
  ((Prod, Prod, Prod, Prod), Prod, [a] -> [a] -> [a] -> [a] -> [a])
forall p.
Signal ((Prod, Prod, Prod, Prod), Prod, p -> p -> p -> p -> p)
cSel 
  where cSel :: Signal ((Prod, Prod, Prod, Prod), Prod, p -> p -> p -> p -> p)
cSel = Prod
-> (Prod -> [Prod] -> Prod)
-> (Prod
    -> (Prod,
        [((Prod, Prod, Prod, Prod), Prod, p -> p -> p -> p -> p)]))
-> Prod
-> Signal Prod
-> Signal ((Prod, Prod, Prod, Prod), Prod, p -> p -> p -> p -> p)
forall s a1 y.
Prod
-> (s -> [a1] -> s)
-> (s -> (Prod, [y]))
-> s
-> Signal a1
-> Signal y
detector11 1 (\_ [s :: Prod
s] -> Prod
s) Prod
-> (Prod,
    [((Prod, Prod, Prod, Prod), Prod, p -> p -> p -> p -> p)])
forall a a p.
(Eq a, Num a, Num a, Show a) =>
a -> (a, [((Prod, Prod, Prod, Prod), Prod, p -> p -> p -> p -> p)])
chSel 0 Signal Prod
sb
        chSel :: a -> (a, [((Prod, Prod, Prod, Prod), Prod, p -> p -> p -> p -> p)])
chSel 1 = (1, [((Prod
c1,0,0,0), Prod
c1, \d :: p
d _ _ _ -> p
d)])
        chSel 2 = (1, [((0,Prod
c2,0,0), Prod
c2, \_ d :: p
d _ _ -> p
d)])
        chSel 3 = (1, [((0,0,Prod
c3,0), Prod
c3, \_ _ d :: p
d _ -> p
d)])
        chSel 4 = (1, [((0,0,0,Prod
c4), Prod
c4, \_ _ _ d :: p
d -> p
d)])
        chSel n :: a
n = [Char]
-> (a, [((Prod, Prod, Prod, Prod), Prod, p -> p -> p -> p -> p)])
forall a. HasCallStack => [Char] -> a
error ([Char]
 -> (a, [((Prod, Prod, Prod, Prod), Prod, p -> p -> p -> p -> p)]))
-> [Char]
-> (a, [((Prod, Prod, Prod, Prod), Prod, p -> p -> p -> p -> p)])
forall a b. (a -> b) -> a -> b
$ "iSelect4: received control token " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ "!"