2024-11-11 13:37:44 -08:00
{- # LANGUAGE BangPatterns # -}
2024-10-05 13:31:09 -07:00
module Check where
import Control.Monad ( guard )
2024-11-11 13:37:44 -08:00
import Data.List ( ( !? ) )
import Debug.Trace ( trace )
import Expr
2024-10-05 13:31:09 -07:00
type Context = [ Expr ]
2024-11-11 13:37:44 -08:00
-- λ S : * . λ P : ∏ x : S . * . ∏ x : S . P x
-- lambda S : * . lambda P : Pi x : S . * . lambda Q : Pi x : S . * . lambda H : (Pi x : S . Pi h : P x . Q x) . lambda G : (Pi x : S . P x) . lambda x : S . H x (G x)
-- lambda S : * . lambda P : (Pi x : S . *). lambda H : (Pi x : S . P x) . lambda x : S . H x
2024-10-05 13:31:09 -07:00
findType :: Context -> Expr -> Maybe Expr
findType g ( Var k ) = do
2024-11-11 13:37:44 -08:00
t <- g !? fromInteger k
kind <- findType g t
guard $ isSort kind
pure t
2024-10-05 13:31:09 -07:00
findType _ Star = Just Square
findType _ Square = Nothing
findType g ( App m n ) = do
2024-11-11 13:37:44 -08:00
let ! _ = trace ( " app: " ++ show m ++ " \ t " ++ show n ) False
Pi a b <- findType g m
let ! _ = trace ( " Pi: " ++ show a ++ " . " ++ show b ) False
a' <- findType g n
let ! _ = trace ( " a': " ++ show a' ++ " \ n " ) False
guard $ betaEquiv a a'
pure $ subst n b
2024-10-05 13:31:09 -07:00
findType g ( Abs t v ) = do
2024-11-11 13:37:44 -08:00
argType <- findType g t
guard $ isSort argType
bodyType <- findType ( incIndices t : map incIndices g ) v
resType <- findType g ( Pi t bodyType )
guard $ isSort resType
pure $ Pi t bodyType
2024-10-05 13:31:09 -07:00
findType g ( Pi t v ) = do
2024-11-11 13:37:44 -08:00
let ! _ = trace ( " Pi rule: " ++ show t ++ " \ t " ++ show v ++ " \ n " ) False
argType <- findType g t
guard $ isSort argType
bodyType <- findType ( incIndices t : map incIndices g ) v
guard $ isSort bodyType
pure bodyType