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.

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