{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric      #-}

module Camfort.Specification.Units.MonadTypes where

import           Camfort.Analysis
import           Camfort.Analysis.Annotations (Annotation)
import           Camfort.Specification.Units.Annotation (UA)
import           Camfort.Specification.Units.Environment (Constraints, PP, UnitInfo, VV)
import           Control.Monad.Reader
import           Control.Monad.State.Strict
import           Data.Binary (Binary)
import           Data.Char (toLower)
import           Data.Data (Data)
import qualified Data.IntMap.Strict as IM
import           Data.List (find, isPrefixOf)
import qualified Data.Map.Strict as M
import qualified Data.Set as S
import           Data.Typeable (Typeable)
import           GHC.Generics (Generic)
import qualified Language.Fortran.AST as F

--------------------------------------------------------------------------------
--  Environment
--------------------------------------------------------------------------------

-- | Some options about how to handle literals.
data LiteralsOpt
  = LitPoly     -- ^ All literals are polymorphic.
  | LitUnitless -- ^ All literals are unitless.
  | LitMixed    -- ^ The literal "0" or "0.0" is fully parametric
                -- polymorphic. All other literals are monomorphic,
                -- possibly unitless.
  deriving (Int -> LiteralsOpt -> ShowS
[LiteralsOpt] -> ShowS
LiteralsOpt -> String
(Int -> LiteralsOpt -> ShowS)
-> (LiteralsOpt -> String)
-> ([LiteralsOpt] -> ShowS)
-> Show LiteralsOpt
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LiteralsOpt -> ShowS
showsPrec :: Int -> LiteralsOpt -> ShowS
$cshow :: LiteralsOpt -> String
show :: LiteralsOpt -> String
$cshowList :: [LiteralsOpt] -> ShowS
showList :: [LiteralsOpt] -> ShowS
Show, LiteralsOpt -> LiteralsOpt -> Bool
(LiteralsOpt -> LiteralsOpt -> Bool)
-> (LiteralsOpt -> LiteralsOpt -> Bool) -> Eq LiteralsOpt
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LiteralsOpt -> LiteralsOpt -> Bool
== :: LiteralsOpt -> LiteralsOpt -> Bool
$c/= :: LiteralsOpt -> LiteralsOpt -> Bool
/= :: LiteralsOpt -> LiteralsOpt -> Bool
Eq, Eq LiteralsOpt
Eq LiteralsOpt
-> (LiteralsOpt -> LiteralsOpt -> Ordering)
-> (LiteralsOpt -> LiteralsOpt -> Bool)
-> (LiteralsOpt -> LiteralsOpt -> Bool)
-> (LiteralsOpt -> LiteralsOpt -> Bool)
-> (LiteralsOpt -> LiteralsOpt -> Bool)
-> (LiteralsOpt -> LiteralsOpt -> LiteralsOpt)
-> (LiteralsOpt -> LiteralsOpt -> LiteralsOpt)
-> Ord LiteralsOpt
LiteralsOpt -> LiteralsOpt -> Bool
LiteralsOpt -> LiteralsOpt -> Ordering
LiteralsOpt -> LiteralsOpt -> LiteralsOpt
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: LiteralsOpt -> LiteralsOpt -> Ordering
compare :: LiteralsOpt -> LiteralsOpt -> Ordering
$c< :: LiteralsOpt -> LiteralsOpt -> Bool
< :: LiteralsOpt -> LiteralsOpt -> Bool
$c<= :: LiteralsOpt -> LiteralsOpt -> Bool
<= :: LiteralsOpt -> LiteralsOpt -> Bool
$c> :: LiteralsOpt -> LiteralsOpt -> Bool
> :: LiteralsOpt -> LiteralsOpt -> Bool
$c>= :: LiteralsOpt -> LiteralsOpt -> Bool
>= :: LiteralsOpt -> LiteralsOpt -> Bool
$cmax :: LiteralsOpt -> LiteralsOpt -> LiteralsOpt
max :: LiteralsOpt -> LiteralsOpt -> LiteralsOpt
$cmin :: LiteralsOpt -> LiteralsOpt -> LiteralsOpt
min :: LiteralsOpt -> LiteralsOpt -> LiteralsOpt
Ord, Typeable LiteralsOpt
Typeable LiteralsOpt
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> LiteralsOpt -> c LiteralsOpt)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c LiteralsOpt)
-> (LiteralsOpt -> Constr)
-> (LiteralsOpt -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c LiteralsOpt))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c LiteralsOpt))
-> ((forall b. Data b => b -> b) -> LiteralsOpt -> LiteralsOpt)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> LiteralsOpt -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> LiteralsOpt -> r)
-> (forall u. (forall d. Data d => d -> u) -> LiteralsOpt -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> LiteralsOpt -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt)
-> Data LiteralsOpt
LiteralsOpt -> Constr
LiteralsOpt -> DataType
(forall b. Data b => b -> b) -> LiteralsOpt -> LiteralsOpt
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> LiteralsOpt -> u
forall u. (forall d. Data d => d -> u) -> LiteralsOpt -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LiteralsOpt -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LiteralsOpt -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LiteralsOpt
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LiteralsOpt -> c LiteralsOpt
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LiteralsOpt)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LiteralsOpt)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LiteralsOpt -> c LiteralsOpt
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LiteralsOpt -> c LiteralsOpt
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LiteralsOpt
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LiteralsOpt
$ctoConstr :: LiteralsOpt -> Constr
toConstr :: LiteralsOpt -> Constr
$cdataTypeOf :: LiteralsOpt -> DataType
dataTypeOf :: LiteralsOpt -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LiteralsOpt)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LiteralsOpt)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LiteralsOpt)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LiteralsOpt)
$cgmapT :: (forall b. Data b => b -> b) -> LiteralsOpt -> LiteralsOpt
gmapT :: (forall b. Data b => b -> b) -> LiteralsOpt -> LiteralsOpt
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LiteralsOpt -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LiteralsOpt -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LiteralsOpt -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LiteralsOpt -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> LiteralsOpt -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> LiteralsOpt -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> LiteralsOpt -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> LiteralsOpt -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt
Data)

