Zulip Chat Archive
Stream: mathlib4
Topic: Making a definition a `simp` lemma
Etienne Marion (Aug 14 2024 at 20:37):
Hi! I have a definition which I would like to be reduced by simp
. Does it make sense (namely does it exist in Mathlib) to have a simp lemma which simply unfolds the definition? Something like this:
import Mathlib
variable {ι : Type*} {X : ι → Type*}
def proj (s : Finset ι) (x : (i : ι) → X i) (i : s) : X i := x i
@[simp]
lemma proj_eq (s : Finset ι) : proj (X := X) s = fun x i ↦ x i := rfl
Violeta Hernández (Aug 14 2024 at 20:39):
If that's what you want to do, you should make proj
an abbrev
instead
Violeta Hernández (Aug 14 2024 at 20:40):
I believe that makes it so that simp
can "see through" it
Etienne Marion (Aug 14 2024 at 20:40):
Well I thought so, but it does not work
Etienne Marion (Aug 14 2024 at 20:47):
Here is an example, it all happens in the have
block:
import Mathlib
variable {ι : Type*} {X : ι → Type*}
abbrev proj (s : Finset ι) (x : (i : ι) → X i) (i : s) : X i := x i
-- @[simp]
-- lemma proj_eq (s : Finset ι) : proj (X := X) s = fun x i ↦ x i := rfl
def cylinder (s : Finset ι) (S : Set ((i : s) → X i)) : Set ((i : ι) → X i) := proj s ⁻¹' S
@[simp]
theorem mem_cylinder (s : Finset ι) (S : Set (∀ i : s, X i)) (f : (i : ι) → X i) :
f ∈ cylinder s S ↔ proj s f ∈ S :=
Set.mem_preimage
example [h_nonempty : Nonempty ((i : ι) → X i)] (s : Finset ι) (S : Set ((i : s) → X i))
(f : (i : s) → X i) (hf : f ∈ S) : cylinder s S ≠ ∅ := by
classical
let f' : (i : ι) → X i := fun i ↦ if hi : i ∈ s then f ⟨i, hi⟩ else h_nonempty.some i
have : f' ∈ cylinder s S := by
rw [mem_cylinder]
-- simp? [proj, f'] -- suggests simp only [f'] and does not unfold proj
unfold proj
simp only [Finset.coe_mem, ↓reduceDIte, f']
exact hf
sorry
Kyle Miller (Aug 15 2024 at 01:07):
Etienne Marion said:
Does it make sense (namely does it exist in Mathlib) to have a simp lemma which simply unfolds the definition?
Yes, you can have proj_eq
be a @[simp]
lemma. There are some places where @[simp]
is right on the definition, but you'll have to see whether it unfolds the definition the way you want.
If it's worth being a definition, and you want to unfold it immediately, there's a question of whether it's worth having the definition at all.
Etienne Marion (Aug 15 2024 at 08:16):
Thanks for the answers. I tried putting @[simp]
on the def
but it doesn't work. I definitely think this definition is worth for what I'm doing, because it gives nice interactions with other things I defined and it avoids a lot of type ascription. However I'm still not sure if I want it to be automatically simplified.
An other way would be that rw [proj]
or simp [proj]
would unfold the definition, but it does not, even when I make it an abbrev
or I put a @[reducible]
. Is it normal?
Etienne Marion (Aug 15 2024 at 12:49):
In fact it looks like simp [proj]
will work with proj x i
, but not with proj x
.
Kyle Miller (Aug 15 2024 at 17:22):
If putting @[simp]
directly on a def doesn't give the correct formulation (as you see, it wants it to be fully applied) then you need to put @[simp]
on a custom-written lemma, like you originally had.
Kyle Miller (Aug 15 2024 at 17:23):
There's also simp (config := { unfoldPartialApp := true }) [proj]
, which might work here, but that's more inconvenient than simp [proj_def]
.
Kyle Miller (Aug 15 2024 at 17:25):
By the way, what putting @[simp]
on a definition effectively does is make all the foo.eq_NNN
theorems into simp lemmas. We can see what the equation theorem is using #check
:
def proj (s : Finset ι) (x : (i : ι) → X i) (i : s) : X i := x i
#check proj.eq_1
/-
proj.eq_1.{u_1, u_2} {ι : Type u_1} {X : ι → Type u_2}
(s : Finset ι) (x : (i : ι) → X i) (i : { x // x ∈ s }) :
proj s x i = x ↑i
-/
There can be more than one for definitions made using pattern matching.
Kyle Miller (Aug 15 2024 at 17:27):
In the future there might be a way to adjust the equation theorem, but I believe this is currently a very-low-priority feature.
Etienne Marion (Aug 15 2024 at 17:33):
I see, thanks a lot for these explanations!
Last updated: May 02 2025 at 03:31 UTC