2024-11-17 18:33:14 -08:00
|
|
|
{-# LANGUAGE LambdaCase #-}
|
|
|
|
|
|
2024-11-22 19:44:31 -08:00
|
|
|
module Check (checkType, findType) where
|
2024-10-05 13:31:09 -07:00
|
|
|
|
2024-12-02 20:39:56 -08:00
|
|
|
import Control.Monad.Except (MonadError (throwError), liftEither)
|
2024-11-17 01:57:53 -08:00
|
|
|
import Data.List ((!?))
|
2024-11-17 18:33:14 -08:00
|
|
|
import Errors
|
2024-12-01 21:43:15 -08:00
|
|
|
import Eval (Env, betaEquiv', envLookupTy, subst, whnf)
|
2024-11-17 18:33:14 -08:00
|
|
|
import Expr (Expr (..), incIndices, occursFree)
|
2024-10-05 13:31:09 -07:00
|
|
|
|
|
|
|
|
type Context = [Expr]
|
|
|
|
|
|
2024-11-17 18:33:14 -08:00
|
|
|
matchPi :: Expr -> Expr -> ReaderT Env Result (Expr, Expr)
|
|
|
|
|
matchPi x mt =
|
|
|
|
|
whnf mt >>= \case
|
2024-12-01 21:43:15 -08:00
|
|
|
(Pi _ a _ b) -> pure (a, b)
|
2024-11-17 18:33:14 -08:00
|
|
|
t -> throwError $ ExpectedPiType x t
|
2024-11-11 17:57:14 -08:00
|
|
|
|
2024-11-28 13:39:23 -08:00
|
|
|
findLevel :: Context -> Expr -> ReaderT Env Result Integer
|
|
|
|
|
findLevel g a = do
|
2024-11-22 19:44:31 -08:00
|
|
|
s <- findType g a
|
2024-11-28 13:39:23 -08:00
|
|
|
whnf s >>= \case
|
|
|
|
|
Level i -> pure i
|
2024-12-02 20:39:56 -08:00
|
|
|
Star -> pure $ -1 -- HACK: but works, so...
|
2024-11-28 13:39:23 -08:00
|
|
|
_ -> throwError $ NotASort a s
|
2024-11-22 19:44:31 -08:00
|
|
|
|
2024-11-28 13:39:23 -08:00
|
|
|
validateType :: Context -> Expr -> ReaderT Env Result ()
|
|
|
|
|
validateType g a = void $ findLevel g a
|
2024-11-22 19:44:31 -08:00
|
|
|
|
2024-12-02 20:39:56 -08:00
|
|
|
isSort :: Expr -> Bool
|
|
|
|
|
isSort Star = True
|
|
|
|
|
isSort (Level _) = True
|
|
|
|
|
isSort _ = False
|
|
|
|
|
|
|
|
|
|
compSort :: Expr -> Expr -> Expr -> Expr -> Result Expr
|
|
|
|
|
compSort _ _ Star Star = pure Star
|
|
|
|
|
compSort _ _ Star r@(Level _) = pure r
|
|
|
|
|
compSort _ _ (Level i) Star
|
|
|
|
|
| i == 0 = pure Star
|
|
|
|
|
| otherwise = pure $ Level i
|
|
|
|
|
compSort _ _ (Level i) (Level j) = pure $ Level $ max i j
|
|
|
|
|
compSort a b left right
|
|
|
|
|
| isSort left = throwError $ NotASort b right
|
|
|
|
|
| otherwise = throwError $ NotASort a left
|
|
|
|
|
|
2024-11-17 18:33:14 -08:00
|
|
|
findType :: Context -> Expr -> ReaderT Env Result Expr
|
2024-12-02 20:39:56 -08:00
|
|
|
findType _ Star = pure $ Level 0
|
2024-11-28 13:39:23 -08:00
|
|
|
findType _ (Level i) = pure $ Level (i + 1)
|
2024-11-22 19:44:31 -08:00
|
|
|
findType g (Var x n) = do
|
|
|
|
|
t <- g !? fromInteger n `whenNothing` throwError (UnboundVariable x)
|
2024-11-28 13:39:23 -08:00
|
|
|
validateType g t
|
2024-11-11 13:37:44 -08:00
|
|
|
pure t
|
2024-11-28 13:39:23 -08:00
|
|
|
findType _ (Free n) = envLookupTy n
|
2024-11-30 23:43:17 -08:00
|
|
|
findType _ (Axiom n) = envLookupTy n
|
2024-11-12 00:00:51 -08:00
|
|
|
findType g e@(App m n) = do
|
|
|
|
|
(a, b) <- findType g m >>= matchPi m
|
2024-11-11 13:37:44 -08:00
|
|
|
a' <- findType g n
|
2024-12-01 21:43:15 -08:00
|
|
|
betaEquiv' e a a'
|
2024-11-11 23:38:10 -08:00
|
|
|
pure $ subst 0 n b
|
2024-12-01 21:43:15 -08:00
|
|
|
findType g f@(Abs x a asc m) = do
|
2024-11-28 13:39:23 -08:00
|
|
|
validateType g a
|
2024-11-11 17:57:14 -08:00
|
|
|
b <- findType (incIndices a : map incIndices g) m
|
2024-12-05 19:05:34 -08:00
|
|
|
whenJust asc (void . liftA2 ($>) (findType g) (betaEquiv' f b))
|
2024-12-01 21:43:15 -08:00
|
|
|
validateType g (Pi x a Nothing b)
|
|
|
|
|
pure $ if occursFree 0 b then Pi x a Nothing b else Pi "" a Nothing b
|
|
|
|
|
findType g f@(Pi _ a asc b) = do
|
2024-12-02 20:39:56 -08:00
|
|
|
aSort <- findType g a
|
|
|
|
|
bSort <- findType (incIndices a : map incIndices g) b
|
2024-12-05 19:05:34 -08:00
|
|
|
whenJust asc (void . liftA2 ($>) (findType g) (betaEquiv' f bSort))
|
2024-12-02 20:39:56 -08:00
|
|
|
liftEither $ compSort a b aSort bSort
|
2024-11-30 22:36:27 -08:00
|
|
|
findType g (Let _ Nothing v b) = findType g (subst 0 v b)
|
|
|
|
|
findType g e@(Let _ (Just t) v b) = do
|
|
|
|
|
res <- findType g (subst 0 v b)
|
2024-12-05 19:05:34 -08:00
|
|
|
_ <- findType g t
|
2024-12-01 21:43:15 -08:00
|
|
|
betaEquiv' e t res
|
2024-11-30 22:36:27 -08:00
|
|
|
pure t
|
2024-11-17 01:57:53 -08:00
|
|
|
|
2024-11-17 18:33:14 -08:00
|
|
|
checkType :: Env -> Expr -> Result Expr
|
|
|
|
|
checkType env t = runReaderT (findType [] t) env
|