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.

400 lines
12 KiB

  1. {-# LANGUAGE LambdaCase #-}
  2. {-# LANGUAGE DeriveAnyClass #-}
  3. {-# LANGUAGE ScopedTypeVariables #-}
  4. module Elab.Eval where
  5. import Control.Monad.Reader
  6. import Control.Exception
  7. import qualified Data.Map.Strict as Map
  8. import qualified Data.Sequence as Seq
  9. import qualified Data.Set as Set
  10. import qualified Data.Text as T
  11. import Data.Sequence (Seq)
  12. import Data.Traversable
  13. import Data.Set (Set)
  14. import Data.Typeable
  15. import Data.Foldable
  16. import Data.IORef
  17. import Data.Maybe
  18. import Elab.Eval.Formula
  19. import Elab.Monad
  20. import Presyntax.Presyntax (Plicity(..))
  21. import Prettyprinter
  22. import Syntax.Pretty
  23. import Syntax
  24. import System.IO.Unsafe
  25. import {-# SOURCE #-} Elab.WiredIn
  26. eval :: Term -> ElabM Value
  27. eval t = asks (flip eval' t)
  28. forceIO :: MonadIO m => Value -> m Value
  29. forceIO vl@(VNe (HMeta (MV _ cell)) args) = do
  30. solved <- liftIO $ readIORef cell
  31. case solved of
  32. Just vl -> forceIO $ foldl applProj vl args
  33. Nothing -> pure vl
  34. forceIO x = pure x
  35. applProj :: Value -> Projection -> Value
  36. applProj fun (PApp p arg) = vApp p fun arg
  37. applProj fun (PIElim l x y i) = ielim l x y fun i
  38. applProj fun PProj1 = vProj1 fun
  39. applProj fun PProj2 = vProj2 fun
  40. force :: Value -> Value
  41. force = unsafePerformIO . forceIO
  42. -- everywhere force
  43. zonkIO :: Value -> IO Value
  44. zonkIO (VNe hd sp) = do
  45. sp' <- traverse zonkSp sp
  46. case hd of
  47. HMeta (MV _ cell) -> do
  48. solved <- liftIO $ readIORef cell
  49. case solved of
  50. Just vl -> zonkIO $ foldl applProj vl sp'
  51. Nothing -> pure $ VNe hd sp'
  52. hd -> pure $ VNe hd sp'
  53. where
  54. zonkSp (PApp p x) = PApp p <$> zonkIO x
  55. zonkSp (PIElim l x y i) = PIElim <$> zonkIO l <*> zonkIO x <*> zonkIO y <*> zonkIO i
  56. zonkSp PProj1 = pure PProj1
  57. zonkSp PProj2 = pure PProj2
  58. zonkIO (VLam p (Closure s k)) = pure $ VLam p (Closure s (zonk . k))
  59. zonkIO (VPi p d (Closure s k)) = VPi p <$> zonkIO d <*> pure (Closure s (zonk . k))
  60. zonkIO (VSigma d (Closure s k)) = VSigma <$> zonkIO d <*> pure (Closure s (zonk . k))
  61. zonkIO (VPair a b) = VPair <$> zonkIO a <*> zonkIO b
  62. zonkIO (VPath line x y) = VPath <$> zonkIO line <*> zonkIO x <*> zonkIO y
  63. zonkIO (VLine line f) = VLine <$> zonkIO line <*> zonkIO f
  64. -- Sorts
  65. zonkIO VType = pure VType
  66. zonkIO VTypeω = pure VTypeω
  67. zonkIO VI = pure VI
  68. zonkIO VI0 = pure VI0
  69. zonkIO VI1 = pure VI1
  70. zonkIO (VIAnd x y) = iand <$> zonkIO x <*> zonkIO y
  71. zonkIO (VIOr x y) = ior <$> zonkIO x <*> zonkIO y
  72. zonkIO (VINot x) = inot <$> zonkIO x
  73. zonkIO (VIsOne x) = VIsOne <$> zonkIO x
  74. zonkIO (VIsOne1 x) = VIsOne1 <$> zonkIO x
  75. zonkIO (VIsOne2 x) = VIsOne2 <$> zonkIO x
  76. zonkIO VItIsOne = pure VItIsOne
  77. zonkIO (VPartial x y) = VPartial <$> zonkIO x <*> zonkIO y
  78. zonkIO (VPartialP x y) = VPartialP <$> zonkIO x <*> zonkIO y
  79. zonkIO (VSystem fs) =
  80. do
  81. t <- for (Map.toList fs) $ \(a, b) -> (,) <$> zonkIO a <*> zonkIO b
  82. pure (mkVSystem (Map.fromList t))
  83. where
  84. mkVSystem map =
  85. case Map.lookup VI1 map of
  86. Just x -> x
  87. Nothing -> VSystem map
  88. zonk :: Value -> Value
  89. zonk = unsafePerformIO . zonkIO
  90. eval' :: ElabEnv -> Term -> Value
  91. eval' env (Ref x) =
  92. case Map.lookup x (getEnv env) of
  93. Just (_, vl) -> vl
  94. _ -> error "variable not in scope when evaluating"
  95. eval' env (App p f x) = vApp p (eval' env f) (eval' env x)
  96. eval' env (Lam p s t) =
  97. VLam p $ Closure s $ \a ->
  98. eval' env { getEnv = Map.insert (Bound s) (error "type of abs", a) (getEnv env) } t
  99. eval' env (Pi p s d t) =
  100. VPi p (eval' env d) $ Closure s $ \a ->
  101. eval' env { getEnv = (Map.insert (Bound s) (error "type of abs", a) (getEnv env))} t
  102. eval' _ (Meta m) = VNe (HMeta m) mempty
  103. eval' env (Sigma s d t) =
  104. VSigma (eval' env d) $ Closure s $ \a ->
  105. eval' env { getEnv = Map.insert (Bound s) (error "type of abs", a) (getEnv env) } t
  106. eval' e (Pair a b) = VPair (eval' e a) (eval' e b)
  107. eval' e (Proj1 a) = vProj1 (eval' e a)
  108. eval' e (Proj2 a) = vProj2 (eval' e a)
  109. eval' _ Type = VType
  110. eval' _ Typeω = VTypeω
  111. eval' _ I = VI
  112. eval' _ I0 = VI0
  113. eval' _ I1 = VI1
  114. eval' e (IAnd x y) = iand (eval' e x) (eval' e y)
  115. eval' e (IOr x y) = ior (eval' e x) (eval' e y)
  116. eval' e (INot x) = inot (eval' e x)
  117. eval' e (PathP l a b) = VPath (eval' e l) (eval' e a) (eval' e b)
  118. eval' e (IElim l x y f i) = ielim (eval' e l) (eval' e x) (eval' e y) (eval' e f) (eval' e i)
  119. eval' e (PathIntro p f) = VLine (eval' e p) (eval' e f)
  120. eval' e (IsOne i) = VIsOne (eval' e i)
  121. eval' e (IsOne1 i) = VIsOne1 (eval' e i)
  122. eval' e (IsOne2 i) = VIsOne2 (eval' e i)
  123. eval' _ ItIsOne = VItIsOne
  124. eval' e (Partial x y) = VPartial (eval' e x) (eval' e y)
  125. eval' e (PartialP x y) = VPartialP (eval' e x) (eval' e y)
  126. eval' e (System fs) = VSystem (Map.fromList $ map (\(x, y) -> (eval' e x, eval' e y)) $ Map.toList $ fs)
  127. vApp :: Plicity -> Value -> Value -> Value
  128. vApp p (VLam p' k) arg
  129. | p == p' = clCont k arg
  130. | otherwise = error $ "wrong plicity " ++ show p ++ " vs " ++ show p' ++ " in app " ++ show (App p (quote (VLam p' k)) (quote arg))
  131. vApp p (VNe h sp) arg = VNe h (sp Seq.:|> PApp p arg)
  132. vApp _ x _ = error $ "can't apply " ++ show x
  133. (@@) :: Value -> Value -> Value
  134. (@@) = vApp Ex
  135. infixl 9 @@
  136. vProj1 :: Value -> Value
  137. vProj1 (VPair a _) = a
  138. vProj1 (VNe h sp) = VNe h (sp Seq.:|> PProj1)
  139. vProj1 x = error $ "can't proj1 " ++ show x
  140. vProj2 :: Value -> Value
  141. vProj2 (VPair _ b) = b
  142. vProj2 (VNe h sp) = VNe h (sp Seq.:|> PProj2)
  143. vProj2 x = error $ "can't proj2 " ++ show x
  144. data NotEqual = NotEqual Value Value
  145. deriving (Show, Typeable, Exception)
  146. unify' :: Value -> Value -> ElabM ()
  147. unify' topa topb = join $ go <$> forceIO topa <*> forceIO topb where
  148. go (VNe (HMeta mv) sp) rhs = solveMeta mv sp rhs
  149. go rhs (VNe (HMeta mv) sp) = solveMeta mv sp rhs
  150. go (VNe x a) (VNe x' a')
  151. | x == x', length a == length a' =
  152. traverse_ (uncurry unify'Spine) (Seq.zip a a')
  153. go (VNe _hd (_ Seq.:|> PIElim _l x y i)) rhs =
  154. case force i of
  155. VI0 -> unify' x rhs
  156. VI1 -> unify' y rhs
  157. _ -> fail
  158. go rhs (VNe _hd (_ Seq.:|> PIElim _l x y i)) =
  159. case force i of
  160. VI0 -> unify' rhs x
  161. VI1 -> unify' rhs y
  162. _ -> fail
  163. go (VLam p (Closure _ k)) vl = do
  164. t <- VVar . Bound <$> newName
  165. unify' (k t) (vApp p vl t)
  166. go vl (VLam p (Closure _ k)) = do
  167. t <- VVar . Bound <$> newName
  168. unify' (vApp p vl t) (k t)
  169. go (VPair a b) vl = unify' a (vProj1 vl) *> unify' b (vProj2 vl)
  170. go vl (VPair a b) = unify' (vProj1 vl) a *> unify' (vProj2 vl) b
  171. go (VPi p d (Closure _ k)) (VPi p' d' (Closure _ k')) | p == p' = do
  172. t <- VVar . Bound <$> newName
  173. unify' d d'
  174. unify' (k t) (k' t)
  175. go (VSigma d (Closure _ k)) (VSigma d' (Closure _ k')) = do
  176. t <- VVar . Bound <$> newName
  177. unify' d d'
  178. unify' (k t) (k' t)
  179. go VType VType = pure ()
  180. go VTypeω VTypeω = pure ()
  181. go VI VI = pure ()
  182. go (VPath l x y) (VPath l' x' y') = do
  183. unify' l l'
  184. unify' x x'
  185. unify' y y'
  186. go (VLine l p) p' = do
  187. n <- VVar . Bound <$> newName
  188. unify (p @@ n) (ielim l (l @@ VI0) (l @@ VI1) p' n)
  189. go p' (VLine l p) = do
  190. n <- VVar . Bound <$> newName
  191. unify (ielim l (l @@ VI0) (l @@ VI1) p' n) (p @@ n)
  192. go (VIsOne x) (VIsOne y) = unify' x y
  193. -- IsOne is proof-irrelevant:
  194. go VItIsOne _ = pure ()
  195. go _ VItIsOne = pure ()
  196. go VIsOne1{} _ = pure ()
  197. go _ VIsOne1{} = pure ()
  198. go VIsOne2{} _ = pure ()
  199. go _ VIsOne2{} = pure ()
  200. go (VPartial phi r) (VPartial phi' r') = unify' phi phi' *> unify r r'
  201. go (VPartialP phi r) (VPartialP phi' r') = unify' phi phi' *> unify r r'
  202. go x y =
  203. case (toDnf x, toDnf y) of
  204. (Just xs, Just ys) -> unify'Formula xs ys
  205. _ -> fail
  206. fail = liftIO . throwIO $ NotEqual topa topb
  207. unify'Spine (PApp a v) (PApp a' v')
  208. | a == a' = unify' v v'
  209. unify'Spine PProj1 PProj1 = pure ()
  210. unify'Spine PProj2 PProj2 = pure ()
  211. unify'Spine (PIElim _ _ _ i) (PIElim _ _ _ j) = unify' i j
  212. unify'Spine _ _ = fail
  213. unify'Formula x y
  214. | compareDNFs x y = pure ()
  215. | otherwise = fail
  216. unify :: Value -> Value -> ElabM ()
  217. unify a b = unify' a b `catchElab` \(_ :: NotEqual) -> liftIO $ throwIO (NotEqual a b)
  218. isConvertibleTo :: Value -> Value -> ElabM (Term -> Term)
  219. VPi Im d (Closure _v k) `isConvertibleTo` ty = do
  220. meta <- newMeta d
  221. cont <- k meta `isConvertibleTo` ty
  222. pure (\f -> cont (App Im f (quote meta)))
  223. VType `isConvertibleTo` VTypeω = pure id
  224. VPi p d (Closure _ k) `isConvertibleTo` VPi p' d' (Closure _ k') | p == p' = do
  225. wp <- d' `isConvertibleTo` d
  226. n <- newName
  227. wp_n <- eval (Lam Ex n (wp (Ref (Bound n))))
  228. wp' <- k (VVar (Bound n)) `isConvertibleTo` k' (wp_n @@ VVar (Bound n))
  229. pure (\f -> Lam p n (wp' (App p f (wp (Ref (Bound n))))))
  230. isConvertibleTo a b = do
  231. unify' a b
  232. pure id
  233. newMeta :: Value -> ElabM Value
  234. newMeta _dom = do
  235. n <- newName
  236. c <- liftIO $ newIORef Nothing
  237. let m = MV n c
  238. env <- asks getEnv
  239. t <- for (Map.toList env) $ \(n, _) -> pure $
  240. case n of
  241. Bound{} -> Just (PApp Ex (VVar n))
  242. _ -> Nothing
  243. pure (VNe (HMeta m) (Seq.fromList (catMaybes t)))
  244. newName :: MonadIO m => m T.Text
  245. newName = liftIO $ do
  246. x <- atomicModifyIORef _nameCounter $ \x -> (x + 1, x + 1)
  247. pure (T.pack (show x))
  248. _nameCounter :: IORef Int
  249. _nameCounter = unsafePerformIO $ newIORef 0
  250. {-# NOINLINE _nameCounter #-}
  251. solveMeta :: MV -> Seq Projection -> Value -> ElabM ()
  252. solveMeta m@(MV _ cell) sp rhs = do
  253. env <- ask
  254. names <- checkSpine Set.empty sp
  255. checkScope (Set.fromList (Bound <$> names)) rhs
  256. `withNote` hsep [prettyTm (quote (VNe (HMeta m) sp)), pretty '≡', prettyTm (quote rhs)]
  257. let tm = quote rhs
  258. lam = eval' env $ foldr (Lam Ex) tm names
  259. liftIO . atomicModifyIORef' cell $ \case
  260. Just _ -> error "filled cell in solvedMeta"
  261. Nothing -> (Just lam, ())
  262. checkScope :: Set Name -> Value -> ElabM ()
  263. checkScope scope (VNe h sp) =
  264. do
  265. case h of
  266. HVar v@Bound{} ->
  267. unless (v `Set.member` scope) . liftIO . throwIO $
  268. NotInScope v
  269. HVar{} -> pure ()
  270. HMeta{} -> pure ()
  271. traverse_ checkProj sp
  272. where
  273. checkProj (PApp _ t) = checkScope scope t
  274. checkProj (PIElim l x y i) = traverse_ (checkScope scope) [l, x, y, i]
  275. checkProj PProj1 = pure ()
  276. checkProj PProj2 = pure ()
  277. checkScope scope (VLam _ (Closure n k)) =
  278. checkScope (Set.insert (Bound n) scope) (k (VVar (Bound n)))
  279. checkScope scope (VPi _ d (Closure n k)) = do
  280. checkScope scope d
  281. checkScope (Set.insert (Bound n) scope) (k (VVar (Bound n)))
  282. checkScope scope (VSigma d (Closure n k)) = do
  283. checkScope scope d
  284. checkScope (Set.insert (Bound n) scope) (k (VVar (Bound n)))
  285. checkScope s (VPair a b) = traverse_ (checkScope s) [a, b]
  286. checkScope _ VType = pure ()
  287. checkScope _ VTypeω = pure ()
  288. checkScope _ VI = pure ()
  289. checkScope _ VI0 = pure ()
  290. checkScope _ VI1 = pure ()
  291. checkScope s (VIAnd x y) = traverse_ (checkScope s) [x, y]
  292. checkScope s (VIOr x y) = traverse_ (checkScope s) [x, y]
  293. checkScope s (VINot x) = checkScope s x
  294. checkScope s (VPath line a b) = traverse_ (checkScope s) [line, a, b]
  295. checkScope s (VLine _ line) = checkScope s line
  296. checkScope s (VIsOne x) = checkScope s x
  297. checkScope s (VIsOne1 x) = checkScope s x
  298. checkScope s (VIsOne2 x) = checkScope s x
  299. checkScope _ VItIsOne = pure ()
  300. checkScope s (VPartial x y) = traverse_ (checkScope s) [x, y]
  301. checkScope s (VPartialP x y) = traverse_ (checkScope s) [x, y]
  302. checkScope s (VSystem fs) =
  303. for_ (Map.toList fs) $ \(x, y) -> traverse_ (checkScope s) [x, y]
  304. checkSpine :: Set Name -> Seq Projection -> ElabM [T.Text]
  305. checkSpine scope (PApp Ex (VVar n@(Bound t)) Seq.:<| xs)
  306. | n `Set.member` scope = liftIO . throwIO $ NonLinearSpine n
  307. | otherwise = (t:) <$> checkSpine scope xs
  308. checkSpine _ (p Seq.:<| _) = liftIO . throwIO $ SpineProj p
  309. checkSpine _ Seq.Empty = pure []
  310. newtype NonLinearSpine = NonLinearSpine { getDupeName :: Name }
  311. deriving (Show, Typeable, Exception)
  312. newtype SpineProjection = SpineProj { getSpineProjection :: Projection }
  313. deriving (Show, Typeable, Exception)