Skip to content

Commit 300984f

Browse files
JovanGerbmichaellee94
authored andcommitted
perf: make Equiv transfer instances more reduced (leanprover-community#41002)
This pr speeds up the instances that are tranferred through `Equiv`s by using the projections `.toFun` and `.invFun` directly in the data. I think that we should eventually deprecate these instances, and instead have a metaprogram that creates these instances for us in each use case.
1 parent 492dd06 commit 300984f

10 files changed

Lines changed: 41 additions & 22 deletions

File tree

Mathlib/Algebra/Algebra/TransferInstance.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ variable {R α β : Type*} [CommSemiring R]
2222
namespace Equiv
2323
variable (e : α ≃ β)
2424

25+
-- See note [instance transfer via equivalence]
2526
variable (R) in
2627
/-- Transfer `Algebra` across an `Equiv` -/
2728
protected abbrev algebra (e : α ≃ β) [Semiring β] :
@@ -30,7 +31,7 @@ protected abbrev algebra (e : α ≃ β) [Semiring β] :
3031
letI := Equiv.semiring e
3132
letI := e.smul R
3233
{ algebraMap :=
33-
{ toFun r := e.symm (algebraMap R β r)
34+
{ toFun r := e.invFun (algebraMap R β r)
3435
__ := e.ringEquiv.symm.toRingHom.comp (algebraMap R β) }
3536
commutes' r x :=
3637
show e.symm ((e (e.symm (algebraMap R β r)) * e x)) =

Mathlib/Algebra/Category/MonCat/Limits.lean

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,7 @@ noncomputable instance forget_createsLimit :
180180
simp only [Types.Small.limitCone_pt, Functor.comp_obj, Functor.mapCone_pt,
181181
Types.Small.limitConeIsLimit_lift, Functor.const_obj_obj, Functor.mapCone_π_app,
182182
ConcreteCategory.hom_ofHom, TypeCat.Fun.coe_mk, map_mul]
183-
congr
184-
simp only [Functor.comp_obj, Equiv.symm_apply_apply]
183+
rw [← equivShrink_mul]
185184
rfl
186185
· exact fun _ ↦ rfl
187186

Mathlib/Algebra/Field/TransferInstance.lean

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ assert_not_exists Module
2121
namespace Equiv
2222
variable {α β : Type*} (e : α ≃ β)
2323

24+
-- See note [instance transfer via equivalence]
2425
/-- Transfer `NNRatCast` across an `Equiv` -/
25-
protected abbrev nnratCast [NNRatCast β] : NNRatCast α where nnratCast q := e.symm q
26+
protected abbrev nnratCast [NNRatCast β] : NNRatCast α where nnratCast q := e.invFun q
2627

2728
/-- Transfer `RatCast` across an `Equiv` -/
28-
protected abbrev ratCast [RatCast β] : RatCast α where ratCast n := e.symm n
29+
protected abbrev ratCast [RatCast β] : RatCast α where ratCast n := e.invFun n
2930

3031
/-- Transfer `DivisionRing` across an `Equiv` -/
3132
protected abbrev divisionRing [DivisionRing β] : DivisionRing α := by

Mathlib/Algebra/Group/TransferInstance.lean

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,25 @@ When adding new definitions that transfer type-classes across an equivalence, pl
2525

2626
assert_not_exists MonoidWithZero MulAction
2727

28+
library_note «instance transfer via equivalence» /--
29+
For many type classes, we have a definition that lets us transfer instances from one type to another
30+
using an equivalence, such as `Equiv.mul` for `Mul`.
31+
Constructing data instances in this way is discouraged because the resulting data is inefficient
32+
to unfold. To somewhat mitigate this problem, in these definitions we don't write the
33+
projections on `Equiv` in the usual way using `Equiv.symm` and `DFunLike.coe`, and instead use
34+
`Equiv.toFun` and `Equiv.invFun` directly. As a result, unification has to do less unfolding.
35+
36+
Note also that when constructing data instances in this way, it usually helps to use
37+
`fast_instance%` to get a faster instance.
38+
-/
39+
2840
namespace Equiv
2941
variable {M α β : Type*} (e : α ≃ β)
3042

43+
-- See note [instance transfer via equivalence]
3144
/-- Transfer `One` across an `Equiv` -/
3245
@[to_additive /-- Transfer `Zero` across an `Equiv` -/]
33-
protected abbrev one [One β] : One α where one := e.symm 1
46+
protected abbrev one [One β] : One α where one := e.invFun 1
3447

3548
@[to_additive]
3649
lemma one_def [One β] :
@@ -39,7 +52,7 @@ lemma one_def [One β] :
3952

4053
/-- Transfer `Mul` across an `Equiv` -/
4154
@[to_additive /-- Transfer `Add` across an `Equiv` -/]
42-
protected abbrev mul [Mul β] : Mul α where mul x y := e.symm (e x * e y)
55+
protected abbrev mul [Mul β] : Mul α where mul x y := e.invFun (e.toFun x * e.toFun y)
4356

4457
@[to_additive]
4558
lemma mul_def [Mul β] (x y : α) :
@@ -49,7 +62,7 @@ lemma mul_def [Mul β] (x y : α) :
4962
/-- Transfer `Div` across an `Equiv` -/
5063
@[to_additive /-- Transfer `Sub` across an `Equiv` -/]
5164
protected abbrev div [Div β] : Div α :=
52-
fun x y => e.symm (e x / e y)⟩
65+
fun x y => e.invFun (e.toFun x / e.toFun y)⟩
5366

5467
@[to_additive]
5568
lemma div_def [Div β] (x y : α) :
@@ -60,7 +73,7 @@ lemma div_def [Div β] (x y : α) :
6073
-- but we already have an `Equiv.inv` (which perhaps should move to `Perm.inv`?)
6174
/-- Transfer `Inv` across an `Equiv` -/
6275
@[to_additive /-- Transfer `Neg` across an `Equiv` -/]
63-
protected abbrev Inv [Inv β] : Inv α where inv x := e.symm (e x)⁻¹
76+
protected abbrev Inv [Inv β] : Inv α where inv x := e.invFun (e.toFun x)⁻¹
6477

6578
@[to_additive]
6679
lemma inv_def [Inv β] (x : α) :
@@ -71,7 +84,7 @@ variable (M) in
7184
/-- Transfer `Pow` across an `Equiv` -/
7285
@[to_additive (attr := to_additive /-- Transfer `VAdd` across an `Equiv` -/) smul
7386
/-- Transfer `SMul` across an `Equiv` -/]
74-
protected abbrev pow [Pow β M] : Pow α M where pow x n := e.symm (e x ^ n)
87+
protected abbrev pow [Pow β M] : Pow α M where pow x n := e.invFun (e.toFun x ^ n)
7588

7689
@[to_additive (attr := to_additive) smul_def]
7790
lemma pow_def [Pow β M] (n : M) (x : α) :

Mathlib/Algebra/Ring/TransferInstance.lean

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,22 @@ protected abbrev nonUnitalSemiring [NonUnitalSemiring β] : NonUnitalSemiring α
6464
let nsmul := e.smul ℕ
6565
apply e.injective.nonUnitalSemiring _ <;> intros <;> exact e.apply_symm_apply _
6666

67+
-- See note [instance transfer via equivalence]
6768
/-- Transfer `AddMonoidWithOne` across an `Equiv` -/
6869
protected abbrev addMonoidWithOne [AddMonoidWithOne β] : AddMonoidWithOne α :=
6970
{ e.addMonoid, e.one with
70-
natCast := fun n => e.symm n
71+
natCast := fun n => e.invFun n
7172
natCast_zero := e.injective (by simp [zero_def])
7273
natCast_succ := fun n => e.injective (by simp [add_def, one_def]) }
7374

7475
/-- Transfer `AddGroupWithOne` across an `Equiv` -/
7576
protected abbrev addGroupWithOne [AddGroupWithOne β] : AddGroupWithOne α :=
7677
{ e.addMonoidWithOne,
7778
e.addGroup with
78-
intCast := fun n => e.symm n
79+
intCast := fun n => e.invFun n
7980
intCast_ofNat := fun n => by simp only [Int.cast_natCast]; rfl
8081
intCast_negSucc := fun _ =>
81-
congr_arg e.symm <| (Int.cast_negSucc _).trans <| congr_arg _ (e.apply_symm_apply _).symm }
82+
congr_arg e.invFun <| (Int.cast_negSucc _).trans <| congr_arg _ (e.apply_symm_apply _).symm }
8283

8384
/-- Transfer `NonAssocSemiring` across an `Equiv` -/
8485
protected abbrev nonAssocSemiring [NonAssocSemiring β] : NonAssocSemiring α := by

Mathlib/Algebra/Star/TransferInstance.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ namespace Equiv
2121

2222
variable (e : R ≃ S)
2323

24+
-- See note [instance transfer via equivalence]
2425
/-- Transfer `Star` across an `Equiv`. See note [reducible non-instances].
2526
2627
For `star : R → R` bundled as an `Equiv`, see `Equiv.Perm.star`. -/
2728
protected abbrev star [Star S] : Star R where
28-
star r := e.symm (star (e r))
29+
star r := e.invFun (star (e.toFun r))
2930

3031
/-- Transfer `InvolutiveStar` across an `Equiv`. See note [reducible non-instances]. -/
3132
protected abbrev involutiveStar [InvolutiveStar S] : InvolutiveStar R :=

Mathlib/RingTheory/PicardGroup.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,14 +472,14 @@ instance : Free R (1 : Pic R) := mk_eq_one_iff_free.mp mk_eq_self
472472

473473
theorem mk_tensor : Pic.mk R (M ⊗[R] N) = Pic.mk R M * Pic.mk R N :=
474474
congr_arg (equivShrink _) <| Units.ext <| by
475-
simp_rw [Pic.mk, Equiv.symm_apply_apply]
475+
simp_rw [Pic.mk, Equiv.toFun_as_coe, Equiv.symm_apply_apply]
476476
refine (Quotient.sound ?_).trans (Skeleton.toSkeleton_tensorObj ..)
477477
exact ⟨(Finite.reprEquivₛ R _ ≪≫ₗ TensorProduct.congr
478478
(Finite.reprEquivₛ R M).symm (Finite.reprEquivₛ R N).symm).toModuleIsoₛ⟩
479479

480480
theorem mk_dual : Pic.mk R (Dual R M) = (Pic.mk R M)⁻¹ :=
481481
congr_arg (equivShrink _) <| Units.ext <| by
482-
rw [Pic.mk, Equiv.symm_apply_apply]
482+
rw [Pic.mk, Equiv.toFun_as_coe, Equiv.symm_apply_apply]
483483
exact Quotient.sound ⟨(Finite.reprEquivₛ R _ ≪≫ₗ (Finite.reprEquivₛ R _).dualMap).toModuleIsoₛ⟩
484484

485485
theorem inv_eq_dual (M : Pic R) : M⁻¹ = Pic.mk R (Dual R M) := by

Mathlib/Topology/Algebra/Module/TransferInstance.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def continuousLinearEquiv (e : α ≃ β) :
5050
{ toLinearEquiv := e.linearEquiv _
5151
continuous_toFun := continuous_induced_dom
5252
continuous_invFun := by
53-
simp +instances only [Equiv.topologicalSpace, ← @coinduced_symm]
53+
simp +instances only [Equiv.topologicalSpace, toFun_as_coe, ← coinduced_symm]
5454
exact continuous_coinduced_rng }
5555

5656
@[simp]

Mathlib/Topology/Homeomorph/TransferInstance.lean

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ variable {R α β : Type*}
2121

2222
namespace Equiv
2323

24+
-- See note [instance transfer via equivalence]
2425
/-- Transfer a `TopologicalSpace` across an `Equiv` -/
2526
protected abbrev topologicalSpace [TopologicalSpace β] (e : α ≃ β) :
2627
TopologicalSpace α :=
27-
.induced e ‹_›
28+
.induced e.toFun ‹_›
2829

2930
/-- An equivalence `e : α ≃ β` gives a homeomorphism `α ≃ₜ β` where the topological space structure
3031
on `α` is the one obtained by transporting the topological space structure on `β` back along `e`. -/
@@ -37,6 +38,7 @@ def homeomorph [TopologicalSpace β] (e : α ≃ β) :
3738
continuous_invFun := by
3839
simp only [Equiv.invFun_as_coe]
3940
convert! continuous_coinduced_rng
40-
rw [e.coinduced_symm] }
41+
rw [e.coinduced_symm]
42+
rfl }
4143

4244
end Equiv

Mathlib/Topology/MetricSpace/TransferInstance.lean

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ namespace Equiv
2222

2323
variable (e : α ≃ β)
2424

25+
-- See note [instance transfer via equivalence]
2526
/-- Transfer a `Dist` across an `Equiv` -/
26-
protected abbrev dist (e : α ≃ β) [Dist β] : Dist α := ⟨fun x y ↦ dist (e x) (e y)⟩
27+
protected abbrev dist (e : α ≃ β) [Dist β] : Dist α := ⟨fun x y ↦ dist (e.toFun x) (e.toFun y)⟩
2728

2829
/-- Transfer a `PseudoMetricSpace` across an `Equiv` -/
2930
protected abbrev pseudometricSpace [PseudoMetricSpace β] (e : α ≃ β) : PseudoMetricSpace α :=
30-
.induced e ‹_›
31+
.induced e.toFun ‹_›
3132

3233
/-- Transfer a `MetricSpace` across an `Equiv` -/
3334
protected abbrev metricSpace [MetricSpace β] (e : α ≃ β) : MetricSpace α :=
34-
.induced e e.injective ‹_›
35+
.induced e.toFun e.injective ‹_›
3536

3637
end Equiv

0 commit comments

Comments
 (0)