2
module Agda.TypeChecking.MetaVars.Occurs where
4
import Control.Applicative
6
import Control.Monad.Error
8
import Agda.Syntax.Common
9
import Agda.Syntax.Internal
10
import Agda.TypeChecking.Monad
11
import Agda.TypeChecking.Reduce
12
import Agda.TypeChecking.Pretty
13
import Agda.Utils.Monad
15
-- | Extended occurs check.
17
occurs :: (TypeError -> TCM ()) -> MetaId -> [Nat] -> t -> TCM t
19
occursCheck :: MonadTCM tcm => MetaId -> [Nat] -> Term -> tcm Term
20
occursCheck m xs v = liftTCM $ do
23
-- Don't fail if trying to instantiate to just itself
24
MetaV m' _ | m == m' -> patternViolation
25
Sort (MetaS m' _) | m == m' -> patternViolation
27
-- Produce nicer error messages
28
occurs typeError m xs v `catchError` \err -> case errError err of
29
TypeError _ cl -> case clValue cl of
30
MetaOccursInItself{} ->
31
typeError . GenericError . show =<<
32
fsep [ text ("Refuse to construct infinite term by instantiating " ++ show m ++ " to")
35
MetaCannotDependOn _ _ i ->
36
ifM ((&&) <$> isSortMeta m <*> (not <$> hasUniversePolymorphism))
37
( typeError . GenericError . show =<<
38
fsep [ text ("Cannot instantiate the metavariable " ++ show m ++ " to")
40
, text "since universe polymorphism is not enabled"
41
, text "(use the --universe-polymorphism flag to enable)"
44
( typeError . GenericError . show =<<
45
fsep [ text ("Cannot instantiate the metavariable " ++ show m ++ " to")
47
, text "since it contains the variable"
48
, enterClosure cl $ \_ -> prettyTCM (Var i [])
49
, text $ "which " ++ show m ++ " cannot depend on"
55
instance Occurs Term where
56
occurs abort m xs v = do
59
-- Don't fail on blocked terms or metas
60
Blocked _ v -> occurs' (const patternViolation) v
61
NotBlocked v -> occurs' abort v
63
occurs' abort v = case v of
65
unless (i `elem` xs) $ abort $ MetaCannotDependOn m xs i
67
Lam h f -> Lam h <$> occ f
69
Def c vs -> Def c <$> occ vs
70
Con c vs -> Con c <$> occ vs
71
Pi a b -> uncurry Pi <$> occ (a,b)
72
Fun a b -> uncurry Fun <$> occ (a,b)
73
Sort s -> Sort <$> occ s
75
when (m == m') $ abort $ MetaOccursInItself m
76
-- Don't fail on flexible occurrence
77
MetaV m' <$> occurs (const patternViolation) m xs vs
79
occ x = occurs abort m xs x
81
instance Occurs Type where
82
occurs abort m xs (El s v) = uncurry El <$> occurs abort m xs (s,v)
84
instance Occurs Sort where
89
when (m == m') $ abort $ MetaOccursInItself m
90
MetaS m' <$> occurs (const patternViolation) m xs args
91
Lub s1 s2 -> uncurry Lub <$> occurs abort m xs (s1,s2)
92
DLub s1 s2 -> uncurry DLub <$> occurs abort m xs (s1, s2)
93
Suc s -> Suc <$> occurs abort m xs s
94
Type a -> Type <$> occurs abort m xs a
98
instance Occurs a => Occurs (Abs a) where
99
occurs abort m xs (Abs s x) = Abs s <$> occurs abort m (0 : map (1+) xs) x
101
instance Occurs a => Occurs (Arg a) where
102
occurs abort m xs (Arg h x) = Arg h <$> occurs abort m xs x
104
instance (Occurs a, Occurs b) => Occurs (a,b) where
105
occurs abort m xs (x,y) = (,) <$> occurs abort m xs x <*> occurs abort m xs y
107
instance Occurs a => Occurs [a] where
108
occurs abort m xs ys = mapM (occurs abort m xs) ys