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.

631 lines
22 KiB

  1. {-# LANGUAGE LambdaCase #-}
  2. {-# LANGUAGE BlockArguments #-}
  3. {-# LANGUAGE TupleSections #-}
  4. {-# LANGUAGE DeriveAnyClass #-}
  5. {-# LANGUAGE ScopedTypeVariables #-}
  6. {-# LANGUAGE DerivingStrategies #-}
  7. {-# LANGUAGE EmptyCase #-}
  8. module Elab where
  9. import Control.Arrow (Arrow(first))
  10. import Control.Monad.Reader
  11. import Control.Exception
  12. import qualified Data.Map.Strict as Map
  13. import qualified Data.Sequence as Seq
  14. import qualified Data.Set as Set
  15. import qualified Data.Text as T
  16. import Data.Maybe (fromMaybe)
  17. import Data.Traversable
  18. import Data.Text (Text)
  19. import Data.Map (Map)
  20. import Data.Typeable
  21. import Data.Foldable
  22. import Elab.Eval.Formula (possible, truthAssignments)
  23. import Elab.WiredIn
  24. import Elab.Monad
  25. import Elab.Eval
  26. import qualified Presyntax.Presyntax as P
  27. import Prettyprinter
  28. import Syntax.Pretty
  29. import Syntax
  30. infer :: P.Expr -> ElabM (Term, NFType)
  31. infer (P.Span ex a b) = withSpan a b $ infer ex
  32. infer (P.Var t) = do
  33. name <- getNameFor t
  34. nft <- getNfType name
  35. pure (Ref name, nft)
  36. infer (P.App p f x) = do
  37. (f, f_ty) <- infer f
  38. porp <- isPiType p f_ty
  39. case porp of
  40. It'sProd d r w -> do
  41. x <- check x d
  42. x_nf <- eval x
  43. pure (App p (w f) x, r x_nf)
  44. It'sPath li le ri wp -> do
  45. x <- check x VI
  46. x_nf <- eval x
  47. pure (IElim (quote (fun li)) (quote le) (quote ri) (wp f) x, li x_nf)
  48. It'sPartial phi a w -> do
  49. x <- check x (VEqStrict VI phi VI1)
  50. pure (App P.Ex (w f) x, a)
  51. It'sPartialP phi a w -> do
  52. x <- check x (VEqStrict VI phi VI1)
  53. x_nf <- eval x
  54. pure (App P.Ex (w f) x, a @@ x_nf)
  55. infer (P.Proj1 x) = do
  56. (tm, ty) <- infer x
  57. (d, _, wp) <- isSigmaType ty
  58. pure (Proj1 (wp tm), d)
  59. infer (P.Proj2 x) = do
  60. (tm, ty) <- infer x
  61. tm_nf <- eval tm
  62. (_, r, wp) <- isSigmaType ty
  63. pure (Proj2 (wp tm), r (vProj1 tm_nf))
  64. infer exp = do
  65. t <- newMeta VType
  66. tm <- switch $ check exp t
  67. pure (tm, t)
  68. check :: P.Expr -> NFType -> ElabM Term
  69. check (P.Span ex a b) ty = withSpan a b $ check ex ty
  70. check (P.Lam p var body) (VPi p' dom (Closure _ rng)) | p == p' =
  71. assume (Bound var 0) dom $ \name ->
  72. Lam p name <$> check body (rng (VVar name))
  73. check tm (VPi P.Im dom (Closure var rng)) =
  74. assume var dom $ \name ->
  75. Lam P.Im name <$> check tm (rng (VVar name))
  76. check (P.Lam p v b) ty = do
  77. porp <- isPiType p =<< forceIO ty
  78. case porp of
  79. It'sProd d r wp ->
  80. assume (Bound v 0) d $ \name ->
  81. wp . Lam p name <$> check b (r (VVar name))
  82. It'sPath li le ri wp -> do
  83. tm <- assume (Bound v 0) VI $ \var ->
  84. Lam P.Ex var <$> check b (force (li (VVar var)))
  85. tm_nf <- eval tm
  86. unify (tm_nf @@ VI0) le `catchElab` (throwElab . WhenCheckingEndpoint (Bound v 0) le ri VI0)
  87. unify (tm_nf @@ VI1) ri `catchElab` (throwElab . WhenCheckingEndpoint (Bound v 0) le ri VI1)
  88. pure (wp (PathIntro (quote (fun li)) (quote le) (quote ri) tm))
  89. It'sPartial phi a wp ->
  90. assume (Bound v 0) (VEqStrict VI phi VI1) $ \var ->
  91. wp . Lam p var <$> check b a
  92. It'sPartialP phi a wp ->
  93. assume (Bound v 0) (VEqStrict VI phi VI1) $ \var ->
  94. wp . Lam p var <$> check b (a @@ VVar var)
  95. check (P.Pair a b) ty = do
  96. (d, r, wp) <- isSigmaType =<< forceIO ty
  97. a <- check a d
  98. a_nf <- eval a
  99. b <- check b (r a_nf)
  100. pure (wp (Pair a b))
  101. check (P.Pi p s d r) ty = do
  102. isSort ty
  103. d <- check d ty
  104. d_nf <- eval d
  105. assume (Bound s 0) d_nf \var -> do
  106. r <- check r ty
  107. pure (Pi p var d r)
  108. check (P.Sigma s d r) ty = do
  109. isSort ty
  110. d <- check d ty
  111. d_nf <- eval d
  112. assume (Bound s 0) d_nf \var -> do
  113. r <- check r ty
  114. pure (Sigma var d r)
  115. check (P.Let items body) ty = do
  116. checkLetItems mempty items \decs -> do
  117. body <- check body ty
  118. pure (Let decs body)
  119. check (P.LamSystem bs) ty = do
  120. (extent, dom) <- isPartialType ty
  121. let dom_q = quote dom
  122. eqns <- for (zip [(0 :: Int)..] bs) $ \(n, (formula, rhs)) -> do
  123. phi <- checkFormula (P.condF formula)
  124. rhses <-
  125. case P.condV formula of
  126. Just t -> assume (Bound t 0) (VEqStrict VI phi VI1) $ \var -> do
  127. env <- ask
  128. for (truthAssignments phi (getEnv env)) $ \e -> do
  129. let env' = env{ getEnv = e }
  130. local (const env') $
  131. (Just var,) <$> check rhs (eval' env' dom_q)
  132. Nothing -> do
  133. env <- ask
  134. for (truthAssignments phi (getEnv env)) $ \e -> do
  135. let env' = env{ getEnv = e }
  136. local (const env') $
  137. (Nothing,) <$> check rhs (eval' env' dom_q)
  138. pure (n, (phi, head rhses))
  139. unify extent (foldl ior VI0 (map (fst . snd) eqns))
  140. for_ eqns $ \(n, (formula, (binding, rhs))) -> do
  141. let
  142. k = case binding of
  143. Just v -> assume v (VEqStrict VI formula VI1) . const
  144. Nothing -> id
  145. k $ for_ eqns $ \(n', (formula', (binding, rhs'))) -> do
  146. let
  147. k = case binding of
  148. Just v -> assume v (VEqStrict VI formula VI1) . const
  149. Nothing -> id
  150. truth = possible mempty (iand formula formula')
  151. add [] = id
  152. add ((~(HVar x), True):xs) = redefine x VI VI1 . add xs
  153. add ((~(HVar x), False):xs) = redefine x VI VI0 . add xs
  154. k $ when ((n /= n') && fst truth) . add (Map.toList (snd truth)) $ do
  155. vl <- eval rhs
  156. vl' <- eval rhs'
  157. unify vl vl'
  158. `withNote` vsep [ pretty "These two cases must agree because they are both possible:"
  159. , indent 2 $ pretty '*' <+> prettyTm (quote formula) <+> operator (pretty "=>") <+> prettyTm rhs
  160. , indent 2 $ pretty '*' <+> prettyTm (quote formula') <+> operator (pretty "=>") <+> prettyTm rhs'
  161. ]
  162. `withNote` (pretty "Consider this face, where both are true:" <+> showFace False (snd truth))
  163. name <- newName
  164. let
  165. mkB name (Just v, b) = App P.Ex (Lam P.Ex v b) (Ref name)
  166. mkB _ (Nothing, b) = b
  167. pure (Lam P.Ex name (System (Map.fromList (map (\(_, (x, y)) -> (quote x, mkB name y)) eqns))))
  168. check (P.LamCase pats) ty =
  169. do
  170. porp <- isPiType P.Ex ty
  171. case porp of
  172. It'sProd dom rng wp -> do
  173. name <- newName
  174. let range = Lam P.Ex name (quote (rng (VVar name)))
  175. cases <- checkPatterns range [] pats \partialPats (pat, rhs) -> do
  176. checkPattern pat dom \pat wp boundary n_lams pat_nf -> do
  177. rhs <- check rhs (rng pat_nf)
  178. case boundary of
  179. -- If we're checking a higher constructor then we need to
  180. -- compute what the case expression computed so far does
  181. -- with all the faces
  182. -- and make sure that the current case agrees with that
  183. -- boundary
  184. Just boundary -> do
  185. rhs_nf <- eval (wp rhs)
  186. cases <- partialPats
  187. let
  188. (ty, a, b) = case pat_nf of
  189. VNe (HCon ty (ConName _ _ a b)) _ -> (ty, a, b)
  190. VNe (HPCon _ ty (ConName _ _ a b)) _ -> (ty, a, b)
  191. _ -> undefined
  192. dummies <- replicateM ((a + b) - length (getBoundaryNames boundary)) newName
  193. let
  194. base = appDummies (VVar <$> dummies) ty rhs_nf
  195. sys = boundaryFormulas (drop a dummies ++ getBoundaryNames boundary) (getBoundaryMap boundary)
  196. for_ (Map.toList sys) \(formula, side) -> do
  197. let rhs = cases @@ side
  198. for_ (truthAssignments formula mempty) $ \i -> do
  199. let vl = foldl (\v n -> vApp P.Ex v (lookup n)) base (getBoundaryNames boundary)
  200. lookup n = fromMaybe (VVar n) (snd <$> (Map.lookup n i))
  201. unify vl rhs
  202. `withNote` (pretty "From the boundary conditions of the constructor" <+> prettyTm (quote pat_nf) <> pretty ":")
  203. `withNote` vcat [ pretty "These must be the same because of the face"
  204. , indent 2 $ prettyVl (zonk formula) <+> operator (pretty "=>") <+> prettyVl (zonk side)
  205. , pretty "which is mapped to"
  206. , indent 2 $ prettyVl (zonk formula) <+> operator (pretty "=>") <+> prettyVl (zonk rhs)
  207. ]
  208. _ -> pure ()
  209. pure (pat, n_lams, wp rhs)
  210. let x = wp (Lam P.Ex name (Case range (Ref name) cases))
  211. pure x
  212. _ -> do
  213. dom <- newMeta VTypeω
  214. n <- newName' (Bound (T.singleton 'x') 0)
  215. assume n dom \_ -> do
  216. rng <- newMeta VTypeω
  217. throwElab $ NotEqual (VPi P.Ex dom (Closure n (const rng))) ty
  218. where
  219. checkPatterns _ acc [] _ = pure (reverse acc)
  220. checkPatterns rng acc (x:xs) k = do
  221. n <- newName
  222. (p, n, t) <- k (eval (Lam P.Ex n (Case rng (Ref n) acc))) x
  223. checkPatterns rng ((p, n, t):acc) xs k
  224. appDummies (v:vl) (VPi p _ (Closure _ r)) x = appDummies vl (r v) (vApp p x v)
  225. appDummies [] _ x = x
  226. appDummies vs t _ = error (show (vs, t))
  227. boundaryFormulas [] (VSystem fs) = fs
  228. boundaryFormulas (x:xs) k = boundaryFormulas xs $ k @@ VVar x
  229. boundaryFormulas a b = error (show (a, b))
  230. check P.Hole ty = do
  231. t <- newMeta ty
  232. pure (quote t)
  233. check exp ty = do
  234. (tm, has) <- switch $ infer exp
  235. wp <- isConvertibleTo has ty
  236. pure (wp tm)
  237. checkPattern :: P.Pattern -> NFSort -> (Term -> (Term -> Term) -> Maybe Boundary -> Int -> Value -> ElabM a) -> ElabM a
  238. checkPattern (P.PCap var) dom cont = do
  239. name <- asks (Map.lookup var . nameMap)
  240. case name of
  241. Just name@(ConName _ _ skip arity) -> do
  242. unless (arity == 0) $ throwElab $ UnsaturatedCon name
  243. (ty, wp, _) <- instantiate =<< getNfType name
  244. unify ty dom
  245. wrap <- skipLams skip
  246. cont (Con name) wrap Nothing 0 =<< eval (wp (Con name))
  247. Just name -> throwElab $ NotACon name
  248. Nothing -> assume (Bound var 0) dom \name -> cont (Ref name) (Lam P.Ex name) Nothing 0 (VVar name)
  249. checkPattern (P.PCon var args) dom cont =
  250. do
  251. name <- asks (Map.lookup var . nameMap)
  252. case name of
  253. Just name@(ConName _ _ nskip arity) -> do
  254. unless (arity == length args) $ throwElab $ UnsaturatedCon name
  255. (ty, wp, xs) <- instantiate =<< getNfType name
  256. _ <- isConvertibleTo (skipBinders arity ty) dom
  257. skip <- skipLams nskip
  258. t <- asks (Map.lookup name . boundaries)
  259. con <- quote <$> getValue name
  260. bindNames args ty $ \names wrap ->
  261. cont (Con name) (skip . wrap) (instBoundary xs <$> t) (length names) =<< eval (foldl (\x y -> App P.Ex x (Ref y)) (wp con) names)
  262. Just name -> throwElab $ NotACon name
  263. _ -> throwElab $ NotInScope (Bound var 0)
  264. where
  265. skipBinders :: Int -> NFType -> NFType
  266. skipBinders 0 t = t
  267. skipBinders n (VPi _ _ (Closure v r)) = skipBinders (n - 1) (r (VVar v))
  268. skipBinders _ _ = error $ "constructor type is wrong?"
  269. bindNames (n:ns) (VPi p d (Closure _ r)) k =
  270. assume (Bound n 0) d \n -> bindNames ns (r (VVar n)) \ns w ->
  271. k (n:ns) (Lam p n . w)
  272. bindNames [] _ k = k [] id
  273. bindNames xs t _ = error $ show (xs, t)
  274. instBoundary :: [Value] -> Boundary -> Boundary
  275. instBoundary metas (Boundary x y) = Boundary x (foldl (vApp P.Ex) y metas)
  276. instantiate :: NFType -> ElabM (NFType, Term -> Term, [Value])
  277. instantiate (VPi P.Im d (Closure _ k)) = do
  278. t <- newMeta d
  279. (ty, w, xs) <- instantiate (k t)
  280. pure (ty, \inner -> w (App P.Im inner (quote t)), t:xs)
  281. instantiate x = pure (x, id, [])
  282. skipLams :: Int -> ElabM (Term -> Term)
  283. skipLams 0 = pure id
  284. skipLams k = do
  285. n <- newName
  286. (Lam P.Im n . ) <$> skipLams (k - 1)
  287. checkLetItems :: Map Text (Maybe (Name, NFType)) -> [P.LetItem] -> ([(Name, Term, Term)] -> ElabM a) -> ElabM a
  288. checkLetItems map [] cont = do
  289. for_ (Map.toList map) $ \case
  290. (_, Nothing) -> pure ()
  291. (n, Just _) -> throwElab $ DeclaredUndefined (Bound n 0)
  292. cont []
  293. checkLetItems map (P.LetDecl v t:xs) cont = do
  294. t <- check t VTypeω
  295. t_nf <- eval t
  296. assume (Defined v 0) t_nf \name ->
  297. checkLetItems (Map.insert v (Just (name, t_nf)) map) xs cont
  298. checkLetItems map (P.LetBind name rhs:xs) cont = do
  299. case Map.lookup name map of
  300. Nothing -> do
  301. (tm, ty) <- infer rhs
  302. tm_nf <- eval tm
  303. makeLetDef (Defined name 0) ty tm_nf \name' ->
  304. checkLetItems map xs \xs ->
  305. cont ((name', quote ty, tm):xs)
  306. Just Nothing -> throwElab $ Redefinition (Defined name 0)
  307. Just (Just (name, ty_nf)) -> do
  308. rhs <- check rhs ty_nf
  309. rhs_nf <- eval rhs
  310. replaceLetDef name ty_nf rhs_nf $
  311. checkLetItems (Map.insert (getNameText name) Nothing map) xs \xs ->
  312. cont ((name, quote ty_nf, rhs):xs)
  313. checkFormula :: P.Formula -> ElabM Value
  314. checkFormula P.FTop = pure VI1
  315. checkFormula P.FBot = pure VI0
  316. checkFormula (P.FAnd x y) = iand <$> checkFormula x <*> checkFormula y
  317. checkFormula (P.FOr x y) = ior <$> checkFormula x <*> checkFormula y
  318. checkFormula (P.FIs0 x) = do
  319. nm <- getNameFor x
  320. ty <- getNfType nm
  321. unify ty VI
  322. pure (inot (VVar nm))
  323. checkFormula (P.FIs1 x) = do
  324. nm <- getNameFor x
  325. ty <- getNfType nm
  326. unify ty VI
  327. pure (VVar nm)
  328. isSort :: NFType -> ElabM ()
  329. isSort t = isSort (force t) where
  330. isSort VType = pure ()
  331. isSort VTypeω = pure ()
  332. isSort vt@(VNe HMeta{} _) = unify vt VType
  333. isSort vt = throwElab $ NotEqual vt VType
  334. data ProdOrPath
  335. = It'sProd { prodDmn :: NFType
  336. , prodRng :: NFType -> NFType
  337. , prodWrap :: Term -> Term
  338. }
  339. | It'sPath { pathLine :: NFType -> NFType
  340. , pathLeft :: Value
  341. , pathRight :: Value
  342. , pathWrap :: Term -> Term
  343. }
  344. | It'sPartial { partialExtent :: NFEndp
  345. , partialDomain :: Value
  346. , partialWrap :: Term -> Term
  347. }
  348. | It'sPartialP { partialExtent :: NFEndp
  349. , partialDomain :: Value
  350. , partialWrap :: Term -> Term
  351. }
  352. isPiType :: P.Plicity -> NFType -> ElabM ProdOrPath
  353. isPiType p x = isPiType p (force x) where
  354. isPiType p (VPi p' d (Closure _ k)) | p == p' = pure (It'sProd d k id)
  355. isPiType P.Ex (VPath li le ri) = pure (It'sPath (li @@) le ri id)
  356. isPiType P.Ex (VPartial phi a) = pure (It'sPartial phi a id)
  357. isPiType P.Ex (VPartialP phi a) = pure (It'sPartialP phi a id)
  358. isPiType P.Ex (VPi P.Im d (Closure _ k)) = do
  359. meta <- newMeta d
  360. porp <- isPiType P.Ex (k meta)
  361. pure $ case porp of
  362. It'sProd d r w -> It'sProd d r (\f -> w (App P.Im f (quote meta)))
  363. It'sPath l x y w -> It'sPath l x y (\f -> w (App P.Im f (quote meta)))
  364. It'sPartial phi a w -> It'sPartial phi a (\f -> w (App P.Im f (quote meta)))
  365. It'sPartialP phi a w -> It'sPartialP phi a (\f -> w (App P.Im f (quote meta)))
  366. isPiType p t = do
  367. dom <- newMeta VType
  368. name <- newName
  369. assume name dom $ \name -> do
  370. rng <- newMeta VType
  371. wp <- isConvertibleTo t (VPi p dom (Closure name (const rng)))
  372. pure (It'sProd dom (const rng) wp)
  373. isSigmaType :: NFType -> ElabM (Value, NFType -> NFType, Term -> Term)
  374. isSigmaType t = isSigmaType (force t) where
  375. isSigmaType (VSigma d (Closure _ k)) = pure (d, k, id)
  376. isSigmaType t = do
  377. dom <- newMeta VType
  378. name <- newName
  379. assume name dom $ \name -> do
  380. rng <- newMeta VType
  381. wp <- isConvertibleTo t (VSigma dom (Closure name (const rng)))
  382. pure (dom, const rng, wp)
  383. isPartialType :: NFType -> ElabM (NFEndp, Value)
  384. isPartialType t = isPartialType (force t) where
  385. isPartialType (VPartial phi a) = pure (phi, a)
  386. isPartialType (VPartialP phi a) = pure (phi, a)
  387. isPartialType t = do
  388. phi <- newMeta VI
  389. dom <- newMeta (VPartial phi VType)
  390. unify t (VPartial phi dom)
  391. pure (phi, dom)
  392. checkStatement :: P.Statement -> ElabM a -> ElabM a
  393. checkStatement (P.SpanSt s a b) k = withSpan a b $ checkStatement s k
  394. checkStatement (P.Decl name ty) k = do
  395. ty <- check ty VTypeω
  396. ty_nf <- eval ty
  397. assumes (flip Defined 0 <$> name) ty_nf (const k)
  398. checkStatement (P.Postulate []) k = k
  399. checkStatement (P.Postulate ((name, ty):xs)) k = do
  400. ty <- check ty VTypeω
  401. ty_nf <- eval ty
  402. assume (Defined name 0) ty_nf \name ->
  403. local (\e -> e { definedNames = Set.insert name (definedNames e) }) (checkStatement (P.Postulate xs) k)
  404. checkStatement (P.Defn name rhs) k = do
  405. ty <- asks (Map.lookup name . nameMap)
  406. case ty of
  407. Nothing -> do
  408. (tm, ty) <- infer rhs
  409. tm_nf <- eval tm
  410. makeLetDef (Defined name 0) ty tm_nf (const k)
  411. Just nm -> do
  412. ty_nf <- getNfType nm
  413. t <- asks (Set.member nm . definedNames)
  414. when t $ throwElab (Redefinition (Defined name 0))
  415. rhs <- check rhs ty_nf
  416. rhs_nf <- evalFix (Defined name 0) ty_nf rhs
  417. makeLetDef (Defined name 0) ty_nf rhs_nf $ \name ->
  418. local (\e -> e { definedNames = Set.insert name (definedNames e) }) k
  419. checkStatement (P.Builtin winame var) k = do
  420. wi <-
  421. case Map.lookup winame wiredInNames of
  422. Just wi -> pure wi
  423. _ -> throwElab $ NoSuchPrimitive winame
  424. let
  425. check = do
  426. nm <- getNameFor var
  427. ty <- getNfType nm
  428. unify ty (wiType wi)
  429. `withNote` hsep [ pretty "Previous definition of", pretty nm, pretty "here" ]
  430. `seeAlso` nm
  431. env <- ask
  432. liftIO $
  433. runElab check env `catch` \(_ :: NotInScope) -> pure ()
  434. define (Defined var 0) (wiType wi) (wiValue wi) $ \name ->
  435. local (\e -> e { definedNames = Set.insert name (definedNames e) }) k
  436. checkStatement (P.ReplNf e) k = do
  437. (e, _) <- infer e
  438. e_nf <- eval e
  439. h <- asks commHook
  440. liftIO $ h . prettyVl =<< zonkIO e_nf
  441. k
  442. checkStatement (P.ReplTy e) k = do
  443. (t, ty) <- infer e
  444. h <- asks commHook
  445. liftIO (h (prettyTm t <+> colon <+> align (prettyVl ty)))
  446. k
  447. checkStatement (P.Data name tele retk constrs) k =
  448. do
  449. checkTeleRetk True tele retk \kind tele undef -> do
  450. kind_nf <- eval kind
  451. defineInternal (Defined name 0) kind_nf (\name' -> VNe (mkHead name') mempty) \name' ->
  452. checkCons tele (VNe (mkHead name') (Seq.fromList (map makeProj tele))) constrs (local (markAsDef name' . undef) k)
  453. where
  454. makeProj (x, p, _) = PApp p (VVar x)
  455. markAsDef x e = e { definedNames = Set.insert x (definedNames e) }
  456. mkHead name
  457. | any (\case { (_, _, P.Path{}) -> True; _ -> False}) constrs = HData True name
  458. | otherwise = HData False name
  459. checkTeleRetk allKan [] retk cont = do
  460. t <- check retk VTypeω
  461. t_nf <- eval t
  462. when allKan $ unify t_nf VType
  463. cont t [] id
  464. checkTeleRetk allKan ((x, p, t):xs) retk cont = do
  465. (t, ty) <- infer t
  466. _ <- isConvertibleTo ty VTypeω
  467. let
  468. allKan' = case ty of
  469. VType -> allKan
  470. _ -> False
  471. t_nf <- eval t
  472. let rm nm e = e{ nameMap = Map.delete (getNameText nm) (nameMap e), getEnv = Map.delete nm (getEnv e) }
  473. assume (Bound x 0) t_nf $ \nm -> checkTeleRetk allKan' xs retk \k xs w -> cont (Pi p nm t k) ((nm, p, t_nf):xs) (rm nm . w)
  474. checkCons _ _et [] k = k
  475. checkCons n ret ((s, e, P.Point x ty):xs) k = withSpan s e $ do
  476. t <- check ty VTypeω
  477. ty_nf <- eval t
  478. let
  479. (args, ret') = splitPi ty_nf
  480. closed = close n t
  481. n' = map (\(x, _, y) -> (x, P.Im, y)) n
  482. unify ret' ret
  483. closed_nf <- eval closed
  484. defineInternal (ConName x 0 (length n') (length args)) closed_nf (makeCon closed_nf mempty n' args) \_ -> checkCons n ret xs k
  485. checkCons n ret ((s, e, P.Path name indices return faces):xs) k = withSpan s e $ do
  486. (con, closed_nf, value, boundary) <- assumes (flip Bound 0 <$> indices) VI \indices -> do
  487. t <- check return VTypeω
  488. ty_nf <- eval t
  489. let
  490. (args, ret') = splitPi ty_nf
  491. closed = close n (addArgs args (addInterval indices (quote ret')))
  492. n' = map (\(x, _, y) -> (x, P.Im, y)) n
  493. addArgs = flip $ foldr (\(x, p, t) -> Pi p x (quote t))
  494. addInterval = flip $ foldr (\n -> Pi P.Ex n I)
  495. envArgs ((x, _, y):xs) = assume x y . const . envArgs xs
  496. envArgs [] = id
  497. closed_nf <- eval closed
  498. unify ret' ret
  499. faces <- envArgs args $ for faces \(f, t) -> do
  500. phi <- checkFormula f
  501. t <- check t ret
  502. pure (phi, (quote phi, t))
  503. system <- eval $ foldr (\x -> Lam P.Ex x) (System (Map.fromList (map snd faces))) (map (\(x, _, _) -> x) n' ++ map (\(x, _, _) -> x) args ++ indices)
  504. unify (foldl ior VI0 (map fst faces)) (totalProp indices)
  505. `withNote` pretty "The formula determining the endpoints of a higher constructor must be a classical tautology"
  506. pure (ConName name 0 (length n') (length args + length indices), closed_nf, makePCon closed_nf mempty n' args indices system, Boundary indices system)
  507. defineInternal con closed_nf value \name -> addBoundary name boundary $ checkCons n ret xs k
  508. close [] t = t
  509. close ((x, _, y):xs) t = Pi P.Im x (quote y) (close xs t)
  510. splitPi (VPi p y (Closure x k)) = first ((x, p, y):) $ splitPi (k (VVar x))
  511. splitPi t = ([], t)
  512. makeCon cty sp [] [] con = VNe (HCon cty con) sp
  513. makeCon cty sp ((nm, p, _):xs) ys con = VLam p $ Closure nm \a -> makeCon cty (sp Seq.:|> PApp p a) xs ys con
  514. makeCon cty sp [] ((nm, p, _):ys) con = VLam p $ Closure nm \a -> makeCon cty (sp Seq.:|> PApp p a) [] ys con
  515. makePCon cty sp [] [] [] sys con = VNe (HPCon sys cty con) sp
  516. makePCon cty sp ((nm, p, _):xs) ys zs sys con = VLam p $ Closure nm \a -> makePCon cty (sp Seq.:|> PApp p a) xs ys zs (sys @@ a) con
  517. makePCon cty sp [] ((nm, p, _):ys) zs sys con = VLam p $ Closure nm \a -> makePCon cty (sp Seq.:|> PApp p a) [] ys zs (sys @@ a) con
  518. makePCon cty sp [] [] (nm:zs) sys con = VLam P.Ex $ Closure nm \a -> makePCon cty (sp Seq.:|> PApp P.Ex a) [] [] zs (sys @@ a) con
  519. totalProp (x:xs) = ior (VVar x) (inot (VVar x) `ior` totalProp xs)
  520. totalProp [] = VI0
  521. checkProgram :: [P.Statement] -> ElabM a -> ElabM a
  522. checkProgram [] k = k
  523. checkProgram (st:sts) k = checkStatement st $ checkProgram sts k
  524. newtype Redefinition = Redefinition { getRedefName :: Name }
  525. deriving (Show, Typeable, Exception)
  526. data WhenCheckingEndpoint = WhenCheckingEndpoint { direction :: Name, leftEndp :: Value, rightEndp :: Value, whichIsWrong :: NFEndp, exc :: SomeException }
  527. deriving (Show, Typeable, Exception)
  528. data UnsaturatedCon = UnsaturatedCon { theConstr :: Name }
  529. deriving (Show, Typeable)
  530. deriving anyclass (Exception)
  531. data NotACon = NotACon { theNotConstr :: Name }
  532. deriving (Show, Typeable)
  533. deriving anyclass (Exception)
  534. newtype DeclaredUndefined = DeclaredUndefined { declaredUndefName :: Name }
  535. deriving (Eq, Show, Exception)