{-# LANGUAGE ScopedTypeVariables #-}
module Copilot.Library.StateMachines where
import Copilot.Language (Stream, Typed, constant, ifThenElse, (&&), (++), (==))
import Prelude hiding ((&&), (++), (==))
type StateMachine a = (a, a, Stream Bool, [(a, Stream Bool, a)], a)
stateMachine :: forall a . (Eq a, Typed a) => StateMachine a -> Stream a
stateMachine :: forall a. (Eq a, Typed a) => StateMachine a -> Stream a
stateMachine (a
initial, a
final, Stream Bool
noInputData, [(a, Stream Bool, a)]
transitions, a
bad) = Stream a
state
where
state :: Stream a
state = [(a, Stream Bool, a)] -> Stream a
ifThenElses [(a, Stream Bool, a)]
transitions
previousState :: Stream a
previousState = [a
initial] [a] -> Stream a -> Stream a
forall a. Typed a => [a] -> Stream a -> Stream a
++ Stream a
state
ifThenElses :: [(a, Stream Bool, a)] -> Stream a
ifThenElses :: [(a, Stream Bool, a)] -> Stream a
ifThenElses [] =
Stream Bool -> Stream a -> Stream a -> Stream a
forall a.
Typed a =>
Stream Bool -> Stream a -> Stream a -> Stream a
ifThenElse (Stream a
previousState Stream a -> Stream a -> Stream Bool
forall a. (Eq a, Typed a) => Stream a -> Stream a -> Stream Bool
== a -> Stream a
forall a. Typed a => a -> Stream a
constant a
final Stream Bool -> Stream Bool -> Stream Bool
&& Stream Bool
noInputData)
(a -> Stream a
forall a. Typed a => a -> Stream a
constant a
final)
(a -> Stream a
forall a. Typed a => a -> Stream a
constant a
bad)
ifThenElses ((a
s1, Stream Bool
i, a
s2):[(a, Stream Bool, a)]
ss) =
Stream Bool -> Stream a -> Stream a -> Stream a
forall a.
Typed a =>
Stream Bool -> Stream a -> Stream a -> Stream a
ifThenElse
(Stream a
previousState Stream a -> Stream a -> Stream Bool
forall a. (Eq a, Typed a) => Stream a -> Stream a -> Stream Bool
== a -> Stream a
forall a. Typed a => a -> Stream a
constant a
s1 Stream Bool -> Stream Bool -> Stream Bool
&& Stream Bool
i)
(a -> Stream a
forall a. Typed a => a -> Stream a
constant a
s2)
([(a, Stream Bool, a)] -> Stream a
ifThenElses [(a, Stream Bool, a)]
ss)
stateMachineEnum :: (Eq b, Typed b, Num b, Enum a)
=> StateMachine a
-> Stream b
stateMachineEnum :: forall b a.
(Eq b, Typed b, Num b, Enum a) =>
StateMachine a -> Stream b
stateMachineEnum (a
initial, a
final, Stream Bool
noInputData, [(a, Stream Bool, a)]
transitions, a
bad) =
StateMachine b -> Stream b
forall a. (Eq a, Typed a) => StateMachine a -> Stream a
stateMachine (a -> b
fe a
initial, a -> b
fe a
final, Stream Bool
noInputData, [(b, Stream Bool, b)]
transitionsE, a -> b
fe a
bad)
where
transitionsE :: [(b, Stream Bool, b)]
transitionsE = ((a, Stream Bool, a) -> (b, Stream Bool, b))
-> [(a, Stream Bool, a)] -> [(b, Stream Bool, b)]
forall a b. (a -> b) -> [a] -> [b]
map (\(a
s1, Stream Bool
t, a
s2) -> (a -> b
fe a
s1, Stream Bool
t, a -> b
fe a
s2)) [(a, Stream Bool, a)]
transitions
fe :: a -> b
fe = Int -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> b) -> (a -> Int) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall a. Enum a => a -> Int
fromEnum