quox/lib/Quox/Typing.idr

186 lines
6 KiB
Idris
Raw Normal View History

2021-12-23 13:05:50 -05:00
module Quox.Typing
2023-03-13 16:41:57 -04:00
import public Quox.Typing.Context as Typing
import public Quox.Typing.EqMode as Typing
import public Quox.Typing.Error as Typing
2021-12-23 13:05:50 -05:00
import public Quox.Syntax
2022-08-22 04:17:08 -04:00
import public Quox.Definition
2023-08-24 12:42:26 -04:00
import public Quox.Whnf
2024-04-04 13:23:08 -04:00
import public Quox.Pretty
2021-12-23 13:05:50 -05:00
2023-04-15 09:13:01 -04:00
import Language.Reflection
2023-03-31 13:23:30 -04:00
import Control.Eff
%default total
2023-04-15 09:13:01 -04:00
%language ElabReflection
private TTName : Type
TTName = TT.Name
%hide TT.Name
2021-12-23 13:05:50 -05:00
2022-04-23 18:21:30 -04:00
public export
2024-05-27 15:28:22 -04:00
CheckResult' : Nat -> Nat -> Type
2023-02-19 11:51:44 -05:00
CheckResult' = QOutput
2022-04-23 18:21:30 -04:00
public export
2024-05-27 15:28:22 -04:00
CheckResult : DimEq d -> Nat -> Nat -> Type
CheckResult eqs q n = IfConsistent eqs $ CheckResult' q n
2023-02-19 11:51:44 -05:00
public export
2024-05-27 15:28:22 -04:00
record InferResult' q d n where
2022-04-23 18:21:30 -04:00
constructor InfRes
2024-05-27 15:28:22 -04:00
type : Term q d n
qout : QOutput q n
2022-04-23 18:21:30 -04:00
2023-02-19 11:51:44 -05:00
public export
InferResult : DimEq d -> TermLike
2024-05-27 15:28:22 -04:00
InferResult eqs q d n = IfConsistent eqs $ InferResult' q d n
2023-02-19 11:51:44 -05:00
2022-04-23 18:21:30 -04:00
2023-02-10 15:40:44 -05:00
export
2023-05-01 21:06:25 -04:00
lookupFree : Has ErrorEff fs => Name -> Loc -> Definitions -> Eff fs Definition
lookupFree x loc defs = maybe (throw $ NotInScope loc x) pure $ lookup x defs
2023-02-10 15:40:44 -05:00
2023-02-12 15:30:08 -05:00
public export
2024-05-27 15:28:22 -04:00
substCasePairRet : BContext 2 -> Term q d n -> ScopeTerm q d n ->
Term q d (2 + n)
2023-05-01 21:06:25 -04:00
substCasePairRet [< x, y] dty retty =
2024-04-04 13:23:08 -04:00
let tm = Pair (BVT 1 x.loc) (BVT 0 y.loc) $ x.loc `extendL` y.loc
arg = Ann tm (dty // fromNat 2) tm.loc in
2023-02-10 15:40:44 -05:00
retty.term // (arg ::: shift 2)
2023-02-11 12:15:50 -05:00
2023-03-26 08:40:54 -04:00
public export
2024-05-27 15:28:22 -04:00
substCaseSuccRet : BContext 2 -> ScopeTerm q d n -> Term q d (2 + n)
2023-05-01 21:06:25 -04:00
substCaseSuccRet [< p, ih] retty =
2024-04-04 13:23:08 -04:00
let loc = p.loc `extendL` ih.loc
arg = Ann (Succ (BVT 1 p.loc) p.loc) (NAT p.loc) loc in
2023-05-01 21:06:25 -04:00
retty.term // (arg ::: shift 2)
2023-03-26 08:40:54 -04:00
2023-03-31 13:11:35 -04:00
public export
2024-05-27 15:28:22 -04:00
substCaseBoxRet : BindName -> Term q d n -> ScopeTerm q d n -> Term q d (S n)
2023-05-01 21:06:25 -04:00
substCaseBoxRet x dty retty =
let arg = Ann (Box (BVT 0 x.loc) x.loc) (weakT 1 dty) x.loc in
retty.term // (arg ::: shift 1)
2023-02-11 12:15:50 -05:00
2023-03-31 13:23:30 -04:00
2024-04-04 13:23:08 -04:00
private
0 ExpectErrorConstructor : Type
ExpectErrorConstructor =
2024-05-27 15:28:22 -04:00
forall q, d, n. Loc -> NameContexts q d n -> Term q d n -> Error
2024-04-04 13:23:08 -04:00
parameters (defs : Definitions)
{auto _ : (Has ErrorEff fs, Has NameGen fs, Has Log fs)}
2023-04-15 09:13:01 -04:00
namespace TyContext
2024-05-27 15:28:22 -04:00
parameters (ctx : TyContext q d n) (sg : SQty) (loc : Loc)
2023-04-15 09:13:01 -04:00
export covering
2023-05-21 14:11:01 -04:00
whnf : {0 isRedex : RedexTest tm} -> CanWhnf tm isRedex =>
2024-05-27 15:28:22 -04:00
tm q d n -> Eff fs (NonRedex tm q d n defs (toWhnfContext ctx) sg)
2023-05-01 21:06:25 -04:00
whnf tm = do
let Val n = ctx.termLen; Val d = ctx.dimLen
res <- lift $ runExcept $ whnf defs (toWhnfContext ctx) sg tm
2023-05-01 21:06:25 -04:00
rethrow res
2023-04-15 09:13:01 -04:00
private covering %macro
2024-04-04 13:23:08 -04:00
expect : ExpectErrorConstructor -> TTImp -> TTImp ->
2024-05-27 15:28:22 -04:00
Elab (Term q d n -> Eff fs a)
2024-04-04 13:23:08 -04:00
expect err pat rhs = Prelude.do
match <- check `(\case ~(pat) => Just ~(rhs); _ => Nothing)
pure $ \term => do
res <- whnf term
maybe (throw $ err loc ctx.names term) pure $ match $ fst res
2023-02-11 12:15:50 -05:00
export covering %inline
2024-05-27 15:28:22 -04:00
expectTYPE : Term q d n -> Eff fs Universe
2023-05-01 21:06:25 -04:00
expectTYPE = expect ExpectedTYPE `(TYPE {l, _}) `(l)
export covering %inline
2024-05-27 15:28:22 -04:00
expectPi : Term q d n -> Eff fs (Qty q, Term q d n, ScopeTerm q d n)
2023-05-01 21:06:25 -04:00
expectPi = expect ExpectedPi `(Pi {qty, arg, res, _}) `((qty, arg, res))
export covering %inline
2024-05-27 15:28:22 -04:00
expectSig : Term q d n -> Eff fs (Term q d n, ScopeTerm q d n)
2023-05-01 21:06:25 -04:00
expectSig = expect ExpectedSig `(Sig {fst, snd, _}) `((fst, snd))
export covering %inline
2024-05-27 15:28:22 -04:00
expectEnum : Term q d n -> Eff fs (SortedSet TagVal)
2023-05-01 21:06:25 -04:00
expectEnum = expect ExpectedEnum `(Enum {cases, _}) `(cases)
export covering %inline
2024-05-27 15:28:22 -04:00
expectEq : Term q d n -> Eff fs (DScopeTerm q d n, Term q d n, Term q d n)
2023-05-01 21:06:25 -04:00
expectEq = expect ExpectedEq `(Eq {ty, l, r, _}) `((ty, l, r))
2023-03-26 08:40:54 -04:00
export covering %inline
2024-05-27 15:28:22 -04:00
expectNAT : Term q d n -> Eff fs ()
2023-11-02 13:14:22 -04:00
expectNAT = expect ExpectedNAT `(NAT {}) `(())
2023-03-26 08:40:54 -04:00
export covering %inline
2024-05-27 15:28:22 -04:00
expectSTRING : Term q d n -> Eff fs ()
expectSTRING = expect ExpectedSTRING `(STRING {}) `(())
2023-03-31 13:11:35 -04:00
export covering %inline
2024-05-27 15:28:22 -04:00
expectBOX : Term q d n -> Eff fs (Qty q, Term q d n)
2023-05-01 21:06:25 -04:00
expectBOX = expect ExpectedBOX `(BOX {qty, ty, _}) `((qty, ty))
2023-04-15 09:13:01 -04:00
2024-04-14 09:48:43 -04:00
export covering %inline
2024-05-27 15:28:22 -04:00
expectIOState : Term q d n -> Eff fs ()
2024-04-14 09:48:43 -04:00
expectIOState = expect ExpectedIOState `(IOState {}) `(())
2023-04-15 09:13:01 -04:00
namespace EqContext
2024-05-27 15:28:22 -04:00
parameters (ctx : EqContext q n) (sg : SQty) (loc : Loc)
2023-04-15 09:13:01 -04:00
export covering
2023-05-21 14:11:01 -04:00
whnf : {0 isRedex : RedexTest tm} -> CanWhnf tm isRedex =>
2024-05-27 15:28:22 -04:00
tm q 0 n -> Eff fs (NonRedex tm q 0 n defs (toWhnfContext ctx) sg)
2023-05-01 21:06:25 -04:00
whnf tm = do
res <- lift $ runExcept $ whnf defs (toWhnfContext ctx) sg tm
2023-05-01 21:06:25 -04:00
rethrow res
2023-03-31 13:11:35 -04:00
2023-04-15 09:13:01 -04:00
private covering %macro
2024-04-04 13:23:08 -04:00
expect : ExpectErrorConstructor -> TTImp -> TTImp ->
2024-05-27 15:28:22 -04:00
Elab (Term q 0 n -> Eff fs a)
2024-04-04 13:23:08 -04:00
expect err pat rhs = do
match <- check `(\case ~(pat) => Just ~(rhs); _ => Nothing)
pure $ \term => do
res <- whnf term
let t0 = delay $ term // shift0 ctx.dimLen
maybe (throw $ err loc ctx.names t0) pure $ match $ fst res
export covering %inline
2024-05-27 15:28:22 -04:00
expectTYPE : Term q 0 n -> Eff fs Universe
2023-05-01 21:06:25 -04:00
expectTYPE = expect ExpectedTYPE `(TYPE {l, _}) `(l)
export covering %inline
2024-05-27 15:28:22 -04:00
expectPi : Term q 0 n -> Eff fs (Qty q, Term q 0 n, ScopeTerm q 0 n)
2023-05-01 21:06:25 -04:00
expectPi = expect ExpectedPi `(Pi {qty, arg, res, _}) `((qty, arg, res))
export covering %inline
2024-05-27 15:28:22 -04:00
expectSig : Term q 0 n -> Eff fs (Term q 0 n, ScopeTerm q 0 n)
2023-05-01 21:06:25 -04:00
expectSig = expect ExpectedSig `(Sig {fst, snd, _}) `((fst, snd))
export covering %inline
2024-05-27 15:28:22 -04:00
expectEnum : Term q 0 n -> Eff fs (SortedSet TagVal)
2023-05-01 21:06:25 -04:00
expectEnum = expect ExpectedEnum `(Enum {cases, _}) `(cases)
export covering %inline
2024-05-27 15:28:22 -04:00
expectEq : Term q 0 n -> Eff fs (DScopeTerm q 0 n, Term q 0 n, Term q 0 n)
2023-05-01 21:06:25 -04:00
expectEq = expect ExpectedEq `(Eq {ty, l, r, _}) `((ty, l, r))
2023-03-26 08:40:54 -04:00
export covering %inline
2024-05-27 15:28:22 -04:00
expectNAT : Term q 0 n -> Eff fs ()
2023-11-02 13:14:22 -04:00
expectNAT = expect ExpectedNAT `(NAT {}) `(())
2023-03-31 13:11:35 -04:00
export covering %inline
2024-05-27 15:28:22 -04:00
expectSTRING : Term q 0 n -> Eff fs ()
expectSTRING = expect ExpectedSTRING `(STRING {}) `(())
2023-03-31 13:11:35 -04:00
export covering %inline
2024-05-27 15:28:22 -04:00
expectBOX : Term q 0 n -> Eff fs (Qty q, Term q 0 n)
2023-05-01 21:06:25 -04:00
expectBOX = expect ExpectedBOX `(BOX {qty, ty, _}) `((qty, ty))
2024-04-14 09:48:43 -04:00
export covering %inline
2024-05-27 15:28:22 -04:00
expectIOState : Term q 0 n -> Eff fs ()
2024-04-14 09:48:43 -04:00
expectIOState = expect ExpectedIOState `(IOState {}) `(())