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

{-# LANGUAGE Safe #-}

-- | Comparison operators applied point-wise on streams.
module Copilot.Language.Operators.Ord
  ( (<=)
  , (>=)
  , (<)
  , (>)
  ) where

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

--------------------------------------------------------------------------------

-- | Compare two streams point-wise for order.
--
-- The output stream contains the value True at a point in time if the
-- element in the first stream is smaller or equal than the element in
-- the second stream at that point in time, and False otherwise.
(<=) :: (P.Ord a, Typed a) => Stream a -> Stream a -> Stream Bool
(Const a
x) <= :: Stream a -> Stream a -> Stream Bool
<= (Const a
y) = Bool -> Stream Bool
forall a. Typed a => a -> Stream a
Const (a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.<= a
y)
Stream a
x <= Stream a
y                 = Op2 a a Bool -> Stream a -> Stream a -> Stream Bool
forall a b c.
(Typed a, Typed b, Typed c) =>
Op2 a b c -> Stream a -> Stream b -> Stream c
Op2 (Type a -> Op2 a a Bool
forall a. Ord a => Type a -> Op2 a a Bool
Core.Le Type a
forall a. Typed a => Type a
typeOf) Stream a
x Stream a
y

-- | Compare two streams point-wise for order.
--
-- The output stream contains the value True at a point in time if the
-- element in the first stream is greater or equal than the element in
-- the second stream at that point in time, and False otherwise.
(>=) :: (P.Ord a, Typed a) => Stream a -> Stream a -> Stream Bool
(Const a
x) >= :: Stream a -> Stream a -> Stream Bool
>= (Const a
y) = Bool -> Stream Bool
forall a. Typed a => a -> Stream a
Const (a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.>= a
y)
Stream a
x >= Stream a
y                 = Op2 a a Bool -> Stream a -> Stream a -> Stream Bool
forall a b c.
(Typed a, Typed b, Typed c) =>
Op2 a b c -> Stream a -> Stream b -> Stream c
Op2 (Type a -> Op2 a a Bool
forall a. Ord a => Type a -> Op2 a a Bool
Core.Ge Type a
forall a. Typed a => Type a
typeOf) Stream a
x Stream a
y

-- | Compare two streams point-wise for order.
--
-- The output stream contains the value True at a point in time if the
-- element in the first stream is smaller than the element in the second stream
-- at that point in time, and False otherwise.
(<) :: (P.Ord a, Typed a) => Stream a -> Stream a -> Stream Bool
(Const a
x) < :: Stream a -> Stream a -> Stream Bool
< (Const a
y) = Bool -> Stream Bool
forall a. Typed a => a -> Stream a
Const (a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.< a
y)
Stream a
x < Stream a
y                 = Op2 a a Bool -> Stream a -> Stream a -> Stream Bool
forall a b c.
(Typed a, Typed b, Typed c) =>
Op2 a b c -> Stream a -> Stream b -> Stream c
Op2 (Type a -> Op2 a a Bool
forall a. Ord a => Type a -> Op2 a a Bool
Core.Lt Type a
forall a. Typed a => Type a
typeOf) Stream a
x Stream a
y

-- | Compare two streams point-wise for order.
--
-- The output stream contains the value True at a point in time if the element
-- in the first stream is greater than the element in the second stream at that
-- point in time, and False otherwise.
(>) :: (P.Ord a, Typed a) => Stream a -> Stream a -> Stream Bool
(Const a
x) > :: Stream a -> Stream a -> Stream Bool
> (Const a
y) = Bool -> Stream Bool
forall a. Typed a => a -> Stream a
Const (a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.> a
y)
Stream a
x > Stream a
y                 = Op2 a a Bool -> Stream a -> Stream a -> Stream Bool
forall a b c.
(Typed a, Typed b, Typed c) =>
Op2 a b c -> Stream a -> Stream b -> Stream c
Op2 (Type a -> Op2 a a Bool
forall a. Ord a => Type a -> Op2 a a Bool
Core.Gt Type a
forall a. Typed a => Type a
typeOf) Stream a
x Stream a
y

--------------------------------------------------------------------------------