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.

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