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.

481 lines
16 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 Syntax.Subst
  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 t x xs) = VCase <$> zonkIO t <*> zonkIO x <*> pure xs
  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 PProj1 = pure PProj1
  81. zonkSp PProj2 = pure PProj2
  82. zonk :: Value -> Value
  83. zonk = unsafePerformIO . zonkIO
  84. eval' :: ElabEnv -> Term -> Value
  85. eval' env (Ref x) =
  86. case Map.lookup x (getEnv env) of
  87. Just (_, vl) -> vl
  88. _ -> VNe (HVar x) mempty
  89. eval' env (Con x) =
  90. case Map.lookup x (getEnv env) of
  91. Just (ty, _) -> VNe (HCon ty x) mempty
  92. Nothing -> error $ "constructor " ++ show x ++ " has no type in scope"
  93. eval' env (PCon sys x) =
  94. case Map.lookup x (getEnv env) of
  95. Just (ty, _) -> VNe (HPCon (eval' env sys) ty x) mempty
  96. Nothing -> error $ "constructor " ++ show x ++ " has no type in scope"
  97. eval' _ (Data n x) = VNe (HData n x) mempty
  98. eval' env (App p f x) = vApp p (eval' env f) (eval' env x)
  99. eval' env (Lam p s t) =
  100. VLam p $ Closure s $ \a ->
  101. eval' env { getEnv = Map.insert s (error "type of abs", a) (getEnv env) } t
  102. eval' env (Pi p s d t) =
  103. VPi p (eval' env d) $ Closure s $ \a ->
  104. eval' env { getEnv = (Map.insert s (error "type of abs", a) (getEnv env))} t
  105. eval' _ (Meta m) = VNe (HMeta m) mempty
  106. eval' env (Sigma s d t) =
  107. VSigma (eval' env d) $ Closure s $ \a ->
  108. eval' env { getEnv = Map.insert s (error "type of abs", a) (getEnv env) } t
  109. eval' e (Pair a b) = VPair (eval' e a) (eval' e b)
  110. eval' e (Proj1 a) = vProj1 (eval' e a)
  111. eval' e (Proj2 a) = vProj2 (eval' e a)
  112. eval' _ Type = VType
  113. eval' _ Typeω = VTypeω
  114. eval' _ I = VI
  115. eval' _ I0 = VI0
  116. eval' _ I1 = VI1
  117. eval' e (IAnd x y) = iand (eval' e x) (eval' e y)
  118. eval' e (IOr x y) = ior (eval' e x) (eval' e y)
  119. eval' e (INot x) = inot (eval' e x)
  120. eval' e (PathP l a b) = VPath (eval' e l) (eval' e a) (eval' e b)
  121. eval' e (IElim l x y f i) = ielim (eval' e l) (eval' e x) (eval' e y) (eval' e f) (eval' e i)
  122. eval' e (PathIntro p x y f) = VLine (eval' e p) (eval' e x) (eval' e y) (eval' e f)
  123. eval' e (IsOne i) = VIsOne (eval' e i)
  124. eval' _ ItIsOne = VItIsOne
  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) = VSystem (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) = VInc (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) -> newe { getEnv = Map.insert n (eval' newe ty, eval' newe x) (getEnv newe) }) e ns
  138. in eval' env' x
  139. eval' e (Case range sc xs) = evalCase e (eval' e range @@) (force (eval' e sc)) xs
  140. evalCase :: ElabEnv -> (Value -> Value) -> Value -> [(Term, Term)] -> Value
  141. evalCase _ _ sc [] = error $ "unmatched pattern for value: " ++ show (prettyTm (quote sc))
  142. evalCase env rng (VHComp a phi u a0) cases =
  143. comp (fun \i -> rng (v i)) phi (system \i is1 -> evalCase env rng (u @@ i @@ is1) cases)
  144. (VInc (rng a) phi (evalCase env rng (outS a0 phi (u @@ VI0) a0) cases))
  145. where
  146. v = Elab.WiredIn.fill a phi u a0
  147. evalCase env _ sc ((Ref _, k):_) = eval' env k @@ sc
  148. evalCase env rng (val@(VNe (HCon _ x) sp)) ((Con x', k):xs)
  149. | x == x' = foldl applProj (eval' env k) sp
  150. | otherwise = evalCase env rng val xs
  151. evalCase env rng (val@(VNe (HPCon _ _ x) sp)) ((Con x', k):xs)
  152. | x == x' = foldl applProj (eval' env k) sp
  153. | otherwise = evalCase env rng val xs
  154. evalCase _ rng sc xs = VCase (fun rng) sc xs
  155. data NotEqual = NotEqual Value Value
  156. deriving (Show, Typeable, Exception)
  157. unify' :: HasCallStack => Value -> Value -> ElabM ()
  158. unify' topa topb = join $ go <$> forceIO topa <*> forceIO topb where
  159. go (VNe (HMeta mv) sp) rhs = solveMeta mv sp rhs
  160. go rhs (VNe (HMeta mv) sp) = solveMeta mv sp rhs
  161. go (VNe (HPCon s _ _) _) rhs
  162. | VSystem _ <- s = go (force s) rhs
  163. go lhs (VNe (HPCon s _ _) _)
  164. | VSystem _ <- s = go lhs (force s)
  165. go (VNe x a) (VNe x' a')
  166. | x == x', length a == length a' =
  167. traverse_ (uncurry unify'Spine) (Seq.zip a a')
  168. go (VLam p (Closure n k)) vl = do
  169. t <- VVar <$> newName' n
  170. unify' (k t) (vApp p vl t)
  171. go vl (VLam p (Closure n k)) = do
  172. t <- VVar <$> newName' n
  173. unify' (vApp p vl t) (k t)
  174. go (VPair a b) vl = unify' a (vProj1 vl) *> unify' b (vProj2 vl)
  175. go vl (VPair a b) = unify' (vProj1 vl) a *> unify' (vProj2 vl) b
  176. go (VPi p d (Closure _ k)) (VPi p' d' (Closure _ k')) | p == p' = do
  177. t <- VVar <$> newName
  178. unify' d d'
  179. unify' (k t) (k' t)
  180. go (VSigma d (Closure _ k)) (VSigma d' (Closure _ k')) = do
  181. t <- VVar <$> newName
  182. unify' d d'
  183. unify' (k t) (k' t)
  184. go VType VType = pure ()
  185. go VTypeω VTypeω = pure ()
  186. go VI VI = pure ()
  187. go (VPath l x y) (VPath l' x' y') = do
  188. unify' l l'
  189. unify' x x'
  190. unify' y y'
  191. go (VLine l x y p) p' = do
  192. n <- VVar <$> newName
  193. unify' (p @@ n) (ielim l x y p' n)
  194. go p' (VLine l x y p) = do
  195. n <- VVar <$> newName
  196. unify' (ielim l x y p' n) (p @@ n)
  197. go (VIsOne x) (VIsOne y) = unify' x y
  198. -- IsOne is proof-irrelevant:
  199. go VItIsOne _ = pure ()
  200. go _ VItIsOne = pure ()
  201. go (VPartial phi r) (VPartial phi' r') = unify' phi phi' *> unify' r r'
  202. go (VPartialP phi r) (VPartialP phi' r') = unify' phi phi' *> unify' r r'
  203. go (VSub a phi u) (VSub a' phi' u') = traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u')]
  204. go (VInc a phi u) (VInc a' phi' u') = traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u')]
  205. go (VComp a phi u a0) (VComp a' phi' u' a0') =
  206. traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u'), (a0, a0')]
  207. go (VGlueTy _ (force -> VI1) u _0) rhs = unify' (u @@ VItIsOne) rhs
  208. go lhs (VGlueTy _ (force -> VI1) u _0) = unify' lhs (u @@ VItIsOne)
  209. go (VGlueTy a phi u a0) (VGlueTy a' phi' u' a0') =
  210. traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u'), (a0, a0')]
  211. go (VGlue a phi u a0 t x) (VGlue a' phi' u' a0' t' x') =
  212. traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u'), (a0, a0'), (t, t'), (x, x')]
  213. go (VSystem sys) rhs = goSystem unify' sys rhs
  214. go rhs (VSystem sys) = goSystem (flip unify') sys rhs
  215. go (VCase _ a b) (VCase _ a' b') = do
  216. unify' a a'
  217. let go a b = join $ unify' <$> eval (snd a) <*> eval (snd b)
  218. zipWithM_ go (sortOn fst b) (sortOn fst b')
  219. go x y
  220. | x == y = pure ()
  221. | otherwise =
  222. case (toDnf x, toDnf y) of
  223. (Just xs, Just ys) -> unify'Formula xs ys
  224. _ -> fail
  225. goSystem :: (Value -> Value -> ElabM ()) -> Map.Map Value Value -> Value -> ElabM ()
  226. goSystem k sys rhs = do
  227. let rhs_q = quote rhs
  228. env <- ask
  229. for_ (Map.toList sys) $ \(f, i) -> do
  230. let i_q = quote i
  231. for (truthAssignments f (getEnv env)) $ \e ->
  232. k (eval' env{getEnv = e} i_q) (eval' env{getEnv = e} rhs_q)
  233. fail = throwElab $ NotEqual topa topb
  234. unify'Spine (PApp a v) (PApp a' v')
  235. | a == a' = unify' v v'
  236. unify'Spine PProj1 PProj1 = pure ()
  237. unify'Spine PProj2 PProj2 = pure ()
  238. unify'Spine (PIElim _ _ _ i) (PIElim _ _ _ j) = unify' i j
  239. unify'Spine (POuc a phi u) (POuc a' phi' u') =
  240. traverse_ (uncurry unify') [(a, a'), (phi, phi'), (u, u')]
  241. unify'Spine _ _ = fail
  242. unify'Formula x y
  243. | compareDNFs x y = pure ()
  244. | otherwise = fail
  245. unify :: HasCallStack => Value -> Value -> ElabM ()
  246. unify a b = unify' a b `catchElab` \(_ :: SomeException) -> liftIO $ throwIO (NotEqual a b)
  247. isConvertibleTo :: Value -> Value -> ElabM (Term -> Term)
  248. isConvertibleTo a b = isConvertibleTo (force a) (force b) where
  249. VPi Im d (Closure _v k) `isConvertibleTo` ty = do
  250. meta <- newMeta d
  251. cont <- k meta `isConvertibleTo` ty
  252. pure (\f -> cont (App Im f (quote meta)))
  253. VType `isConvertibleTo` VTypeω = pure id
  254. VPi p d (Closure _ k) `isConvertibleTo` VPi p' d' (Closure _ k') | p == p' = do
  255. wp <- d' `isConvertibleTo` d
  256. n <- newName
  257. wp_n <- eval (Lam Ex n (wp (Ref n)))
  258. wp' <- k (VVar n) `isConvertibleTo` k' (wp_n @@ VVar n)
  259. pure (\f -> Lam p n (wp' (App p f (wp (Ref n)))))
  260. isConvertibleTo a b = do
  261. unify' a b
  262. pure id
  263. newMeta :: Value -> ElabM Value
  264. newMeta dom = do
  265. loc <- liftM2 (,) <$> asks currentFile <*> asks currentSpan
  266. n <- newName
  267. c <- liftIO $ newIORef Nothing
  268. let m = MV (getNameText n) c dom (flatten <$> loc)
  269. flatten (x, (y, z)) = (x, y, z)
  270. env <- asks getEnv
  271. t <- for (Map.toList env) $ \(n, _) -> pure $
  272. case n of
  273. Bound{} -> Just (PApp Ex (VVar n))
  274. _ -> Nothing
  275. pure (VNe (HMeta m) (Seq.fromList (catMaybes t)))
  276. newName :: MonadIO m => m Name
  277. newName = liftIO $ do
  278. x <- atomicModifyIORef _nameCounter $ \x -> (x + 1, x + 1)
  279. pure (Bound (T.pack (show x)) x)
  280. newName' :: Name -> ElabM Name
  281. newName' n = do
  282. ~(Bound _ x) <- newName
  283. pure (Bound (getNameText n) x)
  284. _nameCounter :: IORef Int
  285. _nameCounter = unsafePerformIO $ newIORef 0
  286. {-# NOINLINE _nameCounter #-}
  287. solveMeta :: MV -> Seq Projection -> Value -> ElabM ()
  288. solveMeta m@(mvCell -> cell) sp rhs = do
  289. env <- ask
  290. names <- tryElab $ checkSpine Set.empty sp
  291. case names of
  292. Right names -> do
  293. checkScope (Set.fromList names) rhs
  294. `withNote` hsep [prettyTm (quote (VNe (HMeta m) sp)), pretty '≡', prettyTm (quote rhs)]
  295. let tm = quote rhs
  296. lam = eval' env $ foldr (Lam Ex) tm names
  297. liftIO . atomicModifyIORef' cell $ \case
  298. Just _ -> error "filled cell in solvedMeta"
  299. Nothing -> (Just lam, ())
  300. Left (_ :: SpineProjection) -> do
  301. liftIO . atomicModifyIORef' (unsolvedMetas env) $ \x -> (, ()) $
  302. case Map.lookup m x of
  303. Just qs -> Map.insert m ((sp, rhs):qs) x
  304. Nothing -> Map.insert m [(sp, rhs)] x
  305. checkScope :: Set Name -> Value -> ElabM ()
  306. checkScope scope (VNe h sp) =
  307. do
  308. case h of
  309. HVar v@Bound{} ->
  310. unless (v `Set.member` scope) . throwElab $
  311. NotInScope v
  312. HVar{} -> pure ()
  313. HCon{} -> pure ()
  314. HPCon{} -> pure ()
  315. HMeta{} -> pure ()
  316. HData{} -> pure ()
  317. traverse_ checkProj sp
  318. where
  319. checkProj (PApp _ t) = checkScope scope t
  320. checkProj (PIElim l x y i) = traverse_ (checkScope scope) [l, x, y, i]
  321. checkProj (POuc a phi u) = traverse_ (checkScope scope) [a, phi, u]
  322. checkProj PProj1 = pure ()
  323. checkProj PProj2 = pure ()
  324. checkScope scope (GluedVl _ _p vl) = checkScope scope vl
  325. checkScope scope (VLam _ (Closure n k)) =
  326. checkScope (Set.insert n scope) (k (VVar n))
  327. checkScope scope (VPi _ d (Closure n k)) = do
  328. checkScope scope d
  329. checkScope (Set.insert n scope) (k (VVar n))
  330. checkScope scope (VSigma d (Closure n k)) = do
  331. checkScope scope d
  332. checkScope (Set.insert n scope) (k (VVar n))
  333. checkScope s (VPair a b) = traverse_ (checkScope s) [a, b]
  334. checkScope _ VType = pure ()
  335. checkScope _ VTypeω = pure ()
  336. checkScope _ VI = pure ()
  337. checkScope _ VI0 = pure ()
  338. checkScope _ VI1 = pure ()
  339. checkScope s (VIAnd x y) = traverse_ (checkScope s) [x, y]
  340. checkScope s (VIOr x y) = traverse_ (checkScope s) [x, y]
  341. checkScope s (VINot x) = checkScope s x
  342. checkScope s (VPath line a b) = traverse_ (checkScope s) [line, a, b]
  343. checkScope s (VLine _ _ _ line) = checkScope s line
  344. checkScope s (VIsOne x) = checkScope s x
  345. checkScope _ VItIsOne = pure ()
  346. checkScope s (VPartial x y) = traverse_ (checkScope s) [x, y]
  347. checkScope s (VPartialP x y) = traverse_ (checkScope s) [x, y]
  348. checkScope s (VSystem fs) =
  349. for_ (Map.toList fs) $ \(x, y) -> traverse_ (checkScope s) [x, y]
  350. checkScope s (VSub a b c) = traverse_ (checkScope s) [a, b, c]
  351. checkScope s (VInc a b c) = traverse_ (checkScope s) [a, b, c]
  352. checkScope s (VComp a phi u a0) = traverse_ (checkScope s) [a, phi, u, a0]
  353. checkScope s (VHComp a phi u a0) = traverse_ (checkScope s) [a, phi, u, a0]
  354. checkScope s (VGlueTy a phi ty eq) = traverse_ (checkScope s) [a, phi, ty, eq]
  355. checkScope s (VGlue a phi ty eq inv x) = traverse_ (checkScope s) [a, phi, ty, eq, inv, x]
  356. checkScope s (VUnglue a phi ty eq vl) = traverse_ (checkScope s) [a, phi, ty, eq, vl]
  357. checkScope s (VCase _ v _) = checkScope s v
  358. checkSpine :: Set Name -> Seq Projection -> ElabM [Name]
  359. checkSpine scope (PApp Ex (VVar n@Bound{}) Seq.:<| xs)
  360. | n `Set.member` scope = throwElab $ NonLinearSpine n
  361. | otherwise = (n:) <$> checkSpine scope xs
  362. checkSpine _ (p Seq.:<| _) = throwElab $ SpineProj p
  363. checkSpine _ Seq.Empty = pure []
  364. newtype NonLinearSpine = NonLinearSpine { getDupeName :: Name }
  365. deriving (Show, Typeable, Exception)
  366. newtype SpineProjection = SpineProj { getSpineProjection :: Projection }
  367. deriving (Show, Typeable, Exception)