Skip to content

Commit 774069a

Browse files
xroblotjcommelin
andcommitted
feat: port GroupTheory.Submonoid.Inverses (#1987)
Co-authored-by: Johan Commelin <johan@commelin.net>
1 parent 1931275 commit 774069a

File tree

2 files changed

+264
-0
lines changed

2 files changed

+264
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ import Mathlib.GroupTheory.Subgroup.Zpowers
642642
import Mathlib.GroupTheory.Submonoid.Basic
643643
import Mathlib.GroupTheory.Submonoid.Center
644644
import Mathlib.GroupTheory.Submonoid.Centralizer
645+
import Mathlib.GroupTheory.Submonoid.Inverses
645646
import Mathlib.GroupTheory.Submonoid.Membership
646647
import Mathlib.GroupTheory.Submonoid.Operations
647648
import Mathlib.GroupTheory.Submonoid.Pointwise
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/-
2+
Copyright (c) 2021 Andrew Yang. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Andrew Yang
5+
6+
! This file was ported from Lean 3 source module group_theory.submonoid.inverses
7+
! leanprover-community/mathlib commit 59694bd07f0a39c5beccba34bd9f413a160782bf
8+
! Please do not edit these lines, except to modify the commit id
9+
! if you have ported upstream changes.
10+
-/
11+
import Mathlib.GroupTheory.Submonoid.Pointwise
12+
13+
/-!
14+
15+
# Submonoid of inverses
16+
17+
Given a submonoid `N` of a monoid `M`, we define the submonoid `N.leftInv` as the submonoid of
18+
left inverses of `N`. When `M` is commutative, we may define `fromCommLeftInv : N.leftInv →* N`
19+
since the inverses are unique. When `N ≤ IsUnit.Submonoid M`, this is precisely
20+
the pointwise inverse of `N`, and we may define `leftInvEquiv : S.leftInv ≃* S`.
21+
22+
For the pointwise inverse of submonoids of groups, please refer to
23+
`GroupTheory.Submonoid.Pointwise`.
24+
25+
## TODO
26+
27+
Define the submonoid of right inverses and two-sided inverses.
28+
See the comments of #10679 for a possible implementation.
29+
30+
-/
31+
32+
33+
variable {M : Type _}
34+
35+
namespace Submonoid
36+
37+
@[to_additive]
38+
noncomputable instance [Monoid M] : Group (IsUnit.submonoid M) :=
39+
{ show Monoid (IsUnit.submonoid M) by
40+
infer_instance with
41+
inv := fun x ↦ ⟨_, x.prop.unit⁻¹.isUnit⟩
42+
mul_left_inv := fun x ↦ by
43+
exact Subtype.mk_eq_mk.2 ((Units.val_mul _ _).trans x.prop.unit.inv_val) }
44+
45+
@[to_additive]
46+
noncomputable instance [CommMonoid M] : CommGroup (IsUnit.submonoid M) :=
47+
{ show Group (IsUnit.submonoid M) by infer_instance
48+
with mul_comm := fun a b ↦ by convert mul_comm a b }
49+
50+
@[to_additive]
51+
theorem IsUnit.Submonoid.coe_inv [Monoid M] (x : IsUnit.submonoid M) :
52+
↑x⁻¹ = (↑x.prop.unit⁻¹ : M) :=
53+
rfl
54+
#align submonoid.is_unit.submonoid.coe_inv Submonoid.IsUnit.Submonoid.coe_inv
55+
#align add_submonoid.is_unit.submonoid.coe_neg AddSubmonoid.IsUnit.Submonoid.coe_neg
56+
57+
section Monoid
58+
59+
variable [Monoid M] (S : Submonoid M)
60+
61+
/-- `S.leftInv` is the submonoid containing all the left inverses of `S`. -/
62+
@[to_additive
63+
"`S.leftNeg` is the additive submonoid containing all the left additive inverses of `S`."]
64+
def leftInv : Submonoid M where
65+
carrier := { x : M | ∃ y : S, x * y = 1 }
66+
one_mem' := ⟨1, mul_one 1
67+
mul_mem' := fun {a} _b ⟨a', ha⟩ ⟨b', hb⟩ ↦
68+
⟨b' * a', by simp only [coe_mul, ← mul_assoc, mul_assoc a, hb, mul_one, ha]⟩
69+
#align submonoid.left_inv Submonoid.leftInv
70+
#align add_submonoid.left_neg AddSubmonoid.leftNeg
71+
72+
@[to_additive]
73+
theorem leftInv_leftInv_le : S.leftInv.leftInv ≤ S := by
74+
rintro x ⟨⟨y, z, h₁⟩, h₂ : x * y = 1
75+
convert z.prop
76+
rw [← mul_one x, ← h₁, ← mul_assoc, h₂, one_mul]
77+
#align submonoid.left_inv_left_inv_le Submonoid.leftInv_leftInv_le
78+
#align add_submonoid.left_neg_left_neg_le AddSubmonoid.leftNeg_leftNeg_le
79+
80+
@[to_additive]
81+
theorem unit_mem_leftInv (x : Mˣ) (hx : (x : M) ∈ S) : ((x⁻¹ : _) : M) ∈ S.leftInv :=
82+
⟨⟨x, hx⟩, x.inv_val⟩
83+
#align submonoid.unit_mem_left_inv Submonoid.unit_mem_leftInv
84+
#align add_submonoid.add_unit_mem_left_neg AddSubmonoid.addUnit_mem_leftNeg
85+
86+
@[to_additive]
87+
theorem leftInv_leftInv_eq (hS : S ≤ IsUnit.submonoid M) : S.leftInv.leftInv = S := by
88+
refine' le_antisymm S.leftInv_leftInv_le _
89+
intro x hx
90+
have : x = ((hS hx).unit⁻¹⁻¹ : Mˣ) :=
91+
by
92+
rw [inv_inv (hS hx).unit]
93+
rfl
94+
rw [this]
95+
exact S.leftInv.unit_mem_leftInv _ (S.unit_mem_leftInv _ hx)
96+
#align submonoid.left_inv_left_inv_eq Submonoid.leftInv_leftInv_eq
97+
#align add_submonoid.left_neg_left_neg_eq AddSubmonoid.leftNeg_leftNeg_eq
98+
99+
/-- The function from `S.leftInv` to `S` sending an element to its right inverse in `S`.
100+
This is a `MonoidHom` when `M` is commutative. -/
101+
@[to_additive
102+
"The function from `S.leftAdd` to `S` sending an element to its right additive
103+
inverse in `S`. This is an `AddMonoidHom` when `M` is commutative."]
104+
noncomputable def fromLeftInv : S.leftInv → S := fun x ↦ x.prop.choose
105+
#align submonoid.from_left_inv Submonoid.fromLeftInv
106+
#align add_submonoid.from_left_neg AddSubmonoid.fromLeftNeg
107+
108+
@[to_additive (attr := simp)]
109+
theorem mul_fromLeftInv (x : S.leftInv) : (x : M) * S.fromLeftInv x = 1 :=
110+
x.prop.choose_spec
111+
#align submonoid.mul_from_left_inv Submonoid.mul_fromLeftInv
112+
#align add_submonoid.add_from_left_neg AddSubmonoid.add_fromLeftNeg
113+
114+
@[to_additive (attr := simp)]
115+
theorem fromLeftInv_one : S.fromLeftInv 1 = 1 :=
116+
(one_mul _).symm.trans (Subtype.eq <| S.mul_fromLeftInv 1)
117+
#align submonoid.from_left_inv_one Submonoid.fromLeftInv_one
118+
#align add_submonoid.from_left_neg_zero AddSubmonoid.fromLeftNeg_zero
119+
120+
end Monoid
121+
122+
section CommMonoid
123+
124+
variable [CommMonoid M] (S : Submonoid M)
125+
126+
@[to_additive (attr := simp)]
127+
theorem fromLeftInv_mul (x : S.leftInv) : (S.fromLeftInv x : M) * x = 1 := by
128+
rw [mul_comm, mul_fromLeftInv]
129+
#align submonoid.from_left_inv_mul Submonoid.fromLeftInv_mul
130+
#align add_submonoid.from_left_neg_add AddSubmonoid.fromLeftNeg_add
131+
132+
@[to_additive]
133+
theorem leftInv_le_is_unit : S.leftInv ≤ IsUnit.submonoid M := fun x ⟨y, hx⟩ ↦
134+
⟨⟨x, y, hx, mul_comm x y ▸ hx⟩, rfl⟩
135+
#align submonoid.left_inv_le_is_unit Submonoid.leftInv_le_is_unit
136+
#align add_submonoid.left_neg_le_is_add_unit AddSubmonoid.leftNeg_le_is_addUnit
137+
138+
@[to_additive]
139+
theorem fromLeftInv_eq_iff (a : S.leftInv) (b : M) : (S.fromLeftInv a : M) = b ↔ (a : M) * b = 1 :=
140+
by rw [← IsUnit.mul_right_inj (leftInv_le_is_unit _ a.prop), S.mul_fromLeftInv, eq_comm]
141+
#align submonoid.from_left_inv_eq_iff Submonoid.fromLeftInv_eq_iff
142+
#align add_submonoid.from_left_neg_eq_iff AddSubmonoid.fromLeftNeg_eq_iff
143+
144+
/-- The `MonoidHom` from `S.leftInv` to `S` sending an element to its right inverse in `S`. -/
145+
@[to_additive (attr := simps)
146+
"The `add_monoid_hom` from `S.leftNeg` to `S` sending an element to its
147+
right additive inverse in `S`."]
148+
noncomputable def fromCommLeftInv : S.leftInv →* S
149+
where
150+
toFun := S.fromLeftInv
151+
map_one' := S.fromLeftInv_one
152+
map_mul' x y :=
153+
Subtype.ext <| by
154+
rw [fromLeftInv_eq_iff, mul_comm x, Submonoid.coe_mul, Submonoid.coe_mul, mul_assoc, ←
155+
mul_assoc (x : M), mul_fromLeftInv, one_mul, mul_fromLeftInv]
156+
#align submonoid.from_comm_left_inv Submonoid.fromCommLeftInv
157+
#align add_submonoid.from_comm_left_neg AddSubmonoid.fromCommLeftNeg
158+
159+
variable (hS : S ≤ IsUnit.submonoid M)
160+
161+
-- Porting note: commented out next line
162+
-- include hS
163+
164+
/-- The submonoid of pointwise inverse of `S` is `MulEquiv` to `S`. -/
165+
@[to_additive (attr := simps apply) "The additive submonoid of pointwise additive inverse of `S` is
166+
`AddEquiv` to `S`."]
167+
noncomputable def leftInvEquiv : S.leftInv ≃* S :=
168+
{ S.fromCommLeftInv with
169+
invFun := fun x ↦ by
170+
choose x' hx using hS x.prop
171+
exact ⟨x'.inv, x, hx ▸ x'.inv_val⟩
172+
left_inv := fun x ↦
173+
Subtype.eq <| by
174+
dsimp only; generalize_proofs h; rw [← h.choose.mul_left_inj]
175+
conv => rhs ; rw [h.choose_spec]
176+
exact h.choose.inv_val.trans (S.mul_fromLeftInv x).symm
177+
right_inv := fun x ↦ by
178+
dsimp only [fromCommLeftInv]
179+
ext
180+
rw [fromLeftInv_eq_iff]
181+
convert (hS x.prop).choose.inv_val
182+
exact (hS x.prop).choose_spec.symm }
183+
#align submonoid.left_inv_equiv Submonoid.leftInvEquiv
184+
#align add_submonoid.left_neg_equiv AddSubmonoid.leftNegEquiv
185+
186+
@[to_additive (attr := simp)]
187+
theorem fromLeftInv_leftInvEquiv_symm (x : S) : S.fromLeftInv ((S.leftInvEquiv hS).symm x) = x :=
188+
(S.leftInvEquiv hS).right_inv x
189+
#align submonoid.from_left_inv_left_inv_equiv_symm Submonoid.fromLeftInv_leftInvEquiv_symm
190+
#align add_submonoid.from_left_neg_left_neg_equiv_symm AddSubmonoid.fromLeftNeg_leftNegEquiv_symm
191+
192+
@[to_additive (attr := simp)]
193+
theorem leftInvEquiv_symm_fromLeftInv (x : S.leftInv) :
194+
(S.leftInvEquiv hS).symm (S.fromLeftInv x) = x :=
195+
(S.leftInvEquiv hS).left_inv x
196+
#align submonoid.left_inv_equiv_symm_from_left_inv Submonoid.leftInvEquiv_symm_fromLeftInv
197+
#align add_submonoid.left_neg_equiv_symm_from_left_neg AddSubmonoid.leftNegEquiv_symm_fromLeftNeg
198+
199+
@[to_additive]
200+
theorem leftInvEquiv_mul (x : S.leftInv) : (S.leftInvEquiv hS x : M) * x = 1 := by
201+
simpa only [leftInvEquiv_apply, fromCommLeftInv] using fromLeftInv_mul S x
202+
203+
#align submonoid.left_inv_equiv_mul Submonoid.leftInvEquiv_mul
204+
#align add_submonoid.left_neg_equiv_add AddSubmonoid.leftNegEquiv_add
205+
206+
@[to_additive]
207+
theorem mul_leftInvEquiv (x : S.leftInv) : (x : M) * S.leftInvEquiv hS x = 1 := by
208+
simp only [leftInvEquiv_apply, fromCommLeftInv, mul_fromLeftInv]
209+
#align submonoid.mul_left_inv_equiv Submonoid.mul_leftInvEquiv
210+
#align add_submonoid.add_left_neg_equiv AddSubmonoid.add_leftNegEquiv
211+
212+
@[to_additive (attr := simp)]
213+
theorem leftInvEquiv_symm_mul (x : S) : ((S.leftInvEquiv hS).symm x : M) * x = 1 := by
214+
convert S.mul_leftInvEquiv hS ((S.leftInvEquiv hS).symm x)
215+
simp
216+
#align submonoid.left_inv_equiv_symm_mul Submonoid.leftInvEquiv_symm_mul
217+
#align add_submonoid.left_neg_equiv_symm_add AddSubmonoid.leftNegEquiv_symm_add
218+
219+
@[to_additive (attr := simp)]
220+
theorem mul_leftInvEquiv_symm (x : S) : (x : M) * (S.leftInvEquiv hS).symm x = 1 := by
221+
convert S.leftInvEquiv_mul hS ((S.leftInvEquiv hS).symm x)
222+
simp
223+
#align submonoid.mul_left_inv_equiv_symm Submonoid.mul_leftInvEquiv_symm
224+
#align add_submonoid.add_left_neg_equiv_symm AddSubmonoid.add_leftNegEquiv_symm
225+
226+
end CommMonoid
227+
228+
section Group
229+
230+
variable [Group M] (S : Submonoid M)
231+
232+
open Pointwise
233+
234+
@[to_additive]
235+
theorem leftInv_eq_inv : S.leftInv = S⁻¹ :=
236+
Submonoid.ext fun _ ↦
237+
fun h ↦ Submonoid.mem_inv.mpr ((inv_eq_of_mul_eq_one_right h.choose_spec).symm ▸
238+
h.choose.prop),
239+
fun h ↦ ⟨⟨_, h⟩, mul_right_inv _⟩⟩
240+
#align submonoid.left_inv_eq_inv Submonoid.leftInv_eq_inv
241+
#align add_submonoid.left_neg_eq_neg AddSubmonoid.leftNeg_eq_neg
242+
243+
@[to_additive (attr := simp)]
244+
theorem fromLeftInv_eq_inv (x : S.leftInv) : (S.fromLeftInv x : M) = (x : M)⁻¹ := by
245+
rw [← mul_right_inj (x : M), mul_right_inv, mul_fromLeftInv]
246+
#align submonoid.from_left_inv_eq_inv Submonoid.fromLeftInv_eq_inv
247+
#align add_submonoid.from_left_neg_eq_neg AddSubmonoid.fromLeftNeg_eq_neg
248+
249+
end Group
250+
251+
section CommGroup
252+
253+
variable [CommGroup M] (S : Submonoid M) (hS : S ≤ IsUnit.submonoid M)
254+
255+
@[to_additive (attr := simp)]
256+
theorem leftInvEquiv_symm_eq_inv (x : S) : ((S.leftInvEquiv hS).symm x : M) = (x : M)⁻¹ := by
257+
rw [← mul_right_inj (x : M), mul_right_inv, mul_leftInvEquiv_symm]
258+
#align submonoid.left_inv_equiv_symm_eq_inv Submonoid.leftInvEquiv_symm_eq_inv
259+
#align add_submonoid.left_neg_equiv_symm_eq_neg AddSubmonoid.leftNegEquiv_symm_eq_neg
260+
261+
end CommGroup
262+
263+
end Submonoid

0 commit comments

Comments
 (0)