pi/src/Core/Check.idr

167 lines
6.3 KiB
Idris
Raw Normal View History

2022-07-23 03:38:15 +02:00
module Core.Check
2022-05-13 19:46:05 +02:00
import Control.Monad.RWS
import Control.Monad.Either
import Control.Monad.Identity
import Data.Vect
import Data.Fin
2022-07-26 23:07:13 +02:00
import Data.IOArray
import Data.IORef
2022-05-13 19:46:05 +02:00
2022-07-23 03:38:15 +02:00
import Core.Term
import Core.Value
import Core.Normalize
import Core.Misc
import Core.Convert
2022-05-13 19:46:05 +02:00
%default total
2022-07-26 23:07:13 +02:00
2022-07-21 19:51:55 +02:00
-- extend environment, used to ensure environment is always in normal form
2022-08-06 02:32:09 +02:00
extV : {auto deftrs : RefA DTR Value}
-> {auto frst : Ref NST Nat}
-> Ctx n -> Value -> PI (Ctx (S n))
2022-07-21 19:51:55 +02:00
extV ctx val = whnf val >>= pure . (`Data.Vect.(::)` ctx)
-- to extend, closure env, term
2022-08-06 02:32:09 +02:00
extT : {auto deftrs : RefA DTR Value}
-> {auto frst : Ref NST Nat}
-> Ctx m -> Ctx n -> Term n -> PI (Ctx (S m))
2022-07-21 19:51:55 +02:00
extT ctx env = extV ctx . VClos env
2022-05-13 19:46:05 +02:00
mutual
public export
-- terms types expected term
2022-07-26 23:07:13 +02:00
check : {auto deftrs : RefA DTR Value}
2022-08-06 02:32:09 +02:00
-> {auto deftys : RefA DTY Value}
-> {auto frst : Ref NST Nat}
-> Ctx n -> Ctx n -> Value -> Term n -> PI Bool
2022-05-13 19:46:05 +02:00
check trs tys xpt' tr = do
xpt <- whnf xpt'
case tr of
2022-07-21 04:18:50 +02:00
TLam sc => case xpt of
VClos env (TPi a b) => do
v <- VGen <$> fresh
2022-07-21 19:51:55 +02:00
check (v :: trs) !(extT tys env a) (VClos (v :: env) b) sc
2022-07-21 04:18:50 +02:00
_ => oops "expected pi"
TPair x y => case xpt of
(VClos env (TSigma a b)) => do
guardS "Pair a" =<< check trs tys (VClos env a) x
check trs tys (VClos env b `VApp` VClos trs x) y
_ => oops "expected sigma"
2022-05-13 19:46:05 +02:00
2022-07-21 19:51:55 +02:00
TLet ty tr tri => do
guardS "let" =<< check trs tys (VClos trs ty) tr
check !(extT trs trs tr) !(extT tys trs ty) xpt tri
2022-05-13 19:46:05 +02:00
_ => convert xpt =<< infer trs tys tr
-- terms types term
2022-07-26 23:07:13 +02:00
public export
2022-08-06 02:32:09 +02:00
infer : {auto deftrs : RefA DTR Value}
-> {auto deftys : RefA DTY Value}
-> {auto frst : Ref NST Nat}
-> Ctx n -> Ctx n -> Term n -> PI Value
2022-05-13 19:46:05 +02:00
infer trs tys TType = pure VType
infer trs tys TTop = pure VType
infer trs tys TBot = pure VType
infer trs tys TNat = pure VType
infer trs tys TStar = pure VTop
infer trs tys TZero = pure VNat
infer trs tys (TVar i) = pure (index i tys)
2022-07-26 23:07:13 +02:00
infer trs tys (TDef i) = do
res <- getArr DTY i
case res of
Just x => pure x
Nothing => oops "TDef type lookup"
2022-05-13 19:46:05 +02:00
infer trs tys (TApp f x) = infer trs tys f >>= whnf >>=
2022-07-26 23:07:13 +02:00
\case
VClos env (TPi a b) => do
guardS ("app x:\n" ++ show !(whnf (VClos env a))) =<< check trs tys (VClos env a) x
tr <- whnf (VClos trs x)
pure (VClos (tr :: env) b)
2022-05-13 19:46:05 +02:00
2022-07-26 23:07:13 +02:00
_ => oops "expected infer pi"
2022-07-21 00:05:45 +02:00
infer trs tys (TPi a b) = do
v <- VGen <$> fresh
guardS "Pi a" =<< check trs tys VType a
guardS "Pi b" =<< check (v :: trs) !(extT tys trs a) VType b
pure VType
infer trs tys (TSigma a b) = do
guardS "Σ a" =<< check trs tys VType a
guardS "Σ b" =<< check trs tys (VClos trs (TPi a TType)) b
pure VType
infer trs tys (TId ty a b) = do
guardS "Id ty" =<< check trs tys VType ty
guardS "Id a" =<< check trs tys (VClos trs ty) a
guardS "Id b" =<< check trs tys (VClos trs ty) b
pure VType
2022-07-21 00:05:45 +02:00
infer trs tys (TSuc n) = do
2022-07-21 04:18:50 +02:00
guardS "suc n" =<< check trs tys VNat n
2022-07-21 00:05:45 +02:00
pure VNat
infer trs tys (TRefl ty tr) = do
guardS "Refl ty" =<< check trs tys VType ty
guardS "Refl tr" =<< check trs tys (VClos trs ty) tr
pure (VClos trs (TId ty tr tr))
2022-07-21 00:05:45 +02:00
infer trs tys (TNatInd c z s) = do
2022-07-21 04:18:50 +02:00
guardS " C" =<< check trs tys (VClos trs (TPi TNat TType)) c
guardS " z" =<< check trs tys (VApp (VClos trs c) (VClos [] TZero)) z
2022-07-21 04:18:50 +02:00
guardS " s" =<< check trs tys (VClos trs (TPi TNat
(TPi (TApp (weakTr c) (TVar 0))
(TApp (weakTr2 c) (TSuc (TVar (FS FZ))))))) s
2022-07-21 00:05:45 +02:00
pure (VClos trs (TPi TNat (TApp (weakTr c) (TVar 0))))
infer trs tys (TJ ty a b c d) = do
guardS "J ty" =<< check trs tys VType ty
guardS "J a" =<< check trs tys (VClos trs ty) a
guardS "J b" =<< check trs tys (VClos trs ty) b
guardS "J c" =<< check trs tys
(VClos trs (TPi ty {- a : A -}
(TPi (weakTr ty) {- b : A -}
(TPi (TId (weakTr2 ty)
(TVar (FS FZ))
(TVar FZ)) {- Id A a b -}
TType)))) c
guardS "J d" =<< check trs tys (VClos trs (c `TApp` a `TApp` a `TApp` TRefl ty a)) d
pure (VClos trs (TPi (TId ty a b) (weakTr c `TApp` weakTr a `TApp` weakTr b `TApp` TVar 0)))
2022-07-21 04:18:50 +02:00
infer trs tys (TSigInd a b c f) = do
guardS "Σ A" =<< check trs tys VType a
guardS "Σ B" =<< check trs tys (VClos trs (TPi a TType)) b
guardS "Σ C" =<< check trs tys (VClos trs (TPi (TSigma a b) TType)) c
guardS "Σ f" =<< check trs tys (VClos trs (TPi a {-a:A-}
(TPi (weakTr b `TApp` TVar 0) {-b:Ba-}
(weakTr2 c `TApp` TPair (TVar (FS FZ)) (TVar 0))))) f
pure (VClos trs (TPi (TSigma a b) (weakTr c `TApp` TVar 0)))
2022-07-21 19:51:55 +02:00
infer trs tys (TLet ty tr tri) = do
guardS "let infer" =<< check trs tys (VClos trs ty) tr
infer !(extT trs trs tr) !(extT tys trs ty) tri
infer trs tys (TTopInd c st) = do
guardS " C" =<< check trs tys (VClos trs (TPi TTop TType)) c
2022-07-26 07:57:44 +02:00
guardS "" =<< check trs tys (VClos trs (TApp c TStar)) st
pure (VClos trs (TPi TTop (TApp (weakTr c) (TVar 0))))
infer trs tys (TBotInd c) = do
guardS "⊥ C" =<< check trs tys (VClos trs (TPi TBot TType)) c
pure (VClos trs (TPi TBot (TApp (weakTr c) (TVar 0))))
infer trs tys x = oops ("cannot infer type " ++ show x)
2022-05-13 19:46:05 +02:00
public export
2022-08-06 02:32:09 +02:00
typecheck : {auto deftrs : RefA DTR Value}
-> {auto deftys : RefA DTY Value}
-> {auto frst : Ref NST Nat}
-> Term 0 -> Term 0 -> IO (Either String Bool)
2022-05-13 19:46:05 +02:00
typecheck tr ty = resolve $ (&&) <$> check [] [] VType ty
<*> delay <$> check [] [] (VClos [] ty) tr