instance Read LiteralsOpt where
  readsPrec :: Int -> ReadS LiteralsOpt
readsPrec Int
_ String
s = case ((String, LiteralsOpt) -> Bool)
-> [(String, LiteralsOpt)] -> Maybe (String, LiteralsOpt)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
s) (String -> Bool)
-> ((String, LiteralsOpt) -> String)
-> (String, LiteralsOpt)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, LiteralsOpt) -> String
forall a b. (a, b) -> a
fst) [(String, LiteralsOpt)]
ms of
                    Just (String
str, LiteralsOpt
con) -> [(LiteralsOpt
con, Int -> ShowS
forall a. Int -> [a] -> [a]
drop (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str) String
s)]
                    Maybe (String, LiteralsOpt)
Nothing         -> []
    where
      ms :: [(String, LiteralsOpt)]
ms = [ (String
"poly", LiteralsOpt
LitPoly), (String
"unitless", LiteralsOpt
LitUnitless), (String
"mixed", LiteralsOpt
LitMixed)
           , (String
"litpoly", LiteralsOpt
LitPoly), (String
"litunitless", LiteralsOpt
LitUnitless), (String
"litmixed", LiteralsOpt
LitMixed) ]

-- | Options for the unit solver
data UnitOpts = UnitOpts
  { UnitOpts -> LiteralsOpt
uoLiterals :: LiteralsOpt               -- ^ how to handle literals
  }
  deriving (Int -> UnitOpts -> ShowS
[UnitOpts] -> ShowS
UnitOpts -> String
(Int -> UnitOpts -> ShowS)
-> (UnitOpts -> String) -> ([UnitOpts] -> ShowS) -> Show UnitOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> UnitOpts -> ShowS
showsPrec :: Int -> UnitOpts -> ShowS
$cshow :: UnitOpts -> String
show :: UnitOpts -> String
$cshowList :: [UnitOpts] -> ShowS
showList :: [UnitOpts] -> ShowS
Show, Typeable UnitOpts
Typeable UnitOpts
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> UnitOpts -> c UnitOpts)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c UnitOpts)
-> (UnitOpts -> Constr)
-> (UnitOpts -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c UnitOpts))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitOpts))
-> ((forall b. Data b => b -> b) -> UnitOpts -> UnitOpts)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> UnitOpts -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> UnitOpts -> r)
-> (forall u. (forall d. Data d => d -> u) -> UnitOpts -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> UnitOpts -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts)
-> Data UnitOpts
UnitOpts -> Constr
UnitOpts -> DataType
(forall b. Data b => b -> b) -> UnitOpts -> UnitOpts
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> UnitOpts -> u
forall u. (forall d. Data d => d -> u) -> UnitOpts -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitOpts -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnitOpts -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnitOpts
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitOpts -> c UnitOpts
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnitOpts)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitOpts)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitOpts -> c UnitOpts
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitOpts -> c UnitOpts
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnitOpts
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnitOpts
$ctoConstr :: UnitOpts -> Constr
toConstr :: UnitOpts -> Constr
$cdataTypeOf :: UnitOpts -> DataType
dataTypeOf :: UnitOpts -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnitOpts)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnitOpts)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitOpts)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitOpts)
$cgmapT :: (forall b. Data b => b -> b) -> UnitOpts -> UnitOpts
gmapT :: (forall b. Data b => b -> b) -> UnitOpts -> UnitOpts
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitOpts -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitOpts -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnitOpts -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnitOpts -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> UnitOpts -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> UnitOpts -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UnitOpts -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UnitOpts -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts
Data, UnitOpts -> UnitOpts -> Bool
(UnitOpts -> UnitOpts -> Bool)
-> (UnitOpts -> UnitOpts -> Bool) -> Eq UnitOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UnitOpts -> UnitOpts -> Bool
== :: UnitOpts -> UnitOpts -> Bool
$c/= :: UnitOpts -> UnitOpts -> Bool
/= :: UnitOpts -> UnitOpts -> Bool
Eq, Eq UnitOpts
Eq UnitOpts
-> (UnitOpts -> UnitOpts -> Ordering)
-> (UnitOpts -> UnitOpts -> Bool)
-> (UnitOpts -> UnitOpts -> Bool)
-> (UnitOpts -> UnitOpts -> Bool)
-> (UnitOpts -> UnitOpts -> Bool)
-> (UnitOpts -> UnitOpts -> UnitOpts)
-> (UnitOpts -> UnitOpts -> UnitOpts)
-> Ord UnitOpts
UnitOpts -> UnitOpts -> Bool
UnitOpts -> UnitOpts -> Ordering
UnitOpts -> UnitOpts -> UnitOpts
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: UnitOpts -> UnitOpts -> Ordering
compare :: UnitOpts -> UnitOpts -> Ordering
$c< :: UnitOpts -> UnitOpts -> Bool
< :: UnitOpts -> UnitOpts -> Bool
$c<= :: UnitOpts -> UnitOpts -> Bool
<= :: UnitOpts -> UnitOpts -> Bool
$c> :: UnitOpts -> UnitOpts -> Bool
> :: UnitOpts -> UnitOpts -> Bool
$c>= :: UnitOpts -> UnitOpts -> Bool
>= :: UnitOpts -> UnitOpts -> Bool
$cmax :: UnitOpts -> UnitOpts -> UnitOpts
max :: UnitOpts -> UnitOpts -> UnitOpts
$cmin :: UnitOpts -> UnitOpts -> UnitOpts
min :: UnitOpts -> UnitOpts -> UnitOpts
Ord)

