a type theory with equality based on setoids
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
6.5 KiB

  1. {-# LANGUAGE NamedFieldPuns #-}
  2. {-# LANGUAGE OverloadedStrings #-}
  3. {-# LANGUAGE FlexibleContexts #-}
  4. {-# LANGUAGE DerivingVia #-}
  5. module Elaboration where
  6. import Control.Monad.Except
  7. import Control.Monad.Reader
  8. import Control.Concurrent
  9. import qualified Data.HashMap.Strict as HashMap
  10. import qualified Data.IntMap.Strict as IntMap
  11. import Data.Text (Text)
  12. import Elaboration.Monad
  13. import Evaluate
  14. import Presyntax
  15. import Syntax
  16. import System.IO.Unsafe ( unsafeDupablePerformIO )
  17. import Value
  18. elabNext :: MVar Int
  19. elabNext = unsafeDupablePerformIO (newMVar 0)
  20. {-# NOINLINE elabNext #-}
  21. freshMeta :: Value -> ElabM Term
  22. freshMeta expected = do
  23. ctx <- ask
  24. names <- getNames
  25. thisMeta <- liftIO $ do
  26. m <- modifyMVar elabNext $ \x -> pure (x + 1, x)
  27. modifyMVar_ elabMetas $ pure . IntMap.insert m (Unsolved names expected)
  28. pure m
  29. pure $ NewMeta (MV thisMeta) (elabBound ctx)
  30. insert :: Term -> VTy -> ElabM (Term, VTy)
  31. insert f (VPi Im _ d r) = do
  32. t <- freshMeta d
  33. t_nf <- asks (flip evaluate t . elabEnv)
  34. insert (App Im f t) (r $$ t_nf)
  35. insert f x = pure (f, x)
  36. insert' :: Term -> VTy -> ElabM (Term, VTy)
  37. insert' t@(Lam Im _ _) ty = pure (t, ty)
  38. insert' t ty = insert t ty
  39. infer :: RawExpr -> ElabM (Term, VTy)
  40. infer (RSrcPos start end expr) = local (\st -> st { elabSourcePos = (start, end) }) (infer expr)
  41. infer (Rvar name) = ask >>= lookup where
  42. lookup ElabState{elabNames, elabConstrs, elabLevel} =
  43. case HashMap.lookup name elabNames of
  44. Just (l, t) -> pure (Bv (lvl2Ix elabLevel l), t)
  45. Nothing ->
  46. case HashMap.lookup name elabConstrs of
  47. Just t -> pure (Con name, t)
  48. Nothing -> typeError (NotInScope name)
  49. infer (Rapp p x y) = do
  50. (x, x_ty) <-
  51. infer x >>= \(x, x_ty) ->
  52. case p of
  53. Ex -> insert x x_ty
  54. _ -> pure (x, x_ty)
  55. (_, d, r) <- isPiType p x_ty
  56. y <- check y d
  57. y_nf <- asks (flip evaluate y . elabEnv)
  58. pure (App p x y, r $$ y_nf)
  59. infer (Rpi e v d r) = do
  60. d <- check d VType
  61. d_nf <- asks (flip evaluate d . elabEnv)
  62. assumeLocal v d_nf $ do
  63. r <- check r VType
  64. pure (Pi e v d r, VType)
  65. infer (Rsigma v d r) = do
  66. d <- check d VType
  67. d_nf <- asks (flip evaluate d . elabEnv)
  68. assumeLocal v d_nf $ do
  69. r <- check r VType
  70. pure (Sigma v d r, VType)
  71. infer (Rlet v t d b) = do
  72. t <- check t VType
  73. t_nf <- asks (flip evaluate t . elabEnv)
  74. d <- check d t_nf
  75. d_nf <- asks (flip evaluate d . elabEnv)
  76. defineLocal v t_nf d_nf $ do
  77. (b, ty) <- infer b
  78. pure (Let v t d b, ty)
  79. infer Rtype = pure (Type, VType)
  80. infer Rhole = do
  81. ty <- freshMeta VType
  82. ty_nf <- asks (flip evaluate ty . elabEnv)
  83. tm <- freshMeta ty_nf
  84. pure (tm, ty_nf)
  85. infer (Rlam p v t) = do
  86. env <- asks elabEnv
  87. lvl <- asks elabLevel
  88. dom <- freshMeta VType
  89. let dom_nf = evaluate env dom
  90. assumeLocal v dom_nf $ do
  91. (b, rng) <- infer t
  92. pure (Lam p v b, VPi p v dom_nf (Closure env (quote (succ lvl) rng)))
  93. infer Rtop = pure (Top, VType)
  94. infer Runit = pure (Unit, VTop)
  95. infer (Req a b) = do
  96. t <- freshMeta VType
  97. t_nf <- asks (flip evaluate t . elabEnv)
  98. a <- check a t_nf
  99. b <- check b t_nf
  100. pure (Id t a b, VType)
  101. infer Rrefl =
  102. pure (Refl, forAll Im "A" VType $ \a -> forAll Im "x" a $ \x -> VEq a x x)
  103. infer Rcoe =
  104. pure ( Coe
  105. , forAll Im "A" VType $ \a ->
  106. forAll Im "B" VType $ \b ->
  107. forAll Ex "_" (VEq VType a b) $ \_ ->
  108. forAll Ex "_" a $ const b
  109. )
  110. infer Rcong =
  111. pure ( Cong
  112. , forAll Im "A" VType $ \a ->
  113. forAll Im "B" VType $ \b ->
  114. forAll Im "x" a $ \x ->
  115. forAll Im "y" a $ \y ->
  116. forAll Ex "f" (forAll Ex "_" a (const b)) $ \f ->
  117. forAll Ex "p" (VEq a x y) $ \_ ->
  118. VEq b (vApp f Ex x) (vApp f Ex y)
  119. )
  120. infer Rsym =
  121. pure ( Sym
  122. , forAll Im "A" VType $ \a -> forAll Im "x" a $ \x -> forAll Im "y" a $ \y -> forAll Ex "p" (VEq a x y) $ \_ -> VEq a y x
  123. )
  124. infer (Rproj1 e) = do
  125. (t, ty) <- infer e
  126. (_, d, _) <- isSigmaType ty
  127. pure (Proj1 t, d)
  128. infer (Rproj2 e) = do
  129. (t, ty) <- infer e
  130. t_nf <- asks (flip evaluate t . elabEnv)
  131. (_, _, r) <- isSigmaType ty
  132. pure (Proj2 t, r $$ vProj1 t_nf)
  133. infer c = do
  134. t <- asks elabSwitches
  135. when (t >= 128) $
  136. error $ "Unhandled case in type checker, stack overflew etc: " ++ show c
  137. t <- freshMeta VType
  138. t_nf <- asks (flip evaluate t . elabEnv)
  139. c <- local (\e -> e { elabSwitches = succ (elabSwitches e)}) $
  140. check c t_nf
  141. pure (c, t_nf)
  142. check :: RawExpr -> VTy -> ElabM Term
  143. check (RSrcPos start end expr) ty = local (\st -> st { elabSourcePos = (start, end) }) (check expr ty)
  144. check (Rlam e v t) (VPi e' _ d r) | e == e' = do
  145. level <- asks (unLvl . elabLevel)
  146. assumeLocal v d $
  147. Lam e v <$> check t (r $$ vVar (Bound level))
  148. check t (VPi Im x d r) = do
  149. level <- asks (unLvl . elabLevel)
  150. assumeLocal x d $
  151. Lam Im x <$> check t (r $$ vVar (Bound level))
  152. check (Rlam e v t) ty = do
  153. (_, d, r) <- isPiType e ty
  154. level <- asks (unLvl . elabLevel)
  155. assumeLocal v d $
  156. Lam e v <$> check t (r $$ vVar (Bound level))
  157. check (Rlet v t d b) ty = do
  158. t <- check t VType
  159. t_nf <- asks (flip evaluate t . elabEnv)
  160. d <- check d t_nf
  161. d_nf <- asks (flip evaluate d . elabEnv)
  162. defineLocal v t_nf d_nf $ do
  163. b <- check b ty
  164. pure (Let v t d b)
  165. check (Rpair a b) ty = do
  166. (_, d, r) <- isSigmaType ty
  167. a <- check a d
  168. a_nf <- asks (flip evaluate a . elabEnv)
  169. b <- check b (r $$ a_nf)
  170. pure (Pair a b)
  171. check e ty = do
  172. (new, e_ty) <- uncurry insert =<< infer e
  173. unify e_ty ty
  174. `catchError` \_ -> do
  175. l <- asks elabLevel
  176. names <- getNames
  177. typeError (NotEqual names (quote l (zonk ty)) (quote l (zonk e_ty)))
  178. pure new
  179. isPiType :: Plicity -> VTy -> ElabM (Text, VTy, Closure)
  180. isPiType i = go . force where
  181. go (VPi i' a b c)
  182. | i == i' = pure (a, b, c)
  183. go ty | not (flexible ty) = do
  184. l <- asks elabLevel
  185. names <- getNames
  186. typeError (NotFunction names (quote l ty))
  187. go ty = do
  188. env <- asks elabEnv
  189. t <- freshMeta VType
  190. let t_nf = evaluate env t
  191. assumeLocal "α" t_nf $ do
  192. r <- freshMeta VType
  193. unify ty (VPi i "α" t_nf (Closure env r))
  194. pure ("α", t_nf, Closure env r)
  195. isSigmaType :: VTy -> ElabM (Text, VTy, Closure)
  196. isSigmaType = go . force where
  197. go (VSigma a b c) = pure (a, b, c)
  198. go ty = do
  199. env <- asks elabEnv
  200. t <- freshMeta VType
  201. let t_nf = evaluate env t
  202. assumeLocal "α" t_nf $ do
  203. r <- freshMeta VType
  204. unify ty (VSigma "α" t_nf (Closure env r))
  205. pure ("α", t_nf, Closure env r)