This PR introduces stricter inference for the `@[defeq]` attribute and a companion `@[backward_defeq]` attribute that preserves the pre-PR behavior as an opt-in. ### What changed * `@[defeq]` is now inferred only when the equation holds at `.instances` transparency (the transparency `dsimp` operates at). * `@[backward_defeq]` is the old set: every theorem whose `rfl` proof the legacy inference would have accepted is tagged `@[backward_defeq]`, so `defeq ⊆ backward_defeq` holds by construction. * The option `backward.defeqAttrib.useBackward` (default `false`) makes `dsimp` also use `@[backward_defeq]` theorems, restoring the pre-PR behavior for a specific proof or file. * The option is eqn-affecting: its value at the point of a function's definition is recorded so that the equation lemmas later generated for that function use the same value, regardless of the ambient option at the use site. ### Mathlib adaption A companion adaption branch (`lean-pr-testing-backward-defeq-attrib` on mathlib4) builds cleanly against this PR and passes `lake test` without warnings. Most adaption changes are scoped `set_option backward.defeqAttrib.useBackward true in` additions on the failing declarations; a small number of files needed proof-level edits where the stored form of a `dsimp%`/`@[reassoc]`/`@[elementwise]` /`@[simps]`/`@[to_app]`-generated lemma had drifted under the stricter regime. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
31 lines
1,010 B
Text
31 lines
1,010 B
Text
/--
|
||
info: equations:
|
||
@[backward_defeq] theorem List.append.eq_1.{u_1} : ∀ {α : Type u_1} (x : List α), [].append x = x
|
||
@[backward_defeq] theorem List.append.eq_2.{u_1} : ∀ {α : Type u_1} (x : List α) (a : α) (as : List α),
|
||
(a :: as).append x = a :: as.append x
|
||
-/
|
||
#guard_msgs in
|
||
#print eqns List.append
|
||
|
||
/--
|
||
info: equations:
|
||
@[backward_defeq] theorem List.append.eq_1.{u_1} : ∀ {α : Type u_1} (x : List α), [].append x = x
|
||
@[backward_defeq] theorem List.append.eq_2.{u_1} : ∀ {α : Type u_1} (x : List α) (a : α) (as : List α),
|
||
(a :: as).append x = a :: as.append x
|
||
-/
|
||
#guard_msgs in
|
||
#print equations List.append
|
||
|
||
@[simp] def ack : Nat → Nat → Nat
|
||
| 0, y => y+1
|
||
| x+1, 0 => ack x 1
|
||
| x+1, y+1 => ack x (ack (x+1) y)
|
||
|
||
/--
|
||
info: equations:
|
||
theorem ack.eq_1 : ∀ (x : Nat), ack 0 x = x + 1
|
||
theorem ack.eq_2 : ∀ (x_2 : Nat), ack x_2.succ 0 = ack x_2 1
|
||
theorem ack.eq_3 : ∀ (x_2 y : Nat), ack x_2.succ y.succ = ack x_2 (ack (x_2 + 1) y)
|
||
-/
|
||
#guard_msgs in
|
||
#print eqns ack
|