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.

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