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.

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