{-# LINE 1 "-" #-}
module Circuits where
{-# LINE 3 "-" #-}
import Arrow
{-# LINE 4 "-" #-}
import Stream
{-# LINE 5 "-" #-}
import StreamArrow
{-# LINE 6 "-" #-}
import ArrowCircuit
{-# LINE 7 "-" #-}
import Monoid
{-# LINE 8 "-" #-}
import Automaton
 
{-# LINE 14 "-" #-}
counter :: (ArrowCircuit a) => a Bool Int
{-# LINE 15 "-" #-}
counter
  = (loop
       (arr
	  (\ (reset, next) ->
	     case if reset then 0 else next of
		 output -> (output, output))
	  >>>
	  (first (arr (\ output -> output + 1) >>> delay 0) >>>
	     arr (\ (next, output) -> (output, next)))))
 
{-# LINE 25 "-" #-}
flush :: (ArrowCircuit a) => Int -> b -> a (b, Bool) b
{-# LINE 26 "-" #-}
flush n d
  = (loop
       (arr (\ ((value, reset), next) -> ((next, reset), value)) >>>
	  (first
	     (arr (\ (next, reset) -> if reset then n else max (next - 1) 0))
	     >>> arr (\ (count, value) -> (count, (count, value))))
	    >>>
	    (first (delay 0) >>>
	       arr (\ (next, (count, value)) -> ((count, value), next))))
       >>> arr (\ (count, value) -> if count > 0 then d else value))
 
{-# LINE 34 "-" #-}
latch :: (ArrowCircuit a) => b -> a (b, Bool) b
{-# LINE 35 "-" #-}
latch init
  = (loop
       (arr
	  (\ ((value, reset), last) ->
	     case if reset then value else last of
		 out -> (out, out))
	  >>> (first (delay init) >>> arr (\ (last, out) -> (out, last)))))
 
{-# LINE 42 "-" #-}
partialRun :: (ArrowRunCircuit a a') => a b c -> a' [b] [c]
{-# LINE 43 "-" #-}
partialRun f
  = (arr (\ xs -> (xs, xs)) >>>
       (first (arr (\ xs -> listToStream xs) >>> runCircuit f) >>>
	  arr (\ (s, xs) -> take (length xs) (streamToList s))))
{-# LINE 49 "-" #-}
test_input = [True, False, True, False, False, True, False, True]
{-# LINE 53 "-" #-}
ts = partialRun (counter :: StreamMap Bool Int) test_input
{-# LINE 55 "-" #-}
ta = partialRun (counter :: Automaton (->) Bool Int) test_input
 
{-# LINE 59 "-" #-}
step :: (ArrowCircuit a) => b -> a (Either b c) b
{-# LINE 60 "-" #-}
step b
  = (loop
       (arr (\ (x, last_b) -> getLeft last_b x) >>>
	  (delay b >>> arr (\ last_b -> (last_b, last_b)))))
  where {-# LINE 63 "-" #-}
	getLeft _ (Left b) = b
	{-# LINE 64 "-" #-}
	getLeft b (Right _) = b
