Skip to content

Commit a2d69bd

Browse files
committed
fix: reintroduce to_fun_as_coe as simp lemma (#931)
This is a proposed fix for the broken simp calls in #922. See https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/.60simp.60.20calls.20broken.20in.20mathlib4.23922/near/314783451 for more details. Note that `to_fun_as_coe` was a syntactic tautology when it was ported, but this is no longer the case because we now have `FunLike`.
1 parent bf9d289 commit a2d69bd

File tree

5 files changed

+128
-32
lines changed

5 files changed

+128
-32
lines changed

Mathlib/Algebra/Group/WithOne/Basic.lean

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -129,30 +129,33 @@ theorem map_comp (f : α →ₙ* β) (g : β →ₙ* γ) : map (g.comp f) = (map
129129
#align with_one.map_comp WithOne.map_comp
130130
#align with_zero.map_comp WithZero.map_comp
131131

132+
-- porting note: this used to have `@[simps apply]` but it was generating lemmas which
133+
-- weren't in simp normal form.
132134
/-- A version of `Equiv.optionCongr` for `WithOne`. -/
133-
@[to_additive "A version of `equiv.option_congr` for `with_zero`.", simps apply]
135+
@[to_additive "A version of `equiv.option_congr` for `with_zero`."]
134136
def _root_.MulEquiv.withOneCongr (e : α ≃* β) : WithOne α ≃* WithOne β :=
135137
{ map e.toMulHom with
136138
toFun := map e.toMulHom, invFun := map e.symm.toMulHom,
137139
left_inv := fun x => (map_map _ _ _).trans <| by
138-
-- porting note: in mathlib3 this worked as: `induction x using WithOne.cases_on <;> simp`
139-
induction x using WithOne.cases_on
140-
· simp
141-
· simp only [map_coe, MulHom.coe_mk, map_comp, MonoidHom.coe_comp, Function.comp_apply,
142-
MulEquiv.toEquiv_symm, coe_inj]
143-
apply Equiv.symm_apply_apply,
144-
-- porting note: I think because of the way coercions are handled, this doesn't get changed
145-
-- by `simp` into something where `Equiv.symm_apply_apply` automatically applies.
140+
induction x using WithOne.cases_on <;> simp
146141
right_inv := fun x => (map_map _ _ _).trans <| by
147-
-- porting note: in mathlib3 this worked as: `induction x using WithOne.cases_on <;> simp`
148-
induction x using WithOne.cases_on
149-
· simp
150-
· simp only [map_coe, MulHom.coe_mk, MulEquiv.toEquiv_symm, map_comp, MonoidHom.coe_comp,
151-
Function.comp_apply, coe_inj]
152-
apply Equiv.apply_symm_apply }
142+
induction x using WithOne.cases_on <;> simp }
153143
#align mul_equiv.with_one_congr MulEquiv.withOneCongr
154144
#align add_equiv.with_zero_congr AddEquiv.withZeroCongr
155145

146+
-- porting note: an approximation to this was being generated by `@[simps apply]` but it
147+
-- mentioned Equiv.toFun so was not in simp normal form. This might be a bug in `@[simps].
148+
@[simp] theorem _root_.MulEquiv.withOneCongr_apply {α β : Type _} [Mul α] [Mul β] (e : α ≃* β)
149+
(a : WithOne α) : (MulEquiv.withOneCongr e).toEquiv a = (map (MulEquiv.toMulHom e)) a := rfl
150+
#align mul_equiv.with_one_congr_apply MulEquiv.withOneCongr_apply
151+
152+
-- porting note: `@[to_additive, simps apply]` was not generating this lemma at the
153+
-- time of writing this note.
154+
@[simp] theorem _root_.AddEquiv.withZeroCongr_apply {α β : Type _} [Add α] [Add β] (e : α ≃+ β)
155+
(a : WithZero α) :
156+
(AddEquiv.withZeroCongr e).toEquiv a = (WithZero.map (AddEquiv.toAddHom e)) a := rfl
157+
#align add_equiv.with_zero_congr_apply AddEquiv.withZeroCongr_apply
158+
156159
-- porting note: for this declaration and the two below I added the `to_additive` attribute because
157160
-- it seemed to be missing from mathlib3, hence the lack of additive `#align`s.
158161
@[simp, to_additive]

Mathlib/Algebra/Hom/Equiv/Basic.lean

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -529,20 +529,31 @@ theorem map_ne_one_iff {M N} [MulOneClass M] [MulOneClass N] (h : M ≃* N) {x :
529529
#align mul_equiv.map_ne_one_iff MulEquiv.map_ne_one_iff
530530
#align add_equiv.map_ne_zero_iff AddEquiv.map_ne_zero_iff
531531

532+
-- porting note: Mathlib 3 had `@[simps apply]` but right now in Lean 4 it's generating
533+
-- simp lemmas which don't lint.
532534
/-- A bijective `Semigroup` homomorphism is an isomorphism -/
533-
@[to_additive "A bijective `AddSemigroup` homomorphism is an isomorphism", simps apply]
535+
@[to_additive "A bijective `AddSemigroup` homomorphism is an isomorphism"]
534536
noncomputable def ofBijective {M N F} [Mul M] [Mul N] [MulHomClass F M N]
535537
(f : F) (hf : Function.Bijective f) :
536538
M ≃* N :=
537539
{ Equiv.ofBijective f hf with map_mul' := map_mul f }
538540
#align mul_equiv.of_bijective MulEquiv.ofBijective
539541
#align add_equiv.of_bijective AddEquiv.ofBijective
540542

541-
@[simp]
543+
-- porting note: `@[simps apply]` should be making this lemma but it actually makes
544+
-- a lemma with `toFun` which isn't in simp normal form.
545+
@[simp, to_additive] theorem ofBijective_apply {M N F} [Mul M] [Mul N] [MulHomClass F M N]
546+
(f : F) (hf : Function.Bijective f) (a : M) : (MulEquiv.ofBijective f hf).toEquiv a = f a :=
547+
rfl
548+
#align mul_equiv.of_bijective_apply MulEquiv.ofBijective_apply
549+
#align add_equiv.of_bijective_apply AddEquiv.ofBijective_apply
550+
551+
@[simp, to_additive]
542552
theorem ofBijective_apply_symm_apply {M N} [MulOneClass M] [MulOneClass N] {n : N} (f : M →* N)
543553
(hf : Function.Bijective f) : f ((Equiv.ofBijective f hf).symm n) = n :=
544554
(MulEquiv.ofBijective f hf).apply_symm_apply n
545555
#align mul_equiv.of_bijective_apply_symm_apply MulEquiv.ofBijective_apply_symm_apply
556+
#align add_equiv.of_bijective_apply_symm_apply AddEquiv.ofBijective_apply_symm_apply
546557

547558
/-- Extract the forward direction of a multiplicative equivalence
548559
as a multiplication-preserving function.
@@ -589,8 +600,9 @@ for multiplicative maps from a monoid to a commutative monoid.
589600
-/
590601
@[to_additive
591602
"An additive analogue of `Equiv.arrowCongr`,
592-
for additive maps from an additive monoid to a commutative additive monoid.",
593-
simps apply]
603+
for additive maps from an additive monoid to a commutative additive monoid."]
604+
-- porting note: @[simps apply] removed because it was making a lemma which
605+
-- wasn't in simp normal form.
594606
def monoidHomCongr {M N P Q} [MulOneClass M] [MulOneClass N] [CommMonoid P] [CommMonoid Q]
595607
(f : M ≃* N) (g : P ≃* Q) :
596608
(M →* P) ≃* (N →* Q) where
@@ -602,6 +614,14 @@ def monoidHomCongr {M N P Q} [MulOneClass M] [MulOneClass N] [CommMonoid P] [Com
602614
#align mul_equiv.monoid_hom_congr MulEquiv.monoidHomCongr
603615
#align add_equiv.add_monoid_hom_congr AddEquiv.addMonoidHomCongr
604616

617+
@[simp, to_additive] theorem monoidHomCongr_apply {M N P Q} [MulOneClass M] [MulOneClass N]
618+
[CommMonoid P] [CommMonoid Q] (f : M ≃* N) (g : P ≃* Q) (h : M →* P) :
619+
(MulEquiv.monoidHomCongr f g).toEquiv h = MonoidHom.comp (MulEquiv.toMonoidHom g)
620+
(MonoidHom.comp h (MulEquiv.toMonoidHom (MulEquiv.symm f))) :=
621+
rfl
622+
#align mul_equiv.monoid_hom_congr_apply MulEquiv.monoidHomCongr_apply
623+
#align add_equiv.add_monoid_hom_congr_apply AddEquiv.addMonoidHomCongr_apply
624+
605625
/-- A family of multiplicative equivalences `Π j, (Ms j ≃* Ns j)` generates a
606626
multiplicative equivalence between `Π j, Ms j` and `Π j, Ns j`.
607627
@@ -647,14 +667,29 @@ theorem piCongrRight_trans {η : Type _} {Ms Ns Ps : η → Type _} [∀ j, Mul
647667
index. -/
648668
@[to_additive
649669
"A family indexed by a nonempty subsingleton type is
650-
equivalent to the element at the single index.",
651-
simps]
670+
equivalent to the element at the single index."]
652671
def piSubsingleton {ι : Type _} (M : ι → Type _) [∀ j, Mul (M j)] [Subsingleton ι]
653672
(i : ι) : (∀ j, M j) ≃* M i :=
654673
{ Equiv.piSubsingleton M i with map_mul' := fun _ _ => Pi.mul_apply _ _ _ }
655674
#align mul_equiv.Pi_subsingleton MulEquiv.piSubsingleton
656675
#align add_equiv.Pi_subsingleton AddEquiv.piSubsingleton
657676

677+
-- porting note: the next two lemmas should be being generated by `@[to_additive, simps]`.
678+
-- They are added manually because `@[simps]` is currently generating lemmas with `toFun` in
679+
@[simp, to_additive] theorem piSubsingleton_apply {ι : Type _} (M : ι → Type _) [∀ j, Mul (M j)]
680+
[Subsingleton ι] (i : ι) (f : (x : ι) → M x) : (MulEquiv.piSubsingleton M i).toEquiv f = f i :=
681+
rfl
682+
#align mul_equiv.Pi_subsingleton_apply MulEquiv.piSubsingleton_apply
683+
#align add_equiv.Pi_subsingleton_apply AddEquiv.piSubsingleton_apply
684+
685+
@[simp, to_additive] theorem piSubsingleton_symmApply {ι : Type _} (M : ι → Type _) [∀ j, Mul (M j)]
686+
[Subsingleton ι] (i : ι) (x : M i) (b : ι) :
687+
(MulEquiv.symm (MulEquiv.piSubsingleton M i)) x b =
688+
cast (Subsingleton.elim i b ▸ rfl : M i = M b) x :=
689+
rfl
690+
#align mul_equiv.Pi_subsingleton_symmApply MulEquiv.piSubsingleton_symmApply
691+
#align add_equiv.Pi_subsingleton_symmApply AddEquiv.piSubsingleton_symmApply
692+
658693
/-!
659694
# Groups
660695
-/
@@ -677,6 +712,10 @@ protected theorem map_div [Group G] [DivisionMonoid H] (h : G ≃* H) (x y : G)
677712

678713
end MulEquiv
679714

715+
-- porting note: we want to add
716+
-- `@[simps (config := { fullyApplied := false })]`
717+
-- here, but it generates simp lemmas which aren't in simp normal form
718+
-- (they have `toFun` in)
680719
/-- Given a pair of multiplicative homomorphisms `f`, `g` such that `g.comp f = id` and
681720
`f.comp g = id`, returns an multiplicative equivalence with `toFun = f` and `invFun = g`. This
682721
constructor is useful if the underlying type(s) have specialized `ext` lemmas for multiplicative
@@ -685,8 +724,7 @@ homomorphisms. -/
685724
"Given a pair of additive homomorphisms `f`, `g` such that `g.comp f = id` and
686725
`f.comp g = id`, returns an additive equivalence with `toFun = f` and `invFun = g`. This
687726
constructor is useful if the underlying type(s) have specialized `ext` lemmas for additive
688-
homomorphisms.",
689-
simps (config := { fullyApplied := false })]
727+
homomorphisms."]
690728
def MulHom.toMulEquiv [Mul M] [Mul N] (f : M →ₙ* N) (g : N →ₙ* M) (h₁ : g.comp f = MulHom.id _)
691729
(h₂ : f.comp g = MulHom.id _) : M ≃* N where
692730
toFun := f
@@ -697,15 +735,32 @@ def MulHom.toMulEquiv [Mul M] [Mul N] (f : M →ₙ* N) (g : N →ₙ* M) (h₁
697735
#align mul_hom.to_mul_equiv MulHom.toMulEquiv
698736
#align add_hom.to_add_equiv AddHom.toAddEquiv
699737

738+
-- porting note: the next two lemmas were added manually because `@[simps]` is generating
739+
-- lemmas with `toFun` in
740+
@[simp, to_additive] theorem MulHom.toMulEquiv_apply [Mul M] [Mul N] (f : M →ₙ* N) (g : N →ₙ* M)
741+
(h₁ : g.comp f = MulHom.id _) (h₂ : f.comp g = MulHom.id _) :
742+
((MulHom.toMulEquiv f g h₁ h₂).toEquiv : M → N) = f :=
743+
rfl
744+
#align mul_hom.to_mul_equiv_apply MulHom.toMulEquiv_apply
745+
#align add_hom.to_add_equiv_apply AddHom.toAddEquiv_apply
746+
747+
@[simp, to_additive] theorem MulHom.toMulEquiv_symmApply [Mul M] [Mul N] (f : M →ₙ* N) (g : N →ₙ* M)
748+
(h₁ : g.comp f = MulHom.id _) (h₂ : f.comp g = MulHom.id _) :
749+
(MulEquiv.symm (MulHom.toMulEquiv f g h₁ h₂) : N → M) = ↑g :=
750+
rfl
751+
#align mul_hom.to_mul_equiv_symm_apply MulHom.toMulEquiv_symmApply
752+
#align add_hom.to_add_equiv_symm_apply AddHom.toAddEquiv_symmApply
753+
754+
-- porting note: `@[simps (config := { fullyApplied := false })]` generates a simp lemma
755+
-- which is not in simp normal form, so we add them manually
700756
/-- Given a pair of monoid homomorphisms `f`, `g` such that `g.comp f = id` and `f.comp g = id`,
701757
returns an multiplicative equivalence with `toFun = f` and `invFun = g`. This constructor is
702758
useful if the underlying type(s) have specialized `ext` lemmas for monoid homomorphisms. -/
703759
@[to_additive
704760
"Given a pair of additive monoid homomorphisms `f`, `g` such that `g.comp f = id`
705761
and `f.comp g = id`, returns an additive equivalence with `toFun = f` and `invFun = g`. This
706762
constructor is useful if the underlying type(s) have specialized `ext` lemmas for additive
707-
monoid homomorphisms.",
708-
simps (config := { fullyApplied := false })]
763+
monoid homomorphisms."]
709764
def MonoidHom.toMulEquiv [MulOneClass M] [MulOneClass N] (f : M →* N) (g : N →* M)
710765
(h₁ : g.comp f = MonoidHom.id _) (h₂ : f.comp g = MonoidHom.id _) : M ≃* N where
711766
toFun := f
@@ -716,6 +771,23 @@ def MonoidHom.toMulEquiv [MulOneClass M] [MulOneClass N] (f : M →* N) (g : N
716771
#align monoid_hom.to_mul_equiv MonoidHom.toMulEquiv
717772
#align add_monoid_hom.to_add_mul_equiv AddMonoidHom.toAddEquiv
718773

774+
-- porting note: the next 2 lemmas should be being generated by
775+
-- `@[to_additive, simps (config := { fullyApplied := false })]`
776+
-- but right now it's generating `simp` lemmas which aren't in `simp` normal form.
777+
@[simp, to_additive] theorem MonoidHom.toMulEquiv_apply [MulOneClass M] [MulOneClass N] (f : M →* N)
778+
(g : N →* M) (h₁ : g.comp f = MonoidHom.id _) (h₂ : f.comp g = MonoidHom.id _) :
779+
((MonoidHom.toMulEquiv f g h₁ h₂).toEquiv : M → N) = ↑f :=
780+
rfl
781+
#align monoid_hom.to_mul_equiv_apply MonoidHom.toMulEquiv_apply
782+
#align add_monoid_hom.to_add_equiv_apply AddMonoidHom.toAddEquiv_apply
783+
784+
@[simp, to_additive] theorem MonoidHom.toMulEquiv_symmApply [MulOneClass M] [MulOneClass N]
785+
(f : M →* N) (g : N →* M) (h₁ : g.comp f = MonoidHom.id _) (h₂ : f.comp g = MonoidHom.id _) :
786+
(MulEquiv.symm (MonoidHom.toMulEquiv f g h₁ h₂) : N → M) = g :=
787+
rfl
788+
#align monoid_hom.to_mul_equiv_symm_apply MonoidHom.toMulEquiv_symmApply
789+
#align add_monoid_hom.to_add_equiv_symm_apply AddMonoidHom.toAddEquiv_symmApply
790+
719791
namespace Equiv
720792

721793
section InvolutiveInv

Mathlib/Algebra/Hom/Equiv/Units/Basic.lean

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,28 @@ end Equiv
220220

221221
-- Porting note: we don't put `@[simp]` on the additive version;
222222
-- mysteriously simp can already prove that one (although not the multiplicative one)!
223+
-- porting note: `@[simps apply]` removed because right now it's generating lemmas which
224+
-- aren't in simp normal form (they contain a `toFun`)
223225
/-- In a `division_comm_monoid`, `equiv.inv` is a `mul_equiv`. There is a variant of this
224226
`mul_equiv.inv' G : G ≃* Gᵐᵒᵖ` for the non-commutative case. -/
225-
@[to_additive "When the `add_group` is commutative, `equiv.neg` is an `add_equiv`.", simps apply]
227+
@[to_additive "When the `add_group` is commutative, `equiv.neg` is an `add_equiv`."]
226228
def MulEquiv.inv (G : Type _) [DivisionCommMonoid G] : G ≃* G :=
227229
{ Equiv.inv G with toFun := Inv.inv, invFun := Inv.inv, map_mul' := mul_inv }
228230
#align mul_equiv.inv MulEquiv.inv
229231
#align add_equiv.neg AddEquiv.neg
230232

233+
-- porting note: this lemma and the next are added manually because `simps` was
234+
-- not quite generating the right thing
235+
@[simp] theorem MulEquiv.inv_apply (G : Type _) [DivisionCommMonoid G] (a : G) :
236+
(MulEquiv.inv G).toEquiv a = a⁻¹ :=
237+
rfl
238+
#align mul_equiv.inv_apply MulEquiv.inv_apply
239+
240+
@[simp] theorem AddEquiv.neg_apply (G : Type _) [SubtractionCommMonoid G] (a : G) :
241+
(AddEquiv.neg G).toEquiv a = -a :=
242+
rfl
243+
#align add_equiv.neg_apply AddEquiv.neg_apply
244+
231245
@[simp]
232246
theorem MulEquiv.inv_symm (G : Type _) [DivisionCommMonoid G] :
233247
(MulEquiv.inv G).symm = MulEquiv.inv G :=

Mathlib/Logic/Equiv/Defs.lean

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,15 @@ protected def trans (e₁ : α ≃ β) (e₂ : β ≃ γ) : α ≃ γ :=
158158
instance : Trans Equiv Equiv Equiv where
159159
trans := Equiv.trans
160160

161-
-- porting note: this lemma is now useless since coercions are eagerly unfolded
162-
-- @[simp] theorem to_fun_as_coe (e : α ≃ β) : e.toFun = e := rfl
161+
-- porting note: this is not a syntactic tautology any more because
162+
-- the coercion from `e` to a function is now `FunLike.coe` not `e.toFun`
163+
@[simp] theorem to_fun_as_coe (e : α ≃ β) : e.toFun = e := rfl
164+
165+
-- porting note: `simp` should prove this using `to_fun_as_coe`, but it doesn't.
166+
-- This might be a bug in `simp` -- see https://github.com/leanprover/lean4/issues/1937
167+
-- If this issue is fixed then the simp linter probably will start complaining, and
168+
-- this theorem can be deleted hopefully without breaking any `simp` proofs.
169+
@[simp] theorem to_fun_as_coe_apply (e : α ≃ β) (x : α) : e.toFun x = e x := rfl
163170

164171
@[simp] theorem inv_fun_as_coe (e : α ≃ β) : e.invFun = e.symm := rfl
165172

Mathlib/Order/RelIso/Group.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ instance : Group (r ≃r r) where
3030
mul_left_inv f := ext f.symm_apply_apply
3131

3232
@[simp]
33-
theorem toFun_one : (1 : r ≃r r).toFun = id :=
33+
theorem coe_one : ((1 : r ≃r r) : α → α) = id :=
3434
rfl
35-
#align rel_iso.coe_one RelIso.toFun_one
35+
#align rel_iso.coe_one RelIso.coe_one
3636

3737
@[simp]
38-
theorem toFun_mul (e₁ e₂ : r ≃r r) : (e₁ * e₂).toFun = e₁ ∘ e₂ :=
38+
theorem coe_mul (e₁ e₂ : r ≃r r) : ((e₁ * e₂) : α → α) = e₁ ∘ e₂ :=
3939
rfl
40-
#align rel_iso.coe_mul RelIso.toFun_mul
40+
#align rel_iso.coe_mul RelIso.coe_mul
4141

4242
theorem mul_apply (e₁ e₂ : r ≃r r) (x : α) : (e₁ * e₂) x = e₁ (e₂ x) :=
4343
rfl

0 commit comments

Comments
 (0)