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.

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