lean4-htt/tests/lean/run/10850.lean
Kyle Miller 005f6ae7cd
fix: let Meta.zetaReduce zeta reduce have expressions (#12695)
This PR fixes a bug in `Meta.zetaReduce` where `have` expressions were
not being zeta reduced. It also adds a feature where applications of
local functions are beta reduced, and another where zeta-delta reduction
can be disabled. These are all controllable by flags:
- `zetaDelta` (default: true) enables unfolding local definitions
- `zetaHave` (default: true) enables zeta reducing `have` expressions
- `beta` (default: true) enables beta reducing applications of local
definitions

Closes #10850
2026-02-27 00:37:52 +00:00

95 lines
1.8 KiB
Text

module
public meta import Lean
/-!
# Testing `Lean.Meta.zetaReduce`
It needs to be able to reduce both `let` and `have` expressions.
Previously it was relying on the fact that `let` creates local definitions,
then zeta-delta reducing.
-/
open Lean Elab Term Meta Tactic
elab "zetaReduce " zd?:"zetaDelta"? zh?:"zetaHave"? beta?:"beta"? ":" t:term : tactic => withMainContext do
let e ← elabTermAndSynthesize t none
let e' ← zetaReduce e (zetaDelta := zd?.isSome) (zetaHave := zh?.isSome) (beta := beta?.isSome)
logInfo m!"Before reduction:{indentExpr e}\nAfter reduction:{indentExpr e'}"
/--
info: Before reduction:
(have m := 0 + 1;
m - 1) =
0
After reduction:
(have m := 0 + 1;
m - 1) =
0
---
info: Before reduction:
(have m := 0 + 1;
m - 1) =
0
After reduction:
0 + 1 - 1 = 0
---
info: Before reduction:
v
After reduction:
v
---
info: Before reduction:
v
After reduction:
2
---
info: Before reduction:
f v
After reduction:
f v
---
info: Before reduction:
f v
After reduction:
(fun n =>
have m := n;
m + 1)
2
---
info: Before reduction:
f v
After reduction:
have m := 2;
m + 1
---
info: Before reduction:
f v
After reduction:
(fun n => n + 1) 2
---
info: Before reduction:
f v
After reduction:
2 + 1
---
error: unsolved goals
v : Nat := 2
f : Nat → Nat :=
fun n =>
have m := n;
let m' := m;
m' + 1
⊢ True
-/
#guard_msgs in
example : True := by
let v := 2
let f n := have m := n; let m' := m; m' + 1
zetaReduce : (have m := 0 + 1; m - 1) = 0
zetaReduce zetaHave : (have m := 0 + 1; m - 1) = 0
zetaReduce : v
zetaReduce zetaDelta : v
zetaReduce : f v
zetaReduce zetaDelta : f v
zetaReduce zetaDelta beta : f v
zetaReduce zetaDelta zetaHave : f v
zetaReduce zetaDelta zetaHave beta : f v