perga/app/Check.hs

49 lines
1.5 KiB
Haskell
Raw Normal View History

2024-10-05 13:31:09 -07:00
module Check where
2024-11-11 17:57:14 -08:00
import Control.Monad.Except
import Data.List (intercalate, (!?))
2024-11-11 13:52:50 -08:00
2024-11-11 17:57:14 -08:00
import Control.Monad (unless)
2024-11-11 13:37:44 -08:00
import Expr
2024-10-05 13:31:09 -07:00
type Context = [Expr]
2024-11-11 20:08:21 -08:00
data TypeCheckError = Err | SquareUntyped | UnboundVariable | NotASort Expr Int | ExpectedFunctionType Expr | NotEquivalent Expr Expr
2024-11-11 17:57:14 -08:00
deriving (Show)
type CheckResult = Either TypeCheckError
matchPi :: Expr -> CheckResult (Expr, Expr)
matchPi (Pi _ a b) = Right (a, b)
matchPi e = Left $ ExpectedFunctionType e
showContext :: Context -> String
showContext g = "[" ++ intercalate ", " (map show g) ++ "]"
findType :: Context -> Expr -> CheckResult Expr
findType _ Star = Right Square
findType _ Square = Left SquareUntyped
2024-11-11 17:57:14 -08:00
findType g (Var n _) = do
t <- maybe (Left UnboundVariable) Right $ g !? fromInteger n
s <- findType g t
2024-11-11 20:08:21 -08:00
unless (isSort s) $ throwError $ NotASort s 32
2024-11-11 13:37:44 -08:00
pure t
2024-10-05 13:31:09 -07:00
findType g (App m n) = do
2024-11-11 17:57:14 -08:00
(a, b) <- findType g m >>= matchPi
2024-11-11 13:37:44 -08:00
a' <- findType g n
2024-11-11 17:57:14 -08:00
unless (betaEquiv a a') $ throwError $ NotEquivalent a a'
pure $ subst 0 n b
2024-11-11 17:57:14 -08:00
findType g (Abs x a m) = do
s1 <- findType g a
2024-11-11 20:08:21 -08:00
unless (isSort s1) $ throwError $ NotASort s1 43
2024-11-11 17:57:14 -08:00
b <- findType (incIndices a : map incIndices g) m
s2 <- findType g (Pi x a b)
2024-11-11 20:08:21 -08:00
unless (isSort s2) $ throwError $ NotASort s2 46
2024-11-11 17:57:14 -08:00
pure $ if occursFree 0 b then Pi x a b else Pi "" a b
findType g (Pi _ a b) = do
s1 <- findType g a
2024-11-11 20:08:21 -08:00
unless (isSort s1) $ throwError $ NotASort s1 51
2024-11-11 17:57:14 -08:00
s2 <- findType (incIndices a : map incIndices g) b
2024-11-11 20:08:21 -08:00
unless (isSort s2) $ throwError $ NotASort s2 53
2024-11-11 17:57:14 -08:00
pure s2