module UHC.Light.Compiler.Gam.Quantify
( tyKiGamQuantifyWithVarMp
, valGamQuantify
, valGamQuantifyWithVarMp
, quantifyPolGam )
where
import UHC.Light.Compiler.Base.Common
import UHC.Light.Compiler.Opts.Base
import UHC.Light.Compiler.Ty
import UHC.Light.Compiler.VarMp
import qualified Data.Set as Set
import UHC.Light.Compiler.Ty.Trf.Quantify
import UHC.Light.Compiler.VarMp
import UHC.Light.Compiler.Substitutable
import UHC.Light.Compiler.Gam
import UHC.Light.Compiler.Gam.ValGam
import UHC.Light.Compiler.Gam.TyKiGam
import UHC.Light.Compiler.Ty.Trf.MergePreds
import UHC.Light.Compiler.Gam.PolGam
valGamQuantify :: TyVarIdS -> [PredOcc] -> ValGam -> (ValGam,TQOGam)
valGamQuantify globTvS prL g
= let g' = gamMapElts (\vgi -> let tmpo = tyMergePreds prL (vgiTy vgi)
ty = valTyQuantify (const kiStar) (`Set.member` globTvS) (tmpoTy tmpo)
in (vgi {vgiTy = ty},tmpo {tmpoTy = ty})
) g
in gamUnzip g'
valGamQuantifyWithVarMp :: Bool -> TyKiGam -> VarMp -> VarMp -> TyVarIdS -> [PredOcc] -> ValGam -> (ValGam,VarMp,(VarMp,TQOGam))
valGamQuantifyWithVarMp doQuant tyKiGam tvKiVarMp gamVarMp globTvS prL valGam
= valGamDoWithVarMp quant gamVarMp (emptyVarMp,emptyGam) valGam
where quant nm (t,tyCycVarMp) newVarMp (cycVarMp,tmpoGam)
= ( ty
, newVarMp
, (tyCycVarMp `varUpd` cycVarMp
, gamAdd nm (tmpo {tmpoTy = ty}) tmpoGam
) )
where tmpo = tyMergePreds prL t
ty | doQuant = valTyQuantify (tvarKi tyKiGam tvKiVarMp gamVarMp) (`Set.member` globTvS) (tmpoTy tmpo)
| otherwise = tmpoTy tmpo
tyKiGamQuantifyWithVarMp :: EHCOpts -> VarMp -> TyVarIdS -> TyKiGam -> (TyKiGam,VarMp,VarMp)
tyKiGamQuantifyWithVarMp opts gamVarMp globTvS gam
= tyKiGamDoWithVarMp
(\_ (t,tyCycMp) m cycMp -> (tyKiQuantify (ehcOptPolyKinds opts) (`Set.member` globTvS) t,m,tyCycMp `varUpd` cycMp))
gamVarMp emptyVarMp gam
quantifyPolGam :: PolGam -> PolGam
quantifyPolGam gam
= let fvs = varFree gam
notElemFtvs tv = not $ elem tv fvs
in mapPolGam (tyQuantify notElemFtvs) gam