Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit e174f42

Browse files
committed
feat(equiv/transfer_instances): other algebraic structures (#3870)
Some updates to `data.equiv.transfer_instances`. 1. Use `@[to_additive]` 2. Add algebraic equivalences between the original and transferred instances. 3. Transfer modules and algebras. Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
1 parent d7621b9 commit e174f42

File tree

1 file changed

+183
-37
lines changed

1 file changed

+183
-37
lines changed

src/data/equiv/transfer_instance.lean

Lines changed: 183 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Authors: Johannes Hölzl
55
-/
66
import data.equiv.basic
77
import algebra.field
8+
import algebra.module
9+
import ring_theory.algebra
810
import algebra.group.type_tags
911

1012
/-!
@@ -15,9 +17,11 @@ group structure and `α ≃ β` then `α` has a group structure, and
1517
similarly for monoids, semigroups, rings, integral domains, fields and
1618
so on.
1719
20+
Note that most of these constructions can also be obtained using the `transport` tactic.
21+
1822
## Tags
1923
20-
equiv, group, ring, field
24+
equiv, group, ring, field, module, algebra
2125
-/
2226

2327
universes u v
@@ -30,89 +34,121 @@ section instances
3034

3135
variables (e : α ≃ β)
3236

33-
/-- Transfer `has_zero` across an `equiv` -/
34-
protected def has_zero [has_zero β] : has_zero α := ⟨e.symm 0
35-
lemma zero_def [has_zero β] : @has_zero.zero _ (equiv.has_zero e) = e.symm 0 := rfl
36-
3737
/-- Transfer `has_one` across an `equiv` -/
38+
@[to_additive "Transfer `has_zero` across an `equiv`"]
3839
protected def has_one [has_one β] : has_one α := ⟨e.symm 1
40+
@[to_additive]
3941
lemma one_def [has_one β] : @has_one.one _ (equiv.has_one e) = e.symm 1 := rfl
4042

4143
/-- Transfer `has_mul` across an `equiv` -/
44+
@[to_additive "Transfer `has_add` across an `equiv`"]
4245
protected def has_mul [has_mul β] : has_mul α := ⟨λ x y, e.symm (e x * e y)⟩
46+
@[to_additive]
4347
lemma mul_def [has_mul β] (x y : α) :
4448
@has_mul.mul _ (equiv.has_mul e) x y = e.symm (e x * e y) := rfl
4549

46-
/-- Transfer `has_add` across an `equiv` -/
47-
protected def has_add [has_add β] : has_add α := ⟨λ x y, e.symm (e x + e y)⟩
48-
lemma add_def [has_add β] (x y : α) :
49-
@has_add.add _ (equiv.has_add e) x y = e.symm (e x + e y) := rfl
50-
5150
/-- Transfer `has_inv` across an `equiv` -/
51+
@[to_additive "Transfer `has_neg` across an `equiv`"]
5252
protected def has_inv [has_inv β] : has_inv α := ⟨λ x, e.symm (e x)⁻¹⟩
53+
@[to_additive]
5354
lemma inv_def [has_inv β] (x : α) : @has_inv.inv _ (equiv.has_inv e) x = e.symm (e x)⁻¹ := rfl
5455

55-
/-- Transfer `has_neg` across an `equiv` -/
56-
protected def has_neg [has_neg β] : has_neg α := ⟨λ x, e.symm (-e x)⟩
57-
lemma neg_def [has_neg β] (x : α) : @has_neg.neg _ (equiv.has_neg e) x = e.symm (-e x) := rfl
56+
/-- Transfer `has_scalar` across an `equiv` -/
57+
protected def has_scalar {R : Type*} [has_scalar R β] : has_scalar R α :=
58+
⟨λ r x, e.symm (r • (e x))⟩
59+
lemma smul_def {R : Type*} [has_scalar R β] (r : R) (x : α) :
60+
@has_scalar.smul _ _ (equiv.has_scalar e) r x = e.symm (r • (e x)) := rfl
61+
62+
/--
63+
An equivalence `e : α ≃ β` gives a multiplicative equivalence `α ≃* β`
64+
where the multiplicative structure on `α` is
65+
the one obtained by transporting a multiplicative structure on `β` back along `e`.
66+
-/
67+
@[to_additive
68+
"An equivalence `e : α ≃ β` gives a additive equivalence `α ≃+ β`
69+
where the additive structure on `α` is
70+
the one obtained by transporting an additive structure on `β` back along `e`."]
71+
def mul_equiv (e : α ≃ β) [has_mul β] :
72+
by { letI := equiv.has_mul e, exact α ≃* β } :=
73+
begin
74+
introsI,
75+
exact
76+
{ map_mul' := λ x y, by { apply e.symm.injective, simp, refl, },
77+
..e }
78+
end
79+
80+
@[simp, to_additive] lemma mul_equiv_apply (e : α ≃ β) [has_mul β] (a : α) :
81+
(mul_equiv e) a = e a := rfl
82+
83+
@[to_additive] lemma mul_equiv_symm_apply (e : α ≃ β) [has_mul β] (b : β) :
84+
by { letI := equiv.has_mul e, exact (mul_equiv e).symm b = e.symm b } :=
85+
begin
86+
intros, refl,
87+
end
88+
89+
/--
90+
An equivalence `e : α ≃ β` gives a ring equivalence `α ≃+* β`
91+
where the ring structure on `α` is
92+
the one obtained by transporting a ring structure on `β` back along `e`.
93+
-/
94+
def ring_equiv (e : α ≃ β) [has_add β] [has_mul β] :
95+
by { letI := equiv.has_add e, letI := equiv.has_mul e, exact α ≃+* β } :=
96+
begin
97+
introsI,
98+
exact
99+
{ map_add' := λ x y, by { apply e.symm.injective, simp, refl, },
100+
map_mul' := λ x y, by { apply e.symm.injective, simp, refl, },
101+
..e }
102+
end
103+
104+
@[simp] lemma ring_equiv_apply (e : α ≃ β) [has_add β] [has_mul β] (a : α) :
105+
(ring_equiv e) a = e a := rfl
106+
107+
lemma ring_equiv_symm_apply (e : α ≃ β) [has_add β] [has_mul β] (b : β) :
108+
by { letI := equiv.has_add e, letI := equiv.has_mul e, exact (ring_equiv e).symm b = e.symm b } :=
109+
begin
110+
intros, refl,
111+
end
58112

59113
/-- Transfer `semigroup` across an `equiv` -/
114+
@[to_additive "Transfer `add_semigroup` across an `equiv`"]
60115
protected def semigroup [semigroup β] : semigroup α :=
61116
{ mul_assoc := by simp [mul_def, mul_assoc],
62117
..equiv.has_mul e }
63118

64119
/-- Transfer `comm_semigroup` across an `equiv` -/
120+
@[to_additive "Transfer `add_comm_semigroup` across an `equiv`"]
65121
protected def comm_semigroup [comm_semigroup β] : comm_semigroup α :=
66122
{ mul_comm := by simp [mul_def, mul_comm],
67123
..equiv.semigroup e }
68124

69125
/-- Transfer `monoid` across an `equiv` -/
126+
@[to_additive "Transfer `add_monoid` across an `equiv`"]
70127
protected def monoid [monoid β] : monoid α :=
71128
{ one_mul := by simp [mul_def, one_def],
72129
mul_one := by simp [mul_def, one_def],
73130
..equiv.semigroup e,
74131
..equiv.has_one e }
75132

76133
/-- Transfer `comm_monoid` across an `equiv` -/
134+
@[to_additive "Transfer `add_comm_monoid` across an `equiv`"]
77135
protected def comm_monoid [comm_monoid β] : comm_monoid α :=
78136
{ ..equiv.comm_semigroup e,
79137
..equiv.monoid e }
80138

81139
/-- Transfer `group` across an `equiv` -/
140+
@[to_additive "Transfer `add_group` across an `equiv`"]
82141
protected def group [group β] : group α :=
83142
{ mul_left_inv := by simp [mul_def, inv_def, one_def],
84143
..equiv.monoid e,
85144
..equiv.has_inv e }
86145

87146
/-- Transfer `comm_group` across an `equiv` -/
147+
@[to_additive "Transfer `add_comm_group` across an `equiv`"]
88148
protected def comm_group [comm_group β] : comm_group α :=
89149
{ ..equiv.group e,
90150
..equiv.comm_semigroup e }
91151

92-
/-- Transfer `add_semigroup` across an `equiv` -/
93-
protected def add_semigroup [add_semigroup β] : add_semigroup α :=
94-
@additive.add_semigroup _ (@equiv.semigroup _ _ e multiplicative.semigroup)
95-
96-
/-- Transfer `add_comm_semigroup` across an `equiv` -/
97-
protected def add_comm_semigroup [add_comm_semigroup β] : add_comm_semigroup α :=
98-
@additive.add_comm_semigroup _ (@equiv.comm_semigroup _ _ e multiplicative.comm_semigroup)
99-
100-
/-- Transfer `add_monoid` across an `equiv` -/
101-
protected def add_monoid [add_monoid β] : add_monoid α :=
102-
@additive.add_monoid _ (@equiv.monoid _ _ e multiplicative.monoid)
103-
104-
/-- Transfer `add_comm_monoid` across an `equiv` -/
105-
protected def add_comm_monoid [add_comm_monoid β] : add_comm_monoid α :=
106-
@additive.add_comm_monoid _ (@equiv.comm_monoid _ _ e multiplicative.comm_monoid)
107-
108-
/-- Transfer `add_group` across an `equiv` -/
109-
protected def add_group [add_group β] : add_group α :=
110-
@additive.add_group _ (@equiv.group _ _ e multiplicative.group)
111-
112-
/-- Transfer `add_comm_group` across an `equiv` -/
113-
protected def add_comm_group [add_comm_group β] : add_comm_group α :=
114-
@additive.add_comm_group _ (@equiv.comm_group _ _ e multiplicative.comm_group)
115-
116152
/-- Transfer `semiring` across an `equiv` -/
117153
protected def semiring [semiring β] : semiring α :=
118154
{ right_distrib := by simp [mul_def, add_def, add_mul],
@@ -174,5 +210,115 @@ protected def field [field β] : field α :=
174210
{ ..equiv.integral_domain e,
175211
..equiv.division_ring e }
176212

213+
variables (R : Type*)
214+
include R
215+
216+
section
217+
variables [monoid R]
218+
219+
/-- Transfer `mul_action` across an `equiv` -/
220+
protected def mul_action (e : α ≃ β) [mul_action R β] : mul_action R α :=
221+
{ one_smul := by simp [smul_def],
222+
mul_smul := by simp [smul_def, mul_smul],
223+
..equiv.has_scalar e }
224+
225+
/-- Transfer `distrib_mul_action` across an `equiv` -/
226+
protected def distrib_mul_action (e : α ≃ β) [add_comm_monoid β] :
227+
begin
228+
letI := equiv.add_comm_monoid e,
229+
exact Π [distrib_mul_action R β], distrib_mul_action R α
230+
end :=
231+
begin
232+
intros,
233+
letI := equiv.add_comm_monoid e,
234+
exact (
235+
{ smul_zero := by simp [zero_def, smul_def],
236+
smul_add := by simp [add_def, smul_def, smul_add],
237+
..equiv.mul_action R e } : distrib_mul_action R α)
238+
end
239+
240+
end
241+
242+
section
243+
variables [semiring R]
244+
245+
/-- Transfer `semimodule` across an `equiv` -/
246+
protected def semimodule (e : α ≃ β) [add_comm_monoid β] :
247+
begin
248+
letI := equiv.add_comm_monoid e,
249+
exact Π [semimodule R β], semimodule R α
250+
end :=
251+
begin
252+
introsI,
253+
exact (
254+
{ zero_smul := by simp [zero_def, smul_def],
255+
add_smul := by simp [add_def, smul_def, add_smul],
256+
..equiv.distrib_mul_action R e } : semimodule R α)
257+
end
258+
259+
/--
260+
An equivalence `e : α ≃ β` gives a linear equivalence `α ≃ₗ[R] β`
261+
where the `R`-module structure on `α` is
262+
the one obtained by transporting an `R`-module structure on `β` back along `e`.
263+
-/
264+
def linear_equiv (e : α ≃ β) [add_comm_monoid β] [semimodule R β] :
265+
begin
266+
letI := equiv.add_comm_monoid e,
267+
letI := equiv.semimodule R e,
268+
exact α ≃ₗ[R] β
269+
end :=
270+
begin
271+
introsI,
272+
exact
273+
{ map_smul' := λ r x, by { apply e.symm.injective, simp, refl, },
274+
..equiv.add_equiv e }
275+
end
276+
277+
end
278+
279+
section
280+
variables [comm_semiring R]
281+
282+
/-- Transfer `algebra` across an `equiv` -/
283+
protected def algebra (e : α ≃ β) [semiring β] :
284+
begin
285+
letI := equiv.semiring e,
286+
exact Π [algebra R β], algebra R α
287+
end :=
288+
begin
289+
introsI,
290+
fapply ring_hom.to_algebra',
291+
{ exact ((ring_equiv e).symm : β →+* α).comp (algebra_map R β), },
292+
{ intros r x,
293+
simp only [function.comp_app, ring_hom.coe_comp],
294+
have p := ring_equiv_symm_apply e,
295+
dsimp at p,
296+
erw p, clear p,
297+
apply (ring_equiv e).injective,
298+
simp only [(ring_equiv e).map_mul],
299+
simp [algebra.commutes], }
300+
end
301+
302+
/--
303+
An equivalence `e : α ≃ β` gives an algebra equivalence `α ≃ₐ[R] β`
304+
where the `R`-algebra structure on `α` is
305+
the one obtained by transporting an `R`-algebra structure on `β` back along `e`.
306+
-/
307+
def alg_equiv (e : α ≃ β) [semiring β] [algebra R β] :
308+
begin
309+
letI := equiv.semiring e,
310+
letI := equiv.algebra R e,
311+
exact α ≃ₐ[R] β
312+
end :=
313+
begin
314+
introsI,
315+
exact
316+
{ commutes' := λ r, by { apply e.symm.injective, simp, refl, },
317+
..equiv.ring_equiv e }
318+
end
319+
320+
end
321+
177322
end instances
178323
end equiv
324+
#lint

0 commit comments

Comments
 (0)