-----------------------------------------------------------------------------
-- |
-- Module  :  ForSyDe.Shallow.MoC.SDF
-- Copyright   :  (c) Ingo Sander, KTH/ICT/ES, ForSyDe-Group
-- License     :  BSD-style (see the file LICENSE)
-- 
-- Maintainer  :  forsyde-dev@ict.kth.se
-- Stability   :  experimental
-- Portability :  portable
--
-- SDFLib.hs, yet to be completed.
-- 
-----------------------------------------------------------------------------

module ForSyDe.Shallow.MoC.SDF (
  -- -- * Combinational Process Constructors
  -- -- | Combinational process constructors are used for processes that
  -- -- do not have a state.
  -- mapSDF, zipWithSDF, zipWith3SDF, zipWith4SDF,
  -- * Sequential Process Constructors
  -- | Sequential process constructors are used for processes that
  -- have a state. One of the input parameters is the initial state.
  delaySDF,
  -- -- * Processes
  -- -- | Processes to unzip a signal of tupels into a tuple of signals
  -- unzipSDF, unzip3SDF, unzip4SDF,
  -- * Actors
  -- | Based on the process constructors in the SDF-MoC, the
  -- SDF-library provides SDF-actors with single or multiple inputs
  actor11SDF, actor12SDF, actor13SDF, actor14SDF,
  actor21SDF, actor22SDF, actor23SDF, actor24SDF,
  actor31SDF, actor32SDF, actor33SDF, actor34SDF,
  actor41SDF, actor42SDF, actor43SDF, actor44SDF
  ) where  

import ForSyDe.Shallow.Core


-------------------------------------
--             --
-- SEQUENTIAL PROCESS CONSTRUCTORS --
--             --
-------------------------------------

-- | The process constructor 'delaySDF' delays the signal one event
--   cycle by introducing a set of initial values at the beginning of
--   the output signal.  Note, that this implies that there is a
--   prefix at the output signal (the first n events) that has no
--   corresponding event at the input signal. This is necessary to
--   initialize feedback loops.
--
-- >>> delaySDF [0,0,0] $ signal [1,2,3,4]
-- {0,0,0,1,2,3,4}
delaySDF :: [a] -> Signal a -> Signal a 
delaySDF :: [a] -> Signal a -> Signal a
delaySDF [a]
initial_tokens Signal a
xs = [a] -> Signal a
forall a. [a] -> Signal a
signal [a]
initial_tokens Signal a -> Signal a -> Signal a
forall a. Signal a -> Signal a -> Signal a
+-+ Signal a
xs 

------------------------------------------------------------------------
--
-- SDF ACTORS
--
------------------------------------------------------------------------

-- > Actors with one output

-- | The process constructor 'actor11SDF' constructs an SDF actor with
-- one input and one output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
--
-- >>> let f [a,b] = [a+b,a-b,a*b]
-- >>> actor11SDF 2 3 f $ signal [1,2,3,4,5]
-- {3,-1,2,7,-1,12}
actor11SDF :: Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
actor11SDF :: Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
actor11SDF = Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
forall a b. Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
mapSDF 

-- | The process constructor 'actor21SDF' constructs an SDF actor with
-- two input and one output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
--
-- >>> let f [a,b] [c] = [a+b+c,b-c]
-- >>> let s1 = signal [1..6]
-- >>> let s2 = signal [1..]
-- >>> actor21SDF (2,1) 2 f s1 s2
-- {4,1,9,2,14,3}
actor21SDF :: (Int, Int) -> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c    
actor21SDF :: (Int, Int)
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
actor21SDF = (Int, Int)
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
forall a b c.
(Int, Int)
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithSDF

-- | The process constructor 'actor31SDF' constructs an SDF actor with
-- three input and one output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor31SDF :: (Int, Int, Int) -> Int -> ([a] -> [b] -> [c] -> [d])
       -> Signal a -> Signal b -> Signal c -> Signal d   
