starting type checking again
This commit is contained in:
parent
96634d08ee
commit
5ce06d1012
3 changed files with 49 additions and 33 deletions
69
app/Check.hs
69
app/Check.hs
|
|
@ -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
|
||||||
|
|
|
||||||
11
app/Main.hs
11
app/Main.hs
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue