2
{-# LANGUAGE FlexibleInstances #-}
3
{-# LANGUAGE PatternGuards #-}
2
{-# LANGUAGE FlexibleInstances #-}
3
{-# LANGUAGE PatternGuards #-}
4
4
{-# LANGUAGE TypeSynonymInstances #-}
6
6
module Agda.TypeChecking.Conversion where
10
10
import Control.Monad.Reader
11
11
import Control.Monad.State
12
import Control.Monad.Error
14
13
import Data.List hiding (sort)
15
14
import qualified Data.List as List
46
45
import Agda.Interaction.Options
48
import Agda.Utils.Size
47
import Agda.Utils.Except ( MonadError(catchError, throwError) )
49
48
import Agda.Utils.Functor (($>))
50
49
import Agda.Utils.Monad
51
50
import Agda.Utils.Maybe
51
import Agda.Utils.Size
52
import Agda.Utils.Tuple
53
#include "../undefined.h"
54
#include "undefined.h"
54
55
import Agda.Utils.Impossible
56
57
{- MOVED to TypeChecking.Level
69
70
sameVars :: Elims -> Elims -> Bool
70
71
sameVars xs ys = and $ zipWith same xs ys
72
same (Apply (Arg _ (Var n []))) (Apply (Arg _ (Var m []))) = n == m
73
same (Apply (Arg _ (Var n []))) (Apply (Arg _ (Var m []))) = n == m
75
76
-- | @intersectVars us vs@ checks whether all relevant elements in @us@ and @vs@
173
174
"shortcut successful\n result: " ++ show u
174
175
-- Should be ok with catchError_ but catchError is much safer since we don't
175
176
-- rethrow errors.
176
m `orelse` h = m `catchError` \err -> case err of
177
PatternErr s -> put s >> h
177
orelse m h = catchError m (\_ -> h)
179
unifyPointers :: Comparison -> Term -> Term -> TCM () -> TCM ()
180
180
unifyPointers _ _ _ action = action
181
181
-- unifyPointers cmp _ _ action | cmp /= CmpEq = action
182
182
-- unifyPointers _ u v action = do
242
242
isrec <- isEtaRecord r
245
dontHaveCopatterns <- not . optCopatterns <$> pragmaOptions
246
246
let ps = fromMaybe __IMPOSSIBLE__ $ allApplyElims es
247
247
-- Andreas, 2010-10-11: allowing neutrals to be blocked things does not seem
248
248
-- to change Agda's behavior
249
249
-- isNeutral Blocked{} = False
250
250
isNeutral = isNeutral' . fmap ignoreSharing
251
251
isMeta = isMeta' . fmap ignoreSharing
252
isNeutral' (NotBlocked Con{}) = False
252
isNeutral' (NotBlocked Con{}) = return False
253
253
-- Andreas, 2013-09-18: this is expensive:
254
254
-- should only do this when copatterns are on
255
isNeutral' (NotBlocked Def{}) = dontHaveCopatterns -- a def by copattern can reduce if projected
255
isNeutral' (NotBlocked (Def q _)) = do
258
Defn {theDef = Function {funCopatternLHS = True}} -> False -- a def by copattern can reduce if projected
260
isNeutral' _ = return True
257
261
isMeta' (NotBlocked MetaV{}) = True
258
262
isMeta' _ = False
260
264
reportSDoc "tc.conv.term" 30 $ prettyTCM a <+> text "is eta record type"
266
mNeutral <- isNeutral m
268
nNeutral <- isNeutral n
264
270
_ | isMeta m || isMeta n ->
265
271
compareAtom cmp a' (ignoreBlocking m) (ignoreBlocking n)
267
_ | isNeutral m && isNeutral n -> do
273
_ | mNeutral && nNeutral -> do
268
274
-- Andreas 2011-03-23: (fixing issue 396)
269
275
-- if we are dealing with a singleton record,
270
276
-- we can succeed immediately
338
344
addCtx name dom1 $
340
then guardConstraint c checkDom
341
else checkDom >> solveConstraint_ c
346
then guardConstraint c checkDom
347
else checkDom >> solveConstraint_ c
344
350
-- Andreas, 2011-05-10 better report message about types
387
393
-- if a PatternErr is thrown, rebuild constraint!
388
394
catchConstraint (ValueCmp cmp t m n) $ do
389
395
reportSDoc "tc.conv.atom" 50 $
390
text "compareAtom" <+> fsep [ prettyTCM m <+> prettyTCM cmp
396
text "compareAtom" <+> fsep [ prettyTCM m <+> prettyTCM cmp
392
398
, text ":" <+> prettyTCM t ]
393
399
-- Andreas: what happens if I cut out the eta expansion here?
394
400
-- Answer: Triggers issue 245, does not resolve 348
395
mb' <- etaExpandBlocked =<< reduceB m
396
nb' <- etaExpandBlocked =<< reduceB n
401
(mb',nb') <- ifM (asks envCompareBlocked) ((NotBlocked -*- NotBlocked) <$> reduce (m,n)) $ do
402
mb' <- etaExpandBlocked =<< reduceB m
403
nb' <- etaExpandBlocked =<< reduceB n
398
406
-- constructorForm changes literal to constructors
399
407
-- only needed if the other side is not a literal
400
408
(mb'', nb'') <- case (ignoreSharing $ ignoreBlocking mb', ignoreSharing $ ignoreBlocking nb') of
401
(Lit _, Lit _) -> return (mb', nb')
409
(Lit _, Lit _) -> return (mb', nb')
402
410
_ -> (,) <$> traverse constructorForm mb'
403
411
<*> traverse constructorForm nb'
425
433
unifyPointers cmp (ignoreBlocking mb') (ignoreBlocking nb') $ do -- this needs to go after eta expansion to avoid creating infinite terms
427
435
reportSDoc "tc.conv.atom" 30 $
428
text "compareAtom" <+> fsep [ prettyTCM mb <+> prettyTCM cmp
436
text "compareAtom" <+> fsep [ prettyTCM mb <+> prettyTCM cmp
430
438
, text ":" <+> prettyTCM t ]
431
439
case (ignoreSharing <$> mb, ignoreSharing <$> nb) of
452
460
-- instantiate later meta variables first
453
461
let (solve1, solve2)
454
462
| (p1,x) > (p2,y) = (l,r)
456
464
where l = assign dir x xArgs n
457
465
r = assign rid y yArgs m
459
467
try m h = m `catchError_` \err -> case err of
460
PatternErr s -> put s >> h
461
469
_ -> throwError err
463
471
-- First try the one with the highest priority. If that doesn't
465
473
try solve1 solve2
467
475
-- one side a meta, the other an unblocked term
468
(NotBlocked (MetaV x es), _) -> assign dir x es n
469
(_, NotBlocked (MetaV x es)) -> assign rid x es m
470
(Blocked{}, Blocked{}) -> checkSyntacticEquality
476
(NotBlocked (MetaV x es), _) -> assign dir x es n
477
(_, NotBlocked (MetaV x es)) -> assign rid x es m
478
(Blocked{}, Blocked{}) -> checkSyntacticEquality
471
479
(Blocked{}, _) -> useInjectivity cmp t m n
472
480
(_,Blocked{}) -> useInjectivity cmp t m n
478
486
m <- elimView False m
479
487
n <- elimView False n
480
488
case (ignoreSharing m, ignoreSharing n) of
481
(Pi{}, Pi{}) -> equalFun m n
483
(Sort s1, Sort s2) -> compareSort CmpEq s1 s2
485
(Lit l1, Lit l2) | l1 == l2 -> return ()
486
(Var i es, Var i' es') | i == i' -> do
489
(Pi{}, Pi{}) -> equalFun m n
491
(Sort s1, Sort s2) -> compareSort CmpEq s1 s2
493
(Lit l1, Lit l2) | l1 == l2 -> return ()
494
(Var i es, Var i' es') | i == i' -> do
488
496
-- Variables are invariant in their arguments
489
compareElims [] a (var i) es es'
497
compareElims [] a (var i) es es'
490
498
(Def f es, Def f' es') | f == f' -> do
491
499
a <- defType <$> getConstInfo f
492
500
pol <- getPolarity' cmp f
543
551
reportSLn "tc.conv.elim" 50 $ "v (raw) = " ++ show v
544
552
compareElims pol a v els1 els2
546
(Con x xArgs, Con y yArgs)
554
(Con x xArgs, Con y yArgs)
548
556
-- Get the type of the constructor instantiated to the datatype parameters.
549
557
a' <- conType x t
550
558
-- Constructors are invariant in their arguments
583
591
equalFun t1 t2 = case (ignoreSharing t1, ignoreSharing t2) of
584
(Pi dom1@(Dom i1 a1@(El a1s a1t)) b1, Pi (Dom i2 a2) b2)
585
| argInfoHiding i1 /= argInfoHiding i2 -> typeError $ UnequalHiding t1 t2
592
(Pi dom1@(Dom i1 a1@(El a1s a1t)) b1, Pi (Dom i2 a2) b2)
593
| argInfoHiding i1 /= argInfoHiding i2 -> typeError $ UnequalHiding t1 t2
586
594
-- Andreas 2010-09-21 compare r1 and r2, but ignore forcing annotations!
587
| not (compareRelevance cmp (ignoreForced $ argInfoRelevance i2)
595
| not (compareRelevance cmp (ignoreForced $ argInfoRelevance i2)
588
596
(ignoreForced $ argInfoRelevance i1))
589
597
-> typeError $ UnequalRelevance cmp t1 t2
590
| otherwise -> verboseBracket "tc.conv.fun" 15 "compare function types" $ do
598
| otherwise -> verboseBracket "tc.conv.fun" 15 "compare function types" $ do
591
599
reportSDoc "tc.conv.fun" 20 $ nest 2 $ vcat
592
600
[ text "t1 =" <+> prettyTCM t1
593
601
, text "t2 =" <+> prettyTCM t2 ]
833
841
compareType cmp ty1@(El s1 a1) ty2@(El s2 a2) =
834
842
verboseBracket "tc.conv.type" 20 "compareType" $
835
843
catchConstraint (TypeCmp cmp ty1 ty2) $ do
836
reportSDoc "tc.conv.type" 50 $ vcat
844
reportSDoc "tc.conv.type" 50 $ vcat
837
845
[ text "compareType" <+> sep [ prettyTCM ty1 <+> prettyTCM cmp
838
846
, prettyTCM ty2 ]
839
847
, hsep [ text " sorts:", prettyTCM s1, text " and ", prettyTCM s2 ]
841
849
-- Andreas, 2011-4-27 should not compare sorts, but currently this is needed
842
850
-- for solving sort and level metas
843
compareSort CmpEq s1 s2 `catchError` \err -> case err of
851
compareSort CmpEq s1 s2 `catchError` \err -> case err of
844
852
TypeError _ e -> do
845
853
reportSDoc "tc.conv.type" 30 $ vcat
846
854
[ text "sort comparison failed"
960
968
ifM typeInType (return ()) $
961
969
catchConstraint (SortCmp CmpLeq s1 s2) $
962
do (s1,s2) <- reduce (s1,s2)
970
do (s1,s2) <- reduce (s1,s2)
963
971
let postpone = addConstraint (SortCmp CmpLeq s1 s2)
964
972
reportSDoc "tc.conv.sort" 30 $
965
973
sep [ text "leqSort"
966
974
, nest 2 $ fsep [ prettyTCM s1 <+> text "=<"
971
979
(Type a, Type b) -> leqLevel a b
973
(Prop , Prop ) -> return ()
974
(Type _ , Prop ) -> notLeq s1 s2
981
(Prop , Prop ) -> return ()
982
(Type _ , Prop ) -> notLeq s1 s2
976
(Prop , Type _ ) -> return ()
984
(Prop , Type _ ) -> return ()
978
986
(_ , Inf ) -> return ()
979
987
(Inf , _ ) -> equalSort s1 s2
980
988
(DLub{} , _ ) -> postpone
981
989
(_ , DLub{} ) -> postpone
983
notLeq s1 s2 = typeError $ NotLeqSort s1 s2
991
notLeq s1 s2 = typeError $ NotLeqSort s1 s2
985
993
leqLevel :: Level -> Level -> TCM ()
986
994
leqLevel a b = liftTCM $ do
1268
1276
, text (show s2) ]
1273
1281
(Type a , Type b ) -> equalLevel a b
1275
(Prop , Prop ) -> return ()
1276
(Type _ , Prop ) -> notEq s1 s2
1277
(Prop , Type _ ) -> notEq s1 s2
1283
(Prop , Prop ) -> return ()
1284
(Type _ , Prop ) -> notEq s1 s2
1285
(Prop , Type _ ) -> notEq s1 s2
1279
1287
(Inf , Inf ) -> return ()
1280
1288
(Inf , Type (Max as@(_:_))) -> mapM_ (isInf $ notEq s1 s2) as
1294
1302
(DLub{} , _ ) -> postpone
1295
1303
(_ , DLub{} ) -> postpone
1297
notEq s1 s2 = typeError $ UnequalSorts s1 s2
1305
notEq s1 s2 = typeError $ UnequalSorts s1 s2
1299
1307
isInf notok ClosedLevel{} = notok
1300
1308
isInf notok (Plus _ l) = case l of