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.

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