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 (force -> 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 (force -> 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. when (mvName m == T.pack "2801") do
  382. traceM (VNe (HMeta m) sp)
  383. traceM rhs
  384. env <- ask
  385. names <- tryElab $ checkSpine Set.empty sp
  386. case names of
  387. Right names -> do
  388. scope <- tryElab $ checkScope m (Set.fromList names) rhs
  389. case scope of
  390. Right () -> do
  391. let tm = quote rhs
  392. lam = eval' env $ foldr (Lam Ex) tm names
  393. liftIO . atomicModifyIORef (unsolvedMetas env) $ \mp -> (Map.delete m mp, ())
  394. liftIO . atomicModifyIORef' cell $ \case
  395. Just _ -> error "filled cell in solvedMeta"
  396. Nothing -> (Just lam, ())
  397. Left (_ :: MetaException) -> abort env
  398. Left (_ :: MetaException) -> abort env
  399. where
  400. abort env =
  401. liftIO . atomicModifyIORef' (unsolvedMetas env) $ \x -> (, ()) $
  402. case Map.lookup m x of
  403. Just qs -> Map.insert m ((sp, rhs):qs) x
  404. Nothing -> Map.insert m [(sp, rhs)] x
  405. checkScope :: MV -> Set Name -> Value -> ElabM ()
  406. checkScope mv scope (VNe h sp) =
  407. do
  408. case h of
  409. HVar v@Bound{} ->
  410. unless (v `Set.member` scope) . throwElab $
  411. ScopeCheckingFail v
  412. HVar{} -> pure ()
  413. HCon{} -> pure ()
  414. HPCon{} -> pure ()
  415. HMeta m' -> when (mv == m') $ throwElab $ CircularSolution mv
  416. HData{} -> pure ()
  417. traverse_ checkProj sp
  418. where
  419. checkProj (PApp _ t) = checkScope mv scope t
  420. checkProj (PIElim l x y i) = traverse_ (checkScope mv scope) [l, x, y, i]
  421. checkProj (PK l x y i) = traverse_ (checkScope mv scope) [l, x, y, i]
  422. checkProj (PJ l x y i j) = traverse_ (checkScope mv scope) [l, x, y, i, j]
  423. checkProj (POuc a phi u) = traverse_ (checkScope mv scope) [a, phi, u]
  424. checkProj PProj1 = pure ()
  425. checkProj PProj2 = pure ()
  426. checkScope mv scope (GluedVl _ _p vl) = checkScope mv scope vl
  427. checkScope mv scope (VLam _ (Closure n k)) =
  428. checkScope mv (Set.insert n scope) (k (VVar n))
  429. checkScope mv scope (VPi _ d (Closure n k)) = do
  430. checkScope mv scope d
  431. checkScope mv (Set.insert n scope) (k (VVar n))
  432. checkScope mv scope (VSigma d (Closure n k)) = do
  433. checkScope mv scope d
  434. checkScope mv (Set.insert n scope) (k (VVar n))
  435. checkScope mv s (VPair a b) = traverse_ (checkScope mv s) [a, b]
  436. checkScope _ _ VType = pure ()
  437. checkScope _ _ VTypeω = pure ()
  438. checkScope _ _ VI = pure ()
  439. checkScope _ _ VI0 = pure ()
  440. checkScope _ _ VI1 = pure ()
  441. checkScope mv s (VIAnd x y) = traverse_ (checkScope mv s) [x, y]
  442. checkScope mv s (VIOr x y) = traverse_ (checkScope mv s) [x, y]
  443. checkScope mv s (VINot x) = checkScope mv s x
  444. checkScope mv s (VPath line a b) = traverse_ (checkScope mv s) [line, a, b]
  445. checkScope mv s (VLine _ _ _ line) = checkScope mv s line
  446. checkScope mv s (VPartial x y) = traverse_ (checkScope mv s) [x, y]
  447. checkScope mv s (VPartialP x y) = traverse_ (checkScope mv s) [x, y]
  448. checkScope mv s (VSystem fs) =
  449. for_ (Map.toList fs) $ \(x, y) -> traverse_ (checkScope mv s) [x, y]
  450. checkScope mv s (VSub a b c) = traverse_ (checkScope mv s) [a, b, c]
  451. checkScope mv s (VInc a b c) = traverse_ (checkScope mv s) [a, b, c]
  452. checkScope mv s (VComp a phi u a0) = traverse_ (checkScope mv s) [a, phi, u, a0]
  453. checkScope mv s (VHComp a phi u a0) = traverse_ (checkScope mv s) [a, phi, u, a0]
  454. checkScope mv s (VGlueTy a phi ty eq) = traverse_ (checkScope mv s) [a, phi, ty, eq]
  455. checkScope mv s (VGlue a phi ty eq inv x) = traverse_ (checkScope mv s) [a, phi, ty, eq, inv, x]
  456. checkScope mv s (VUnglue a phi ty eq vl) = traverse_ (checkScope mv s) [a, phi, ty, eq, vl]
  457. checkScope mv s (VCase _ _ v _) = checkScope mv s v
  458. checkScope mv s (VEqStrict a x y) = traverse_ (checkScope mv s) [a, x, y]
  459. checkScope mv s (VReflStrict a x) = traverse_ (checkScope mv s) [a, x]
  460. checkSpine :: Set Name -> Seq Projection -> ElabM [Name]
  461. checkSpine scope (PApp Ex (VVar n@Bound{}) Seq.:<| xs)
  462. | n `Set.member` scope = throwElab $ NonLinearSpine n
  463. | otherwise = (n:) <$> checkSpine scope xs
  464. checkSpine _ (p Seq.:<| _) = throwElab $ SpineProj p
  465. checkSpine _ Seq.Empty = pure []
  466. data MetaException = NonLinearSpine { getDupeName :: Name }
  467. | SpineProj { getSpineProjection :: Projection }
  468. | CircularSolution { getCycle :: MV }
  469. | ScopeCheckingFail { outOfScope :: Name }
  470. deriving (Show, Typeable, Exception)
  471. substituteIO :: Map.Map Name Value -> Value -> IO Value
  472. substituteIO sub = substituteIO . force where
  473. substituteIO (VNe hd sp) = do
  474. sp' <- traverse (substituteSp sub) sp
  475. case hd of
  476. HVar v ->
  477. case Map.lookup v sub of
  478. Just vl -> substituteIO $ foldl applProj vl sp'
  479. Nothing -> pure $ foldl applProj (VNe hd mempty) sp'
  480. hd -> pure $ VNe hd sp'
  481. substituteIO (GluedVl h sp vl) = GluedVl h <$> traverse (substituteSp sub) sp <*> substituteIO vl
  482. substituteIO (VLam p (Closure s k)) = pure $ VLam p (Closure s (substitute (Map.delete s sub) . k))
  483. substituteIO (VPi p d (Closure s k)) = VPi p <$> substituteIO d <*> pure (Closure s (substitute (Map.delete s sub) . k))
  484. substituteIO (VSigma d (Closure s k)) = VSigma <$> substituteIO d <*> pure (Closure s (substitute (Map.delete s sub) . k))
  485. substituteIO (VPair a b) = VPair <$> substituteIO a <*> substituteIO b
  486. substituteIO (VPath line x y) = VPath <$> substituteIO line <*> substituteIO x <*> substituteIO y
  487. substituteIO (VLine line x y f) = VLine <$> substituteIO line <*> substituteIO x <*> substituteIO y <*> substituteIO f
  488. substituteIO VType = pure VType
  489. substituteIO VTypeω = pure VTypeω
  490. substituteIO VI = pure VI
  491. substituteIO VI0 = pure VI0
  492. substituteIO VI1 = pure VI1
  493. substituteIO (VIAnd x y) = iand <$> substituteIO x <*> substituteIO y
  494. substituteIO (VIOr x y) = ior <$> substituteIO x <*> substituteIO y
  495. substituteIO (VINot x) = inot <$> substituteIO x
  496. substituteIO (VPartial x y) = VPartial <$> substituteIO x <*> substituteIO y
  497. substituteIO (VPartialP x y) = VPartialP <$> substituteIO x <*> substituteIO y
  498. substituteIO (VSystem fs) = do
  499. t <- for (Map.toList fs) $ \(a, b) -> (,) <$> substituteIO a <*> substituteIO b
  500. pure (mkVSystem (Map.fromList t))
  501. substituteIO (VSub a b c) = VSub <$> substituteIO a <*> substituteIO b <*> substituteIO c
  502. substituteIO (VInc a b c) = incS <$> substituteIO a <*> substituteIO b <*> substituteIO c
  503. substituteIO (VComp a b c d) = comp <$> substituteIO a <*> substituteIO b <*> substituteIO c <*> substituteIO d
  504. substituteIO (VHComp a b c d) = hComp <$> substituteIO a <*> substituteIO b <*> substituteIO c <*> substituteIO d
  505. substituteIO (VGlueTy a phi ty e) = glueType <$> substituteIO a <*> substituteIO phi <*> substituteIO ty <*> substituteIO e
  506. substituteIO (VGlue a phi ty e t x) = glueElem <$> substituteIO a <*> substituteIO phi <*> substituteIO ty <*> substituteIO e <*> substituteIO t <*> substituteIO x
  507. substituteIO (VUnglue a phi ty e x) = unglue <$> substituteIO a <*> substituteIO phi <*> substituteIO ty <*> substituteIO e <*> substituteIO x
  508. substituteIO (VCase env t x xs) = VCase env <$> substituteIO t <*> substituteIO x <*> pure xs
  509. substituteIO (VEqStrict a x y) = VEqStrict <$> substituteIO a <*> substituteIO x <*> substituteIO y
  510. substituteIO (VReflStrict a x) = VReflStrict <$> substituteIO a <*> substituteIO x
  511. substitute :: Map Name Value -> Value -> Value
  512. substitute sub = unsafePerformIO . substituteIO sub
  513. substituteSp :: Map Name Value -> Projection -> IO Projection
  514. substituteSp sub (PApp p x) = PApp p <$> substituteIO sub x
  515. substituteSp sub (PIElim l x y i) = PIElim <$> substituteIO sub l <*> substituteIO sub x <*> substituteIO sub y <*> substituteIO sub i
  516. substituteSp sub (PK l x y i) = PK <$> substituteIO sub l <*> substituteIO sub x <*> substituteIO sub y <*> substituteIO sub i
  517. substituteSp sub (PJ l x y i j) = PJ <$> substituteIO sub l <*> substituteIO sub x <*> substituteIO sub y <*> substituteIO sub i <*> substituteIO sub j
  518. substituteSp sub (POuc a phi u) = POuc <$> substituteIO sub a <*> substituteIO sub phi <*> substituteIO sub u
  519. substituteSp _ PProj1 = pure PProj1
  520. substituteSp _ PProj2 = pure PProj2
  521. mkVSystem :: Map.Map Value Value -> Value
  522. mkVSystem vals =
  523. let map' = Map.fromList (Map.toList vals >>= go)
  524. go (x, y) =
  525. case (force x, y) of
  526. (VI0, _) -> []
  527. (VIOr _ _, VSystem y) -> Map.toList y >>= go
  528. (a, b) -> [(a, b)]
  529. in case Map.lookup VI1 map' of
  530. Just x -> x
  531. Nothing -> VSystem map'
  532. forceIO :: MonadIO m => Value -> m Value
  533. forceIO mv@(VNe (HMeta (mvCell -> cell)) args) = do
  534. solved <- liftIO $ readIORef cell
  535. case solved of
  536. Just vl -> forceIO (foldl applProj vl args)
  537. Nothing -> pure mv
  538. forceIO vl@(VSystem fs) =
  539. case Map.lookup VI1 fs of
  540. Just x -> forceIO x
  541. Nothing -> pure vl
  542. forceIO (GluedVl _ _ vl) = forceIO vl
  543. forceIO (VComp line phi u a0) = comp <$> forceIO line <*> forceIO phi <*> pure u <*> pure a0
  544. forceIO (VHComp line phi u a0) = hComp <$> forceIO line <*> forceIO phi <*> pure u <*> pure a0
  545. forceIO (VCase env rng v vs) = do
  546. env' <- liftIO emptyEnv
  547. r <- forceIO rng
  548. evalCase env'{getEnv=env} (r @@) <$> forceIO v <*> pure vs
  549. forceIO x = pure x
  550. force :: Value -> Value
  551. force = unsafePerformIO . forceIO
  552. applProj :: HasCallStack => Value -> Projection -> Value
  553. applProj fun (PApp p arg) = vApp p fun arg
  554. applProj fun (PIElim l x y i) = ielim l x y fun i
  555. applProj fun (POuc a phi u) = outS a phi u fun
  556. applProj fun (PK a x p pr) = strictK a x p pr fun
  557. applProj fun (PJ a x p pr y) = strictJ a x p pr y fun
  558. applProj fun PProj1 = vProj1 fun
  559. applProj fun PProj2 = vProj2 fun
  560. vApp :: HasCallStack => Plicity -> Value -> Value -> Value
  561. vApp _ (VLam _ k) arg = clCont k arg
  562. vApp p (VNe (HData True n) _) _ | T.unpack (getNameText n) == "S1" = undefined
  563. vApp p (VNe h sp) arg = VNe h (sp Seq.:|> PApp p arg)
  564. vApp p (GluedVl h sp vl) arg = GluedVl h (sp Seq.:|> PApp p arg) (vApp p vl arg)
  565. vApp p (VSystem fs) arg = mkVSystem (fmap (flip (vApp p) arg) fs)
  566. vApp p (VCase env rng sc branches) arg =
  567. VCase env (fun \x -> let VPi _ _ (Closure _ r) = rng @@ x in r arg) sc
  568. (map (projIntoCase (flip (App p) (quote arg))) branches)
  569. -- vApp _ (VLine _ _ _ (VLam _ k)) arg = clCont k arg
  570. vApp _ x _ = error $ "can't apply " ++ show (prettyTm (quote x))
  571. (@@) :: HasCallStack => Value -> Value -> Value
  572. (@@) = vApp Ex
  573. infixl 9 @@
  574. vProj1 :: HasCallStack => Value -> Value
  575. vProj1 (VPair a _) = a
  576. vProj1 (VNe h sp) = VNe h (sp Seq.:|> PProj1)
  577. vProj1 (GluedVl h sp vl) = GluedVl h (sp Seq.:|> PProj1) (vProj1 vl)
  578. vProj1 (VSystem fs) = VSystem (fmap vProj1 fs)
  579. vProj1 (VInc (VSigma a _) b c) = incS a b (vProj1 c)
  580. vProj1 (VCase env rng sc branches) =
  581. VCase env rng sc (map (projIntoCase Proj1) branches)
  582. vProj1 x = error $ "can't proj1 " ++ show x
  583. vProj2 :: HasCallStack => Value -> Value
  584. vProj2 (VPair _ b) = b
  585. vProj2 (VNe h sp) = VNe h (sp Seq.:|> PProj2)
  586. vProj2 (GluedVl h sp vl) = GluedVl h (sp Seq.:|> PProj2) (vProj2 vl)
  587. vProj2 (VSystem fs) = VSystem (fmap vProj2 fs)
  588. vProj2 (VInc (VSigma _ (Closure _ r)) b c) = incS (r (vProj1 c)) b (vProj2 c)
  589. vProj2 (VCase env rng sc branches) =
  590. VCase env rng sc (map (projIntoCase Proj2) branches)
  591. vProj2 x = error $ "can't proj2 " ++ show (prettyTm (quote x))