data UnitEnv = UnitEnv
  { UnitEnv -> UnitOpts
unitOpts     :: UnitOpts
  , UnitEnv -> ProgramFile Annotation
unitProgramFile :: F.ProgramFile Annotation
  }

--------------------------------------------------------------------------------
--  State
--------------------------------------------------------------------------------

-- | Function/subroutine name -> associated, parametric polymorphic constraints
type TemplateMap = M.Map F.Name Constraints

-- | Things that can be exported from modules
data NameParamKey
  = NPKParam PP Int     -- ^ Function/subroutine name, position of parameter
  | NPKVariable VV      -- ^ variable
  deriving (Eq NameParamKey
Eq NameParamKey
-> (NameParamKey -> NameParamKey -> Ordering)
-> (NameParamKey -> NameParamKey -> Bool)
-> (NameParamKey -> NameParamKey -> Bool)
-> (NameParamKey -> NameParamKey -> Bool)
-> (NameParamKey -> NameParamKey -> Bool)
-> (NameParamKey -> NameParamKey -> NameParamKey)
-> (NameParamKey -> NameParamKey -> NameParamKey)
-> Ord NameParamKey
NameParamKey -> NameParamKey -> Bool
NameParamKey -> NameParamKey -> Ordering
NameParamKey -> NameParamKey -> NameParamKey
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: NameParamKey -> NameParamKey -> Ordering
compare :: NameParamKey -> NameParamKey -> Ordering
$c< :: NameParamKey -> NameParamKey -> Bool
< :: NameParamKey -> NameParamKey -> Bool
$c<= :: NameParamKey -> NameParamKey -> Bool
<= :: NameParamKey -> NameParamKey -> Bool
$c> :: NameParamKey -> NameParamKey -> Bool
> :: NameParamKey -> NameParamKey -> Bool
$c>= :: NameParamKey -> NameParamKey -> Bool
>= :: NameParamKey -> NameParamKey -> Bool
$cmax :: NameParamKey -> NameParamKey -> NameParamKey
max :: NameParamKey -> NameParamKey -> NameParamKey
$cmin :: NameParamKey -> NameParamKey -> NameParamKey
min :: NameParamKey -> NameParamKey -> NameParamKey
Ord, NameParamKey -> NameParamKey -> Bool
(NameParamKey -> NameParamKey -> Bool)
-> (NameParamKey -> NameParamKey -> Bool) -> Eq NameParamKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NameParamKey -> NameParamKey -> Bool
== :: NameParamKey -> NameParamKey -> Bool
$c/= :: NameParamKey -> NameParamKey -> Bool
/= :: NameParamKey -> NameParamKey -> Bool
Eq, Int -> NameParamKey -> ShowS
[NameParamKey] -> ShowS
NameParamKey -> String
(Int -> NameParamKey -> ShowS)
-> (NameParamKey -> String)
-> ([NameParamKey] -> ShowS)
-> Show NameParamKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NameParamKey -> ShowS
showsPrec :: Int -> NameParamKey -> ShowS
$cshow :: NameParamKey -> String
show :: NameParamKey -> String
$cshowList :: [NameParamKey] -> ShowS
showList :: [NameParamKey] -> ShowS
Show, Typeable NameParamKey
Typeable NameParamKey
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> NameParamKey -> c NameParamKey)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c NameParamKey)
-> (NameParamKey -> Constr)
-> (NameParamKey -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c NameParamKey))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c NameParamKey))
-> ((forall b. Data b => b -> b) -> NameParamKey -> NameParamKey)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> NameParamKey -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> NameParamKey -> r)
-> (forall u. (forall d. Data d => d -> u) -> NameParamKey -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> NameParamKey -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey)
-> Data NameParamKey
NameParamKey -> Constr
NameParamKey -> DataType
(forall b. Data b => b -> b) -> NameParamKey -> NameParamKey
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> NameParamKey -> u
forall u. (forall d. Data d => d -> u) -> NameParamKey -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NameParamKey -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NameParamKey -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NameParamKey
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NameParamKey -> c NameParamKey
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NameParamKey)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c NameParamKey)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NameParamKey -> c NameParamKey
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NameParamKey -> c NameParamKey
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NameParamKey
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NameParamKey
$ctoConstr :: NameParamKey -> Constr
toConstr :: NameParamKey -> Constr
$cdataTypeOf :: NameParamKey -> DataType
dataTypeOf :: NameParamKey -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NameParamKey)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NameParamKey)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c NameParamKey)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c NameParamKey)
$cgmapT :: (forall b. Data b => b -> b) -> NameParamKey -> NameParamKey
gmapT :: (forall b. Data b => b -> b) -> NameParamKey -> NameParamKey
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NameParamKey -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NameParamKey -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NameParamKey -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NameParamKey -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> NameParamKey -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> NameParamKey -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> NameParamKey -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> NameParamKey -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey
Data, Typeable, (forall x. NameParamKey -> Rep NameParamKey x)
-> (forall x. Rep NameParamKey x -> NameParamKey)
-> Generic NameParamKey
forall x. Rep NameParamKey x -> NameParamKey
forall x. NameParamKey -> Rep NameParamKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NameParamKey -> Rep NameParamKey x
from :: forall x. NameParamKey -> Rep NameParamKey x
$cto :: forall x. Rep NameParamKey x -> NameParamKey
to :: forall x. Rep NameParamKey x -> NameParamKey
Generic)

