module ForSyDe.Shallow.MoC.SDF (
delaySDF,
actor11SDF, actor12SDF, actor13SDF, actor14SDF,
actor21SDF, actor22SDF, actor23SDF, actor24SDF,
actor31SDF, actor32SDF, actor33SDF, actor34SDF,
actor41SDF, actor42SDF, actor43SDF, actor44SDF
) where
import ForSyDe.Shallow.Core
delaySDF :: [a] -> Signal a -> Signal a
delaySDF initial_tokens xs = signal initial_tokens +-+ xs
actor11SDF :: Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
actor11SDF = mapSDF
actor21SDF :: (Int, Int) -> Int -> ([a] -> [b] -> [c]) -> Signal a -> Signal b -> Signal c
actor21SDF = zipWithSDF
actor31SDF :: (Int, Int, Int) -> Int -> ([a] -> [b] -> [c] -> [d])
-> Signal a -> Signal b -> Signal c -> Signal d
actor31SDF = zipWith3SDF
actor41SDF :: (Int, Int, Int, Int) -> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
actor41SDF = zipWith4SDF
actor12SDF :: Int -> (Int, Int) -> ([a] -> ([b], [c]))
-> Signal a -> (Signal b, Signal c)
actor12SDF c (p1,p2) f xs = unzipSDF (p1,p2) $ mapSDF c 1 (wrapF1 f) xs
actor22SDF :: (Int, Int) -> (Int, Int) -> ([a] -> [b] -> ([c], [d]))
-> Signal a -> Signal b -> (Signal c, Signal d)
actor22SDF (c1,c2) (p1,p2) f xs ys = unzipSDF (p1,p2) $ zipWithSDF (c1,c2) 1 (wrapF2 f) xs ys
actor32SDF :: (Int, Int, Int) -> (Int, Int)
-> ([a] -> [b] -> [c] -> ([d], [e]))
-> Signal a -> Signal b -> Signal c -> (Signal d, Signal e)
actor32SDF (c1,c2,c3) (p1,p2) f as bs cs
= unzipSDF (p1,p2) $ zipWith3SDF (c1,c2,c3) 1 (wrapF3 f) as bs cs
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 (c1,c2,c3,c4) (p1,p2) f as bs cs ds
= unzipSDF (p1,p2) $ zipWith4SDF (c1,c2,c3,c4) 1 (wrapF4 f) as bs cs ds
actor13SDF :: Int -> (Int, Int, Int)
-> ([a] -> ([b], [c], [d]))
-> Signal a -> (Signal b, Signal c, Signal d)
actor13SDF c (p1,p2,p3) f xs = unzip3SDF (p1,p2,p3) $ mapSDF c 1 (wrapF1 f) xs
actor23SDF :: (Int, Int) -> (Int, Int, Int)
-> ([a] -> [b] -> ([c], [d], [e]))
-> Signal a -> Signal b
-> (Signal c, Signal d, Signal e)
actor23SDF (c1,c2) (p1,p2,p3) f xs ys
= unzip3SDF (p1,p2,p3) $ zipWithSDF (c1,c2) 1 (wrapF2 f) xs ys
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 (c1,c2,c3) (p1,p2,p3) f as bs cs
= unzip3SDF (p1,p2,p3) $ zipWith3SDF (c1,c2,c3) 1 (wrapF3 f) as bs cs
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 (c1,c2,c3,c4) (p1,p2,p3) f as bs cs ds
= unzip3SDF (p1,p2,p3)$ zipWith4SDF (c1,c2,c3,c4) 1 (wrapF4 f) as bs cs ds
actor14SDF :: Int -> (Int, Int, Int, Int)
-> ([a] -> ([b], [c], [d], [e]))
-> Signal a -> (Signal b, Signal c, Signal d, Signal e)
actor14SDF c (p1,p2,p3,p4) f xs = unzip4SDF (p1,p2,p3,p4) $ mapSDF c 1 (wrapF1 f) xs
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 (c1,c2) (p1,p2,p3,p4) f xs ys
= unzip4SDF (p1,p2,p3,p4) $ zipWithSDF (c1,c2) 1 (wrapF2 f) xs ys
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 (c1,c2,c3) (p1,p2,p3,p4) f as bs cs
= unzip4SDF (p1,p2,p3,p4) $ zipWith3SDF (c1,c2,c3) 1 (wrapF3 f) as bs cs
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 (c1,c2,c3,c4) (p1,p2,p3,p4) f as bs cs ds
= unzip4SDF (p1,p2,p3,p4) $ zipWith4SDF (c1,c2,c3,c4) 1 (wrapF4 f) as bs cs ds
mapSDF :: Int -> Int -> ([a] -> [b]) -> Signal a -> Signal b
mapSDF _ _ _ NullS = NullS
mapSDF c p f xs
| c <= 0 = error "mapSDF: Number of consumed tokens must be positive integer"
| not $ sufficient_tokens c xs = NullS
| otherwise = if length produced_tokens == p then
signal produced_tokens +-+ mapSDF c p f (dropS c xs)
else
error "mapSDF: Function does not produce correct number of tokens"
where consumed_tokens = fromSignal $ takeS c xs
produced_tokens = f consumed_tokens
zipWithSDF :: (Int, Int) -> Int -> ([a] -> [b] -> [c])
-> Signal a -> Signal b -> Signal c
zipWithSDF (_, _) _ _ NullS _ = NullS
zipWithSDF (_, _) _ _ _ NullS = NullS
zipWithSDF (c1, c2) p f as bs
| c1 <= 0 || c2 <= 0 = error "zipWithSDF: Number of consumed tokens must be positive integer"
| (not $ sufficient_tokens c1 as)
|| (not $ sufficient_tokens c2 bs) = NullS
| otherwise = if length produced_tokens == p then
signal produced_tokens +-+ zipWithSDF (c1, c2) p f (dropS c1 as) (dropS c2 bs)
else
error "zipWithSDF: Function does not produce correct number of tokens"
where consumed_tokens_as = fromSignal $ takeS c1 as
consumed_tokens_bs = fromSignal $ takeS c2 bs
produced_tokens = f consumed_tokens_as consumed_tokens_bs
zipWith3SDF :: (Int, Int, Int) -> Int -> ([a] -> [b] -> [c] -> [d])
-> Signal a -> Signal b -> Signal c -> Signal d
zipWith3SDF (_, _, _) _ _ NullS _ _= NullS
zipWith3SDF (_, _, _) _ _ _ NullS _= NullS
zipWith3SDF (_, _, _) _ _ _ _ NullS= NullS
zipWith3SDF (c1, c2, c3) p f as bs cs
| c1 <= 0 || c2 <= 0 || c3 <= 0
= error "zipWith3SDF: Number of consumed tokens must be positive integer"
| (not $ sufficient_tokens c1 as)
|| (not $ sufficient_tokens c2 bs)
|| (not $ sufficient_tokens c3 cs)
= NullS
| otherwise
= if length produced_tokens == p then
signal produced_tokens +-+ zipWith3SDF (c1, c2, c3) p f
(dropS c1 as) (dropS c2 bs) (dropS c3 cs)
else
error "zipWith3SDF: Function does not produce correct number of tokens"
where consumed_tokens_as = fromSignal $ takeS c1 as
consumed_tokens_bs = fromSignal $ takeS c2 bs
consumed_tokens_cs = fromSignal $ takeS c3 cs
produced_tokens = f consumed_tokens_as consumed_tokens_bs consumed_tokens_cs
zipWith4SDF :: (Int, Int, Int, Int) -> Int
-> ([a] -> [b] -> [c] -> [d] -> [e])
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
zipWith4SDF (_, _, _, _) _ _ NullS _ _ _ = NullS
zipWith4SDF (_, _, _, _) _ _ _ NullS _ _ = NullS
zipWith4SDF (_, _, _, _) _ _ _ _ NullS _ = NullS
zipWith4SDF (_, _, _, _) _ _ _ _ _ NullS = NullS
zipWith4SDF (c1, c2, c3, c4) p f as bs cs ds
| c1 <= 0 || c2 <= 0 || c3 <= 0 || c4 <= 0
= error "zipWith4SDF: Number of consumed tokens must be positive integer"
| (not $ sufficient_tokens c1 as)
|| (not $ sufficient_tokens c2 bs)
|| (not $ sufficient_tokens c3 cs)
|| (not $ sufficient_tokens c4 ds)
= NullS
| otherwise
= if length produced_tokens == p then
signal produced_tokens +-+ zipWith4SDF (c1, c2, c3, c4) p f
(dropS c1 as) (dropS c2 bs) (dropS c3 cs) (dropS c4 ds)
else
error "zipWith4SDF: Function does not produce correct number of tokens"
where consumed_tokens_as = fromSignal $ takeS c1 as
consumed_tokens_bs = fromSignal $ takeS c2 bs
consumed_tokens_cs = fromSignal $ takeS c3 cs
consumed_tokens_ds = fromSignal $ takeS c4 ds
produced_tokens = f consumed_tokens_as consumed_tokens_bs
consumed_tokens_cs consumed_tokens_ds
unzipSDF :: (Int, Int) -> Signal ([a], [b])
-> (Signal a, Signal b)
unzipSDF (p1, p2) xs = (s1, s2)
where
s1 = signal $ f1 xs
s2 = signal $ f2 xs
f1 NullS = []
f1 ((as, _):-xs)
| length as == p1 = as ++ f1 xs
| otherwise = error "unzipSDF: Process does not produce correct number of tokens"
f2 NullS = []
f2 ((_, bs):-xs)
| length bs == p2 = bs ++ f2 xs
| otherwise = error "unzipSDF: Process does not produce correct number of tokens"
unzip3SDF :: (Int, Int, Int) -> Signal ([a], [b], [c])
-> (Signal a, Signal b, Signal c)
unzip3SDF (p1, p2, p3) xs = (s1, s2, s3)
where
s1 = signal $ f1 xs
s2 = signal $ f2 xs
s3 = signal $ f3 xs
f1 NullS = []
f1 ((as, _, _):-xs)
| length as == p1 = as ++ f1 xs
| otherwise = error "unzip3SDF: Process does not produce correct number of tokens"
f2 NullS = []
f2 ((_, bs, _):-xs)
| length bs == p2 = bs ++ f2 xs
| otherwise = error "unzip3SDF: Process does not produce correct number of tokens"
f3 NullS = []
f3 ((_, _, cs):-xs)
| length cs == p3 = cs ++ f3 xs
| otherwise = error "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 (p1, p2, p3, p4) xs = (s1, s2, s3, s4)
where
s1 = signal $ f1 xs
s2 = signal $ f2 xs
s3 = signal $ f3 xs
s4 = signal $ f4 xs
f1 NullS = []
f1 ((as, _, _, _):-xs)
| length as == p1 = as ++ f1 xs
| otherwise = error "unzip4SDF: Process does not produce correct number of tokens"
f2 NullS = []
f2 ((_, bs, _, _):-xs)
| length bs == p2 = bs ++ f2 xs
| otherwise = error "unzip4SDF: Process does not produce correct number of tokens"
f3 NullS = []
f3 ((_, _, cs, _):-xs)
| length cs == p3 = cs ++ f3 xs
| otherwise = error "unzip4SDF: Process does not produce correct number of tokens"
f4 NullS = []
f4 ((_, _, _, ds):-xs)
| length ds == p4 = ds ++ f4 xs
| otherwise = error "unzip4SDF: Process does not produce correct number of tokens"
sufficient_tokens :: (Num a, Eq a, Ord a) => a -> Signal t -> Bool
sufficient_tokens 0 _ = True
sufficient_tokens _ NullS = False
sufficient_tokens n (_:-xs)
= if n < 0 then
error "sufficient_tokens: n must not be negative"
else
sufficient_tokens (n-1) xs
wrapF1 :: ([a] -> y) -> [a] -> [y]
wrapF1 f = (\a -> [f a])
wrapF2 :: ([a] -> [b] -> y) -> [a] -> [b] -> [y]
wrapF2 f = (\a b -> [f a b])
wrapF3 :: ([a] -> [b] -> [c] -> y) -> [a] -> [b] -> [c] -> [y]
wrapF3 f = (\a b c -> [f a b c])
wrapF4 :: ([a] -> [b] -> [c] -> [d] -> y) -> [a] -> [b] -> [c] -> [d] -> [y]
wrapF4 f = (\a b c d -> [f a b c d])