Repository navigation
feat: keep haves above a split match in equation lemmas - #16235
Open
leodemoura wants to merge 15 commits into
Open
leodemoura wants to merge 15 commits into
leodemoura wants to merge 15 commits into
Conversation
This PR makes the equation lemmas `f.eq_<i>` keep the `have`s and `let`s of the right-hand side when they split a `match` below them, instead of inlining their values into each equation. Inlining duplicated the values, exponentially for nested `have`s, and lost the sharing of the join points that `do` notation introduces, which `vcgen +jp [f]` needs (#16122). The generated equations are otherwise the same: inlining the `have`s gives back the previous equations. `mkEqnTypes` now introduces the root `have`s as let-declarations, and commits a step only if it simplifies or splits a `match`. A `match` in the value of a `have` is reduced or split in place, and the `have` is inlined only where splitting requires it, for example when its value depends on a split variable and the `match` elaborator made it a discriminant. `saveEqn` puts the used declarations back into the right-hand side. Breaking change: after `rw [f]`, the goal can contain `have`s above a split `match`. Use `dsimp only` after `rw [f]`, or `simp only [f]` instead of `rw [f]`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
leodemoura
force-pushed
the
eqns-keep-have-match
branch
from
November 3, 2026 21:37
e3265a2 to
a1e65b3
Compare
Unused `have`s at the root of the right-hand side are now dropped from the equation lemmas, also when no `match` is split below them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A `have` whose value has a `match` to split or simplify is moved back into the right-hand side, where `Split.splitMatch` and `simpMatch?` rewrite its value, also with the hypotheses of overlapping patterns. The `have` is kept instead of inlined. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When splitting a `match` fails, `splitMatch?` first tries the other `match`es, and only then zeta-reduces let-variables. This keeps the `have`s that the `match` elaborator generalizes as discriminants of an outer `match`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep let/have bindings in their lexical scopes while generating equations. Separate matcher case refinement from RHS normalization and construct equality proofs for scoped telescope rewrites. Isolate simplifier caches when entering local scopes. Add regression coverage for nested bindings, dependent values, computed discriminants, and normalization proofs.
This PR fixes generated equations whose have bindings become invalid after reducing dependent matches. Track the definitions unfolded while typechecking normalized telescopes, then substitute the corresponding have values throughout their scopes. Apply the pass after simp and dsimp, and add regressions for dependent types, named-match proof arguments, and fixed binding values.
Rebuild changed binding bodies with let and run letToHave before revisiting the result. Preserve sharing for dependent bindings, and cover conversion of existing lets and nested shared values in the tests and benchmarks.
This PR avoids duplicate equation theorems by eliminating contradictory branches after matcher refinement. Use the existing contradiction checker in Split.refineMatch to close branches whose discriminant equalities or overlap exclusions become contradictory after substitution. Add regressions for dependent bindings, constant discriminants, and quantified overlap exclusions, and update the expected trace names after removing an impossible equation.
Member
Author
|
!bench |
|
Benchmark results for 354bae1 against aab5551 are in. There are significant results. @leodemoura
Large changes (3✅, 4🟥)
Medium changes (1✅, 1🟥)
Small changes (8✅, 207🟥)
|
|
The adaptation PR for this PR is leanprover/downstream-lean4#227. |
`rwMatcher` instantiated the matcher congruence equation with all arguments of the matcher application. If the matcher is applied to more arguments than its arity, the extra arguments land on the pattern variables of the equation, and the overlap hypotheses cannot be discharged. Equation generation then keeps the `match` unsplit, for example in the `@[to_dual]` translation `WithInitial.comp` of Mathlib's `WithTerminal.comp`. `rwMatcher` now rewrites the matcher application and reapplies the extra arguments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D74FF1zb7wKmojVzQB51CA
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Nov 4, 2026
`mkEqnTypes` computes an equation statement by rewriting a matcher with its congruence equation, also when the discriminants of that alternative are not constructor applications. `mkEqnProof` then cannot reduce the matcher on the left-hand side if the compiled matcher cases on such a discriminant, for example `AugmentedSimplexCategory.tensorHom` in Mathlib. `mkEqnProof` now tries the same rewrite on the left-hand side before it fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D74FF1zb7wKmojVzQB51CA
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Nov 4, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR makes the equation lemmas
f.eq_<i>keep thehaves andlets of the right-hand side when they split amatchbelow them, instead of inlining their values into each equation. Inlining duplicated the values, exponentially for nestedhaves, and lost the sharing of the join points thatdonotation introduces, whichvcgen +jp [f]needs (#16122). The generated equations are otherwise the same: inlining thehaves gives back the previous equations.mkEqnTypesnow introduces the roothaves as let-declarations, and commits a step only if it simplifies or splits amatch. Amatchin the value of ahaveis reduced or split in place, and thehaveis inlined only where splitting requires it, for example when its value depends on a split variable and thematchelaborator made it a discriminant.saveEqnputs the used declarations back into the right-hand side.Breaking change: after
rw [f], the goal can containhaves above a splitmatch. Usedsimp onlyafterrw [f], orsimp only [f]instead ofrw [f].🤖 Generated with Claude Code