quox/lib/Quox/Whnf/ComputeElimType.idr

110 lines
3.2 KiB
Idris
Raw Normal View History

2023-08-24 12:42:26 -04:00
module Quox.Whnf.ComputeElimType
import Quox.Whnf.Interface
import Quox.Displace
2024-01-13 09:32:12 -05:00
import Quox.Pretty
2023-08-24 12:42:26 -04:00
%default total
||| performs the minimum work required to recompute the type of an elim.
|||
||| - assumes the elim is already typechecked
||| - the return value is not reduced
export covering
2023-09-30 12:31:23 -04:00
computeElimType :
CanWhnf Term Interface.isRedexT =>
CanWhnf Elim Interface.isRedexE =>
(defs : Definitions) -> (ctx : WhnfContext d n) -> (0 sg : SQty) ->
(e : Elim d n) -> (0 ne : No (isRedexE defs ctx sg e)) =>
2023-09-30 12:31:23 -04:00
Eff Whnf (Term d n)
2023-09-17 07:54:26 -04:00
||| computes a type and then reduces it to whnf
export covering
2023-09-30 12:31:23 -04:00
computeWhnfElimType0 :
CanWhnf Term Interface.isRedexT =>
CanWhnf Elim Interface.isRedexE =>
(defs : Definitions) -> (ctx : WhnfContext d n) -> (0 sg : SQty) ->
(e : Elim d n) -> (0 ne : No (isRedexE defs ctx sg e)) =>
2023-09-30 12:31:23 -04:00
Eff Whnf (Term d n)
2024-01-13 09:32:12 -05:00
private covering
computeElimTypeNoLog, computeWhnfElimType0NoLog :
CanWhnf Term Interface.isRedexT =>
CanWhnf Elim Interface.isRedexE =>
(defs : Definitions) -> WhnfContext d n -> (0 sg : SQty) ->
(e : Elim d n) -> (0 ne : No (isRedexE defs ctx sg e)) =>
Eff Whnf (Term d n)
computeElimTypeNoLog defs ctx sg e =
2023-08-24 12:42:26 -04:00
case e of
2023-09-17 07:54:26 -04:00
F x u loc => do
2023-08-24 12:42:26 -04:00
let Just def = lookup x defs
| Nothing => throw $ NotInScope loc x
2023-10-15 10:23:38 -04:00
pure $ def.typeWithAt ctx.dimLen ctx.termLen u
2023-08-24 12:42:26 -04:00
2023-09-17 07:54:26 -04:00
B i _ =>
pure (ctx.tctx !! i).type
2023-08-24 12:42:26 -04:00
2023-09-17 07:54:26 -04:00
App f s loc =>
2024-01-13 09:32:12 -05:00
case !(computeWhnfElimType0NoLog defs ctx sg f {ne = noOr1 ne}) of
2023-09-17 07:54:26 -04:00
Pi {arg, res, _} => pure $ sub1 res $ Ann s arg loc
2023-09-18 15:52:51 -04:00
ty => throw $ ExpectedPi loc ctx.names ty
2023-08-24 12:42:26 -04:00
CasePair {pair, ret, _} =>
pure $ sub1 ret pair
2023-09-18 15:52:51 -04:00
Fst pair loc =>
2024-01-13 09:32:12 -05:00
case !(computeWhnfElimType0NoLog defs ctx sg pair {ne = noOr1 ne}) of
2023-09-18 15:52:51 -04:00
Sig {fst, _} => pure fst
ty => throw $ ExpectedSig loc ctx.names ty
Snd pair loc =>
2024-01-13 09:32:12 -05:00
case !(computeWhnfElimType0NoLog defs ctx sg pair {ne = noOr1 ne}) of
2023-09-18 15:52:51 -04:00
Sig {snd, _} => pure $ sub1 snd $ Fst pair loc
ty => throw $ ExpectedSig loc ctx.names ty
2023-08-24 12:42:26 -04:00
CaseEnum {tag, ret, _} =>
pure $ sub1 ret tag
CaseNat {nat, ret, _} =>
pure $ sub1 ret nat
CaseBox {box, ret, _} =>
pure $ sub1 ret box
2023-09-17 07:54:26 -04:00
DApp {fun = f, arg = p, loc} =>
2024-01-13 09:32:12 -05:00
case !(computeWhnfElimType0NoLog defs ctx sg f {ne = noOr1 ne}) of
2023-09-17 07:54:26 -04:00
Eq {ty, _} => pure $ dsub1 ty p
t => throw $ ExpectedEq loc ctx.names t
2023-08-24 12:42:26 -04:00
Ann {ty, _} =>
pure ty
Coe {ty, q, _} =>
pure $ dsub1 ty q
Comp {ty, _} =>
pure ty
TypeCase {ret, _} =>
pure ret
2023-09-17 07:54:26 -04:00
2024-01-13 09:32:12 -05:00
computeElimType defs ctx sg e {ne} = do
let Val n = ctx.termLen
2024-01-29 12:17:17 -05:00
say "whnf" 90 e.loc "computeElimType"
say "whnf" 95 e.loc $ hsep ["ctx =", runPretty $ prettyWhnfContext ctx]
say "whnf" 90 e.loc $
hsep ["e =", runPretty $ prettyElim ctx.dnames ctx.tnames e]
2024-01-13 09:32:12 -05:00
res <- computeElimTypeNoLog defs ctx sg e {ne}
2024-01-29 12:17:17 -05:00
say "whnf" 91 e.loc $
hsep ["", runPretty $ prettyTerm ctx.dnames ctx.tnames res]
2024-01-13 09:32:12 -05:00
pure res
2023-09-30 12:31:23 -04:00
computeWhnfElimType0 defs ctx sg e =
computeElimType defs ctx sg e >>= whnf0 defs ctx SZero
2024-01-13 09:32:12 -05:00
computeWhnfElimType0NoLog defs ctx sg e {ne} =
computeElimTypeNoLog defs ctx sg e {ne} >>= whnf0 defs ctx SZero