actor31SDF :: (Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
actor31SDF = (Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
forall a b c d.
(Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
zipWith3SDF

-- | The process constructor 'actor41SDF' constructs an SDF actor with
-- four input and one output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor41SDF :: (Int, Int, Int, Int) -> Int 
    -> ([a] -> [b] -> [c] -> [d] -> [e]) 
    -> Signal a -> Signal b -> Signal c -> Signal d -> Signal e 
actor41SDF :: (Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
actor41SDF = (Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
forall a b c d e.
(Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
zipWith4SDF


-- > Actors with two outputs

-- | The process constructor 'actor12SDF' constructs an SDF actor with
-- one input and two output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor12SDF :: Int -> (Int, Int) -> ([a] -> ([b], [c]))
           -> Signal a -> (Signal b, Signal c)
actor12SDF :: Int
-> (Int, Int)
-> ([a] -> ([b], [c]))
-> Signal a
-> (Signal b, Signal c)
actor12SDF Int
c (Int
p1,Int
p2) [a] -> ([b], [c])
f Signal a
xs = (Int, Int) -> Signal ([b], [c]) -> (Signal b, Signal c)
forall a b. (Int, Int) -> Signal ([a], [b]) -> (Signal a, Signal b)
unzipSDF (Int
p1,Int
p2) (Signal ([b], [c]) -> (Signal b, Signal c))
-> Signal ([b], [c]) -> (Signal b, Signal c)
forall a b. (a -> b) -> a -> b
$ Int
-> Int -> ([a] -> [([b], [c])]) -> Signal a -> Signal ([b], [c])
forall a b. Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
mapSDF Int
c Int
1 (([a] -> ([b], [c])) -> [a] -> [([b], [c])]
forall a y. ([a] -> y) -> [a] -> [y]
wrapF1 [a] -> ([b], [c])
f) Signal a
xs  

-- | The process constructor 'actor22SDF' constructs an SDF actor with
-- two input and two output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor22SDF :: (Int, Int) -> (Int, Int) -> ([a] -> [b] -> ([c], [d]))
           -> Signal a -> Signal b -> (Signal c, Signal d)
actor22SDF :: (Int, Int)
-> (Int, Int)
-> ([a] -> [b] -> ([c], [d]))
-> Signal a
-> Signal b
-> (Signal c, Signal d)
actor22SDF (Int
c1,Int
c2) (Int
p1,Int
p2) [a] -> [b] -> ([c], [d])
f Signal a
xs Signal b
ys = (Int, Int) -> Signal ([c], [d]) -> (Signal c, Signal d)
forall a b. (Int, Int) -> Signal ([a], [b]) -> (Signal a, Signal b)
unzipSDF (Int
p1,Int
p2) (Signal ([c], [d]) -> (Signal c, Signal d))
-> Signal ([c], [d]) -> (Signal c, Signal d)
forall a b. (a -> b) -> a -> b
$ (Int, Int)
-> Int
-> ([a] -> [b] -> [([c], [d])])
-> Signal a
-> Signal b
-> Signal ([c], [d])
forall a b c.
(Int, Int)
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithSDF (Int
c1,Int
c2) Int
1 (([a] -> [b] -> ([c], [d])) -> [a] -> [b] -> [([c], [d])]
forall a b y. ([a] -> [b] -> y) -> [a] -> [b] -> [y]
wrapF2 [a] -> [b] -> ([c], [d])
f) Signal a
xs Signal b
ys

-- | The process constructor 'actor32SDF' constructs an SDF actor with
-- three input and two output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor32SDF :: (Int, Int, Int) -> (Int, Int)
           -> ([a] -> [b] -> [c] -> ([d], [e]))
           -> Signal a -> Signal b -> Signal c -> (Signal d, Signal e)
actor32SDF :: (Int, Int, Int)
-> (Int, Int)
-> ([a] -> [b] -> [c] -> ([d], [e]))
-> Signal a
-> Signal b
-> Signal c
-> (Signal d, Signal e)
actor32SDF (Int
c1,Int
c2,Int
c3) (Int
p1,Int
p2) [a] -> [b] -> [c] -> ([d], [e])
f Signal a
as Signal b
bs Signal c
cs
  = (Int, Int) -> Signal ([d], [e]) -> (Signal d, Signal e)
forall a b. (Int, Int) -> Signal ([a], [b]) -> (Signal a, Signal b)
unzipSDF (Int
p1,Int
p2) (Signal ([d], [e]) -> (Signal d, Signal e))
-> Signal ([d], [e]) -> (Signal d, Signal e)
forall a b. (a -> b) -> a -> b
$ (Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [([d], [e])])
-> Signal a
-> Signal b
-> Signal c
-> Signal ([d], [e])
forall a b c d.
(Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
zipWith3SDF (Int
c1,Int
c2,Int
c3) Int
1 (([a] -> [b] -> [c] -> ([d], [e]))
-> [a] -> [b] -> [c] -> [([d], [e])]
forall a b c y.
([a] -> [b] -> [c] -> y) -> [a] -> [b] -> [c] -> [y]
wrapF3 [a] -> [b] -> [c] -> ([d], [e])
f) Signal a
as Signal b
bs Signal c
cs

-- | The process constructor 'actor42SDF' constructs an SDF actor with
-- four input and two output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor42SDF :: (Int, Int, Int, Int) -> (Int, Int) 
           -> ([a] -> [b] -> [c] -> [d] -> ([e], [f])) 
           -> Signal a -> Signal b -> Signal c -> Signal d 
           -> (Signal e, Signal f)
actor42SDF :: (Int, Int, Int, Int)
-> (Int, Int)
-> ([a] -> [b] -> [c] -> [d] -> ([e], [f]))
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> (Signal e, Signal f)
actor42SDF (Int
c1,Int
c2,Int
c3,Int
c4) (Int
p1,Int
p2) [a] -> [b] -> [c] -> [d] -> ([e], [f])
f Signal a
as Signal b
bs Signal c
cs Signal d
ds 
  = (Int, Int) -> Signal ([e], [f]) -> (Signal e, Signal f)
forall a b. (Int, Int) -> Signal ([a], [b]) -> (Signal a, Signal b)
unzipSDF (Int
p1,Int
p2) (Signal ([e], [f]) -> (Signal e, Signal f))
-> Signal ([e], [f]) -> (Signal e, Signal f)
forall a b. (a -> b) -> a -> b
$ (Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [([e], [f])])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal ([e], [f])
forall a b c d e.
(Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
zipWith4SDF (Int
c1,Int
c2,Int
c3,Int
c4) Int
1 (([a] -> [b] -> [c] -> [d] -> ([e], [f]))
-> [a] -> [b] -> [c] -> [d] -> [([e], [f])]
forall a b c d y.
([a] -> [b] -> [c] -> [d] -> y) -> [a] -> [b] -> [c] -> [d] -> [y]
wrapF4 [a] -> [b] -> [c] -> [d] -> ([e], [f])
f) Signal a
as Signal b
bs Signal c
cs Signal d
ds

-- > Actors with three outputs

-- | The process constructor 'actor13SDF' constructs an SDF actor with
-- one input and three output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor13SDF :: Int -> (Int, Int, Int) 
           -> ([a] -> ([b], [c], [d])) 
           -> Signal a -> (Signal b, Signal c, Signal d)
actor13SDF :: Int
-> (Int, Int, Int)
-> ([a] -> ([b], [c], [d]))
-> Signal a
-> (Signal b, Signal c, Signal d)
actor13SDF Int
c (Int
p1,Int
p2,Int
p3) [a] -> ([b], [c], [d])
f Signal a
xs = (Int, Int, Int)
-> Signal ([b], [c], [d]) -> (Signal b, Signal c, Signal d)
forall a b c.
(Int, Int, Int)
-> Signal ([a], [b], [c]) -> (Signal a, Signal b, Signal c)
unzip3SDF (Int
p1,Int
p2,Int
p3) (Signal ([b], [c], [d]) -> (Signal b, Signal c, Signal d))
-> Signal ([b], [c], [d]) -> (Signal b, Signal c, Signal d)
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> ([a] -> [([b], [c], [d])])
-> Signal a
-> Signal ([b], [c], [d])
forall a b. Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
mapSDF Int
c Int
1 (([a] -> ([b], [c], [d])) -> [a] -> [([b], [c], [d])]
forall a y. ([a] -> y) -> [a] -> [y]
wrapF1 [a] -> ([b], [c], [d])
f) Signal a
xs  

-- | The process constructor 'actor23SDF' constructs an SDF actor with
-- two input and three output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor23SDF :: (Int, Int) -> (Int, Int, Int) 
           -> ([a] -> [b] -> ([c], [d], [e])) 
           -> Signal a -> Signal b 
           -> (Signal c, Signal d, Signal e)
actor23SDF :: (Int, Int)
-> (Int, Int, Int)
-> ([a] -> [b] -> ([c], [d], [e]))
-> Signal a
-> Signal b
-> (Signal c, Signal d, Signal e)
actor23SDF (Int
c1,Int
c2) (Int
p1,Int
p2,Int
p3) [a] -> [b] -> ([c], [d], [e])
f Signal a
xs Signal b
ys
  = (Int, Int, Int)
-> Signal ([c], [d], [e]) -> (Signal c, Signal d, Signal e)
forall a b c.
(Int, Int, Int)
-> Signal ([a], [b], [c]) -> (Signal a, Signal b, Signal c)
unzip3SDF (Int
p1,Int
p2,Int
p3) (Signal ([c], [d], [e]) -> (Signal c, Signal d, Signal e))
-> Signal ([c], [d], [e]) -> (Signal c, Signal d, Signal e)
forall a b. (a -> b) -> a -> b
$ (Int, Int)
-> Int
-> ([a] -> [b] -> [([c], [d], [e])])
-> Signal a
-> Signal b
-> Signal ([c], [d], [e])
forall a b c.
(Int, Int)
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithSDF (Int
c1,Int
c2) Int
1 (([a] -> [b] -> ([c], [d], [e])) -> [a] -> [b] -> [([c], [d], [e])]
forall a b y. ([a] -> [b] -> y) -> [a] -> [b] -> [y]
wrapF2 [a] -> [b] -> ([c], [d], [e])
f) Signal a
xs Signal b
ys

-- | The process constructor 'actor33SDF' constructs an SDF actor with
-- three input and three output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor33SDF :: (Int, Int, Int) -> (Int, Int, Int) 
           -> ([a] -> [b] -> [c] -> ([d], [e], [f])) 
           -> Signal a -> Signal b -> Signal c -> (Signal d, Signal e, Signal f)
actor33SDF :: (Int, Int, Int)
-> (Int, Int, Int)
-> ([a] -> [b] -> [c] -> ([d], [e], [f]))
-> Signal a
-> Signal b
-> Signal c
-> (Signal d, Signal e, Signal f)
actor33SDF (Int
c1,Int
c2,Int
c3) (Int
p1,Int
p2,Int
p3) [a] -> [b] -> [c] -> ([d], [e], [f])
f Signal a
as Signal b
bs Signal c
cs
  = (Int, Int, Int)
-> Signal ([d], [e], [f]) -> (Signal d, Signal e, Signal f)
forall a b c.
(Int, Int, Int)
-> Signal ([a], [b], [c]) -> (Signal a, Signal b, Signal c)
unzip3SDF (Int
p1,Int
p2,Int
p3) (Signal ([d], [e], [f]) -> (Signal d, Signal e, Signal f))
-> Signal ([d], [e], [f]) -> (Signal d, Signal e, Signal f)
forall a b. (a -> b) -> a -> b
$ (Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [([d], [e], [f])])
-> Signal a
-> Signal b
-> Signal c
-> Signal ([d], [e], [f])
forall a b c d.
(Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
zipWith3SDF (Int
c1,Int
c2,Int
c3) Int
1 (([a] -> [b] -> [c] -> ([d], [e], [f]))
-> [a] -> [b] -> [c] -> [([d], [e], [f])]
forall a b c y.
([a] -> [b] -> [c] -> y) -> [a] -> [b] -> [c] -> [y]
wrapF3 [a] -> [b] -> [c] -> ([d], [e], [f])
f) Signal a
as Signal b
bs Signal c
cs

-- | The process constructor 'actor43SDF' constructs an SDF actor with
-- four input and three output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor43SDF :: (Int, Int, Int, Int) -> (Int, Int, Int) 
           -> ([a] -> [b] -> [c] -> [d] -> ([e], [f], [g])) 
           -> Signal a -> Signal b -> Signal c -> Signal d 
           -> (Signal e, Signal f, Signal g)
actor43SDF :: (Int, Int, Int, Int)
-> (Int, Int, Int)
-> ([a] -> [b] -> [c] -> [d] -> ([e], [f], [g]))
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> (Signal e, Signal f, Signal g)
actor43SDF (Int
c1,Int
c2,Int
c3,Int
c4) (Int
p1,Int
p2,Int
p3) [a] -> [b] -> [c] -> [d] -> ([e], [f], [g])
f Signal a
as Signal b
bs Signal c
cs Signal d
ds 
  = (Int, Int, Int)
-> Signal ([e], [f], [g]) -> (Signal e, Signal f, Signal g)
forall a b c.
(Int, Int, Int)
-> Signal ([a], [b], [c]) -> (Signal a, Signal b, Signal c)
unzip3SDF (Int
p1,Int
p2,Int
p3)(Signal ([e], [f], [g]) -> (Signal e, Signal f, Signal g))
-> Signal ([e], [f], [g]) -> (Signal e, Signal f, Signal g)
forall a b. (a -> b) -> a -> b
$ (Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [([e], [f], [g])])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal ([e], [f], [g])
forall a b c d e.
(Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
zipWith4SDF (Int
c1,Int
c2,Int
c3,Int
c4) Int
1 (([a] -> [b] -> [c] -> [d] -> ([e], [f], [g]))
-> [a] -> [b] -> [c] -> [d] -> [([e], [f], [g])]
forall a b c d y.
([a] -> [b] -> [c] -> [d] -> y) -> [a] -> [b] -> [c] -> [d] -> [y]
wrapF4 [a] -> [b] -> [c] -> [d] -> ([e], [f], [g])
f) Signal a
as Signal b
bs Signal c
cs Signal d
ds

-- > Actors with four outputs

-- | The process constructor 'actor14SDF' constructs an SDF actor with
-- one input and four output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor14SDF :: Int -> (Int, Int, Int, Int) 
           -> ([a] -> ([b], [c], [d], [e])) 
           -> Signal a -> (Signal b, Signal c, Signal d, Signal e)
actor14SDF :: Int
-> (Int, Int, Int, Int)
-> ([a] -> ([b], [c], [d], [e]))
-> Signal a
-> (Signal b, Signal c, Signal d, Signal e)
actor14SDF Int
c (Int
p1,Int
p2,Int
p3,Int
p4) [a] -> ([b], [c], [d], [e])
f Signal a
xs = (Int, Int, Int, Int)
-> Signal ([b], [c], [d], [e])
-> (Signal b, Signal c, Signal d, Signal e)
forall a b c d.
(Int, Int, Int, Int)
-> Signal ([a], [b], [c], [d])
-> (Signal a, Signal b, Signal c, Signal d)
unzip4SDF (Int
p1,Int
p2,Int
p3,Int
p4) (Signal ([b], [c], [d], [e])
 -> (Signal b, Signal c, Signal d, Signal e))
-> Signal ([b], [c], [d], [e])
-> (Signal b, Signal c, Signal d, Signal e)
forall a b. (a -> b) -> a -> b
$ Int
-> Int
-> ([a] -> [([b], [c], [d], [e])])
-> Signal a
-> Signal ([b], [c], [d], [e])
forall a b. Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
mapSDF Int
c Int
1 (([a] -> ([b], [c], [d], [e])) -> [a] -> [([b], [c], [d], [e])]
forall a y. ([a] -> y) -> [a] -> [y]
wrapF1 [a] -> ([b], [c], [d], [e])
f) Signal a
xs  

-- | The process constructor 'actor24SDF' constructs an SDF actor with
-- two input and four output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor24SDF :: (Int, Int) -> (Int, Int, Int, Int) 
       -> ([a] -> [b] -> ([c], [d], [e], [f])) 
       -> Signal a -> Signal b 
       -> (Signal c, Signal d, Signal e, Signal f)
actor24SDF :: (Int, Int)
-> (Int, Int, Int, Int)
-> ([a] -> [b] -> ([c], [d], [e], [f]))
-> Signal a
-> Signal b
-> (Signal c, Signal d, Signal e, Signal f)
actor24SDF (Int
c1,Int
c2) (Int
p1,Int
p2,Int
p3,Int
p4) [a] -> [b] -> ([c], [d], [e], [f])
f Signal a
xs Signal b
ys
  = (Int, Int, Int, Int)
-> Signal ([c], [d], [e], [f])
-> (Signal c, Signal d, Signal e, Signal f)
forall a b c d.
(Int, Int, Int, Int)
-> Signal ([a], [b], [c], [d])
-> (Signal a, Signal b, Signal c, Signal d)
unzip4SDF (Int
p1,Int
p2,Int
p3,Int
p4) (Signal ([c], [d], [e], [f])
 -> (Signal c, Signal d, Signal e, Signal f))
-> Signal ([c], [d], [e], [f])
-> (Signal c, Signal d, Signal e, Signal f)
forall a b. (a -> b) -> a -> b
$ (Int, Int)
-> Int
-> ([a] -> [b] -> [([c], [d], [e], [f])])
-> Signal a
-> Signal b
-> Signal ([c], [d], [e], [f])
forall a b c.
(Int, Int)
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithSDF (Int
c1,Int
c2) Int
1 (([a] -> [b] -> ([c], [d], [e], [f]))
-> [a] -> [b] -> [([c], [d], [e], [f])]
forall a b y. ([a] -> [b] -> y) -> [a] -> [b] -> [y]
wrapF2 [a] -> [b] -> ([c], [d], [e], [f])
f) Signal a
xs Signal b
ys

-- | The process constructor 'actor34SDF' constructs an SDF actor with
-- three input and four output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor34SDF :: (Int, Int, Int) -> (Int, Int, Int, Int) 
           -> ([a] -> [b] -> [c] -> ([d], [e], [f], [g])) 
           -> Signal a -> Signal b -> Signal c
           -> (Signal d, Signal e, Signal f, Signal g)
actor34SDF :: (Int, Int, Int)
-> (Int, Int, Int, Int)
-> ([a] -> [b] -> [c] -> ([d], [e], [f], [g]))
-> Signal a
-> Signal b
-> Signal c
-> (Signal d, Signal e, Signal f, Signal g)
actor34SDF (Int
c1,Int
c2,Int
c3) (Int
p1,Int
p2,Int
p3,Int
p4) [a] -> [b] -> [c] -> ([d], [e], [f], [g])
f Signal a
as Signal b
bs Signal c
cs 
  = (Int, Int, Int, Int)
-> Signal ([d], [e], [f], [g])
-> (Signal d, Signal e, Signal f, Signal g)
forall a b c d.
(Int, Int, Int, Int)
-> Signal ([a], [b], [c], [d])
-> (Signal a, Signal b, Signal c, Signal d)
unzip4SDF (Int
p1,Int
p2,Int
p3,Int
p4) (Signal ([d], [e], [f], [g])
 -> (Signal d, Signal e, Signal f, Signal g))
-> Signal ([d], [e], [f], [g])
-> (Signal d, Signal e, Signal f, Signal g)
forall a b. (a -> b) -> a -> b
$ (Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [([d], [e], [f], [g])])
-> Signal a
-> Signal b
-> Signal c
-> Signal ([d], [e], [f], [g])
forall a b c d.
(Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
zipWith3SDF (Int
c1,Int
c2,Int
c3) Int
1 (([a] -> [b] -> [c] -> ([d], [e], [f], [g]))
-> [a] -> [b] -> [c] -> [([d], [e], [f], [g])]
forall a b c y.
([a] -> [b] -> [c] -> y) -> [a] -> [b] -> [c] -> [y]
wrapF3 [a] -> [b] -> [c] -> ([d], [e], [f], [g])
f) Signal a
as Signal b
bs Signal c
cs

-- | The process constructor 'actor14SDF' constructs an SDF actor with
-- four input and four output signals. For each input or output signal,
-- the process constructor takes the number of consumed and produced
-- tokens and the function of the actor as arguments.
actor44SDF :: (Int, Int, Int, Int) -> (Int, Int, Int, Int) 
           -> ([a] -> [b] -> [c] -> [d] -> ([e], [f], [g], [h])) 
           -> Signal a -> Signal b -> Signal c -> Signal d 
           -> (Signal e, Signal f, Signal g, Signal h)
actor44SDF :: (Int, Int, Int, Int)
-> (Int, Int, Int, Int)
-> ([a] -> [b] -> [c] -> [d] -> ([e], [f], [g], [h]))
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> (Signal e, Signal f, Signal g, Signal h)
actor44SDF (Int
c1,Int
c2,Int
c3,Int
c4) (Int
p1,Int
p2,Int
p3,Int
p4) [a] -> [b] -> [c] -> [d] -> ([e], [f], [g], [h])
f Signal a
as Signal b
bs Signal c
cs Signal d
ds 
  = (Int, Int, Int, Int)
-> Signal ([e], [f], [g], [h])
-> (Signal e, Signal f, Signal g, Signal h)
forall a b c d.
(Int, Int, Int, Int)
-> Signal ([a], [b], [c], [d])
-> (Signal a, Signal b, Signal c, Signal d)
unzip4SDF (Int
p1,Int
p2,Int
p3,Int
p4) (Signal ([e], [f], [g], [h])
 -> (Signal e, Signal f, Signal g, Signal h))
-> Signal ([e], [f], [g], [h])
-> (Signal e, Signal f, Signal g, Signal h)
forall a b. (a -> b) -> a -> b
$ (Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [([e], [f], [g], [h])])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal ([e], [f], [g], [h])
forall a b c d e.
(Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
zipWith4SDF (Int
c1,Int
c2,Int
c3,Int
c4) Int
1 (([a] -> [b] -> [c] -> [d] -> ([e], [f], [g], [h]))
-> [a] -> [b] -> [c] -> [d] -> [([e], [f], [g], [h])]
forall a b c d y.
([a] -> [b] -> [c] -> [d] -> y) -> [a] -> [b] -> [c] -> [d] -> [y]
wrapF4 [a] -> [b] -> [c] -> [d] -> ([e], [f], [g], [h])
f) Signal a
as Signal b
bs Signal c
cs Signal d
ds

---------------------------------------------------------------------
-- COMBINATIONAL PROCESS CONSTRUCTORS
---------------------------------------------------------------------

-- | The process constructor 'mapSDF' takes the number of consumed
-- (@c@) and produced (@p@) tokens and a function @f@ that operates on
-- a list, and results in an SDF-process that takes an input signal
-- and results in an output signal
mapSDF :: Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
mapSDF :: Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
mapSDF Int
_ Int
_ [a] -> [b]
_ Signal a
NullS   = Signal b
forall a. Signal a
NullS
mapSDF Int
c Int
p [a] -> [b]
f Signal a
xs     
  | Int
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = [Char] -> Signal b
forall a. HasCallStack => [Char] -> a
error [Char]
"mapSDF: Number of consumed tokens must be positive integer" 
  | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> Signal a -> Bool
forall a t. (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens Int
c Signal a
xs  = Signal b
forall a. Signal a
NullS
  | Bool
otherwise  = if [b] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [b]
produced_tokens Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p then
                   [b] -> Signal b
forall a. [a] -> Signal a
signal [b]
produced_tokens Signal b -> Signal b -> Signal b
forall a. Signal a -> Signal a -> Signal a
+-+ Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
forall a b. Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
mapSDF Int
c Int
p [a] -> [b]
f (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c Signal a
xs) 
                 else   
                   [Char] -> Signal b
forall a. HasCallStack => [Char] -> a
error [Char]
"mapSDF: Function does not produce correct number of tokens" 
  where consumed_tokens :: [a]
consumed_tokens = Signal a -> [a]
forall a. Signal a -> [a]
fromSignal (Signal a -> [a]) -> Signal a -> [a]
forall a b. (a -> b) -> a -> b
$ Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
c Signal a
xs
        produced_tokens :: [b]
produced_tokens = [a] -> [b]
f [a]
consumed_tokens

-- | The process constructor 'zipWithSDF' takes a tuple @(c1, c2)@
-- denoting the number of consumed tokens and an integer @p@ denoting
-- the number of produced tokens and a function @f@
-- that operates on two lists, and results in an SDF-process that takes two
-- input signals and results in an output signal
zipWithSDF :: (Int, Int) -> Int -> ([a] -> [b] -> [c])
           -> Signal a -> Signal b -> Signal c                  
zipWithSDF :: (Int, Int)
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithSDF (Int
_, Int
_) Int
_ [a] -> [b] -> [c]
_ Signal a
NullS Signal b
_ = Signal c
forall a. Signal a
NullS
zipWithSDF (Int
_, Int
_) Int
_ [a] -> [b] -> [c]
_ Signal a
_ Signal b
NullS = Signal c
forall a. Signal a
NullS
zipWithSDF (Int
c1, Int
c2) Int
p [a] -> [b] -> [c]
f Signal a
as Signal b
bs 
  | Int
c1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 Bool -> Bool -> Bool
|| Int
c2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0  = [Char] -> Signal c
forall a. HasCallStack => [Char] -> a
error [Char]
"zipWithSDF: Number of consumed tokens must be positive integer"
  | (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> Signal a -> Bool
forall a t. (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens Int
c1 Signal a
as) 
    Bool -> Bool -> Bool
|| (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> Signal b -> Bool
forall a t. (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens Int
c2 Signal b
bs) = Signal c
forall a. Signal a
NullS
  | Bool
otherwise = if [c] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [c]
produced_tokens Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p then
                  [c] -> Signal c
forall a. [a] -> Signal a
signal [c]
produced_tokens Signal c -> Signal c -> Signal c
forall a. Signal a -> Signal a -> Signal a
+-+ (Int, Int)
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
forall a b c.
(Int, Int)
-> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
zipWithSDF (Int
c1, Int
c2) Int
p [a] -> [b] -> [c]
f (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c1 Signal a
as) (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
dropS Int
c2 Signal b
bs)  
                else
                  [Char] -> Signal c
forall a. HasCallStack => [Char] -> a
error [Char]
"zipWithSDF: Function does not produce correct number of tokens"
  where consumed_tokens_as :: [a]
consumed_tokens_as = Signal a -> [a]
forall a. Signal a -> [a]
fromSignal (Signal a -> [a]) -> Signal a -> [a]
forall a b. (a -> b) -> a -> b
$ Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
c1 Signal a
as
        consumed_tokens_bs :: [b]
consumed_tokens_bs = Signal b -> [b]
forall a. Signal a -> [a]
fromSignal (Signal b -> [b]) -> Signal b -> [b]
forall a b. (a -> b) -> a -> b
$ Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
takeS Int
c2 Signal b
bs
        produced_tokens :: [c]
produced_tokens = [a] -> [b] -> [c]
f [a]
consumed_tokens_as [b]
consumed_tokens_bs

-- | The process constructor 'zipWith3SDF' takes a tuple @(c1, c2, c3)@
-- denoting the number of consumed tokens and an integer @p@ denoting
-- the number of produced tokens and a function @f@
-- that operates on three lists, and results in an SDF-process that takes three
-- input signals and results in an output signal  
zipWith3SDF :: (Int, Int, Int) -> Int -> ([a] -> [b] -> [c] -> [d]) 
            -> Signal a -> Signal b -> Signal c -> Signal d                 
zipWith3SDF :: (Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
zipWith3SDF (Int
_, Int
_, Int
_) Int
_ [a] -> [b] -> [c] -> [d]
_ Signal a
NullS Signal b
_ Signal c
_= Signal d
forall a. Signal a
NullS
zipWith3SDF (Int
_, Int
_, Int
_) Int
_ [a] -> [b] -> [c] -> [d]
_ Signal a
_ Signal b
NullS Signal c
_= Signal d
forall a. Signal a
NullS
zipWith3SDF (Int
_, Int
_, Int
_) Int
_ [a] -> [b] -> [c] -> [d]
_ Signal a
_ Signal b
_ Signal c
NullS= Signal d
forall a. Signal a
NullS
zipWith3SDF (Int
c1, Int
c2, Int
c3) Int
p [a] -> [b] -> [c] -> [d]
f Signal a
as Signal b
bs Signal c
cs
  | Int
c1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 Bool -> Bool -> Bool
|| Int
c2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 Bool -> Bool -> Bool
|| Int
c3 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0
  = [Char] -> Signal d
forall a. HasCallStack => [Char] -> a
error [Char]
"zipWith3SDF: Number of consumed tokens must be positive integer"
  | (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> Signal a -> Bool
forall a t. (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens Int
c1 Signal a
as) 
    Bool -> Bool -> Bool
|| (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> Signal b -> Bool
forall a t. (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens Int
c2 Signal b
bs)    
    Bool -> Bool -> Bool
|| (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> Signal c -> Bool
forall a t. (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens Int
c3 Signal c
cs)
  = Signal d
forall a. Signal a
NullS
  | Bool
otherwise
  = if [d] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [d]
produced_tokens Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p then
      [d] -> Signal d
forall a. [a] -> Signal a
signal [d]
produced_tokens Signal d -> Signal d -> Signal d
forall a. Signal a -> Signal a -> Signal a
+-+ (Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
forall a b c d.
(Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
zipWith3SDF (Int
c1, Int
c2, Int
c3) Int
p [a] -> [b] -> [c] -> [d]
f
                                 (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c1 Signal a
as) (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
dropS Int
c2 Signal b
bs) (Int -> Signal c -> Signal c
forall a. Int -> Signal a -> Signal a
dropS Int
c3 Signal c
cs)
    else
      [Char] -> Signal d
forall a. HasCallStack => [Char] -> a
error [Char]
"zipWith3SDF: Function does not produce correct number of tokens"
  where consumed_tokens_as :: [a]
consumed_tokens_as = Signal a -> [a]
forall a. Signal a -> [a]
fromSignal (Signal a -> [a]) -> Signal a -> [a]
forall a b. (a -> b) -> a -> b
$ Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
c1 Signal a
as
        consumed_tokens_bs :: [b]
consumed_tokens_bs = Signal b -> [b]
forall a. Signal a -> [a]
fromSignal (Signal b -> [b]) -> Signal b -> [b]
forall a b. (a -> b) -> a -> b
$ Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
takeS Int
c2 Signal b
bs
        consumed_tokens_cs :: [c]
consumed_tokens_cs = Signal c -> [c]
forall a. Signal a -> [a]
fromSignal (Signal c -> [c]) -> Signal c -> [c]
forall a b. (a -> b) -> a -> b
$ Int -> Signal c -> Signal c
forall a. Int -> Signal a -> Signal a
takeS Int
c3 Signal c
cs
        produced_tokens :: [d]
produced_tokens = [a] -> [b] -> [c] -> [d]
f [a]
consumed_tokens_as [b]
consumed_tokens_bs [c]
consumed_tokens_cs
  

-- | The process constructor 'zipWith4SDF' takes a tuple @(c1, c2, c3,c4)@
-- denoting the number of consumed tokens and an integer @p@
-- denoting the number of produced tokens and a function @f@ that
-- operates on three lists, and results in an SDF-process that takes
-- three input signals and results in an output signal
zipWith4SDF :: (Int, Int, Int, Int) -> Int 
            -> ([a] -> [b] -> [c] -> [d] -> [e]) 
            -> Signal a -> Signal b -> Signal c -> Signal d -> Signal e 
zipWith4SDF :: (Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
zipWith4SDF (Int
_, Int
_, Int
_, Int
_) Int
_ [a] -> [b] -> [c] -> [d] -> [e]
_ Signal a
NullS Signal b
_ Signal c
_ Signal d
_ = Signal e
forall a. Signal a
NullS
zipWith4SDF (Int
_, Int
_, Int
_, Int
_) Int
_ [a] -> [b] -> [c] -> [d] -> [e]
_ Signal a
_ Signal b
NullS Signal c
_ Signal d
_ = Signal e
forall a. Signal a
NullS
zipWith4SDF (Int
_, Int
_, Int
_, Int
_) Int
_ [a] -> [b] -> [c] -> [d] -> [e]
_ Signal a
_ Signal b
_ Signal c
NullS Signal d
_ = Signal e
forall a. Signal a
NullS
zipWith4SDF (Int
_, Int
_, Int
_, Int
_) Int
_ [a] -> [b] -> [c] -> [d] -> [e]
_ Signal a
_ Signal b
_ Signal c
_ Signal d
NullS = Signal e
forall a. Signal a
NullS
zipWith4SDF (Int
c1, Int
c2, Int
c3, Int
c4) Int
p [a] -> [b] -> [c] -> [d] -> [e]
f Signal a
as Signal b
bs Signal c
cs Signal d
ds
  | Int
c1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 Bool -> Bool -> Bool
|| Int
c2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 Bool -> Bool -> Bool
|| Int
c3 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 Bool -> Bool -> Bool
|| Int
c4 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0
  = [Char] -> Signal e
forall a. HasCallStack => [Char] -> a
error [Char]
"zipWith4SDF: Number of consumed tokens must be positive integer"
  | (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> Signal a -> Bool
forall a t. (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens Int
c1 Signal a
as) 
    Bool -> Bool -> Bool
|| (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> Signal b -> Bool
forall a t. (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens Int
c2 Signal b
bs)    
    Bool -> Bool -> Bool
|| (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> Signal c -> Bool
forall a t. (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens Int
c3 Signal c
cs)    
    Bool -> Bool -> Bool
|| (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> Signal d -> Bool
forall a t. (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens Int
c4 Signal d
ds)    
  = Signal e
forall a. Signal a
NullS
  | Bool
otherwise    
  = if [e] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [e]
produced_tokens Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p then
      [e] -> Signal e
forall a. [a] -> Signal a
signal [e]
produced_tokens Signal e -> Signal e -> Signal e
forall a. Signal a -> Signal a -> Signal a
+-+ (Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
forall a b c d e.
(Int, Int, Int, Int)
-> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a
-> Signal b
-> Signal c
-> Signal d
-> Signal e
zipWith4SDF (Int
c1, Int
c2, Int
c3, Int
c4) Int
p [a] -> [b] -> [c] -> [d] -> [e]
f
             (Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
dropS Int
c1 Signal a
as) (Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
dropS Int
c2 Signal b
bs) (Int -> Signal c -> Signal c
forall a. Int -> Signal a -> Signal a
dropS Int
c3 Signal c
cs) (Int -> Signal d -> Signal d
forall a. Int -> Signal a -> Signal a
dropS Int
c4 Signal d
ds)
    else
      [Char] -> Signal e
forall a. HasCallStack => [Char] -> a
error [Char]
"zipWith4SDF: Function does not produce correct number of tokens"
  where consumed_tokens_as :: [a]
consumed_tokens_as = Signal a -> [a]
forall a. Signal a -> [a]
fromSignal (Signal a -> [a]) -> Signal a -> [a]
forall a b. (a -> b) -> a -> b
$ Int -> Signal a -> Signal a
forall a. Int -> Signal a -> Signal a
takeS Int
c1 Signal a
as
        consumed_tokens_bs :: [b]
consumed_tokens_bs = Signal b -> [b]
forall a. Signal a -> [a]
fromSignal (Signal b -> [b]) -> Signal b -> [b]
forall a b. (a -> b) -> a -> b
$ Int -> Signal b -> Signal b
forall a. Int -> Signal a -> Signal a
takeS Int
c2 Signal b
bs
        consumed_tokens_cs :: [c]
consumed_tokens_cs = Signal c -> [c]
forall a. Signal a -> [a]
fromSignal (Signal c -> [c]) -> Signal c -> [c]
forall a b. (a -> b) -> a -> b
$ Int -> Signal c -> Signal c
forall a. Int -> Signal a -> Signal a
takeS Int
c3 Signal c
cs
        consumed_tokens_ds :: [d]
consumed_tokens_ds = Signal d -> [d]
forall a. Signal a -> [a]
fromSignal (Signal d -> [d]) -> Signal d -> [d]
forall a b. (a -> b) -> a -> b
$ Int -> Signal d -> Signal d
forall a. Int -> Signal a -> Signal a
takeS Int
c4 Signal d
ds
        produced_tokens :: [e]
produced_tokens = [a] -> [b] -> [c] -> [d] -> [e]
f [a]
consumed_tokens_as [b]
consumed_tokens_bs
                            [c]
consumed_tokens_cs [d]
consumed_tokens_ds
                            
---------------------------------------------------------------------
-- unzipSDF Processes
---------------------------------------------------------------------

unzipSDF :: (Int, Int) -> Signal ([a], [b]) 
         -> (Signal a, Signal b)
unzipSDF :: (Int, Int) -> Signal ([a], [b]) -> (Signal a, Signal b)
unzipSDF (Int
p1, Int
p2) Signal ([a], [b])
xs = (Signal a
s1, Signal b
s2) 
  where
    s1 :: Signal a
s1 = [a] -> Signal a
forall a. [a] -> Signal a
signal ([a] -> Signal a) -> [a] -> Signal a
forall a b. (a -> b) -> a -> b
$ Signal ([a], [b]) -> [a]
forall a b. Signal ([a], b) -> [a]
f1 Signal ([a], [b])
xs
    s2 :: Signal b
s2 = [b] -> Signal b
forall a. [a] -> Signal a
signal ([b] -> Signal b) -> [b] -> Signal b
forall a b. (a -> b) -> a -> b
$ Signal ([a], [b]) -> [b]
forall a a. Signal (a, [a]) -> [a]
f2 Signal ([a], [b])
xs
    f1 :: Signal ([a], b) -> [a]
f1 Signal ([a], b)
NullS     = []
    f1 (([a]
as, b
_):-Signal ([a], b)
xs)
      | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
as Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p1 = [a]
as [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Signal ([a], b) -> [a]
f1 Signal ([a], b)
xs
      | Bool
otherwise = [Char] -> [a]
forall a. HasCallStack => [Char] -> a
error [Char]
"unzipSDF: Process does not produce correct number of tokens"
    f2 :: Signal (a, [a]) -> [a]
f2 Signal (a, [a])
NullS     = []
    f2 ((a
_, [a]
bs):-Signal (a, [a])
xs)
      | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p2 = [a]
bs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Signal (a, [a]) -> [a]
f2 Signal (a, [a])
xs
      | Bool
otherwise = [Char] -> [a]
forall a. HasCallStack => [Char] -> a
error [Char]
"unzipSDF: Process does not produce correct number of tokens"  


unzip3SDF :: (Int, Int, Int) -> Signal ([a], [b], [c]) 
      -> (Signal a, Signal b, Signal c)
unzip3SDF :: (Int, Int, Int)
-> Signal ([a], [b], [c]) -> (Signal a, Signal b, Signal c)
unzip3SDF (Int
p1, Int
p2, Int
p3) Signal ([a], [b], [c])
xs = (Signal a
s1, Signal b
s2, Signal c
s3) 
  where
    s1 :: Signal a
s1 = [a] -> Signal a
forall a. [a] -> Signal a
signal ([a] -> Signal a) -> [a] -> Signal a
forall a b. (a -> b) -> a -> b
$ Signal ([a], [b], [c]) -> [a]
forall a b c. Signal ([a], b, c) -> [a]
f1 Signal ([a], [b], [c])
xs
    s2 :: Signal b
s2 = [b] -> Signal b
forall a. [a] -> Signal a
signal ([b] -> Signal b) -> [b] -> Signal b
forall a b. (a -> b) -> a -> b
$ Signal ([a], [b], [c]) -> [b]
forall a a c. Signal (a, [a], c) -> [a]
f2 Signal ([a], [b], [c])
xs
    s3 :: Signal c
s3 = [c] -> Signal c
forall a. [a] -> Signal a
signal ([c] -> Signal c) -> [c] -> Signal c
forall a b. (a -> b) -> a -> b
$ Signal ([a], [b], [c]) -> [c]
forall a b a. Signal (a, b, [a]) -> [a]
f3 Signal ([a], [b], [c])
xs
    f1 :: Signal ([a], b, c) -> [a]
f1 Signal ([a], b, c)
NullS      = []
    f1 (([a]
as, b
_, c
_):-Signal ([a], b, c)
xs) 
      | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
as Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p1 = [a]
as [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Signal ([a], b, c) -> [a]
f1 Signal ([a], b, c)
xs
      | Bool
otherwise = [Char] -> [a]
forall a. HasCallStack => [Char] -> a
error [Char]
"unzip3SDF: Process does not produce correct number of tokens"
    f2 :: Signal (a, [a], c) -> [a]
f2 Signal (a, [a], c)
NullS      = []
    f2 ((a
_, [a]
bs, c
_):-Signal (a, [a], c)
xs) 
      | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p2 = [a]
bs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Signal (a, [a], c) -> [a]
f2 Signal (a, [a], c)
xs
      | Bool
otherwise = [Char] -> [a]
forall a. HasCallStack => [Char] -> a
error [Char]
"unzip3SDF: Process does not produce correct number of tokens"  
    f3 :: Signal (a, b, [a]) -> [a]
f3 Signal (a, b, [a])
NullS      = []
    f3 ((a
_, b
_, [a]
cs):-Signal (a, b, [a])
xs) 
      | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
cs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p3 = [a]
cs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Signal (a, b, [a]) -> [a]
f3 Signal (a, b, [a])
xs
      | Bool
otherwise = [Char] -> [a]
forall a. HasCallStack => [Char] -> a
error [Char]
"unzip3SDF: Process does not produce correct number of tokens"  
  

unzip4SDF :: (Int, Int, Int, Int) -> Signal ([a], [b], [c], [d]) 
          -> (Signal a, Signal b, Signal c, Signal d)
unzip4SDF :: (Int, Int, Int, Int)
-> Signal ([a], [b], [c], [d])
-> (Signal a, Signal b, Signal c, Signal d)
unzip4SDF (Int
p1, Int
p2, Int
p3, Int
p4) Signal ([a], [b], [c], [d])
xs = (Signal a
s1, Signal b
s2, Signal c
s3, Signal d
s4) 
  where
    s1 :: Signal a
s1 = [a] -> Signal a
forall a. [a] -> Signal a
signal ([a] -> Signal a) -> [a] -> Signal a
forall a b. (a -> b) -> a -> b
$ Signal ([a], [b], [c], [d]) -> [a]
forall a b c d. Signal ([a], b, c, d) -> [a]
f1 Signal ([a], [b], [c], [d])
xs
    s2 :: Signal b
s2 = [b] -> Signal b
forall a. [a] -> Signal a
signal ([b] -> Signal b) -> [b] -> Signal b
forall a b. (a -> b) -> a -> b
$ Signal ([a], [b], [c], [d]) -> [b]
forall a a c d. Signal (a, [a], c, d) -> [a]
f2 Signal ([a], [b], [c], [d])
xs
    s3 :: Signal c
s3 = [c] -> Signal c
forall a. [a] -> Signal a
signal ([c] -> Signal c) -> [c] -> Signal c
forall a b. (a -> b) -> a -> b
$ Signal ([a], [b], [c], [d]) -> [c]
forall a b a d. Signal (a, b, [a], d) -> [a]
f3 Signal ([a], [b], [c], [d])
xs
    s4 :: Signal d
s4 = [d] -> Signal d
forall a. [a] -> Signal a
signal ([d] -> Signal d) -> [d] -> Signal d
forall a b. (a -> b) -> a -> b
$ Signal ([a], [b], [c], [d]) -> [d]
forall a b c a. Signal (a, b, c, [a]) -> [a]
f4 Signal ([a], [b], [c], [d])
xs
    f1 :: Signal ([a], b, c, d) -> [a]
f1 Signal ([a], b, c, d)
NullS      = []
    f1 (([a]
as, b
_, c
_, d
_):-Signal ([a], b, c, d)
xs) 
      | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
as Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p1 = [a]
as [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Signal ([a], b, c, d) -> [a]
f1 Signal ([a], b, c, d)
xs
      | Bool
otherwise = [Char] -> [a]
forall a. HasCallStack => [Char] -> a
error [Char]
"unzip4SDF: Process does not produce correct number of tokens"
    f2 :: Signal (a, [a], c, d) -> [a]
f2 Signal (a, [a], c, d)
NullS      = []
    f2 ((a
_, [a]
bs, c
_, d
_):-Signal (a, [a], c, d)
xs) 
      | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p2 = [a]
bs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Signal (a, [a], c, d) -> [a]
f2 Signal (a, [a], c, d)
xs
      | Bool
otherwise = [Char] -> [a]
forall a. HasCallStack => [Char] -> a
error [Char]
"unzip4SDF: Process does not produce correct number of tokens"  
    f3 :: Signal (a, b, [a], d) -> [a]
f3 Signal (a, b, [a], d)
NullS      = []
    f3 ((a
_, b
_, [a]
cs, d
_):-Signal (a, b, [a], d)
xs) 
      | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
cs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p3 = [a]
cs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Signal (a, b, [a], d) -> [a]
f3 Signal (a, b, [a], d)
xs
      | Bool
otherwise = [Char] -> [a]
forall a. HasCallStack => [Char] -> a
error [Char]
"unzip4SDF: Process does not produce correct number of tokens" 
    f4 :: Signal (a, b, c, [a]) -> [a]
f4 Signal (a, b, c, [a])
NullS      = []
    f4 ((a
_, b
_, c
_, [a]
ds):-Signal (a, b, c, [a])
xs) 
      | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
ds Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
p4 = [a]
ds [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Signal (a, b, c, [a]) -> [a]
f4 Signal (a, b, c, [a])
xs
      | Bool
otherwise = [Char] -> [a]
forall a. HasCallStack => [Char] -> a
error [Char]
"unzip4SDF: Process does not produce correct number of tokens" 

------------------------------------------------------------------------
--
-- Helper functions (not exported!)
--
------------------------------------------------------------------------


sufficient_tokens :: (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens :: a -> Signal t -> Bool
sufficient_tokens a
0 Signal t
_     = Bool
True
sufficient_tokens a
_ Signal t
NullS = Bool
False
sufficient_tokens a
n (t
_:-Signal t
xs)
 = if a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 then
     [Char] -> Bool
forall a. HasCallStack => [Char] -> a
error [Char]
"sufficient_tokens: n must not be negative"
   else
     a -> Signal t -> Bool
forall a t. (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1) Signal t
xs

-- outputTokens :: [(a, b, c)] -> [b]
-- outputTokens [] = []
-- outputTokens ((_, b, _):xs) = b : outputTokens xs

wrapF1 :: ([a] -> y) -> [a] -> [y]
wrapF1 :: ([a] -> y) -> [a] -> [y]
wrapF1 [a] -> y
f = (\[a]
a -> [[a] -> y
f [a]
a])

wrapF2 :: ([a] -> [b] -> y) -> [a] -> [b] -> [y]
wrapF2 :: ([a] -> [b] -> y) -> [a] -> [b] -> [y]
wrapF2 [a] -> [b] -> y
f = (\[a]
a [b]
b -> [[a] -> [b] -> y
f [a]
a [b]
b])

wrapF3 :: ([a] -> [b] -> [c] -> y) -> [a] -> [b] -> [c] -> [y]
wrapF3 :: ([a] -> [b] -> [c] -> y) -> [a] -> [b] -> [c] -> [y]
wrapF3 [a] -> [b] -> [c] -> y
f = (\[a]
a [b]
b [c]
c -> [[a] -> [b] -> [c] -> y
f [a]
a [b]
b [c]
c])

wrapF4 :: ([a] -> [b] -> [c] -> [d] -> y) -> [a] -> [b] -> [c] -> [d] -> [y]
wrapF4 :: ([a] -> [b] -> [c] -> [d] -> y) -> [a] -> [b] -> [c] -> [d] -> [y]
wrapF4 [a] -> [b] -> [c] -> [d] -> y
f = (\[a]
a [b]
b [c]
c [d]
d -> [[a] -> [b] -> [c] -> [d] -> y
f [a]
a [b]
b [c]
c [d]
d])

------------------------------------------------------------------------
--
-- Test of Library (not exported)
--
------------------------------------------------------------------------

{-
s1 = takeS 10 $ signal [1..]
s2 = takeS 10 $ signal [10,20..]

f1 [x] = [([x,x], [x,x,x])]

s3 = unzipSDF (2,3) $ mapSDF 1 1 f1 s1    
         
s4 = actor12SDF 1 (2,3) f1 s1

s5 = signal [1.0,2.0,3.0,4.0,5.0]

multiply [x1,x2] [y] = [(x1+x2)* y]
multiply _   _   = error "Single list item expected"

feedback input = (i1,output) 
   where output = actor21SDF (2,1) 1 multiply input i1
     i1 = delaySDF 1 output
-}