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.

86 lines
2.2 KiB

  1. {-# LANGUAGE TupleSections, OverloadedStrings #-}
  2. module Elab where
  3. import Elab.Monad
  4. import qualified Presyntax.Presyntax as P
  5. import Syntax
  6. import Elab.Eval
  7. infer :: P.Expr -> ElabM (Term, NFType)
  8. infer (P.Var t) = (Ref (Bound t),) <$> getNfType (Bound t)
  9. infer (P.App p f x) = do
  10. (f, f_ty) <- infer f
  11. (d, r, w) <- isPiType p f_ty
  12. x <- check x d
  13. x_nf <- eval x
  14. pure (App p (w f) x, r x_nf)
  15. infer (P.Pi p s d r) = do
  16. d <- check d VType
  17. d_nf <- eval d
  18. assume (Bound s) d_nf $ do
  19. r <- check r VType
  20. pure (Pi p s d r, VType)
  21. infer (P.Sigma s d r) = do
  22. d <- check d VType
  23. d_nf <- eval d
  24. assume (Bound s) d_nf $ do
  25. r <- check r VType
  26. pure (Sigma s d r, VType)
  27. infer exp = do
  28. t <- newMeta VType
  29. tm <- check exp t
  30. pure (tm, t)
  31. check :: P.Expr -> NFType -> ElabM Term
  32. check (P.Lam p var body) (VPi p' dom (Closure _ rng)) | p == p' =
  33. assume (Bound var) dom $
  34. Lam p var <$> check body (rng (VVar (Bound var)))
  35. check tm (VPi P.Im dom (Closure var rng)) =
  36. assume (Bound var) dom $
  37. Lam P.Im var <$> check tm (rng (VVar (Bound var)))
  38. check (P.Lam p v b) ty = do
  39. (d, r, wp) <- isPiType p ty
  40. assume (Bound v) d $
  41. wp . Lam P.Im v <$> check b (r (VVar (Bound v)))
  42. check (P.Pair a b) ty = do
  43. (d, r, wp) <- isSigmaType ty
  44. a <- check a d
  45. a_nf <- eval a
  46. b <- check b (r a_nf)
  47. pure (wp (Pair a b))
  48. check exp ty = do
  49. (tm, has) <- infer exp
  50. unify has ty
  51. pure tm
  52. isPiType :: P.Plicity -> NFType -> ElabM (Value, NFType -> NFType, Term -> Term)
  53. isPiType p (VPi p' d (Closure _ k)) | p == p' = pure (d, k, id)
  54. isPiType p t = do
  55. dom <- newMeta VType
  56. name <- newName
  57. assume (Bound name) dom $ do
  58. rng <- newMeta VType
  59. wp <- isConvertibleTo t (VPi p dom (Closure name (const rng)))
  60. pure (dom, const rng, wp)
  61. isSigmaType :: NFType -> ElabM (Value, NFType -> NFType, Term -> Term)
  62. isSigmaType (VSigma d (Closure _ k)) = pure (d, k, id)
  63. isSigmaType t = do
  64. dom <- newMeta VType
  65. name <- newName
  66. assume (Bound name) dom $ do
  67. rng <- newMeta VType
  68. wp <- isConvertibleTo t (VSigma dom (Closure name (const rng)))
  69. pure (dom, const rng, wp)
  70. identityTy :: NFType
  71. identityTy = VPi P.Im VType (Closure "A" $ \t -> VPi P.Ex t (Closure "_" (const t)))