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

{-# LANGUAGE ExistentialQuantification, GADTs #-}
{-# LANGUAGE Safe #-}

-- | Types suported by the modular transition systems.
module Copilot.Theorem.TransSys.Type
  ( Type (..)
  , U (..)
  , U2 (..)
  ) where

import Copilot.Core.Type.Equality

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

-- | A type at both value and type level.
--
-- Real numbers are mapped to 'Double's.
data Type a where
  Bool    :: Type Bool
  Integer :: Type Integer
  Real    :: Type Double

-- | Proofs of type equality.
instance EqualType Type where
  Bool    =~= :: Type a -> Type b -> Maybe (Equal a b)
=~= Bool     = Equal a a -> Maybe (Equal a a)
forall a. a -> Maybe a
Just Equal a a
forall a. Equal a a
Refl
  Integer =~= Integer  = Equal a a -> Maybe (Equal a a)
forall a. a -> Maybe a
Just Equal a a
forall a. Equal a a
Refl
  Real    =~= Real     = Equal a a -> Maybe (Equal a a)
forall a. a -> Maybe a
Just Equal a a
forall a. Equal a a
Refl
  _       =~= _        = Maybe (Equal a b)
forall a. Maybe a
Nothing

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

-- | Unknown types.
--
-- For instance, 'U Expr' is the type of an expression of unknown type
data U f = forall t . U (f t)
data U2 f g = forall t . U2 (f t) (g t)

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

instance Show (Type t) where
  show :: Type t -> String
show Integer = "Int"
  show Bool    = "Bool"
  show Real    = "Real"

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