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.

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