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.

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