less prototype, less bad code implementation of CCHM type theory
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.

227 lines
6.1 KiB

  1. {-# LANGUAGE TupleSections, OverloadedStrings #-}
  2. {-# LANGUAGE DeriveAnyClass #-}
  3. {-# LANGUAGE ScopedTypeVariables #-}
  4. module Elab where
  5. import Control.Monad.Reader
  6. import Control.Exception
  7. import qualified Data.Map.Strict as Map
  8. import Data.Typeable
  9. import Elab.WiredIn
  10. import Elab.Monad
  11. import Elab.Eval
  12. import qualified Presyntax.Presyntax as P
  13. import Prettyprinter
  14. import Syntax.Pretty
  15. import Syntax
  16. infer :: P.Expr -> ElabM (Term, NFType)
  17. infer (P.Span ex a b) = withSpan a b $ infer ex
  18. infer (P.Var t) = do
  19. name <- getNameFor t
  20. nft <- getNfType name
  21. pure (Ref name, nft)
  22. infer (P.App p f x) = do
  23. (f, f_ty) <- infer f
  24. porp <- isPiType p f_ty
  25. case porp of
  26. It'sProd d r w -> do
  27. x <- check x d
  28. x_nf <- eval x
  29. pure (App p (w f) x, r x_nf)
  30. It'sPath li le ri wp -> do
  31. x <- check x VI
  32. x_nf <- eval x
  33. pure (IElim (quote (fun li)) (quote le) (quote ri) (wp f) x, li x_nf)
  34. infer (P.Proj1 x) = do
  35. (tm, ty) <- infer x
  36. (d, _, wp) <- isSigmaType ty
  37. pure (Proj1 (wp tm), d)
  38. infer (P.Proj2 x) = do
  39. (tm, ty) <- infer x
  40. tm_nf <- eval tm
  41. (_, r, wp) <- isSigmaType ty
  42. pure (Proj2 (wp tm), r (vProj1 tm_nf))
  43. infer exp = do
  44. t <- newMeta VType
  45. tm <- switch $ check exp t
  46. pure (tm, t)
  47. check :: P.Expr -> NFType -> ElabM Term
  48. check (P.Span ex a b) ty = withSpan a b $ check ex ty
  49. check (P.Lam p var body) (VPi p' dom (Closure _ rng)) | p == p' =
  50. assume (Bound var) dom $
  51. Lam p var <$> check body (rng (VVar (Bound var)))
  52. check tm (VPi P.Im dom (Closure var rng)) =
  53. assume (Bound var) dom $
  54. Lam P.Im var <$> check tm (rng (VVar (Bound var)))
  55. check (P.Lam p v b) ty = do
  56. porp <- isPiType p =<< forceIO ty
  57. case porp of
  58. It'sProd d r wp -> do
  59. assume (Bound v) d $
  60. wp . Lam p v <$> check b (r (VVar (Bound v)))
  61. It'sPath li le ri wp -> do
  62. tm <- assume (Bound v) VI $
  63. Lam P.Ex v <$> check b (li (VVar (Bound v)))
  64. tm_nf <- eval tm
  65. unify (tm_nf @@ VI0) le
  66. `catchElab` (throwElab . WhenCheckingEndpoint le ri VI0)
  67. unify (tm_nf @@ VI1) ri
  68. `catchElab` (throwElab . WhenCheckingEndpoint le ri VI1)
  69. pure (wp (PathIntro (quote (fun li)) tm))
  70. check (P.Pair a b) ty = do
  71. (d, r, wp) <- isSigmaType =<< forceIO ty
  72. a <- check a d
  73. a_nf <- eval a
  74. b <- check b (r a_nf)
  75. pure (wp (Pair a b))
  76. check (P.Pi p s d r) ty = do
  77. isSort ty
  78. d <- check d ty
  79. d_nf <- eval d
  80. assume (Bound s) d_nf $ do
  81. r <- check r ty
  82. pure (Pi p s d r)
  83. check (P.Sigma s d r) ty = do
  84. isSort ty
  85. d <- check d ty
  86. d_nf <- eval d
  87. assume (Bound s) d_nf $ do
  88. r <- check r ty
  89. pure (Sigma s d r)
  90. check exp ty = do
  91. (tm, has) <- switch $ infer exp
  92. wp <- isConvertibleTo has ty
  93. pure (wp tm)
  94. isSort :: NFType -> ElabM ()
  95. isSort VType = pure ()
  96. isSort VTypeω = pure ()
  97. isSort vt@(VNe HMeta{} _) = unify vt VType
  98. isSort vt = liftIO . throwIO $ NotEqual vt VType
  99. data ProdOrPath
  100. = It'sProd { prodDmn :: NFType
  101. , prodRng :: NFType -> NFType
  102. , prodWrap :: Term -> Term
  103. }
  104. | It'sPath { pathLine :: NFType -> NFType
  105. , pathLeft :: Value
  106. , pathRight :: Value
  107. , pathWrap :: Term -> Term
  108. }
  109. isPiType :: P.Plicity -> NFType -> ElabM ProdOrPath
  110. isPiType p (VPi p' d (Closure _ k)) | p == p' = pure (It'sProd d k id)
  111. isPiType P.Ex (VPath li le ri) = pure (It'sPath (li @@) le ri id)
  112. isPiType P.Ex (VPi P.Im d (Closure _ k)) = do
  113. meta <- newMeta d
  114. porp <- isPiType P.Ex (k meta)
  115. pure $ case porp of
  116. It'sProd d r w -> It'sProd d r (\f -> w (App P.Im f (quote meta)))
  117. It'sPath l x y w -> It'sPath l x y (\f -> w (App P.Im f (quote meta)))
  118. isPiType p t = do
  119. dom <- newMeta VType
  120. name <- newName
  121. assume (Bound name) dom $ do
  122. rng <- newMeta VType
  123. wp <- isConvertibleTo t (VPi p dom (Closure name (const rng)))
  124. pure (It'sProd dom (const rng) wp)
  125. isSigmaType :: NFType -> ElabM (Value, NFType -> NFType, Term -> Term)
  126. isSigmaType (VSigma d (Closure _ k)) = pure (d, k, id)
  127. isSigmaType t = do
  128. dom <- newMeta VType
  129. name <- newName
  130. assume (Bound name) dom $ do
  131. rng <- newMeta VType
  132. wp <- isConvertibleTo t (VSigma dom (Closure name (const rng)))
  133. pure (dom, const rng, wp)
  134. identityTy :: NFType
  135. identityTy = VPi P.Im VType (Closure "A" $ \t -> VPi P.Ex t (Closure "_" (const t)))
  136. checkStatement :: P.Statement -> ElabM a -> ElabM a
  137. checkStatement (P.SpanSt s a b) k = withSpan a b $ checkStatement s k
  138. checkStatement (P.Decl name ty) k = do
  139. ty <- check ty VTypeω
  140. ty_nf <- eval ty
  141. assumes (Defined <$> name) ty_nf k
  142. checkStatement (P.Defn name rhs) k = do
  143. ty <- asks (Map.lookup (Defined name) . getEnv)
  144. case ty of
  145. Nothing -> do
  146. (tm, ty) <- infer rhs
  147. tm_nf <- eval tm
  148. define (Defined name) ty tm_nf k
  149. Just (ty_nf, nm) -> do
  150. case nm of
  151. VVar (Defined n') | n' == name -> pure ()
  152. _ -> liftIO . throwIO $ Redefinition (Defined name)
  153. rhs <- check rhs ty_nf
  154. rhs_nf <- eval rhs
  155. define (Defined name) ty_nf rhs_nf k
  156. checkStatement (P.Builtin winame var) k = do
  157. wi <-
  158. case Map.lookup winame wiredInNames of
  159. Just wi -> pure wi
  160. _ -> liftIO . throwIO $ NoSuchPrimitive winame
  161. let
  162. check = do
  163. nm <- getNameFor var
  164. ty <- getNfType nm
  165. unify ty (wiType wi)
  166. `withNote` hsep [ "Previous definition of", pretty nm, "here" ]
  167. `seeAlso` nm
  168. env <- ask
  169. liftIO $
  170. runElab check env `catch` \(_ :: NotInScope) -> pure ()
  171. define (Defined var) (wiType wi) (wiValue wi) k
  172. checkStatement (P.ReplNf e) k = do
  173. (e, _) <- infer e
  174. e_nf <- eval e
  175. h <- asks commHook
  176. liftIO (h e_nf)
  177. k
  178. checkStatement (P.ReplTy e) k = do
  179. (_, ty) <- infer e
  180. h <- asks commHook
  181. liftIO (h ty)
  182. k
  183. checkProgram :: [P.Statement] -> ElabM a -> ElabM a
  184. checkProgram [] k = k
  185. checkProgram (st:sts) k = checkStatement st $ checkProgram sts k
  186. newtype Redefinition = Redefinition { getRedefName :: Name }
  187. deriving (Show, Typeable, Exception)
  188. data WhenCheckingEndpoint = WhenCheckingEndpoint { leftEndp :: Value, rightEndp :: Value, whichIsWrong :: NFEndp, exc :: SomeException }
  189. deriving (Show, Typeable, Exception)