1
{-# LANGUAGE CPP, FlexibleInstances, UndecidableInstances,
2
GeneralizedNewtypeDeriving, ScopedTypeVariables
2
{-# LANGUAGE FlexibleInstances #-}
3
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4
{-# LANGUAGE ScopedTypeVariables #-}
5
{-# LANGUAGE TypeSynonymInstances #-}
6
{-# LANGUAGE UndecidableInstances #-}
5
8
{-| Primitive functions, such as addition on builtin integers.
7
10
module Agda.TypeChecking.Primitive where
9
12
import Control.Monad
10
import Control.Monad.Error
13
import Control.Applicative
11
16
import Data.Map (Map)
12
17
import qualified Data.Map as Map
15
19
import Agda.Interaction.Options
17
21
import Agda.Syntax.Position
18
22
import Agda.Syntax.Common hiding (Nat)
19
import Agda.Syntax.Internal
23
import Agda.Syntax.Internal as I
20
24
import Agda.Syntax.Literal
21
25
import Agda.Syntax.Concrete.Pretty ()
22
import Agda.Syntax.Abstract.Name
23
import qualified Agda.Syntax.Concrete.Name as C
25
import Agda.TypeChecking.Monad
27
import Agda.TypeChecking.Monad hiding (getConstInfo, typeOfConst)
28
import qualified Agda.TypeChecking.Monad as TCM
26
29
import Agda.TypeChecking.Monad.Builtin
27
30
import Agda.TypeChecking.Reduce
31
import Agda.TypeChecking.Reduce.Monad
28
32
import Agda.TypeChecking.Substitute
29
33
import Agda.TypeChecking.Errors
30
import Agda.TypeChecking.Quote (quoteType, quotingKit)
34
import Agda.TypeChecking.Level
35
import Agda.TypeChecking.Quote (quotingKit)
31
36
import Agda.TypeChecking.Pretty () -- instances only
32
import {-# SOURCE #-} Agda.TypeChecking.Conversion
33
import Agda.TypeChecking.Constraints
34
import Agda.TypeChecking.Level
36
38
import Agda.Utils.Monad
37
39
import Agda.Utils.Pretty (pretty)
40
import Agda.Utils.Maybe
39
42
#include "../undefined.h"
40
43
import Agda.Utils.Impossible
42
constructorForm :: Term -> TCM Term
43
constructorForm v = case ignoreSharing v of
44
{- 2012-04-02 changed semantics of DontCare
45
DontCare v -> constructorForm v
47
Lit (LitInt r n) -> cons primZero primSuc (Lit . LitInt r) n
54
return $ s `apply` [defaultArg $ lit $ n - 1]
55
| otherwise = return v
57
46
---------------------------------------------------------------------------
58
47
-- * Primitive functions
72
57
newtype Nat = Nat { unNat :: Integer }
73
deriving (Eq, Ord, Num, Integral, Enum, Real)
58
deriving (Eq, Ord, Num, Enum, Real)
60
-- TODO: ghc-7.7 bug: deriving Integral causes an unnecessary toInteger
61
-- warning. Once 7.8 is out check if we can go back to deriving.
62
instance Integral Nat where
64
quotRem (Nat a) (Nat b) = (Nat q, Nat r)
65
where (q, r) = quotRem a b
75
67
newtype Lvl = Lvl { unLvl :: Integer }
214
206
isCon (Lam _ b) = isCon $ absBody b
215
207
isCon (Con c _) = return c
216
isCon (Shared p) = isCon (derefPtr p)
219
typeError $ GenericError $ "expected constructor in built-in binding to " ++ show d
220
-- TODO: check this when binding the things
208
isCon (Shared p) = __IMPOSSIBLE__ -- isCon (derefPtr p)
209
isCon v = __IMPOSSIBLE__
222
211
mkList nil cons toA fromA t = do
224
213
let t = ignoreBlocking b
225
let arg = Arg (argHiding t) (argRelevance t)
214
let arg = Arg (ArgInfo { argInfoHiding = getHiding t
215
, argInfoRelevance = getRelevance t
216
, argInfoColors = argColors t
228
| c == nil -> return $ YesReduction []
220
| c == nil -> return $ YesReduction NoSimplification []
237
229
_ -> return $ NoReduction (reduced b)
239
231
-- | Conceptually: @redBind m f k = either (return . Left . f) k =<< m@
240
redBind :: TCM (Reduced a a') -> (a -> b) ->
241
(a' -> TCM (Reduced b b')) -> TCM (Reduced b b')
232
redBind :: ReduceM (Reduced a a') -> (a -> b) ->
233
(a' -> ReduceM (Reduced b b')) -> ReduceM (Reduced b b')
242
234
redBind ma f k = do
245
NoReduction x -> return $ NoReduction $ f x
246
YesReduction y -> k y
237
NoReduction x -> return $ NoReduction $ f x
238
YesReduction _ y -> k y
248
redReturn :: a -> TCM (Reduced a' a)
249
redReturn = return . YesReduction
240
redReturn :: a -> ReduceM (Reduced a' a)
241
redReturn = return . YesReduction YesSimplification
251
243
fromReducedTerm :: (Term -> Maybe a) -> TCM (FromTermFunction a)
252
244
fromReducedTerm f = return $ \t -> do
254
246
case f $ ignoreSharing $ unArg (ignoreBlocking b) of
255
Just x -> return $ YesReduction x
247
Just x -> return $ YesReduction NoSimplification x
256
248
Nothing -> return $ NoReduction (reduced b)
258
250
fromLiteral :: (Literal -> Maybe a) -> TCM (FromTermFunction a)
272
264
El (varSort 3) <$>
273
265
primEquality <#> varM 3 <#> varM 2 <@> varM 1 <@> varM 0
274
266
Con rf [] <- ignoreSharing <$> primRefl
275
n <- conPars . theDef <$> getConstInfo rf
276
let refl x | n == 2 = Con rf [Arg Hidden Forced x]
267
n <- conPars . theDef <$> getConInfo rf
268
let refl x | n == 2 = Con rf [setRelevance Forced $ hide $ defaultArg x]
277
269
| n == 3 = Con rf []
278
270
| otherwise = __IMPOSSIBLE__
279
271
return $ PrimImpl t $ PrimFun __IMPOSSIBLE__ 4 $ \ts ->
281
[a, t, x, y] -> liftTCM $ do
274
-- Andreas, 2013-07-22.
275
-- Note that we cannot call the conversion checker here,
276
-- because 'reduce' might be called in a context where
277
-- some bound variables do not have a type (just 'Prop),
278
-- and the conversion checker for eliminations does not
280
-- We can only do untyped equality, e.g., by normalisation.
281
(u', v') <- normalise' (u, v)
282
if (u' == v') then redReturn (refl $ unArg u) else
283
return (NoReduction $ map notReduced [a, t, u, v])
283
equalTerm (El (Type $ lvlView $ unArg a) (unArg t))
285
redReturn (refl $ unArg x)
286
`catchError` \_ -> return (NoReduction $ map notReduced [a, t, x, y])
288
equalTerm (El (Type $ lvlView $ unArg a) (unArg t)) (unArg u) (unArg v)
289
redReturn (refl $ unArg u)
290
`catchError` \_ -> return (NoReduction $ map notReduced [a, t, u, v])
287
292
_ -> __IMPOSSIBLE__
289
294
primQNameType :: TCM PrimitiveImpl
290
primQNameType = mkPrimFun1TCM (el primQName --> el primAgdaType) typeOfConst
295
primQNameType = mkPrimFun1TCM (el primQName --> el primAgdaType)
296
(\q -> defType <$> getConstInfo q)
297
-- Note: gets the top-level type! All bounds variables have been lifted.
292
299
primQNameDefinition :: TCM PrimitiveImpl
293
300
primQNameDefinition = do
301
agdaFunDef <- primAgdaDefinitionFunDef
302
agdaDefinitionFunDef <- primAgdaDefinitionFunDef
303
agdaDefinitionDataDef <- primAgdaDefinitionDataDef
304
agdaDefinitionRecordDef <- primAgdaDefinitionRecordDef
305
agdaDefinitionPostulate <- primAgdaDefinitionPostulate
306
agdaDefinitionPrimitive <- primAgdaDefinitionPrimitive
307
agdaDefinitionDataConstructor <- primAgdaDefinitionDataConstructor
294
309
let argQName qn = [defaultArg (Lit (LitQName noRange qn))]
295
app mt xs = do t <- mt
298
con qn Function{} = app primAgdaDefinitionFunDef (argQName qn)
299
con qn Datatype{} = app primAgdaDefinitionDataDef (argQName qn)
300
con qn Record{} = app primAgdaDefinitionRecordDef (argQName qn)
301
con _ Axiom{} = app primAgdaDefinitionPostulate []
302
con _ Primitive{} = app primAgdaDefinitionPrimitive []
303
con _ Constructor{} = app primAgdaDefinitionDataConstructor []
310
con qn Function{} = apply agdaDefinitionFunDef (argQName qn)
311
con qn Datatype{} = apply agdaDefinitionDataDef (argQName qn)
312
con qn Record{} = apply agdaDefinitionRecordDef (argQName qn)
313
con _ Axiom{} = apply agdaDefinitionPostulate []
314
con _ Primitive{} = apply agdaDefinitionPrimitive []
315
con _ Constructor{} = apply agdaDefinitionDataConstructor []
305
317
unquoteQName <- fromTerm
306
318
t <- el primQName --> el primAgdaDefinition
307
319
return $ PrimImpl t $ PrimFun __IMPOSSIBLE__ 1 $ \ts ->
310
322
redBind (unquoteQName v)
311
323
(\v' -> [v']) $ \x ->
312
redReturn =<< con x . theDef =<< getConstInfo x
324
redReturn =<< (con x . theDef <$> getConstInfo x)
313
325
_ -> __IMPOSSIBLE__
315
327
primDataConstructors :: TCM PrimitiveImpl
316
primDataConstructors = mkPrimFun1TCM (el primAgdaDataDef --> el (list primQName))
317
(fmap (dataCons . theDef) . getConstInfo)
328
primDataConstructors =
329
mkPrimFun1TCM (el primAgdaDataDef --> el (list primQName))
330
(fmap (dataCons . theDef) . getConstInfo)
319
332
mkPrimLevelZero :: TCM PrimitiveImpl
320
333
mkPrimLevelZero = do
324
337
mkPrimLevelSuc :: TCM PrimitiveImpl
325
338
mkPrimLevelSuc = do
326
339
t <- primType (id :: Lvl -> Lvl)
327
return $ PrimImpl t $ PrimFun __IMPOSSIBLE__ 1 $ \ ~[a] -> liftTCM $ do
328
l <- levelView $ unArg a
340
return $ PrimImpl t $ PrimFun __IMPOSSIBLE__ 1 $ \ ~[a] -> do
341
l <- levelView' $ unArg a
329
342
redReturn $ Level $ levelSuc l
331
344
mkPrimLevelMax :: TCM PrimitiveImpl
332
345
mkPrimLevelMax = do
333
346
t <- primType (max :: Op Lvl)
334
return $ PrimImpl t $ PrimFun __IMPOSSIBLE__ 2 $ \ ~[a, b] -> liftTCM $ do
335
Max as <- levelView $ unArg a
336
Max bs <- levelView $ unArg b
347
return $ PrimImpl t $ PrimFun __IMPOSSIBLE__ 2 $ \ ~[a, b] -> do
348
Max as <- levelView' $ unArg a
349
Max bs <- levelView' $ unArg b
337
350
redReturn $ Level $ levelMax $ as ++ bs
339
mkPrimFun1TCM :: (FromTerm a, ToTerm b) => TCM Type -> (a -> TCM b) -> TCM PrimitiveImpl
352
mkPrimFun1TCM :: (FromTerm a, ToTerm b) => TCM Type -> (a -> ReduceM b) -> TCM PrimitiveImpl
340
353
mkPrimFun1TCM mt f = do
344
357
return $ PrimImpl t $ PrimFun __IMPOSSIBLE__ 1 $ \ts ->
348
361
(\v' -> [v']) $ \x ->
349
362
redReturn . fromB =<< f x
436
return $ El (getSort a' `sLub` getSort b') $ Pi (Dom NotHidden Irrelevant a') (NoAbs "_" b')
449
return $ El (getSort a' `sLub` getSort b') $
450
Pi (Dom (setRelevance Irrelevant defaultArgInfo) a') (NoAbs "_" b')
438
gpi :: Hiding -> Relevance -> String -> TCM Type -> TCM Type -> TCM Type
439
gpi h r name a b = do
452
gpi :: I.ArgInfo -> String -> TCM Type -> TCM Type -> TCM Type
453
gpi info name a b = do
442
b <- addCtx x (Dom h r a) b
443
return $ El (getSort a `dLub` Abs name (getSort b))
444
(Pi (Dom h r a) (Abs name b))
455
b <- addContext (name, Dom info a) b
456
let y = stringToArgName name
457
return $ El (getSort a `dLub` Abs y (getSort b))
458
(Pi (Dom info a) (Abs y b))
446
460
hPi, nPi :: String -> TCM Type -> TCM Type -> TCM Type
447
hPi = gpi Hidden Relevant
448
nPi = gpi NotHidden Relevant
461
hPi = gpi $ setHiding Hidden $ defaultArgInfo
462
nPi = gpi defaultArgInfo
450
464
varM :: Int -> TCM Term
451
465
varM = return . var
475
489
tset = return $ sort (mkType 0)
478
argN = Arg NotHidden Relevant
479
domN = Dom NotHidden Relevant
482
argH = Arg Hidden Relevant
483
domH = Dom Hidden Relevant
491
-- | Abbreviation: @argN = 'Arg' 'defaultArgInfo'@.
493
argN = Arg defaultArgInfo
494
domN = Dom defaultArgInfo
496
-- | Abbreviation: @argH = 'hide' 'Arg' 'defaultArgInfo'@.
498
argH = Arg $ setHiding Hidden defaultArgInfo
499
domH = Dom $ setHiding Hidden defaultArgInfo
485
501
---------------------------------------------------------------------------
486
502
-- * The actual primitive functions