starting type checking again

This commit is contained in:
William Ball 2024-11-11 17:57:14 -08:00
parent 96634d08ee
commit 5ce06d1012
3 changed files with 49 additions and 33 deletions

View file

@ -1,37 +1,54 @@
-- {-# LANGUAGE BangPatterns #-} {-# LANGUAGE BangPatterns #-}
module Check where module Check where
import Control.Monad (guard) import Control.Monad.Except
import Data.List ((!?)) import Data.List (intercalate, (!?))
-- import Debug.Trace (trace) import Control.Monad (unless)
import Expr import Expr
import Debug.Trace
type Context = [Expr] type Context = [Expr]
findType :: Context -> Expr -> Maybe Expr data TypeCheckError = Err | SquareUntyped | UnboundVariable | NotASort Expr | ExpectedFunctionType Expr | NotEquivalent Expr Expr
findType g (Var k) = do deriving (Show)
t <- g !? fromInteger k
kind <- findType g t type CheckResult = Either TypeCheckError
guard $ isSort kind
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
findType g (Var n _) = do
!_ <- trace ("var:\t" ++ showContext g ++ "\n n:\t" ++ show n) (Right Star)
t <- maybe (Left UnboundVariable) Right $ g !? fromInteger n
s <- findType g t
unless (isSort s) $ throwError $ NotASort s
pure t pure t
findType _ Star = Just Square
findType _ Square = Nothing
findType g (App m n) = do findType g (App m n) = do
Pi a b <- findType g m !_ <- trace ("app:\t" ++ showContext g ++ "\n m:\t" ++ show m ++ "\n n: \t" ++ show n) (Right Star)
(a, b) <- findType g m >>= matchPi
a' <- findType g n a' <- findType g n
guard $ betaEquiv a a' unless (betaEquiv a a') $ throwError $ NotEquivalent a a'
pure $ subst n b pure $ subst n b
findType g (Abs t v) = do findType g (Abs x a m) = do
argType <- findType g t !_ <- trace ("abs:\t" ++ showContext g ++ "\n a:\t" ++ show a ++ "\n m:\t" ++ show m) (Right Star)
guard $ isSort argType s1 <- findType g a
bodyType <- findType (incIndices t : map incIndices g) v unless (isSort s1) $ throwError $ NotASort s1
resType <- findType g (Pi t bodyType) b <- findType (incIndices a : map incIndices g) m
guard $ isSort resType s2 <- findType g (Pi x a b)
pure $ Pi t bodyType unless (isSort s2) $ throwError $ NotASort s2
findType g (Pi t v) = do pure $ if occursFree 0 b then Pi x a b else Pi "" a b
argType <- findType g t findType g (Pi _ a b) = do
guard $ isSort argType !_ <- trace ("pi:\t" ++ showContext g ++ "\n a:\t" ++ show a ++ "\n b:\t" ++ show b) (Right Star)
bodyType <- findType (incIndices t : map incIndices g) v s1 <- findType g a
guard $ isSort bodyType unless (isSort s1) $ throwError $ NotASort s1
pure bodyType s2 <- findType (incIndices a : map incIndices g) b
unless (isSort s2) $ throwError $ NotASort s2
pure s2

View file

@ -1,11 +1,10 @@
module Main where module Main where
import Check
import Expr import Expr
import Parser import Parser
import System.IO import System.IO
-- import Check
main :: IO () main :: IO ()
main = do main = do
_ <- putStr "> " _ <- putStr "> "
@ -13,8 +12,8 @@ main = do
input <- getLine input <- getLine
case pAll input of case pAll input of
Left err -> putStrLn err Left err -> putStrLn err
Right expr -> putStrLn (pretty expr) -- Right expr -> putStrLn (pretty expr)
-- Right expr -> case findType [] expr of Right expr -> case findType [] expr of
-- Just ty -> putStrLn $ pretty expr ++ " : " ++ pretty ty Right ty -> putStrLn $ pretty expr ++ " : " ++ pretty ty
-- Nothing -> putStrLn $ "Unable to find type for " ++ pretty expr ++ "!" Left err -> print err
main main

View file

@ -63,7 +63,7 @@ executable lambda-D
-- Modules included in this executable, other than Main. -- Modules included in this executable, other than Main.
other-modules: Expr other-modules: Expr
-- Check Check
Parser Parser
-- LANGUAGE extensions used by modules in this package. -- LANGUAGE extensions used by modules in this package.