{-# 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
showList :: [LiteralsOpt] -> ShowS
$cshowList :: [LiteralsOpt] -> ShowS
show :: LiteralsOpt -> String
$cshow :: LiteralsOpt -> String
showsPrec :: Int -> LiteralsOpt -> ShowS
$cshowsPrec :: Int -> LiteralsOpt -> ShowS
Show, LiteralsOpt -> LiteralsOpt -> Bool
(LiteralsOpt -> LiteralsOpt -> Bool)
-> (LiteralsOpt -> LiteralsOpt -> Bool) -> Eq LiteralsOpt
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LiteralsOpt -> LiteralsOpt -> Bool
$c/= :: LiteralsOpt -> LiteralsOpt -> Bool
== :: LiteralsOpt -> LiteralsOpt -> Bool
$c== :: 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
min :: LiteralsOpt -> LiteralsOpt -> LiteralsOpt
$cmin :: LiteralsOpt -> LiteralsOpt -> LiteralsOpt
max :: LiteralsOpt -> LiteralsOpt -> LiteralsOpt
$cmax :: LiteralsOpt -> LiteralsOpt -> LiteralsOpt
>= :: LiteralsOpt -> LiteralsOpt -> Bool
$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
compare :: LiteralsOpt -> LiteralsOpt -> Ordering
$ccompare :: LiteralsOpt -> LiteralsOpt -> Ordering
$cp1Ord :: Eq LiteralsOpt
Ord, Typeable LiteralsOpt
DataType
Constr
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 -> DataType
LiteralsOpt -> Constr
(forall b. Data b => b -> b) -> LiteralsOpt -> LiteralsOpt
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LiteralsOpt -> c LiteralsOpt
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c 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)
$cLitMixed :: Constr
$cLitUnitless :: Constr
$cLitPoly :: Constr
$tLiteralsOpt :: DataType
gmapMo :: (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
gmapMp :: (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
gmapM :: (forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> LiteralsOpt -> m LiteralsOpt
gmapQi :: Int -> (forall d. Data d => d -> u) -> LiteralsOpt -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> LiteralsOpt -> u
gmapQ :: (forall d. Data d => d -> u) -> LiteralsOpt -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> LiteralsOpt -> [u]
gmapQr :: (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
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LiteralsOpt -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> LiteralsOpt -> r
gmapT :: (forall b. Data b => b -> b) -> LiteralsOpt -> LiteralsOpt
$cgmapT :: (forall b. Data b => b -> b) -> LiteralsOpt -> LiteralsOpt
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LiteralsOpt)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LiteralsOpt)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c LiteralsOpt)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LiteralsOpt)
dataTypeOf :: LiteralsOpt -> DataType
$cdataTypeOf :: LiteralsOpt -> DataType
toConstr :: LiteralsOpt -> Constr
$ctoConstr :: LiteralsOpt -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LiteralsOpt
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LiteralsOpt
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LiteralsOpt -> c LiteralsOpt
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LiteralsOpt -> c LiteralsOpt
$cp1Data :: Typeable 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 (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
showList :: [UnitOpts] -> ShowS
$cshowList :: [UnitOpts] -> ShowS
show :: UnitOpts -> String
$cshow :: UnitOpts -> String
showsPrec :: Int -> UnitOpts -> ShowS
$cshowsPrec :: Int -> UnitOpts -> ShowS
Show, Typeable UnitOpts
DataType
Constr
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 -> DataType
UnitOpts -> Constr
(forall b. Data b => b -> b) -> UnitOpts -> UnitOpts
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitOpts -> c UnitOpts
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c 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)
$cUnitOpts :: Constr
$tUnitOpts :: DataType
gmapMo :: (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
gmapMp :: (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
gmapM :: (forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UnitOpts -> m UnitOpts
gmapQi :: Int -> (forall d. Data d => d -> u) -> UnitOpts -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UnitOpts -> u
gmapQ :: (forall d. Data d => d -> u) -> UnitOpts -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> UnitOpts -> [u]
gmapQr :: (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
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitOpts -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitOpts -> r
gmapT :: (forall b. Data b => b -> b) -> UnitOpts -> UnitOpts
$cgmapT :: (forall b. Data b => b -> b) -> UnitOpts -> UnitOpts
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitOpts)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitOpts)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c UnitOpts)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnitOpts)
dataTypeOf :: UnitOpts -> DataType
$cdataTypeOf :: UnitOpts -> DataType
toConstr :: UnitOpts -> Constr
$ctoConstr :: UnitOpts -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnitOpts
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnitOpts
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitOpts -> c UnitOpts
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitOpts -> c UnitOpts
$cp1Data :: Typeable UnitOpts
Data, UnitOpts -> UnitOpts -> Bool
(UnitOpts -> UnitOpts -> Bool)
-> (UnitOpts -> UnitOpts -> Bool) -> Eq UnitOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UnitOpts -> UnitOpts -> Bool
$c/= :: UnitOpts -> UnitOpts -> Bool
== :: UnitOpts -> UnitOpts -> Bool
$c== :: 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
min :: UnitOpts -> UnitOpts -> UnitOpts
$cmin :: UnitOpts -> UnitOpts -> UnitOpts
max :: UnitOpts -> UnitOpts -> UnitOpts
$cmax :: UnitOpts -> UnitOpts -> UnitOpts
>= :: UnitOpts -> UnitOpts -> Bool
$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
compare :: UnitOpts -> UnitOpts -> Ordering
$ccompare :: UnitOpts -> UnitOpts -> Ordering
$cp1Ord :: Eq 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
min :: NameParamKey -> NameParamKey -> NameParamKey
$cmin :: NameParamKey -> NameParamKey -> NameParamKey
max :: NameParamKey -> NameParamKey -> NameParamKey
$cmax :: NameParamKey -> NameParamKey -> NameParamKey
>= :: NameParamKey -> NameParamKey -> Bool
$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
compare :: NameParamKey -> NameParamKey -> Ordering
$ccompare :: NameParamKey -> NameParamKey -> Ordering
$cp1Ord :: Eq NameParamKey
Ord, NameParamKey -> NameParamKey -> Bool
(NameParamKey -> NameParamKey -> Bool)
-> (NameParamKey -> NameParamKey -> Bool) -> Eq NameParamKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NameParamKey -> NameParamKey -> Bool
$c/= :: NameParamKey -> NameParamKey -> Bool
== :: NameParamKey -> NameParamKey -> Bool
$c== :: 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
showList :: [NameParamKey] -> ShowS
$cshowList :: [NameParamKey] -> ShowS
show :: NameParamKey -> String
$cshow :: NameParamKey -> String
showsPrec :: Int -> NameParamKey -> ShowS
$cshowsPrec :: Int -> NameParamKey -> ShowS
Show, Typeable NameParamKey
DataType
Constr
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 -> DataType
NameParamKey -> Constr
(forall b. Data b => b -> b) -> NameParamKey -> NameParamKey
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NameParamKey -> c NameParamKey
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c 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)
$cNPKVariable :: Constr
$cNPKParam :: Constr
$tNameParamKey :: DataType
gmapMo :: (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
gmapMp :: (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
gmapM :: (forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NameParamKey -> m NameParamKey
gmapQi :: Int -> (forall d. Data d => d -> u) -> NameParamKey -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> NameParamKey -> u
gmapQ :: (forall d. Data d => d -> u) -> NameParamKey -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> NameParamKey -> [u]
gmapQr :: (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
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NameParamKey -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NameParamKey -> r
gmapT :: (forall b. Data b => b -> b) -> NameParamKey -> NameParamKey
$cgmapT :: (forall b. Data b => b -> b) -> NameParamKey -> NameParamKey
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c NameParamKey)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c NameParamKey)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c NameParamKey)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NameParamKey)
dataTypeOf :: NameParamKey -> DataType
$cdataTypeOf :: NameParamKey -> DataType
toConstr :: NameParamKey -> Constr
$ctoConstr :: NameParamKey -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NameParamKey
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NameParamKey
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NameParamKey -> c NameParamKey
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NameParamKey -> c NameParamKey
$cp1Data :: Typeable 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
$cto :: forall x. Rep NameParamKey x -> NameParamKey
$cfrom :: forall x. NameParamKey -> Rep NameParamKey x
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
showList :: [UnitState] -> ShowS
$cshowList :: [UnitState] -> ShowS
show :: UnitState -> String
$cshow :: UnitState -> String
showsPrec :: Int -> UnitState -> ShowS
$cshowsPrec :: Int -> UnitState -> ShowS
Show, Typeable UnitState
DataType
Constr
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 -> DataType
UnitState -> Constr
(forall b. Data b => b -> b) -> UnitState -> UnitState
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitState -> c UnitState
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c 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)
$cUnitState :: Constr
$tUnitState :: DataType
gmapMo :: (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
gmapMp :: (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
gmapM :: (forall d. Data d => d -> m d) -> UnitState -> m UnitState
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UnitState -> m UnitState
gmapQi :: Int -> (forall d. Data d => d -> u) -> UnitState -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UnitState -> u
gmapQ :: (forall d. Data d => d -> u) -> UnitState -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> UnitState -> [u]
gmapQr :: (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
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitState -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitState -> r
gmapT :: (forall b. Data b => b -> b) -> UnitState -> UnitState
$cgmapT :: (forall b. Data b => b -> b) -> UnitState -> UnitState
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitState)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UnitState)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c UnitState)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UnitState)
dataTypeOf :: UnitState -> DataType
$cdataTypeOf :: UnitState -> DataType
toConstr :: UnitState -> Constr
$ctoConstr :: UnitState -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnitState
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UnitState
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitState -> c UnitState
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitState -> c UnitState
$cp1Data :: Typeable 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