instance Binary NameParamKey

-- | mapped to a list of units (to be multiplied together)
type NameParamMap = M.Map F.ProgramUnitName (M.Map NameParamKey [UnitInfo])

-- | Variable => unit
type VarUnitMap   = M.Map VV UnitInfo
-- | Set of variables given explicit unit annotations
type GivenVarSet  = S.Set F.Name
-- | Alias name => definition
type UnitAliasMap = M.Map String UnitInfo
-- | Map of CallId to CallId
type CallIdMap    = IM.IntMap Int

-- | Working state for the monad
data UnitState = UnitState
  { UnitState -> ProgramFile UA
usProgramFile  :: F.ProgramFile UA
  , UnitState -> VarUnitMap
usVarUnitMap   :: VarUnitMap
  , UnitState -> GivenVarSet
usGivenVarSet  :: GivenVarSet
  , UnitState -> UnitAliasMap
usUnitAliasMap :: UnitAliasMap
  , UnitState -> TemplateMap
usTemplateMap  :: TemplateMap
  , UnitState -> NameParamMap
usNameParamMap :: NameParamMap
  , UnitState -> CallIdMap
usCallIdRemap  :: CallIdMap
    -- | Next number to returned by 'freshId'.
  , UnitState -> Int
usNextUnique   :: Int
  , UnitState -> Constraints
usConstraints  :: Constraints }
  deriving (Int -> UnitState -> ShowS
[UnitState] -> ShowS
UnitState -> String
(Int -> UnitState -> ShowS)
-> (UnitState -> String)
-> ([UnitState] -> ShowS)
-> Show UnitState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> UnitState -> ShowS
showsPrec :: Int -> UnitState -> ShowS
$cshow :: UnitState -> String
show :: UnitState -> String
$cshowList :: [UnitState] -> ShowS
showList :: [UnitState] -> ShowS
Show, Typeable UnitState
Typeable UnitState
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> UnitState -> c UnitState)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c UnitState)
-> (UnitState -> Constr)
-> (UnitState -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c UnitState))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitState))
-> ((forall b. Data b => b -> b) -> UnitState -> UnitState)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> UnitState -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> UnitState -> r)
-> (forall u. (forall d. Data d => d -> u) -> UnitState -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> UnitState -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> UnitState -> m UnitState)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UnitState -> m UnitState)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UnitState -> m UnitState)
-> Data UnitState
UnitState -> Constr
UnitState -> DataType
(forall b. Data b => b -> b) -> UnitState -> UnitState
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> UnitState -> u
forall u. (forall d. Data d => d -> u) -> UnitState -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitState -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnitState -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UnitState -> m UnitState
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnitState -> m UnitState
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnitState
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitState -> c UnitState
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnitState)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitState)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitState -> c UnitState
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitState -> c UnitState
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnitState
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnitState
$ctoConstr :: UnitState -> Constr
toConstr :: UnitState -> Constr
$cdataTypeOf :: UnitState -> DataType
dataTypeOf :: UnitState -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnitState)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnitState)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitState)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitState)
$cgmapT :: (forall b. Data b => b -> b) -> UnitState -> UnitState
gmapT :: (forall b. Data b => b -> b) -> UnitState -> UnitState
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitState -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitState -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnitState -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnitState -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> UnitState -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> UnitState -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UnitState -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UnitState -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UnitState -> m UnitState
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UnitState -> m UnitState
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnitState -> m UnitState
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnitState -> m UnitState
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnitState -> m UnitState
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UnitState -> m UnitState
Data)

--------------------------------------------------------------------------------
--  Monads
--------------------------------------------------------------------------------

-- | Analysis with access to 'UnitEnv' information.
type UnitAnalysis = ReaderT UnitEnv (AnalysisT () () IO)

-- | UnitSolvers are analyses annotated with unit information.
type UnitSolver = StateT UnitState UnitAnalysis