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.

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