Skip to content

Commit 1377815

Browse files
committed
feat(Algebra/Algebra/Opposite): A ≃ₐ[R] Aᵐᵒᵖᵐᵒᵖ and (A ≃ₐ[R] Bᵐᵒᵖ) ≃ (Aᵐᵒᵖ ≃ₐ[R] B) (#6525)
This also adds the missing `AlgEquiv.equivCongr` as a more general version of `AlgEquiv.autCongr`.
1 parent 4e823e1 commit 1377815

4 files changed

Lines changed: 87 additions & 25 deletions

File tree

Mathlib/Algebra/Algebra/Equiv.lean

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,18 @@ end AlgEquivClass
8383

8484
namespace AlgEquiv
8585

86-
variable {R : Type u} {A₁ : Type v} {A₂ : Type w} {A₃ : Type u₁}
86+
universe uR uA₁ uA₂ uA₃ uA₁' uA₂' uA₃'
87+
variable {R : Type uR}
88+
variable {A₁ : Type uA₁} {A₂ : Type uA₂} {A₃ : Type uA₃}
89+
variable {A₁' : Type uA₁'} {A₂' : Type uA₂'} {A₃' : Type uA₃'}
8790

8891
section Semiring
8992

9093
variable [CommSemiring R] [Semiring A₁] [Semiring A₂] [Semiring A₃]
94+
variable [Semiring A₁'] [Semiring A₂'] [Semiring A₃']
9195

9296
variable [Algebra R A₁] [Algebra R A₂] [Algebra R A₃]
97+
variable [Algebra R A₁'] [Algebra R A₂'] [Algebra R A₃']
9398

9499
variable (e : A₁ ≃ₐ[R] A₂)
95100

@@ -438,9 +443,8 @@ theorem rightInverse_symm (e : A₁ ≃ₐ[R] A₂) : Function.RightInverse e.sy
438443

439444
/-- If `A₁` is equivalent to `A₁'` and `A₂` is equivalent to `A₂'`, then the type of maps
440445
`A₁ →ₐ[R] A₂` is equivalent to the type of maps `A₁' →ₐ[R] A₂'`. -/
441-
def arrowCongr {A₁' A₂' : Type*} [Semiring A₁'] [Semiring A₂'] [Algebra R A₁'] [Algebra R A₂']
442-
(e₁ : A₁ ≃ₐ[R] A₁') (e₂ : A₂ ≃ₐ[R] A₂') : (A₁ →ₐ[R] A₂) ≃ (A₁' →ₐ[R] A₂')
443-
where
446+
@[simps apply]
447+
def arrowCongr (e₁ : A₁ ≃ₐ[R] A₁') (e₂ : A₂ ≃ₐ[R] A₂') : (A₁ →ₐ[R] A₂) ≃ (A₁' →ₐ[R] A₂') where
444448
toFun f := (e₂.toAlgHom.comp f).comp e₁.symm.toAlgHom
445449
invFun f := (e₂.symm.toAlgHom.comp f).comp e₁.toAlgHom
446450
left_inv f := by
@@ -451,8 +455,7 @@ def arrowCongr {A₁' A₂' : Type*} [Semiring A₁'] [Semiring A₂'] [Algebra
451455
simp only [← AlgHom.comp_assoc, comp_symm, AlgHom.id_comp, AlgHom.comp_id]
452456
#align alg_equiv.arrow_congr AlgEquiv.arrowCongr
453457

454-
theorem arrowCongr_comp {A₁' A₂' A₃' : Type*} [Semiring A₁'] [Semiring A₂'] [Semiring A₃']
455-
[Algebra R A₁'] [Algebra R A₂'] [Algebra R A₃'] (e₁ : A₁ ≃ₐ[R] A₁') (e₂ : A₂ ≃ₐ[R] A₂')
458+
theorem arrowCongr_comp (e₁ : A₁ ≃ₐ[R] A₁') (e₂ : A₂ ≃ₐ[R] A₂')
456459
(e₃ : A₃ ≃ₐ[R] A₃') (f : A₁ →ₐ[R] A₂) (g : A₂ →ₐ[R] A₃) :
457460
arrowCongr e₁ e₃ (g.comp f) = (arrowCongr e₂ e₃ g).comp (arrowCongr e₁ e₂ f) := by
458461
ext
@@ -468,22 +471,52 @@ theorem arrowCongr_refl : arrowCongr AlgEquiv.refl AlgEquiv.refl = Equiv.refl (A
468471
#align alg_equiv.arrow_congr_refl AlgEquiv.arrowCongr_refl
469472

470473
@[simp]
471-
theorem arrowCongr_trans {A₁' A₂' A₃' : Type*} [Semiring A₁'] [Semiring A₂'] [Semiring A₃']
472-
[Algebra R A₁'] [Algebra R A₂'] [Algebra R A₃'] (e₁ : A₁ ≃ₐ[R] A₂) (e₁' : A₁' ≃ₐ[R] A₂')
474+
theorem arrowCongr_trans (e₁ : A₁ ≃ₐ[R] A₂) (e₁' : A₁' ≃ₐ[R] A₂')
473475
(e₂ : A₂ ≃ₐ[R] A₃) (e₂' : A₂' ≃ₐ[R] A₃') :
474476
arrowCongr (e₁.trans e₂) (e₁'.trans e₂') = (arrowCongr e₁ e₁').trans (arrowCongr e₂ e₂') := by
475477
ext
476478
rfl
477479
#align alg_equiv.arrow_congr_trans AlgEquiv.arrowCongr_trans
478480

479481
@[simp]
480-
theorem arrowCongr_symm {A₁' A₂' : Type*} [Semiring A₁'] [Semiring A₂'] [Algebra R A₁']
481-
[Algebra R A₂'] (e₁ : A₁ ≃ₐ[R] A₁') (e₂ : A₂ ≃ₐ[R] A₂') :
482+
theorem arrowCongr_symm (e₁ : A₁ ≃ₐ[R] A₁') (e₂ : A₂ ≃ₐ[R] A₂') :
482483
(arrowCongr e₁ e₂).symm = arrowCongr e₁.symm e₂.symm := by
483484
ext
484485
rfl
485486
#align alg_equiv.arrow_congr_symm AlgEquiv.arrowCongr_symm
486487

488+
/-- If `A₁` is equivalent to `A₂` and `A₁'` is equivalent to `A₂'`, then the type of maps
489+
`A₁ ≃ₐ[R] A₁'` is equivalent to the type of maps `A₂ ≃ ₐ[R] A₂'`.
490+
491+
This is the `AlgEquiv` version of `AlgEquiv.arrowCongr`. -/
492+
@[simps apply]
493+
def equivCongr (e : A₁ ≃ₐ[R] A₂) (e' : A₁' ≃ₐ[R] A₂') : (A₁ ≃ₐ[R] A₁') ≃ A₂ ≃ₐ[R] A₂' where
494+
toFun ψ := e.symm.trans (ψ.trans e')
495+
invFun ψ := e.trans (ψ.trans e'.symm)
496+
left_inv ψ := by
497+
ext
498+
simp_rw [trans_apply, symm_apply_apply]
499+
right_inv ψ := by
500+
ext
501+
simp_rw [trans_apply, apply_symm_apply]
502+
503+
@[simp]
504+
theorem equivCongr_refl : equivCongr AlgEquiv.refl AlgEquiv.refl = Equiv.refl (A₁ ≃ₐ[R] A₁') := by
505+
ext
506+
rfl
507+
508+
@[simp]
509+
theorem equivCongr_symm (e : A₁ ≃ₐ[R] A₂) (e' : A₁' ≃ₐ[R] A₂') :
510+
(equivCongr e e').symm = equivCongr e.symm e'.symm :=
511+
rfl
512+
513+
@[simp]
514+
theorem equivCongr_trans (e₁₂ : A₁ ≃ₐ[R] A₂) (e₁₂' : A₁' ≃ₐ[R] A₂')
515+
(e₂₃ : A₂ ≃ₐ[R] A₃) (e₂₃' : A₂' ≃ₐ[R] A₃') :
516+
(equivCongr e₁₂ e₁₂').trans (equivCongr e₂₃ e₂₃') =
517+
equivCongr (e₁₂.trans e₂₃) (e₁₂'.trans e₂₃') :=
518+
rfl
519+
487520
/-- If an algebra morphism has an inverse, it is an algebra isomorphism. -/
488521
def ofAlgHom (f : A₁ →ₐ[R] A₂) (g : A₂ →ₐ[R] A₁) (h₁ : f.comp g = AlgHom.id R A₂)
489522
(h₂ : g.comp f = AlgHom.id R A₁) : A₁ ≃ₐ[R] A₂ :=
@@ -527,20 +560,13 @@ theorem ofBijective_apply {f : A₁ →ₐ[R] A₂} {hf : Function.Bijective f}
527560
#align alg_equiv.of_bijective_apply AlgEquiv.ofBijective_apply
528561

529562
/-- Forgetting the multiplicative structures, an equivalence of algebras is a linear equivalence. -/
530-
-- Porting note: writing the `@[simps apply]`-generated lemma by hand
531-
-- Maybe fixed by the changes in #2435?
563+
@[simps apply]
532564
def toLinearEquiv (e : A₁ ≃ₐ[R] A₂) : A₁ ≃ₗ[R] A₂ :=
533565
{ e with
534566
toFun := e
535567
map_smul' := e.map_smul
536568
invFun := e.symm }
537569
#align alg_equiv.to_linear_equiv AlgEquiv.toLinearEquiv
538-
539-
-- Porting note: writing the `@[simps apply]`-generated lemma by hand
540-
-- Maybe fixed by the changes in #2435?
541-
@[simp]
542-
theorem toLinearEquiv_apply : e.toLinearEquiv x = e x :=
543-
rfl
544570
#align alg_equiv.to_linear_equiv_apply AlgEquiv.toLinearEquiv_apply
545571

546572
@[simp]
@@ -675,17 +701,14 @@ theorem mul_apply (e₁ e₂ : A₁ ≃ₐ[R] A₁) (x : A₁) : (e₁ * e₂) x
675701
rfl
676702
#align alg_equiv.mul_apply AlgEquiv.mul_apply
677703

678-
/-- An algebra isomorphism induces a group isomorphism between automorphism groups -/
704+
/-- An algebra isomorphism induces a group isomorphism between automorphism groups.
705+
706+
This is a more bundled version of `AlgEquiv.equivCongr`. -/
679707
@[simps apply]
680708
def autCongr (ϕ : A₁ ≃ₐ[R] A₂) : (A₁ ≃ₐ[R] A₁) ≃* A₂ ≃ₐ[R] A₂ where
709+
__ := equivCongr ϕ ϕ
681710
toFun ψ := ϕ.symm.trans (ψ.trans ϕ)
682711
invFun ψ := ϕ.trans (ψ.trans ϕ.symm)
683-
left_inv ψ := by
684-
ext
685-
simp_rw [trans_apply, symm_apply_apply]
686-
right_inv ψ := by
687-
ext
688-
simp_rw [trans_apply, apply_symm_apply]
689712
map_mul' ψ χ := by
690713
ext
691714
simp only [mul_apply, trans_apply, symm_apply_apply]

Mathlib/Algebra/Algebra/Opposite.lean

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ import Mathlib.Algebra.Ring.Opposite
1515
* `MulOpposite.instAlgebra`: the algebra on `Aᵐᵒᵖ`
1616
* `AlgHom.op`/`AlgHom.unop`: simultaneously convert the domain and codomain of a morphism to the
1717
opposite algebra.
18+
* `AlgHom.opComm`: swap which side of a morphism lies in the opposite algebra.
1819
* `AlgEquiv.op`/`AlgEquiv.unop`: simultaneously convert the source and target of an isomorphism to
1920
the opposite algebra.
21+
* `AlgEquiv.opOp`: any algebra is isomorphic to the opposite of its opposite.
2022
* `AlgEquiv.toOpposite`: in a commutative algebra, the opposite algebra is isomorphic to the
2123
original algebra.
24+
* `AlgEquiv.opComm`: swap which side of an isomorphism lies in the opposite algebra.
2225
-/
2326

2427

@@ -51,6 +54,19 @@ theorem algebraMap_apply (c : R) : algebraMap R Aᵐᵒᵖ c = op (algebraMap R
5154

5255
end MulOpposite
5356

57+
namespace AlgEquiv
58+
variable (R A)
59+
60+
/-- An algebra is isomorphic to the opposite of its opposite. -/
61+
@[simps!]
62+
def opOp : A ≃ₐ[R] Aᵐᵒᵖᵐᵒᵖ where
63+
__ := RingEquiv.opOp A
64+
commutes' _ := rfl
65+
66+
@[simp] theorem toRingEquiv_opOp : (opOp R A : A ≃+* Aᵐᵒᵖᵐᵒᵖ) = RingEquiv.opOp A := rfl
67+
68+
end AlgEquiv
69+
5470
namespace AlgHom
5571

5672
/--
@@ -109,6 +125,11 @@ abbrev unop : (Aᵐᵒᵖ →ₐ[R] Bᵐᵒᵖ) ≃ (A →ₐ[R] B) := AlgHom.op
109125
theorem toRingHom_unop (f : Aᵐᵒᵖ →ₐ[R] Bᵐᵒᵖ) : f.unop.toRingHom = RingHom.unop f.toRingHom :=
110126
rfl
111127

128+
/-- Swap the `ᵐᵒᵖ` on an algebra hom to the opposite side. -/
129+
@[simps!]
130+
def opComm : (A →ₐ[R] Bᵐᵒᵖ) ≃ (Aᵐᵒᵖ →ₐ[R] B) :=
131+
AlgHom.op.trans <| AlgEquiv.refl.arrowCongr (AlgEquiv.opOp R B).symm
132+
112133
end AlgHom
113134

114135
namespace AlgEquiv
@@ -144,6 +165,11 @@ theorem toRingEquiv_unop (f : Aᵐᵒᵖ ≃ₐ[R] Bᵐᵒᵖ) :
144165
(AlgEquiv.unop f).toRingEquiv = RingEquiv.unop f.toRingEquiv :=
145166
rfl
146167

168+
/-- Swap the `ᵐᵒᵖ` on an algebra isomorphism to the opposite side. -/
169+
@[simps!]
170+
def opComm : (A ≃ₐ[R] Bᵐᵒᵖ) ≃ (Aᵐᵒᵖ ≃ₐ[R] B) :=
171+
AlgEquiv.op.trans <| AlgEquiv.refl.equivCongr (opOp R B).symm
172+
147173
end AlgEquiv
148174

149175
end Semiring

Mathlib/Algebra/Group/Opposite.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,13 @@ def MonoidHom.unop {M N} [MulOneClass M] [MulOneClass N] : (Mᵐᵒᵖ →* Nᵐ
570570
#align monoid_hom.unop MonoidHom.unop
571571
#align add_monoid_hom.unop AddMonoidHom.unop
572572

573+
/-- A monoid is isomorphic to the opposite of its opposite. -/
574+
@[to_additive (attr := simps!)
575+
"A additive monoid is isomorphic to the opposite of its opposite."]
576+
def MulEquiv.opOp (M : Type*) [Mul M] : M ≃* Mᵐᵒᵖᵐᵒᵖ where
577+
__ := MulOpposite.opEquiv.trans MulOpposite.opEquiv
578+
map_mul' _ _ := rfl
579+
573580
/-- An additive homomorphism `M →+ N` can equivalently be viewed as an additive homomorphism
574581
`Mᵐᵒᵖ →+ Nᵐᵒᵖ`. This is the action of the (fully faithful) `ᵐᵒᵖ`-functor on morphisms. -/
575582
@[simps]

Mathlib/Algebra/Ring/Equiv.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,12 @@ protected def unop {α β} [Add α] [Mul α] [Add β] [Mul β] : αᵐᵒᵖ ≃
402402
RingEquiv.op.symm
403403
#align ring_equiv.unop RingEquiv.unop
404404

405+
/-- A ring is isomorphic to the opposite of its opposite. -/
406+
@[simps!]
407+
def opOp (R : Type*) [Add R] [Mul R] : R ≃+* Rᵐᵒᵖᵐᵒᵖ where
408+
__ := MulEquiv.opOp R
409+
map_add' _ _ := rfl
410+
405411
section NonUnitalCommSemiring
406412

407413
variable (R) [NonUnitalCommSemiring R]

0 commit comments

Comments
 (0)