liquidhaskell-0.1: Language/Haskell/Liquid/Tidy.hs
module Language.Haskell.Liquid.Tidy (tidySpecType) where
import Outputable (showPpr) -- hiding (empty)
import Control.Applicative
import qualified Data.HashMap.Strict as M
import qualified Data.HashSet as S
import qualified Data.List as L
import Language.Fixpoint.Misc
import Language.Fixpoint.Names (symSepName)
import Language.Fixpoint.Types
import Language.Haskell.Liquid.GhcMisc (stringTyVar)
import Language.Haskell.Liquid.Types
import Language.Haskell.Liquid.RefType
---------------------------------------------------------------------
---------- SYB Magic: Cleaning Reftypes Up Before Rendering ---------
---------------------------------------------------------------------
tidySpecType :: SpecType -> SpecType
tidySpecType = tidyDSymbols
. tidySymbols
. tidyLocalRefas
. tidyFunBinds
. tidyTyVars
tidySymbols :: SpecType -> SpecType
tidySymbols t = substa dropSuffix $ mapBind dropBind t
where
xs = S.fromList (syms t)
dropBind x = if x `S.member` xs then dropSuffix x else nonSymbol
dropSuffix = S . takeWhile (/= symSepName) . symbolString
tidyLocalRefas :: SpecType -> SpecType
tidyLocalRefas = mapReft (txReft)
where
txReft (U (Reft (v,ras)) p) = U (Reft (v, dropLocals ras)) p
dropLocals = filter (not . any isTmp . syms) . flattenRefas
isTmp x = any (`L.isPrefixOf` (symbolString x)) [anfPrefix, "ds_"]
isTmpSymbol x = any (`L.isPrefixOf` str) [anfPrefix, tempPrefix, "ds_"]
where str = symbolString x
tidyDSymbols :: SpecType -> SpecType
tidyDSymbols t = mapBind tx $ substa tx t
where
tx = bindersTx [x | x <- syms t, isTmp x]
isTmp = (tempPrefix `L.isPrefixOf`) . symbolString
tidyFunBinds :: SpecType -> SpecType
tidyFunBinds t = mapBind tx $ substa tx t
where
tx = bindersTx $ filter isTmpSymbol $ funBinds t
tidyTyVars :: SpecType -> SpecType
tidyTyVars t = subsTyVarsAll αβs t
where
-- zz = [(a, b) | (a, _, (RVar b _)) <- αβs]
αβs = zipWith (\α β -> (α, toRSort β, β)) αs βs
αs = L.nub (tyVars t)
βs = map (rVar . stringTyVar) pool
pool = [[c] | c <- ['a'..'z']] ++ [ "t" ++ show i | i <- [1..]]
bindersTx ds = \y -> M.lookupDefault y y m
where
m = M.fromList $ zip ds $ var <$> [1..]
var = stringSymbol . ('x' :) . show
tyVars (RAllP _ t) = tyVars t
tyVars (RAllT α t) = α : tyVars t
tyVars (RFun _ t t' _) = tyVars t ++ tyVars t'
tyVars (RAppTy t t' _) = tyVars t ++ tyVars t'
tyVars (RApp _ ts _ _) = concatMap tyVars ts
tyVars (RCls _ ts) = concatMap tyVars ts
tyVars (RVar α _) = [α]
tyVars (RAllE _ _ t) = tyVars t
tyVars (REx _ _ t) = tyVars t
tyVars (RExprArg _) = []
tyVars (ROth _) = []
subsTyVarsAll ats = go
where
abm = M.fromList [(a, b) | (a, _, (RVar b _)) <- ats]
go (RAllT a t) = RAllT (M.lookupDefault a a abm) (go t)
go t = subsTyVars_meet ats t
funBinds (RAllT _ t) = funBinds t
funBinds (RAllP _ t) = funBinds t
funBinds (RFun b t1 t2 _) = b : funBinds t1 ++ funBinds t2
funBinds (RApp _ ts _ _) = concatMap funBinds ts
funBinds (RCls _ ts) = concatMap funBinds ts
funBinds (RAllE b t1 t2) = b : funBinds t1 ++ funBinds t2
funBinds (REx b t1 t2) = b : funBinds t1 ++ funBinds t2
funBinds (RVar _ _) = []
funBinds (ROth _) = []
funBinds (RAppTy t1 t2 r) = funBinds t1 ++ funBinds t2
funBinds (RExprArg e) = []