module Language.Haskell.Liquid.Bare.SymSort (
txRefSort
) where
import qualified Data.HashMap.Strict as M
import Prelude hiding (error)
import qualified GHC
import qualified Data.List as L
import Data.Maybe (fromMaybe)
import TyCon (TyCon)
import Language.Fixpoint.Misc (fst3, snd3)
import Language.Fixpoint.Types.Sorts
import Language.Fixpoint.Types (atLoc, meet, Reftable, Symbolic, Symbol)
import Language.Haskell.Liquid.Types.RefType (appRTyCon, strengthen)
import Language.Haskell.Liquid.Types
import Language.Haskell.Liquid.GHC.Misc (fSrcSpan)
import Language.Haskell.Liquid.Misc (safeZipWithError)
import Language.Haskell.Liquid.Bare.Env
txRefSort :: TCEnv -> TCEmb TyCon -> Located SpecType -> Located SpecType
txRefSort tyi tce t = atLoc t $ mapBot (addSymSort (fSrcSpan t) tce tyi) (val t)
addSymSort :: (PPrint t, Reftable t)
=> GHC.SrcSpan
-> M.HashMap TyCon FTycon
-> M.HashMap TyCon RTyCon
-> RType RTyCon RTyVar (UReft t)
-> RType RTyCon RTyVar (UReft t)
addSymSort sp tce tyi (RApp rc@(RTyCon {}) ts rs r)
= RApp rc ts (zipWith3 (addSymSortRef sp rc) pvs rargs [1..]) r'
where
rc' = appRTyCon tce tyi rc ts
pvs = rTyConPVs rc'
(rargs, rrest) = splitAt (length pvs) rs
r' = L.foldl' go r rrest
go r (RProp _ (RHole r')) = r' `meet` r
go r (RProp _ t' ) = let r' = fromMaybe mempty (stripRTypeBase t') in r `meet` r'
addSymSort _ _ _ t
= t
addSymSortRef :: (PPrint t, PPrint a, Symbolic tv, Reftable t)
=> GHC.SrcSpan
-> a
-> PVar (RType c tv ())
-> Ref (RType c tv ()) (RType c tv (UReft t))
-> Int
-> Ref (RType c tv ()) (RType c tv (UReft t))
addSymSortRef sp rc p r i
| isPropPV p
= addSymSortRef' sp rc i p r
| otherwise
= panic Nothing "addSymSortRef: malformed ref application"
addSymSortRef' :: (PPrint t, PPrint a, Symbolic tv, Reftable t)
=> GHC.SrcSpan
-> a
-> Int
-> PVar (RType c tv ())
-> Ref (RType c tv ()) (RType c tv (UReft t))
-> Ref (RType c tv ()) (RType c tv (UReft t))
addSymSortRef' _ _ _ p (RProp s (RVar v r)) | isDummy v
= RProp xs t
where
t = ofRSort (pvType p) `strengthen` r
xs = spliceArgs "addSymSortRef 1" s p
addSymSortRef' sp rc i p (RProp _ (RHole r@(MkUReft _ (Pr [up]) _)))
| length xs == length ts
= RProp xts (RHole r)
| otherwise
= uError $ ErrPartPred sp (pprint rc) (pprint $ pname up) i (length xs) (length ts)
where
xts = safeZipWithError "addSymSortRef'" xs ts
xs = snd3 <$> pargs up
ts = fst3 <$> pargs p
addSymSortRef' _ _ _ _ (RProp s (RHole r))
= RProp s (RHole r)
addSymSortRef' _ _ _ p (RProp s t)
= RProp xs t
where
xs = spliceArgs "addSymSortRef 2" s p
spliceArgs :: String -> [(Symbol, b)] -> PVar t -> [(Symbol, t)]
spliceArgs msg s p = go (fst <$> s) (pargs p)
where
go [] [] = []
go [] ((s,x,_):as) = (x, s):go [] as
go (x:xs) ((s,_,_):as) = (x,s):go xs as
go xs [] = panic Nothing $ "spliceArgs: " ++ msg ++ "on XS=" ++ show xs