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.

498 lines
16 KiB

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