Files
iris/BidirTT/Eval.lean
T

151 lines
4.1 KiB
Lean4
Raw Normal View History

2026-04-19 04:17:45 +00:00
import BidirTT.Value
namespace BidirTT
abbrev EvalM := Except String
mutual
partial def eval : Env Tm EvalM Val
| env, .var i =>
match env[i]? with
| some v => pure v
| none =>
throw s!"bad de Bruijn index {i} in environment of size {env.length}"
| env, .lam t => pure (.lam (.mk env t))
| env, .app t u => do
let vt eval env t
let vu eval env u
vApp vt vu
| env, .pi a b => do
let va eval env a
pure (.pi va (.mk env b))
| env, .sig a b => do
let va eval env a
pure (.sig va (.mk env b))
| env, .pair t u => do
let vt eval env t
let vu eval env u
pure (.pair vt vu)
| env, .fst t => do
let vt eval env t
vFst vt
| env, .snd t => do
let vt eval env t
vSnd vt
| _, .univ i => pure (.univ i)
| env, .letE _ t u => do
let vt eval env t
eval (vt :: env) u
partial def vApp : Val Val EvalM Val
| .lam c, u => cApp c u
| t, u => pure (.app t u)
partial def vFst : Val EvalM Val
| .pair a _ => pure a
| t => pure (.fst t)
partial def vSnd : Val EvalM Val
| .pair _ b => pure b
| t => pure (.snd t)
partial def cApp : Closure Val EvalM Val
| .mk env body, v => eval (v :: env) body
end
partial def quote : Lvl Val EvalM Tm
| l, .var x =>
if x < l then
pure (.var (l - x - 1))
else
throw s!"bad level {x} while quoting at level {l}"
| l, .app t u => do
let qt quote l t
let qu quote l u
pure (.app qt qu)
| l, .fst t => do
let qt quote l t
pure (.fst qt)
| l, .snd t => do
let qt quote l t
pure (.snd qt)
| l, .lam c => do
let body cApp c (.var l)
let qb quote (l + 1) body
pure (.lam qb)
| l, .pi a c => do
let qa quote l a
let body cApp c (.var l)
let qb quote (l + 1) body
pure (.pi qa qb)
| l, .sig a c => do
let qa quote l a
let body cApp c (.var l)
let qb quote (l + 1) body
pure (.sig qa qb)
| l, .pair a b => do
let qa quote l a
let qb quote l b
pure (.pair qa qb)
| _, .univ i => pure (.univ i)
private def andThen (lhs : EvalM Bool) (rhs : Unit EvalM Bool) : EvalM Bool := do
if ( lhs) then
rhs ()
else
pure false
partial def conv : Lvl Val Val EvalM Bool
| _, .univ i, .univ j => pure (i == j)
| l, .pi a c, .pi a' c' =>
andThen (conv l a a') fun _ => do
let b cApp c (.var l)
let b' cApp c' (.var l)
conv (l + 1) b b'
| l, .sig a c, .sig a' c' =>
andThen (conv l a a') fun _ => do
let b cApp c (.var l)
let b' cApp c' (.var l)
conv (l + 1) b b'
| l, .lam c, .lam c' =>
do
let body cApp c (.var l)
let body' cApp c' (.var l)
conv (l + 1) body body'
| l, .lam c, t =>
do
let body cApp c (.var l)
let apped vApp t (.var l)
conv (l + 1) body apped
| l, t, .lam c =>
do
let apped vApp t (.var l)
let body cApp c (.var l)
conv (l + 1) apped body
| l, .pair a b, .pair a' b' =>
andThen (conv l a a') fun _ => conv l b b'
| l, .pair a b, p =>
andThen
(do
let fstp vFst p
conv l a fstp)
fun _ => do
let sndp vSnd p
conv l b sndp
| l, p, .pair a b =>
andThen
(do
let fstp vFst p
conv l fstp a)
fun _ => do
let sndp vSnd p
conv l sndp b
| _, .var x, .var y => pure (x == y)
| l, .app t u, .app t' u' =>
andThen (conv l t t') fun _ => conv l u u'
| l, .fst t, .fst t' => conv l t t'
| l, .snd t, .snd t' => conv l t t'
| _, _, _ => pure false
end BidirTT