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.

674 lines
25 KiB

  1. {-# LANGUAGE BlockArguments #-}
  2. {-# LANGUAGE LambdaCase #-}
  3. {-# LANGUAGE DeriveAnyClass #-}
  4. {-# LANGUAGE ScopedTypeVariables #-}
  5. {-# LANGUAGE ViewPatterns #-}
  6. {-# LANGUAGE TupleSections #-}
  7. module Elab.Eval where
  8. import Control.Monad.Reader
  9. import Control.Exception
  10. import qualified Data.Map.Strict as Map
  11. import qualified Data.Sequence as Seq
  12. import qualified Data.Set as Set
  13. import qualified Data.Text as T
  14. import Data.Map.Strict (Map)
  15. import Data.Sequence (Seq)
  16. import Data.List (sortOn)
  17. import Data.Traversable
  18. import Data.Set (Set)
  19. import Data.Typeable
  20. import Data.Foldable
  21. import Data.IORef
  22. import Data.Maybe
  23. import Elab.Eval.Formula
  24. import Elab.Monad
  25. import GHC.Stack
  26. import Presyntax.Presyntax (Plicity(..))
  27. import Prettyprinter
  28. import Syntax.Pretty
  29. import Syntax
  30. import System.IO.Unsafe ( unsafePerformIO )
  31. import {-# SOURCE #-} Elab.WiredIn
  32. eval :: HasCallStack => Term -> ElabM Value
  33. eval t = asks (flip eval' t)
  34. -- everywhere force
  35. zonkIO :: Value -> IO Value
  36. zonkIO (VNe hd sp) = do
  37. sp' <- traverse zonkSp sp
  38. case hd of
  39. HMeta (mvCell -> cell) -> do
  40. solved <- liftIO $ readIORef cell
  41. case solved of
  42. Just vl -> zonkIO $ foldl applProj vl sp'
  43. Nothing -> pure $ VNe hd sp'
  44. hd -> pure $ VNe hd sp'
  45. zonkIO (GluedVl h sp vl) = GluedVl h <$> traverse zonkSp sp <*> zonkIO vl
  46. zonkIO (VLam p (Closure s k)) = pure $ VLam p (Closure s (zonk . k))
  47. zonkIO (VPi p d (Closure s k)) = VPi p <$> zonkIO d <*> pure (Closure s (zonk . k))
  48. zonkIO (VSigma d (Closure s k)) = VSigma <$> zonkIO d <*> pure (Closure s (zonk . k))
  49. zonkIO (VPair a b) = VPair <$> zonkIO a <*> zonkIO b
  50. zonkIO (VPath line x y) = VPath <$> zonkIO line <*> zonkIO x <*> zonkIO y
  51. zonkIO (VLine line x y f) = VLine <$> zonkIO line <*> zonkIO x <*> zonkIO y <*> zonkIO f
  52. -- Sorts
  53. zonkIO VType = pure VType
  54. zonkIO VTypeω = pure VTypeω
  55. zonkIO VI = pure VI
  56. zonkIO VI0 = pure VI0
  57. zonkIO VI1 = pure VI1
  58. zonkIO (VIAnd x y) = iand <$> zonkIO x <*> zonkIO y
  59. zonkIO (VIOr x y) = ior <$> zonkIO x <*> zonkIO y
  60. zonkIO (VINot x) = inot <$> zonkIO x
  61. zonkIO (VIsOne x) = VIsOne <$> zonkIO x
  62. zonkIO VItIsOne = pure VItIsOne
  63. zonkIO (VPartial x y) = VPartial <$> zonkIO x <*> zonkIO y
  64. zonkIO (VPartialP x y) = VPartialP <$> zonkIO x <*> zonkIO y
  65. zonkIO (VSystem fs) = do
  66. t <- for (Map.toList fs) $ \(a, b) -> (,) <$> zonkIO a <*> zonkIO b
  67. pure (mkVSystem (Map.fromList t))
  68. zonkIO (VSub a b c) = VSub <$> zonkIO a <*> zonkIO b <*> zonkIO c
  69. zonkIO (VInc a b c) = VInc <$> zonkIO a <*> zonkIO b <*> zonkIO c
  70. zonkIO (VComp a b c d) = comp <$> zonkIO a <*> zonkIO b <*> zonkIO c <*> zonkIO d
  71. zonkIO (VHComp a b c d) = hComp <$> zonkIO a <*> zonkIO b <*> zonkIO c <*> zonkIO d
  72. zonkIO (VGlueTy a phi ty e) = glueType <$> zonkIO a <*> zonkIO phi <*> zonkIO ty <*> zonkIO e
  73. zonkIO (VGlue a phi ty e t x) = glueElem <$> zonkIO a <*> zonkIO phi <*> zonkIO ty <*> zonkIO e <*> zonkIO t <*> zonkIO x
  74. zonkIO (VUnglue a phi ty e x) = unglue <$> zonkIO a <*> zonkIO phi <*> zonkIO ty <*> zonkIO e <*> zonkIO x
  75. zonkIO (VCase env t x xs) = do
  76. env' <- (\x -> x {getEnv = env}) <$> emptyEnv
  77. let xs' = map (\(a, i, n) -> (a, i, quote (eval' env' n))) xs
  78. evalCase env' . (@@) <$> zonkIO t <*> zonkIO x <*> pure xs'
  79. zonkIO (VEqStrict a x y) = VEqStrict <$> zonkIO a <*> zonkIO x <*> zonkIO y
  80. zonkIO (VReflStrict a x) = VReflStrict <$> zonkIO a <*> zonkIO x
  81. zonkSp :: Projection -> IO Projection
  82. zonkSp (PApp p x) = PApp p <$> zonkIO x
  83. zonkSp (PIElim l x y i) = PIElim <$> zonkIO l <*> zonkIO x <*> zonkIO y <*> zonkIO i
  84. zonkSp (POuc a phi u) = POuc <$> zonkIO a <*> zonkIO phi <*> zonkIO u
  85. zonkSp (PK a x p pr) = PK <$> zonkIO a <*> zonkIO x <*> zonkIO p <*> zonkIO pr
  86. zonkSp (PJ a x p pr y) = PJ <$> zonkIO a <*> zonkIO x <*> zonkIO p <*> zonkIO pr <*> zonkIO y
  87. zonkSp PProj1 = pure PProj1
  88. zonkSp PProj2 = pure PProj2
  89. zonk :: Value -> Value
  90. zonk = unsafePerformIO . zonkIO
  91. eval' :: HasCallStack => ElabEnv -> Term -> Value
  92. eval' env (Ref x) =
  93. case Map.lookup x (getEnv env) of
  94. Just (_, vl) -> vl
  95. _ -> VNe (HVar x) mempty
  96. eval' env (Con x) =
  97. case Map.lookup x (getEnv env) of
  98. Just (ty, _) -> VNe (HCon ty x) mempty
  99. Nothing -> error $ "constructor " ++ show x ++ " has no type in scope"
  100. eval' env (PCon sys x) =
  101. case Map.lookup x (getEnv env) of
  102. Just (ty, _) -> VNe (HPCon (eval' env sys) ty x) mempty
  103. Nothing -> error $ "constructor " ++ show x ++ " has no type in scope"
  104. eval' _ (Data n x) = VNe (HData n x) mempty
  105. eval' env (App p f x) = vApp p (eval' env f) (eval' env x)
  106. eval' env (Lam p s t) =
  107. VLam p $ Closure s $ \a ->
  108. eval' env { getEnv = Map.insert s (error "type of abs", a) (getEnv env) } t
  109. eval' env (Pi p s d t) =
  110. VPi p (eval' env d) $ Closure s $ \a ->
  111. eval' env { getEnv = (Map.insert s (error "type of abs", a) (getEnv env))} t
  112. eval' _ (Meta m) = VNe (HMeta m) mempty
  113. eval' env (Sigma s d t) =
  114. VSigma (eval' env d) $ Closure s $ \a ->
  115. eval' env { getEnv = Map.insert s (error "type of abs", a) (getEnv env) } t
  116. eval' e (Pair a b) = VPair (eval' e a) (eval' e b)
  117. eval' e (Proj1 a) = vProj1 (eval' e a)
  118. eval' e (Proj2 a) = vProj2 (eval' e a)
  119. eval' _ Type = VType
  120. eval' _ Typeω = VTypeω
  121. eval' _ I = VI
  122. eval' _ I0 = VI0
  123. eval' _ I1 = VI1
  124. eval' e (IAnd x y) = iand (eval' e x) (eval' e y)
  125. eval' e (IOr x y) = ior (eval' e x) (eval' e y)
  126. eval' e (INot x) = inot (eval' e x)
  127. eval' e (PathP l a b) = VPath (eval' e l) (eval' e a) (eval' e b)
  128. eval' e (IElim l x y f i) = ielim (eval' e l) (eval' e x) (eval' e y) (eval' e f) (eval' e i)
  129. eval' e (PathIntro p x y f) = VLine (eval' e p) (eval' e x) (eval' e y) (eval' e f)
  130. eval' e (IsOne i) = VIsOne (eval' e i)
  131. eval' _ ItIsOne = VItIsOne
  132. eval' e (Partial x y) = VPartial (eval' e x) (eval' e y)
  133. eval' e (PartialP x y) = VPartialP (eval' e x) (eval' e y)
  134. eval' e (System fs) = mkVSystem (Map.fromList $ map (\(x, y) -> (eval' e x, eval' e y)) $ Map.toList $ fs)
  135. eval' e (Sub a phi u) = VSub (eval' e a) (eval' e phi) (eval' e u)
  136. eval' e (Inc a phi u) = VInc (eval' e a) (eval' e phi) (eval' e u)
  137. eval' e (Ouc a phi u x) = outS (eval' e a) (eval' e phi) (eval' e u) (eval' e x)
  138. eval' e (Comp a phi u a0) = comp (eval' e a) (eval' e phi) (eval' e u) (eval' e a0)
  139. eval' e (HComp a phi u a0) = hComp (eval' e a) (eval' e phi) (eval' e u) (eval' e a0)
  140. eval' e (GlueTy a phi tys f) = glueType (eval' e a) (eval' e phi) (eval' e tys) (eval' e f)
  141. eval' e (Glue a phi tys eqvs t x) = glueElem (eval' e a) (eval' e phi) (eval' e tys) (eval' e eqvs) (eval' e t) (eval' e x)
  142. eval' e (Unglue a phi tys f x) = unglue (eval' e a) (eval' e phi) (eval' e tys) (eval' e f) (eval' e x)
  143. eval' e (Let ns x) =
  144. let env' = foldl (\newe (n, ty, x) ->
  145. let nft = eval' newe ty
  146. in newe { getEnv = Map.insert n (nft, evalFix' newe n nft x) (getEnv newe) })
  147. e
  148. ns
  149. in eval' env' x
  150. eval' e (Case range sc xs) = evalCase e (eval' e range @@) (force (eval' e sc)) xs
  151. eval' e (EqS a x y) = VEqStrict (eval' e a) (eval' e x) (eval' e y)
  152. eval' e (Syntax.Refl a x) = VReflStrict (eval' e a) (eval' e x)
  153. eval' e (Syntax.AxK a x p pr eq) = strictK (eval' e a) (eval' e x) (eval' e p) (eval' e pr) (eval' e eq)
  154. eval' e (Syntax.AxJ a x p pr y eq) = strictJ (eval' e a) (eval' e x) (eval' e p) (eval' e pr) (eval' e y) (eval' e eq)
  155. evalCase :: ElabEnv -> (Value -> Value) -> Value -> [(Term, Int, Term)] -> Value
  156. evalCase _ _ sc [] = error $ "unmatched pattern for value: " ++ show (prettyTm (quote sc))
  157. evalCase env rng (VSystem fs) cases = VSystem (fmap (flip (evalCase env rng) cases) fs)
  158. evalCase env rng (VHComp a phi u a0) cases =
  159. comp (fun \i -> rng (v i)) phi (system \i is1 -> evalCase env rng (u @@ i @@ is1) cases)
  160. (VInc (rng a) phi (evalCase env rng (outS a0 phi (u @@ VI0) a0) cases))
  161. where
  162. v = Elab.WiredIn.fill (fun (const a)) phi u a0
  163. evalCase env _ sc ((Ref _, _, k):_) = eval' env k @@ sc
  164. evalCase env rng (val@(VNe (HCon _ x) sp)) ((Con x', _, k):xs)
  165. | x == x' = foldl applProj (eval' env k) sp
  166. | otherwise = evalCase env rng val xs
  167. evalCase env rng (val@(VNe (HPCon _ _ x) sp)) ((Con x', _, k):xs)
  168. | x == x' = foldl applProj (eval' env k) sp
  169. | otherwise = evalCase env rng val xs
  170. evalCase env rng sc xs = VCase (getEnv env) (fun rng) sc xs
  171. evalFix' :: ElabEnv -> Name -> NFType -> Term -> Value
  172. evalFix' env name nft term = fix $ \val -> eval' env{ getEnv = Map.insert name (nft, val) (getEnv env) } term
  173. evalFix :: Name -> NFType -> Term -> ElabM Value
  174. evalFix name nft term = do
  175. t <- ask
  176. pure (evalFix' t name nft term)
  177. data NotEqual = NotEqual Value Value
  178. deriving (Show, Typeable, Exception)
  179. unify' :: HasCallStack => Value -> Value -> ElabM ()
  180. unify' topa topb = join $ go <$> forceIO topa <*> forceIO topb where
  181. go (VNe (HMeta mv) sp) rhs = solveMeta mv sp rhs
  182. go rhs (VNe (HMeta mv) sp) = solveMeta mv sp rhs
  183. go (VNe (HPCon s _ _) _) rhs = go (force s) rhs
  184. go lhs (VNe (HPCon s _ _) _) = go lhs (force s)
  185. go (VCase e _ a b) (VCase e' _ a' b') = do
  186. env <- ask
  187. unify' a a'
  188. let go (_, _, a) (_, _, b) = unify' (eval' env{getEnv=e} a) (eval' env{getEnv=e'} b)
  189. zipWithM_ go (sortOn (\(x, _, _) -> x) b) (sortOn (\(x, _, _) -> x) b')
  190. go (VCase e _ _ b) y = do
  191. env <- ask
  192. let
  193. go (_, n, a') = do
  194. ns <- replicateM n (VVar <$> newName)
  195. let a = foldl (vApp Ex) (eval' env{getEnv=e} a') ns
  196. unify' a y
  197. traverse_ go b
  198. go (VNe x a) (VNe x' a')
  199. | x == x', length a == length a' =
  200. traverse_ (uncurry unify'Spine) (Seq.zip a a')
  201. go (VLam p (Closure n k)) vl = do
  202. t <- VVar <$> newName' n
  203. unify' (k t) (vApp p vl t)
  204. go vl (VLam p (Closure n k)) = do
  205. t <- VVar <$> newName' n
  206. unify' (vApp p vl t) (k t)
  207. go (VPair a b) vl = unify' a (vProj1 vl) *> unify' b (vProj2 vl)
  208. go vl (VPair a b) = unify' (vProj1 vl) a *> unify' (vProj2 vl) b
  209. go (VPi p d (Closure _ k)) (VPi p' d' (Closure _ k')) | p == p' = do
  210. t <- VVar <$> newName
  211. unify' d d'
  212. unify' (k t) (k' t)
  213. go (VSigma d (Closure _ k)) (VSigma d' (Closure _ k')) = do
  214. t <- VVar <$> newName
  215. unify' d d'
  216. unify' (k t) (k' t)
  217. go VType VType = pure ()
  218. go VTypeω VTypeω = pure ()
  219. go VI VI = pure ()
  220. go (VPath l x y) (VPath l' x' y') = do
  221. unify' l l'
  222. unify' x x'
  223. unify' y y'
  224. go (VLine l x y p) p' = do
  225. n <- VVar <$> newName
  226. unify' (p @@ n) (ielim l x y p' n)
  227. go p' (VLine l x y p) = do
  228. n <- VVar <$> newName
  229. unify' (ielim l x y p' n) (p @@ n)
  230. go (VIsOne x) (VIsOne y) = unify' x y
  231. -- IsOne is proof-irrelevant:
  232. go VItIsOne _ = pure ()
  233. go _ VItIsOne = pure ()
  234. go (VPartial phi r) (VPartial phi' r') = unify' phi phi' *> unify' r r'
  235. go (VPartialP phi r) (VPartialP phi' r') = unify' phi phi' *> unify' r r'
  236. go (VSub a phi u) (VSub a' phi' u') = traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u')]
  237. go (VInc a phi u) (VInc a' phi' u') = traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u')]
  238. go (VComp a phi u a0) (VComp a' phi' u' a0') =
  239. traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u'), (a0, a0')]
  240. go (VGlueTy _ (force -> VI1) u _0) rhs = unify' (u @@ VItIsOne) rhs
  241. go lhs (VGlueTy _ (force -> VI1) u _0) = unify' lhs (u @@ VItIsOne)
  242. go (VGlueTy a phi u a0) (VGlueTy a' phi' u' a0') =
  243. traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u'), (a0, a0')]
  244. go (VGlue a phi u a0 t x) (VGlue a' phi' u' a0' t' x') =
  245. traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u'), (a0, a0'), (t, t'), (x, x')]
  246. go (VSystem sys) rhs = goSystem unify' sys rhs
  247. go rhs (VSystem sys) = goSystem (flip unify') sys rhs
  248. go (VEqStrict a x y) (VEqStrict a' x' y') = traverse_ (uncurry unify') [(a, a'), (x, x'), (y, y')]
  249. go (VReflStrict a x) (VReflStrict a' x') = traverse_ (uncurry unify') [(a, a'), (x, x')]
  250. go x y
  251. | x == y = pure ()
  252. | otherwise =
  253. case (toDnf x, toDnf y) of
  254. (Just xs, Just ys) -> unify'Formula xs ys
  255. _ -> fail
  256. goSystem :: (Value -> Value -> ElabM ()) -> Map.Map Value Value -> Value -> ElabM ()
  257. goSystem k sys rhs = do
  258. let rhs_q = quote rhs
  259. env <- ask
  260. for_ (Map.toList sys) $ \(f, i) -> do
  261. let i_q = quote i
  262. for (truthAssignments f (getEnv env)) $ \e ->
  263. k (eval' env{getEnv = e} i_q) (eval' env{getEnv = e} rhs_q)
  264. fail = throwElab $ NotEqual topa topb
  265. unify'Spine (PApp a v) (PApp a' v')
  266. | a == a' = unify' v v'
  267. unify'Spine PProj1 PProj1 = pure ()
  268. unify'Spine PProj2 PProj2 = pure ()
  269. unify'Spine (PIElim _ _ _ i) (PIElim _ _ _ j) = unify' i j
  270. unify'Spine (POuc a phi u) (POuc a' phi' u') =
  271. traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u')]
  272. unify'Spine (PK a x p pr) (PK a' x' p' pr') =
  273. traverse_ (uncurry unify') [(a, a'), (x, x'), (p, p'), (pr, pr')]
  274. unify'Spine (PJ a x p pr y) (PJ a' x' p' pr' y') =
  275. traverse_ (uncurry unify') [(a, a'), (x, x'), (p, p'), (pr, pr'), (y, y')]
  276. unify'Spine _ _ = fail
  277. unify'Formula x y
  278. | compareDNFs x y = pure ()
  279. | otherwise = fail
  280. unify :: HasCallStack => Value -> Value -> ElabM ()
  281. unify a b = unify' a b `catchElab` \(_ :: SomeException) -> liftIO $ throwIO (NotEqual a b)
  282. isConvertibleTo :: Value -> Value -> ElabM (Term -> Term)
  283. isConvertibleTo a b = isConvertibleTo (force a) (force b) where
  284. VPi Im d (Closure _v k) `isConvertibleTo` ty = do
  285. meta <- newMeta d
  286. cont <- k meta `isConvertibleTo` ty
  287. pure (\f -> cont (App Im f (quote meta)))
  288. VType `isConvertibleTo` VTypeω = pure id
  289. VPi p d (Closure _ k) `isConvertibleTo` VPi p' d' (Closure _ k') | p == p' = do
  290. wp <- d' `isConvertibleTo` d
  291. n <- newName
  292. wp_n <- eval (Lam Ex n (wp (Ref n)))
  293. wp' <- k (VVar n) `isConvertibleTo` k' (wp_n @@ VVar n)
  294. pure (\f -> Lam p n (wp' (App p f (wp (Ref n)))))
  295. isConvertibleTo a b = do
  296. unify' a b
  297. pure id
  298. newMeta :: Value -> ElabM Value
  299. newMeta dom = do
  300. loc <- liftM2 (,) <$> asks currentFile <*> asks currentSpan
  301. n <- newName
  302. c <- liftIO $ newIORef Nothing
  303. let m = MV (getNameText n) c dom (flatten <$> loc)
  304. flatten (x, (y, z)) = (x, y, z)
  305. env <- asks getEnv
  306. t <- for (Map.toList env) $ \(n, _) -> pure $
  307. case n of
  308. Bound{} -> Just (PApp Ex (VVar n))
  309. _ -> Nothing
  310. pure (VNe (HMeta m) (Seq.fromList (catMaybes t)))
  311. newName :: MonadIO m => m Name
  312. newName = liftIO $ do
  313. x <- atomicModifyIORef _nameCounter $ \x -> (x + 1, x + 1)
  314. pure (Bound (T.pack (show x)) x)
  315. newName' :: Name -> ElabM Name
  316. newName' n = do
  317. ~(Bound _ x) <- newName
  318. pure (Bound (getNameText n) x)
  319. _nameCounter :: IORef Int
  320. _nameCounter = unsafePerformIO $ newIORef 0
  321. {-# NOINLINE _nameCounter #-}
  322. solveMeta :: MV -> Seq Projection -> Value -> ElabM ()
  323. solveMeta m@(mvCell -> cell) sp rhs = do
  324. env <- ask
  325. names <- tryElab $ checkSpine Set.empty sp
  326. case names of
  327. Right names -> do
  328. checkScope (Set.fromList names) rhs
  329. `withNote` hsep [prettyTm (quote (VNe (HMeta m) sp)), pretty '≡', prettyTm (quote rhs)]
  330. let tm = quote rhs
  331. lam = eval' env $ foldr (Lam Ex) tm names
  332. liftIO . atomicModifyIORef' cell $ \case
  333. Just _ -> error "filled cell in solvedMeta"
  334. Nothing -> (Just lam, ())
  335. Left (_ :: SpineProjection) -> do
  336. liftIO . atomicModifyIORef' (unsolvedMetas env) $ \x -> (, ()) $
  337. case Map.lookup m x of
  338. Just qs -> Map.insert m ((sp, rhs):qs) x
  339. Nothing -> Map.insert m [(sp, rhs)] x
  340. checkScope :: Set Name -> Value -> ElabM ()
  341. checkScope scope (VNe h sp) =
  342. do
  343. case h of
  344. HVar v@Bound{} ->
  345. unless (v `Set.member` scope) . throwElab $
  346. NotInScope v
  347. HVar{} -> pure ()
  348. HCon{} -> pure ()
  349. HPCon{} -> pure ()
  350. HMeta{} -> pure ()
  351. HData{} -> pure ()
  352. traverse_ checkProj sp
  353. where
  354. checkProj (PApp _ t) = checkScope scope t
  355. checkProj (PIElim l x y i) = traverse_ (checkScope scope) [l, x, y, i]
  356. checkProj (PK l x y i) = traverse_ (checkScope scope) [l, x, y, i]
  357. checkProj (PJ l x y i j) = traverse_ (checkScope scope) [l, x, y, i, j]
  358. checkProj (POuc a phi u) = traverse_ (checkScope scope) [a, phi, u]
  359. checkProj PProj1 = pure ()
  360. checkProj PProj2 = pure ()
  361. checkScope scope (GluedVl _ _p vl) = checkScope scope vl
  362. checkScope scope (VLam _ (Closure n k)) =
  363. checkScope (Set.insert n scope) (k (VVar n))
  364. checkScope scope (VPi _ d (Closure n k)) = do
  365. checkScope scope d
  366. checkScope (Set.insert n scope) (k (VVar n))
  367. checkScope scope (VSigma d (Closure n k)) = do
  368. checkScope scope d
  369. checkScope (Set.insert n scope) (k (VVar n))
  370. checkScope s (VPair a b) = traverse_ (checkScope s) [a, b]
  371. checkScope _ VType = pure ()
  372. checkScope _ VTypeω = pure ()
  373. checkScope _ VI = pure ()
  374. checkScope _ VI0 = pure ()
  375. checkScope _ VI1 = pure ()
  376. checkScope s (VIAnd x y) = traverse_ (checkScope s) [x, y]
  377. checkScope s (VIOr x y) = traverse_ (checkScope s) [x, y]
  378. checkScope s (VINot x) = checkScope s x
  379. checkScope s (VPath line a b) = traverse_ (checkScope s) [line, a, b]
  380. checkScope s (VLine _ _ _ line) = checkScope s line
  381. checkScope s (VIsOne x) = checkScope s x
  382. checkScope _ VItIsOne = pure ()
  383. checkScope s (VPartial x y) = traverse_ (checkScope s) [x, y]
  384. checkScope s (VPartialP x y) = traverse_ (checkScope s) [x, y]
  385. checkScope s (VSystem fs) =
  386. for_ (Map.toList fs) $ \(x, y) -> traverse_ (checkScope s) [x, y]
  387. checkScope s (VSub a b c) = traverse_ (checkScope s) [a, b, c]
  388. checkScope s (VInc a b c) = traverse_ (checkScope s) [a, b, c]
  389. checkScope s (VComp a phi u a0) = traverse_ (checkScope s) [a, phi, u, a0]
  390. checkScope s (VHComp a phi u a0) = traverse_ (checkScope s) [a, phi, u, a0]
  391. checkScope s (VGlueTy a phi ty eq) = traverse_ (checkScope s) [a, phi, ty, eq]
  392. checkScope s (VGlue a phi ty eq inv x) = traverse_ (checkScope s) [a, phi, ty, eq, inv, x]
  393. checkScope s (VUnglue a phi ty eq vl) = traverse_ (checkScope s) [a, phi, ty, eq, vl]
  394. checkScope s (VCase _ _ v _) = checkScope s v
  395. checkScope s (VEqStrict a x y) = traverse_ (checkScope s) [a, x, y]
  396. checkScope s (VReflStrict a x) = traverse_ (checkScope s) [a, x]
  397. checkSpine :: Set Name -> Seq Projection -> ElabM [Name]
  398. checkSpine scope (PApp Ex (VVar n@Bound{}) Seq.:<| xs)
  399. | n `Set.member` scope = throwElab $ NonLinearSpine n
  400. | otherwise = (n:) <$> checkSpine scope xs
  401. checkSpine _ (p Seq.:<| _) = throwElab $ SpineProj p
  402. checkSpine _ Seq.Empty = pure []
  403. newtype NonLinearSpine = NonLinearSpine { getDupeName :: Name }
  404. deriving (Show, Typeable, Exception)
  405. newtype SpineProjection = SpineProj { getSpineProjection :: Projection }
  406. deriving (Show, Typeable, Exception)
  407. substituteIO :: Map.Map Name Value -> Value -> IO Value
  408. substituteIO sub = substituteIO . force where
  409. substituteIO (VNe hd sp) = do
  410. sp' <- traverse (substituteSp sub) sp
  411. case hd of
  412. HMeta (mvCell -> cell) -> do
  413. solved <- liftIO $ readIORef cell
  414. case solved of
  415. Just vl -> substituteIO $ foldl applProj vl sp'
  416. Nothing -> pure $ VNe hd sp'
  417. HVar v ->
  418. case Map.lookup v sub of
  419. Just vl -> substituteIO $ foldl applProj vl sp'
  420. Nothing -> pure $ VNe hd sp'
  421. hd -> pure $ VNe hd sp'
  422. substituteIO (GluedVl h sp vl) = GluedVl h <$> traverse (substituteSp sub) sp <*> substituteIO vl
  423. substituteIO (VLam p (Closure s k)) = pure $ VLam p (Closure s (substitute (Map.delete s sub) . k))
  424. substituteIO (VPi p d (Closure s k)) = VPi p <$> substituteIO d <*> pure (Closure s (substitute (Map.delete s sub) . k))
  425. substituteIO (VSigma d (Closure s k)) = VSigma <$> substituteIO d <*> pure (Closure s (substitute (Map.delete s sub) . k))
  426. substituteIO (VPair a b) = VPair <$> substituteIO a <*> substituteIO b
  427. substituteIO (VPath line x y) = VPath <$> substituteIO line <*> substituteIO x <*> substituteIO y
  428. substituteIO (VLine line x y f) = VLine <$> substituteIO line <*> substituteIO x <*> substituteIO y <*> substituteIO f
  429. -- Sorts
  430. substituteIO VType = pure VType
  431. substituteIO VTypeω = pure VTypeω
  432. substituteIO VI = pure VI
  433. substituteIO VI0 = pure VI0
  434. substituteIO VI1 = pure VI1
  435. substituteIO (VIAnd x y) = iand <$> substituteIO x <*> substituteIO y
  436. substituteIO (VIOr x y) = ior <$> substituteIO x <*> substituteIO y
  437. substituteIO (VINot x) = inot <$> substituteIO x
  438. substituteIO (VIsOne x) = VIsOne <$> substituteIO x
  439. substituteIO VItIsOne = pure VItIsOne
  440. substituteIO (VPartial x y) = VPartial <$> substituteIO x <*> substituteIO y
  441. substituteIO (VPartialP x y) = VPartialP <$> substituteIO x <*> substituteIO y
  442. substituteIO (VSystem fs) = do
  443. t <- for (Map.toList fs) $ \(a, b) -> (,) <$> substituteIO a <*> substituteIO b
  444. pure (mkVSystem (Map.fromList t))
  445. substituteIO (VSub a b c) = VSub <$> substituteIO a <*> substituteIO b <*> substituteIO c
  446. substituteIO (VInc a b c) = VInc <$> substituteIO a <*> substituteIO b <*> substituteIO c
  447. substituteIO (VComp a b c d) = comp <$> substituteIO a <*> substituteIO b <*> substituteIO c <*> substituteIO d
  448. substituteIO (VHComp a b c d) = hComp <$> substituteIO a <*> substituteIO b <*> substituteIO c <*> substituteIO d
  449. substituteIO (VGlueTy a phi ty e) = glueType <$> substituteIO a <*> substituteIO phi <*> substituteIO ty <*> substituteIO e
  450. substituteIO (VGlue a phi ty e t x) = glueElem <$> substituteIO a <*> substituteIO phi <*> substituteIO ty <*> substituteIO e <*> substituteIO t <*> substituteIO x
  451. substituteIO (VUnglue a phi ty e x) = unglue <$> substituteIO a <*> substituteIO phi <*> substituteIO ty <*> substituteIO e <*> substituteIO x
  452. substituteIO (VCase env t x xs) = VCase env <$> substituteIO t <*> substituteIO x <*> pure xs
  453. substituteIO (VEqStrict a x y) = VEqStrict <$> zonkIO a <*> zonkIO x <*> zonkIO y
  454. substituteIO (VReflStrict a x) = VReflStrict <$> zonkIO a <*> zonkIO x
  455. substitute :: Map Name Value -> Value -> Value
  456. substitute sub = unsafePerformIO . substituteIO sub
  457. substituteSp :: Map Name Value -> Projection -> IO Projection
  458. substituteSp sub (PApp p x) = PApp p <$> substituteIO sub x
  459. substituteSp sub (PIElim l x y i) = PIElim <$> substituteIO sub l <*> substituteIO sub x <*> substituteIO sub y <*> substituteIO sub i
  460. substituteSp sub (PK l x y i) = PK <$> substituteIO sub l <*> substituteIO sub x <*> substituteIO sub y <*> substituteIO sub i
  461. substituteSp sub (PJ l x y i j) = PJ <$> substituteIO sub l <*> substituteIO sub x <*> substituteIO sub y <*> substituteIO sub i <*> substituteIO sub j
  462. substituteSp sub (POuc a phi u) = POuc <$> substituteIO sub a <*> substituteIO sub phi <*> substituteIO sub u
  463. substituteSp _ PProj1 = pure PProj1
  464. substituteSp _ PProj2 = pure PProj2
  465. mkVSystem :: Map.Map Value Value -> Value
  466. mkVSystem vals =
  467. let map' = Map.fromList (Map.toList vals >>= go)
  468. go (x, y) =
  469. case (force x, y) of
  470. (VI0, _) -> []
  471. (VIOr _ _, VSystem y) -> Map.toList y >>= go
  472. (a, b) -> [(a, b)]
  473. in case Map.lookup VI1 map' of
  474. Just x -> x
  475. Nothing -> VSystem map'
  476. forceIO :: MonadIO m => Value -> m Value
  477. forceIO mv@(VNe (HMeta (mvCell -> cell)) args) = do
  478. solved <- liftIO $ readIORef cell
  479. case solved of
  480. Just vl -> forceIO (foldl applProj vl args)
  481. Nothing -> pure mv
  482. forceIO vl@(VSystem fs) =
  483. case Map.lookup VI1 fs of
  484. Just x -> forceIO x
  485. Nothing -> pure vl
  486. forceIO (GluedVl _ _ vl) = forceIO vl
  487. forceIO (VComp line phi u a0) = comp <$> forceIO line <*> forceIO phi <*> pure u <*> pure a0
  488. forceIO (VHComp line phi u a0) = hComp <$> forceIO line <*> forceIO phi <*> pure u <*> pure a0
  489. forceIO (VCase env rng v vs) = do
  490. env' <- liftIO emptyEnv
  491. r <- forceIO rng
  492. evalCase env'{getEnv=env} (r @@) <$> forceIO v <*> pure vs
  493. forceIO x = pure x
  494. force :: Value -> Value
  495. force = unsafePerformIO . forceIO
  496. applProj :: HasCallStack => Value -> Projection -> Value
  497. applProj fun (PApp p arg) = vApp p fun arg
  498. applProj fun (PIElim l x y i) = ielim l x y fun i
  499. applProj fun (POuc a phi u) = outS a phi u fun
  500. applProj fun (PK a x p pr) = strictK a x p pr fun
  501. applProj fun (PJ a x p pr y) = strictJ a x p pr y fun
  502. applProj fun PProj1 = vProj1 fun
  503. applProj fun PProj2 = vProj2 fun
  504. vApp :: HasCallStack => Plicity -> Value -> Value -> Value
  505. vApp p (VLam p' k) arg
  506. | p == p' = clCont k arg
  507. vApp p (VNe h sp) arg = VNe h (sp Seq.:|> PApp p arg)
  508. vApp p (GluedVl h sp vl) arg = GluedVl h (sp Seq.:|> PApp p arg) (vApp p vl arg)
  509. vApp p (VSystem fs) arg = mkVSystem (fmap (flip (vApp p) arg) fs)
  510. vApp p (VCase env rng sc branches) arg =
  511. VCase env (fun \x -> let VPi _ _ (Closure _ r) = rng @@ x in r arg) sc
  512. (map (projIntoCase (flip (App p) (quote arg))) branches)
  513. vApp _ x _ = error $ "can't apply " ++ show (prettyTm (quote x))
  514. (@@) :: HasCallStack => Value -> Value -> Value
  515. (@@) = vApp Ex
  516. infixl 9 @@
  517. vProj1 :: HasCallStack => Value -> Value
  518. vProj1 (VPair a _) = a
  519. vProj1 (VNe h sp) = VNe h (sp Seq.:|> PProj1)
  520. vProj1 (GluedVl h sp vl) = GluedVl h (sp Seq.:|> PProj1) (vProj1 vl)
  521. vProj1 (VSystem fs) = VSystem (fmap vProj1 fs)
  522. vProj1 (VInc (VSigma a _) b c) = VInc a b (vProj1 c)
  523. vProj1 (VCase env rng sc branches) =
  524. VCase env rng sc (map (projIntoCase Proj1) branches)
  525. vProj1 x = error $ "can't proj1 " ++ show (prettyTm (quote x))
  526. vProj2 :: HasCallStack => Value -> Value
  527. vProj2 (VPair _ b) = b
  528. vProj2 (VNe h sp) = VNe h (sp Seq.:|> PProj2)
  529. vProj2 (GluedVl h sp vl) = GluedVl h (sp Seq.:|> PProj2) (vProj2 vl)
  530. vProj2 (VSystem fs) = VSystem (fmap vProj2 fs)
  531. vProj2 (VInc (VSigma _ (Closure _ r)) b c) = VInc (r (vProj1 c)) b (vProj2 c)
  532. vProj2 (VCase env rng sc branches) =
  533. VCase env rng sc (map (projIntoCase Proj2) branches)
  534. vProj2 x = error $ "can't proj2 " ++ show (prettyTm (quote x))