Agda-2.6.2: src/full/Agda/TypeChecking/ReconstructParameters.hs
-- | Reconstruct dropped parameters from constructors. Used by
-- with-abstraction to avoid ill-typed abstractions (#745). Note that the
-- term is invalid after parameter reconstruction. Parameters need to be
-- dropped again before using it.
module Agda.TypeChecking.ReconstructParameters where
import Data.Maybe
import Agda.Syntax.Common
import Agda.Syntax.Internal
import Agda.Syntax.Internal.Generic
import Agda.TypeChecking.Monad
import Agda.TypeChecking.CheckInternal
import Agda.TypeChecking.Irrelevance
import Agda.TypeChecking.ProjectionLike
import Agda.TypeChecking.Substitute
import Agda.TypeChecking.Reduce
import Agda.TypeChecking.Telescope
import Agda.TypeChecking.Pretty
import Agda.TypeChecking.Records
import Agda.TypeChecking.Datatypes
import Agda.Utils.Size
import Agda.Utils.Either
import Agda.Utils.Impossible
reconstructParametersInType :: Type -> TCM Type
reconstructParametersInType = reconstructParametersInType' defaultAction
reconstructParametersInType' :: Action TCM -> Type -> TCM Type
reconstructParametersInType' act a =
traverse (reconstructParameters' act (sort $ getSort a)) a
reconstructParametersInTel :: Telescope -> TCM Telescope
reconstructParametersInTel EmptyTel = return EmptyTel
reconstructParametersInTel (ExtendTel a tel) = do
ar <- reconstructParametersInType (unDom a)
addContext (absName tel, a) $
ExtendTel (ar <$ a) <$> traverse reconstructParametersInTel tel
reconstructParametersInEqView :: EqualityView -> TCM EqualityView
reconstructParametersInEqView (EqualityType s eq l a u v) =
EqualityType s eq l <$> traverse (reconstructParameters $ sort s) a
<*> traverse (reconstructParameters $ El s $ unArg a) u
<*> traverse (reconstructParameters $ El s $ unArg a) v
reconstructParametersInEqView (OtherType a) = OtherType <$> reconstructParametersInType a
reconstructParametersInEqView (IdiomType a) = IdiomType <$> reconstructParametersInType a
reconstructParameters :: Type -> Term -> TCM Term
reconstructParameters = reconstructParameters' defaultAction
reconstructParameters' :: Action TCM -> Type -> Term -> TCM Term
reconstructParameters' act a v = do
reportSDoc "tc.with.reconstruct" 30 $
sep [ "reconstructing parameters in"
, nest 2 $ sep [ prettyTCM v <+> ":", nest 2 $ prettyTCM a ] ]
v <- checkInternal' reconstructAction v CmpLeq a
reportSDoc "tc.with.reconstruct" 30 $
nest 2 $ "-->" <+> prettyTCM v
return v
where
reconstructAction = defaultAction{ postAction = reconstruct }
reconstruct a v = do
reportSDoc "tc.with.reconstruct" 30 $
sep [ "reconstructing in"
, nest 2 $ sep [ prettyTCM v <+> ":", nest 2 $ prettyTCM a ] ]
case unSpine v of
Con h ci vs -> do
hh <- fromRight __IMPOSSIBLE__ <$> getConHead (conName h)
TelV tel a <- telView a
let under = size tel -- under-applied when under > 0
reportSDoc "tc.reconstruct" 50 $
sep [ "reconstructing"
, nest 2 $ sep [ prettyTCM v <+> ":"
, nest 2 $ prettyTCM a ] ]
case (unEl a) of
Def d es -> do
Just n <- defParameters <$> getConstInfo d
let prePs = applySubst (strengthenS impossible under) . take n $ es
let hiddenPs = map (Apply . hideAndRelParams) $ fromMaybe __IMPOSSIBLE__ $
allApplyElims prePs
reportSDoc "tc.reconstruct" 50 $ "The hiddenPs are" <+> pretty hiddenPs
tyCon <- defType <$> getConstInfo (conName hh)
reportSDoc "tc.reconstruct" 50 $ "Here we start infering spine"
((_,Con hh ci psAfterAct),_) <- inferSpine' act tyCon (Con hh ci []) (Con hh ci []) hiddenPs
((_,conWithPars),_) <- inferSpine' reconstructAction tyCon (Con hh ci []) (Con hh ci []) psAfterAct
reportSDoc "tc.reconstruct" 50 $ "The spine has been inferred:" <+> pretty conWithPars
return $ applyWithoutReversing conWithPars vs
_ -> __IMPOSSIBLE__
_ -> do
vv <- elimView EvenLone v
unSpineAndReconstruct a vv
unSpineAndReconstruct :: Type -> Term -> TCM Term
unSpineAndReconstruct a v =
case v of
Var i vs -> do
ty <- typeOfBV i
ctx <- getContextTelescope
reportSDoc "tc.reconstruct" 50 $ (text ("Var case "++(show i)++" with context")) <+> prettyTCM ctx
loop ty (Var i) vs
Def nam vs -> do
reportSDoc "tc.reconstruct" 50 $ "Def case"
ty <- defType <$> getConstInfo nam
loop ty (Def nam) vs
MetaV id vs -> do
reportSDoc "tc.reconstruct" 50 $ "MetaVar case"
ty <- getMetaType id
loop ty (MetaV id) vs
_ -> do
reportSDoc "tc.reconstruct" 50 $ "Another case" <+> pretty v
return v
-- @loop ty f vs@ where @ty@ is the type of @f []@ and vs are valid
-- arguments to something of type @ty@
loop :: Type -> (Elims -> Term) -> Elims -> TCM Term
loop ty f = loop' ty f f
-- We duplicate @f@ because we don't want the parameters to be reconstructed in
-- type, since it would cause type-checking error when running @checkInternal'@.
-- The first one @fTe@ is for term, the other one @fTy@ for type.
loop' ty fTe _ [] = do
reportSDoc "tc.reconstruct" 50 $ "Loop ended" <+> (pretty $ fTe [])
return $ fTe []
loop' ty fTe fTy (Apply u:es) = do
reportSDoc "tc.reconstruct" 50 $ "The type before app is:" <+> pretty ty
reportSDoc "tc.reconstruct" 50 $ "The term before app is:" <+> prettyTCM (fTe [])
uu <- dropParameters u
reportSDoc "tc.reconstruct" 50 $ "The app is:" <+> pretty uu
ty' <- piApplyM ty uu
reportSDoc "tc.reconstruct" 50 $ "The type after app is:" <+> pretty ty'
loop' ty' (fTe . (Apply u :)) (fTy . (Apply uu :)) es
loop' ty fTe fTy (Proj o p:es) = do
reportSDoc "tc.reconstruct" 50 $ "The type is:" <+> pretty ty
reportSDoc "tc.reconstruct" 50 $ "The term is:" <+> pretty (fTe [])
reportSDoc "tc.reconstruct" 50 $ "The proj is:" <+> prettyTCM p
ty' <- reduce ty
case unEl ty' of
Def r pars -> do
~(Just (El _ (Pi _ b))) <- getDefType p ty'
tyProj <- defType <$> getConstInfo p
let reconstructWithoutPostFixing = reconstructAction { elimViewAction = elimView NoPostfix }
let hiddenPs = map Apply $ mapHide tyProj $ fromMaybe __IMPOSSIBLE__ $
allApplyElims pars
reportSDoc "tc.reconstruct" 50 $ "The params are" <+> pretty hiddenPs
((_,Def p psAfterAct),_) <- inferSpine' act tyProj (Def p []) (Def p []) hiddenPs
((_,projWithPars),_) <- inferSpine' reconstructWithoutPostFixing tyProj (Def p []) (Def p []) psAfterAct
reportSDoc "tc.reconstruct" 50 $ "Spine infered" <+> pretty projWithPars
let fTe' x = applyWithoutReversing projWithPars ((Apply $ defaultArg $ fTe []):x)
loop' (absApp b (fTy [])) fTe' (fTy . (Proj o p:)) es
_ -> __IMPOSSIBLE__
loop' ty _ _ (IApply {}:vs) = __IMPOSSIBLE__
applyWithoutReversing :: Term -> Elims -> Term
applyWithoutReversing (Var i es) ess = Var i (es++ess)
applyWithoutReversing (Def n es) ess = Def n (es++ess)
applyWithoutReversing (Con h i es) ess = Con h i (es++ess)
applyWithoutReversing (MetaV i es) ess = MetaV i (es++ess)
applyWithoutReversing (Dummy s es) ess = Dummy s (es++ess)
applyWithoutReversing _ _ = __IMPOSSIBLE__
mapHide (El _ (Pi a b)) (p:tl) =
case argInfoHiding (domInfo a) of
Hidden -> (hideAndRelParams p):(mapHide (unAbs b) tl)
_ -> p:(mapHide (unAbs b) tl)
mapHide t l = l
dropParameters :: TermLike a => a -> TCM a
dropParameters = traverseTermM dropPars
where
dropPars v =
case v of
Con c ci vs -> do
Constructor{ conData = d } <- theDef <$> getConstInfo (conName c)
Just n <- defParameters <$> getConstInfo d
return $ Con c ci $ drop n vs
Def f vs -> do
isProj <- isProjection f
case isProj of
Nothing -> return v
Just pr -> return $ applyE (projDropPars pr ProjSystem) vs
_ -> return v