-- Copyright © 2011 National Institute of Aerospace / Galois, Inc.

{-# LANGUAGE Safe #-}

-- | Pick values from one of two streams, depending whether a condition is true
-- or false.
module Copilot.Language.Operators.Mux
  ( mux
  , ifThenElse
  ) where

import Copilot.Core (Typed, typeOf)
import qualified Copilot.Core as Core
import Copilot.Language.Prelude
import Copilot.Language.Stream
import Prelude ()

-- | Convenient synonym for 'ifThenElse'.
mux :: Typed a => Stream Bool -> Stream a -> Stream a -> Stream a
mux :: forall a.
Typed a =>
Stream Bool -> Stream a -> Stream a -> Stream a
mux (Const Bool
True) Stream a
t Stream a
_  = Stream a
t
mux (Const Bool
False) Stream a
_ Stream a
f = Stream a
f
mux Stream Bool
b Stream a
t Stream a
f             = Op3 Bool a a a -> Stream Bool -> Stream a -> Stream a -> Stream a
forall a1 b c a.
(Typed a1, Typed b, Typed c, Typed a) =>
Op3 a1 b c a -> Stream a1 -> Stream b -> Stream c -> Stream a
Op3 (Type a -> Op3 Bool a a a
forall b. Type b -> Op3 Bool b b b
Core.Mux Type a
forall a. Typed a => Type a
typeOf) Stream Bool
b Stream a
t Stream a
f

-- | If-then-else applied point-wise to three streams (a condition stream, a
-- then-branch stream, and an else-branch stream).
--
-- Produce a stream that, at any point in time, if the value of the first
-- stream at that point is true, contains the value in the second stream at
-- that time, otherwise it contains the value in the third stream.
ifThenElse :: Typed a => Stream Bool -> Stream a -> Stream a -> Stream a
ifThenElse :: forall a.
Typed a =>
Stream Bool -> Stream a -> Stream a -> Stream a
ifThenElse = Stream Bool -> Stream a -> Stream a -> Stream a
forall a.
Typed a =>
Stream Bool -> Stream a -> Stream a -> Stream a
mux