Skip to content

feat: auto eta-expand structures in grind when equality with constructor is present#12860

Draft
kim-em wants to merge 4 commits intomasterfrom
grind-eta-struct-for-eq
Draft

feat: auto eta-expand structures in grind when equality with constructor is present#12860
kim-em wants to merge 4 commits intomasterfrom
grind-eta-struct-for-eq

Conversation

@kim-em
Copy link
Collaborator

@kim-em kim-em commented Mar 10, 2026

This PR adds Eq-triggered eta-expansion for structures in grind. When grind internalizes Eq α a b where one side is a structure constructor and the other isn't, it eta-expands the non-constructor side. This lets grind go from field equalities to structure equality without requiring @[grind] or @[grind ext] on the structure type.

For example, this now works without any annotation on LoopRange:

structure LoopRange where
  start : Nat
  end_ : Option Nat

def isZero (r : LoopRange) : Prop := r = ⟨0, some 0def isZeroVar (r : LoopRange) : Prop :=
  match r.end_ with
  | some x => r.start = 0 ∧ x = 0
  | none => False

example (r : LoopRange) : isZeroVar r ↔ isZero r := by
  unfold isZeroVar isZero; grind

Previously grind would deduce r.start = 0 and r.end_ = some 0 but couldn't reconstruct r = ⟨0, some 0⟩ unless LoopRange was registered with @[grind ext].

The approach is more targeted than unconditionally eta-expanding all structure terms — it only fires when a constructor appears in an equality, which avoids performance issues from cascading expansions on types like nested Prod.

Side effect: grind now proves additional theorems in the #grind_lint test suite (e.g. Array.get_max?, Array.min_mem), so expected outputs are updated.

🤖 Prepared with Claude Code

@kim-em kim-em added the changelog-tactics User facing tactics label Mar 10, 2026
@kim-em
Copy link
Collaborator Author

kim-em commented Mar 10, 2026

!radar

@kim-em kim-em force-pushed the grind-eta-struct-for-eq branch from c094082 to 7f3a54f Compare March 10, 2026 03:09
@github-actions github-actions bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Mar 10, 2026
@mathlib-lean-pr-testing
Copy link

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 71ff36621103dfab119dfbead39dea3995d5832d --onto e8048291010c815d0d30926924e7ad7afc18b1c0. You can force Mathlib CI using the force-mathlib-ci label. (2026-03-10 03:55:41)

@leanprover-bot
Copy link
Collaborator

leanprover-bot commented Mar 10, 2026

Reference manual CI status:

  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase 71ff36621103dfab119dfbead39dea3995d5832d --onto a165292462a973c20d3cc8c8b23a3ac2334a2a4a. You can force reference manual CI using the force-manual-ci label. (2026-03-10 03:55:44)
  • ❗ Reference manual CI can not be attempted yet, as the nightly-testing-2026-03-09 tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto nightly-with-manual, reference manual CI should run now. You can force reference manual CI using the force-manual-ci label. (2026-03-10 11:30:15)

@kim-em
Copy link
Collaborator Author

kim-em commented Mar 10, 2026

!radar

@leanprover-radar
Copy link

leanprover-radar commented Mar 10, 2026

Benchmark results for 474e02b against 71ff366 are in. There are no significant changes. @kim-em

  • 🟥 build//instructions: +1.7G (+0.01%)

Medium changes (1🟥)

  • 🟥 build/module/Std.Tactic.BVDecide.LRAT.Internal.Formula.RupAddResult//instructions: +1.2G (+2.32%) (reduced significance based on absolute threshold)

Small changes (3✅, 3🟥)

  • 🟥 build/module/Lean.Meta.Tactic.Grind.Internalize//instructions: +703.6M (+2.87%) (reduced significance based on *//lines)
  • 🟥 build/module/Std.Tactic.BVDecide.LRAT.Internal.Formula.Lemmas//instructions: +77.8M (+0.41%)
  • 🟥 build/module/Std.Tactic.BVDecide.LRAT.Internal.Formula.RatAddResult//instructions: +52.7M (+0.41%)
  • compiled/unionfind//task-clock: -91ms (-9.34%)
  • compiled/unionfind//wall-clock: -91ms (-9.29%)
  • elab/bv_decide_realworld//wall-clock: -40ms (-3.36%)

kim-em and others added 4 commits March 10, 2026 10:34
…uctor is present

This PR adds automatic structure eta-expansion in `grind` when an equality
`Eq α a b` is internalized where one side is a structure constructor and the
other isn't. Previously, `grind` could only connect field equalities to
structure equality for types explicitly marked `@[grind]` or `@[grind ext]`.
Now goals like `r = ⟨0, some 0⟩` can be closed without requiring the
annotation, as long as the constructor appears directly in an equality.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Eq-triggered eta-expansion causes grind to prove additional theorems
about Array and Vector, so the #grind_lint #guard_msgs output changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Make `foo` irreducible so grind can't see the constructor through it,
preserving the test's intent of exercising the `first_par` path in `try?`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…uct matching

This PR fixes the grind_lint test files to use `#grind_lint skip` entries
(in LintExceptions.lean and locally) instead of pinning exact `#guard_msgs`
output for changed theorem counts. Also refactors `doEtaExpandStruct` to
accept pre-matched structure info as parameters, avoiding redundant
`matchConstNonRecStructure` calls, and reuses `αWhnf` from the Eq type
in `propagateEtaStructForEq`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kim-em kim-em force-pushed the grind-eta-struct-for-eq branch from 221622b to 9ecc7e2 Compare March 10, 2026 10:34
mathlib-nightly-testing bot pushed a commit to leanprover-community/batteries that referenced this pull request Mar 10, 2026
@github-actions github-actions bot added the mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN label Mar 10, 2026
mathlib-nightly-testing bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Mar 10, 2026
@mathlib-lean-pr-testing mathlib-lean-pr-testing bot added the builds-mathlib CI has verified that Mathlib builds against this PR label Mar 10, 2026
@mathlib-lean-pr-testing
Copy link

Mathlib CI status (docs):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

builds-mathlib CI has verified that Mathlib builds against this PR changelog-tactics User facing tactics mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants