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

Commit f0451d8

Browse files
feat(algebra/group/defs): ext lemmas for (semi)groups and monoids (#8391)
[Zulip discussion](https://leanprover.zulipchat.com/#narrow/stream/144837-PR-reviews/topic/.236476.20boolean_algebra.2Eto_boolean_ring/near/242118386) Co-authored-by: Kevin Buzzard <k.buzzard@imperial.ac.uk>
1 parent 065a35d commit f0451d8

File tree

3 files changed

+226
-16
lines changed

3 files changed

+226
-16
lines changed

src/algebra/group/defs.lean

Lines changed: 224 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import algebra.group.to_additive
77
import tactic.basic
88

99
/-!
10-
# Typeclasses for (semi)groups and monoid
10+
# Typeclasses for (semi)groups and monoids
1111
1212
In this file we define typeclasses for algebraic structures with one binary operation.
1313
The classes are named `(add_)?(comm_)?(semigroup|monoid|group)`, where `add_` means that
@@ -62,10 +62,10 @@ def right_mul : G → G → G := λ g : G, λ x : G, x * g
6262
end has_mul
6363

6464
/-- A semigroup is a type with an associative `(*)`. -/
65-
@[protect_proj, ancestor has_mul] class semigroup (G : Type u) extends has_mul G :=
65+
@[protect_proj, ancestor has_mul, ext] class semigroup (G : Type u) extends has_mul G :=
6666
(mul_assoc : ∀ a b c : G, a * b * c = a * (b * c))
6767
/-- An additive semigroup is a type with an associative `(+)`. -/
68-
@[protect_proj, ancestor has_add] class add_semigroup (G : Type u) extends has_add G :=
68+
@[protect_proj, ancestor has_add, ext] class add_semigroup (G : Type u) extends has_add G :=
6969
(add_assoc : ∀ a b c : G, a + b + c = a + (b + c))
7070
attribute [to_additive] semigroup
7171

@@ -85,12 +85,12 @@ instance semigroup.to_is_associative : is_associative G (*) :=
8585
end semigroup
8686

8787
/-- A commutative semigroup is a type with an associative commutative `(*)`. -/
88-
@[protect_proj, ancestor semigroup]
88+
@[protect_proj, ancestor semigroup, ext]
8989
class comm_semigroup (G : Type u) extends semigroup G :=
9090
(mul_comm : ∀ a b : G, a * b = b * a)
9191

9292
/-- A commutative additive semigroup is a type with an associative commutative `(+)`. -/
93-
@[protect_proj, ancestor add_semigroup]
93+
@[protect_proj, ancestor add_semigroup, ext]
9494
class add_comm_semigroup (G : Type u) extends add_semigroup G :=
9595
(add_comm : ∀ a b : G, a + b = b + a)
9696
attribute [to_additive] comm_semigroup
@@ -110,12 +110,12 @@ instance comm_semigroup.to_is_commutative : is_commutative G (*) :=
110110
end comm_semigroup
111111

112112
/-- A `left_cancel_semigroup` is a semigroup such that `a * b = a * c` implies `b = c`. -/
113-
@[protect_proj, ancestor semigroup]
113+
@[protect_proj, ancestor semigroup, ext]
114114
class left_cancel_semigroup (G : Type u) extends semigroup G :=
115115
(mul_left_cancel : ∀ a b c : G, a * b = a * c → b = c)
116116
/-- An `add_left_cancel_semigroup` is an additive semigroup such that
117117
`a + b = a + c` implies `b = c`. -/
118-
@[protect_proj, ancestor add_semigroup]
118+
@[protect_proj, ancestor add_semigroup, ext]
119119
class add_left_cancel_semigroup (G : Type u) extends add_semigroup G :=
120120
(add_left_cancel : ∀ a b c : G, a + b = a + c → b = c)
121121
attribute [to_additive add_left_cancel_semigroup] left_cancel_semigroup
@@ -146,13 +146,13 @@ theorem mul_ne_mul_right (a : G) {b c : G} : a * b ≠ a * c ↔ b ≠ c :=
146146
end left_cancel_semigroup
147147

148148
/-- A `right_cancel_semigroup` is a semigroup such that `a * b = c * b` implies `a = c`. -/
149-
@[protect_proj, ancestor semigroup]
149+
@[protect_proj, ancestor semigroup, ext]
150150
class right_cancel_semigroup (G : Type u) extends semigroup G :=
151151
(mul_right_cancel : ∀ a b c : G, a * b = c * b → a = c)
152152

153153
/-- An `add_right_cancel_semigroup` is an additive semigroup such that
154154
`a + b = c + b` implies `a = c`. -/
155-
@[protect_proj, ancestor add_semigroup]
155+
@[protect_proj, ancestor add_semigroup, ext]
156156
class add_right_cancel_semigroup (G : Type u) extends add_semigroup G :=
157157
(add_right_cancel : ∀ a b c : G, a + b = c + b → a = c)
158158
attribute [to_additive add_right_cancel_semigroup] right_cancel_semigroup
@@ -198,6 +198,16 @@ class add_zero_class (M : Type u) extends has_zero M, has_add M :=
198198

199199
attribute [to_additive] mul_one_class
200200

201+
@[ext, to_additive]
202+
lemma mul_one_class.ext {M : Type u} : ∀ ⦃m₁ m₂ : mul_one_class M⦄, m₁.mul = m₂.mul → m₁ = m₂ :=
203+
begin
204+
rintros ⟨one₁, mul₁, one_mul₁, mul_one₁⟩ ⟨one₂, mul₂, one_mul₂, mul_one₂⟩ (rfl : mul₁ = mul₂),
205+
congr,
206+
exact (one_mul₂ one₁).symm.trans (mul_one₁ one₂),
207+
end
208+
209+
attribute [ext] add_zero_class.ext
210+
201211
section mul_one_class
202212
variables {M : Type u} [mul_one_class M]
203213

@@ -352,6 +362,28 @@ class monoid (M : Type u) extends semigroup M, mul_one_class M :=
352362

353363
export monoid (npow)
354364

365+
@[ext, to_additive]
366+
lemma monoid.ext {M : Type*} ⦃m₁ m₂ : monoid M⦄ (h_mul : m₁.mul = m₂.mul) : m₁ = m₂ :=
367+
begin
368+
unfreezingI {
369+
cases m₁ with mul₁ _ one₁ one_mul₁ mul_one₁ npow₁ npow_zero₁ npow_succ₁,
370+
cases m₂ with mul₂ _ one₂ one_mul₂ mul_one₂ npow₂ npow_zero₂ npow_succ₂ },
371+
change mul₁ = mul₂ at h_mul,
372+
subst h_mul,
373+
have h_one : one₁ = one₂,
374+
{ rw ←one_mul₂ one₁,
375+
exact mul_one₁ one₂ },
376+
subst h_one,
377+
have h_npow : npow₁ = npow₂,
378+
{ ext n,
379+
induction n with d hd,
380+
{ rw [npow_zero₁, npow_zero₂] },
381+
{ rw [npow_succ₁, npow_succ₂, hd] } },
382+
subst h_npow,
383+
end
384+
385+
attribute [ext] add_monoid.ext
386+
355387
section monoid
356388
variables {M : Type u} [monoid M]
357389

@@ -388,6 +420,20 @@ class add_comm_monoid (M : Type u) extends add_monoid M, add_comm_semigroup M
388420
@[protect_proj, ancestor monoid comm_semigroup, to_additive]
389421
class comm_monoid (M : Type u) extends monoid M, comm_semigroup M
390422

423+
@[to_additive]
424+
lemma comm_monoid.to_monoid_injective {M : Type u} :
425+
function.injective (@comm_monoid.to_monoid M) :=
426+
begin
427+
rintros ⟨⟩ ⟨⟩ h,
428+
congr'; injection h,
429+
end
430+
431+
@[ext, to_additive]
432+
lemma comm_monoid.ext {M : Type*} ⦃m₁ m₂ : comm_monoid M⦄ (h_mul : m₁.mul = m₂.mul) : m₁ = m₂ :=
433+
comm_monoid.to_monoid_injective $ monoid.ext h_mul
434+
435+
attribute [ext] add_comm_monoid.ext
436+
391437
section left_cancel_monoid
392438

393439
/-- An additive monoid in which addition is left-cancellative.
@@ -400,6 +446,21 @@ class add_left_cancel_monoid (M : Type u) extends add_left_cancel_semigroup M, a
400446
@[protect_proj, ancestor left_cancel_semigroup monoid, to_additive add_left_cancel_monoid]
401447
class left_cancel_monoid (M : Type u) extends left_cancel_semigroup M, monoid M
402448

449+
@[to_additive]
450+
lemma left_cancel_monoid.to_monoid_injective {M : Type u} :
451+
function.injective (@left_cancel_monoid.to_monoid M) :=
452+
begin
453+
rintros ⟨⟩ ⟨⟩ h,
454+
congr'; injection h,
455+
end
456+
457+
@[ext, to_additive]
458+
lemma left_cancel_monoid.ext {M : Type*} ⦃m₁ m₂ : left_cancel_monoid M⦄
459+
(h_mul : m₁.mul = m₂.mul) : m₁ = m₂ :=
460+
left_cancel_monoid.to_monoid_injective $ monoid.ext h_mul
461+
462+
attribute [ext] add_left_cancel_monoid.ext
463+
403464
end left_cancel_monoid
404465

405466
section right_cancel_monoid
@@ -414,6 +475,21 @@ class add_right_cancel_monoid (M : Type u) extends add_right_cancel_semigroup M,
414475
@[protect_proj, ancestor right_cancel_semigroup monoid, to_additive add_right_cancel_monoid]
415476
class right_cancel_monoid (M : Type u) extends right_cancel_semigroup M, monoid M
416477

478+
@[to_additive]
479+
lemma right_cancel_monoid.to_monoid_injective {M : Type u} :
480+
function.injective (@right_cancel_monoid.to_monoid M) :=
481+
begin
482+
rintros ⟨⟩ ⟨⟩ h,
483+
congr'; injection h,
484+
end
485+
486+
@[ext, to_additive]
487+
lemma right_cancel_monoid.ext {M : Type*} ⦃m₁ m₂ : right_cancel_monoid M⦄
488+
(h_mul : m₁.mul = m₂.mul) : m₁ = m₂ :=
489+
right_cancel_monoid.to_monoid_injective $ monoid.ext h_mul
490+
491+
attribute [ext] add_right_cancel_monoid.ext
492+
417493
end right_cancel_monoid
418494

419495
section cancel_monoid
@@ -429,6 +505,21 @@ class add_cancel_monoid (M : Type u)
429505
@[protect_proj, ancestor left_cancel_monoid right_cancel_monoid, to_additive add_cancel_monoid]
430506
class cancel_monoid (M : Type u) extends left_cancel_monoid M, right_cancel_monoid M
431507

508+
@[to_additive]
509+
lemma cancel_monoid.to_left_cancel_monoid_injective {M : Type u} :
510+
function.injective (@cancel_monoid.to_left_cancel_monoid M) :=
511+
begin
512+
rintros ⟨⟩ ⟨⟩ h,
513+
congr'; injection h,
514+
end
515+
516+
@[ext, to_additive]
517+
lemma cancel_monoid.ext {M : Type*} ⦃m₁ m₂ : cancel_monoid M⦄
518+
(h_mul : m₁.mul = m₂.mul) : m₁ = m₂ :=
519+
cancel_monoid.to_left_cancel_monoid_injective $ left_cancel_monoid.ext h_mul
520+
521+
attribute [ext] add_cancel_monoid.ext
522+
432523
/-- Commutative version of add_cancel_monoid. -/
433524
@[protect_proj, ancestor add_left_cancel_monoid add_comm_monoid]
434525
class add_cancel_comm_monoid (M : Type u) extends add_left_cancel_monoid M, add_comm_monoid M
@@ -437,6 +528,21 @@ class add_cancel_comm_monoid (M : Type u) extends add_left_cancel_monoid M, add_
437528
@[protect_proj, ancestor left_cancel_monoid comm_monoid, to_additive add_cancel_comm_monoid]
438529
class cancel_comm_monoid (M : Type u) extends left_cancel_monoid M, comm_monoid M
439530

531+
@[to_additive]
532+
lemma cancel_comm_monoid.to_comm_monoid_injective {M : Type u} :
533+
function.injective (@cancel_comm_monoid.to_comm_monoid M) :=
534+
begin
535+
rintros ⟨⟩ ⟨⟩ h,
536+
congr'; injection h,
537+
end
538+
539+
@[ext, to_additive]
540+
lemma cancel_comm_monoid.ext {M : Type*} ⦃m₁ m₂ : cancel_comm_monoid M⦄
541+
(h_mul : m₁.mul = m₂.mul) : m₁ = m₂ :=
542+
cancel_comm_monoid.to_comm_monoid_injective $ comm_monoid.ext h_mul
543+
544+
attribute [ext] add_cancel_comm_monoid.ext
545+
440546
@[priority 100, to_additive] -- see Note [lower instance priority]
441547
instance cancel_comm_monoid.to_cancel_monoid (M : Type u) [cancel_comm_monoid M] :
442548
cancel_monoid M :=
@@ -485,9 +591,9 @@ class div_inv_monoid (G : Type u) extends monoid G, has_inv G, has_div G :=
485591
(gpow : ℤ → G → G := gpow_rec)
486592
(gpow_zero' : ∀ (a : G), gpow 0 a = 1 . try_refl_tac)
487593
(gpow_succ' :
488-
∀ (n : ℕ) (a : G), gpow (int.of_nat n.succ) a = a * gpow (int.of_nat n) a . try_refl_tac)
594+
∀ (n : ℕ) (a : G), gpow (int.of_nat n.succ) a = a * gpow (int.of_nat n) a . try_refl_tac)
489595
(gpow_neg' :
490-
∀ (n : ℕ) (a : G), gpow (-[1+ n]) a = (gpow n.succ a) ⁻¹ . try_refl_tac)
596+
∀ (n : ℕ) (a : G), gpow (-[1+ n]) a = (gpow n.succ a)⁻¹ . try_refl_tac)
491597

492598
export div_inv_monoid (gpow)
493599

@@ -515,14 +621,63 @@ class sub_neg_monoid (G : Type u) extends add_monoid G, has_neg G, has_sub G :=
515621
(gsmul : ℤ → G → G := gsmul_rec)
516622
(gsmul_zero' : ∀ (a : G), gsmul 0 a = 0 . try_refl_tac)
517623
(gsmul_succ' :
518-
∀ (n : ℕ) (a : G), gsmul (int.of_nat n.succ) a = a + gsmul (int.of_nat n) a . try_refl_tac)
624+
∀ (n : ℕ) (a : G), gsmul (int.of_nat n.succ) a = a + gsmul (int.of_nat n) a . try_refl_tac)
519625
(gsmul_neg' :
520626
∀ (n : ℕ) (a : G), gsmul (-[1+ n]) a = - (gsmul n.succ a) . try_refl_tac)
521627

522628
export sub_neg_monoid (gsmul)
523629

524630
attribute [to_additive sub_neg_monoid] div_inv_monoid
525631

632+
@[ext, to_additive]
633+
lemma div_inv_monoid.ext {M : Type*} ⦃m₁ m₂ : div_inv_monoid M⦄ (h_mul : m₁.mul = m₂.mul)
634+
(h_inv : m₁.inv = m₂.inv) : m₁ = m₂ :=
635+
begin
636+
let iM : div_inv_monoid M := m₁,
637+
unfreezingI {
638+
cases m₁ with mul₁ _ one₁ one_mul₁ mul_one₁ npow₁ npow_zero₁ npow_succ₁ inv₁ div₁
639+
div_eq_mul_inv₁ gpow₁ gpow_zero'₁ gpow_succ'₁ gpow_neg'₁,
640+
cases m₂ with mul₂ _ one₂ one_mul₂ mul_one₂ npow₂ npow_zero₂ npow_succ₂ inv₂ div₂
641+
div_eq_mul_inv₂ gpow₂ gpow_zero'₂ gpow_succ'₂ gpow_neg'₂ },
642+
change mul₁ = mul₂ at h_mul,
643+
subst h_mul,
644+
have h_one : one₁ = one₂,
645+
{ rw ←one_mul₂ one₁,
646+
exact mul_one₁ one₂ },
647+
subst h_one,
648+
have h_npow : npow₁ = npow₂,
649+
{ ext n,
650+
induction n with d hd,
651+
{ rw [npow_zero₁, npow_zero₂] },
652+
{ rw [npow_succ₁, npow_succ₂, hd] } },
653+
subst h_npow,
654+
change inv₁ = inv₂ at h_inv,
655+
subst h_inv,
656+
have h_div : div₁ = div₂,
657+
{ ext a b,
658+
convert (rfl : a * b⁻¹ = a * b⁻¹),
659+
{ exact div_eq_mul_inv₁ a b },
660+
{ exact div_eq_mul_inv₂ a b } },
661+
subst h_div,
662+
have h_gpow_aux : ∀ n g, gpow₁ (int.of_nat n) g = gpow₂ (int.of_nat n) g,
663+
{ intros n g,
664+
induction n with n IH,
665+
{ convert (rfl : (1 : M) = 1),
666+
{ exact gpow_zero'₁ g },
667+
{ exact gpow_zero'₂ g } },
668+
{ rw [gpow_succ'₁, gpow_succ'₂, IH] } },
669+
have h_gpow : gpow₁ = gpow₂,
670+
{ ext z,
671+
cases z with z z,
672+
{ exact h_gpow_aux z x },
673+
{ rw [gpow_neg'₁, gpow_neg'₂],
674+
congr',
675+
exact h_gpow_aux _ _ } },
676+
subst h_gpow,
677+
end
678+
679+
attribute [ext] sub_neg_monoid.ext
680+
526681
@[to_additive]
527682
lemma div_eq_mul_inv {G : Type u} [div_inv_monoid G] :
528683
∀ a b : G, a / b = a * b⁻¹ :=
@@ -602,6 +757,45 @@ instance group.to_cancel_monoid : cancel_monoid G :=
602757

603758
end group
604759

760+
@[to_additive]
761+
lemma group.to_div_inv_monoid_injective {G : Type*} :
762+
function.injective (@group.to_div_inv_monoid G) :=
763+
begin
764+
rintros ⟨⟩ ⟨⟩ h,
765+
replace h := div_inv_monoid.mk.inj h,
766+
dsimp at h,
767+
rcases h with ⟨rfl, rfl, rfl, rfl, rfl, rfl⟩,
768+
refl
769+
end
770+
771+
@[ext, to_additive]
772+
lemma group.ext {G : Type*} ⦃g₁ g₂ : group G⦄ (h_mul : g₁.mul = g₂.mul) : g₁ = g₂ :=
773+
group.to_div_inv_monoid_injective $ div_inv_monoid.ext h_mul
774+
begin
775+
let iG : group G := g₁,
776+
unfreezingI {
777+
cases g₁ with mul₁ _ one₁ one_mul₁ mul_one₁ npow₁ npow_zero'₁ npow_succ'₁ inv₁ div₁
778+
div_eq_mul_inv₁ gpow₁ gpow_zero'₁ gpow_succ'₁ gpow_neg'₁ mul_left_inv₁,
779+
cases g₂ with mul₂ _ one₂ one_mul₂ mul_one₂ npow₂ npow_zero'₂ npow_succ'₂ inv₂ div₂
780+
div_eq_mul_inv₂ gpow₂ gpow_zero'₂ gpow_succ'₂ gpow_neg'₂ mul_left_inv₂, },
781+
change mul₁ = mul₂ at h_mul,
782+
subst h_mul,
783+
have h_one : one₁ = one₂,
784+
{ rw ← mul_one₂ one₁,
785+
exact one_mul₁ one₂ },
786+
subst h_one,
787+
have h_inv : inv₁ = inv₂,
788+
{ ext a,
789+
-- this uses the group.to_cancel_monoid instance, so this lemma can't be moved higher
790+
rw [← mul_left_inj a],
791+
convert (rfl : (1 : G) = 1),
792+
{ exact mul_left_inv₁ a },
793+
{ exact mul_left_inv₂ a } },
794+
exact h_inv
795+
end
796+
797+
attribute [ext] add_group.ext
798+
605799
/-- A commutative group is a group with commutative `(*)`. -/
606800
@[protect_proj, ancestor group comm_monoid]
607801
class comm_group (G : Type u) extends group G, comm_monoid G
@@ -611,6 +805,24 @@ class add_comm_group (G : Type u) extends add_group G, add_comm_monoid G
611805
attribute [to_additive] comm_group
612806
attribute [instance, priority 300] add_comm_group.to_add_comm_monoid
613807

808+
@[to_additive]
809+
lemma comm_group.to_group_injective {G : Type u} :
810+
function.injective (@comm_group.to_group G) :=
811+
begin
812+
rintros ⟨⟩ ⟨⟩ h,
813+
replace h := group.mk.inj h,
814+
dsimp at h,
815+
rcases h with ⟨rfl, rfl, rfl, rfl, rfl, rfl⟩,
816+
refl
817+
end
818+
819+
@[ext, to_additive]
820+
lemma comm_group.ext {G : Type*} ⦃g₁ g₂ : comm_group G⦄
821+
(h_mul : g₁.mul = g₂.mul) : g₁ = g₂ :=
822+
comm_group.to_group_injective $ group.ext h_mul
823+
824+
attribute [ext] add_comm_group.ext
825+
614826
section comm_group
615827

616828
variables {G : Type u} [comm_group G]

src/category_theory/preadditive/schur.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ variables [is_alg_closed 𝕜] [linear 𝕜 C]
8787
-- To get around this, we use `convert I`,
8888
-- then check the various instances agree field-by-field,
8989
-- using `ext` equipped with the following extra lemmas:
90-
local attribute [ext] add_comm_group module distrib_mul_action mul_action has_scalar
90+
local attribute [ext] module distrib_mul_action mul_action has_scalar
9191

9292
/--
9393
An auxiliary lemma for Schur's lemma.
@@ -109,7 +109,7 @@ begin
109109
{ intro f,
110110
haveI : nontrivial (End X) := nontrivial_of_ne _ _ id_nonzero,
111111
obtain ⟨c, nu⟩ := @exists_spectrum_of_is_alg_closed_of_finite_dimensional 𝕜 _ _ (End X) _ _ _
112-
(by { convert I, ext; refl, ext; refl, }) (End.of f),
112+
(by { convert I, ext, refl, ext, refl, }) (End.of f),
113113
use c,
114114
rw [is_unit_iff_is_iso, is_iso_iff_nonzero, ne.def, not_not, sub_eq_zero,
115115
algebra.algebra_map_eq_smul_one] at nu,

test/equiv_rw.lean

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,6 @@ begin
254254
end :=
255255
rfl
256256

257-
attribute [ext] semigroup
258-
259257
lemma semigroup.id_map (α : Type) : semigroup.map (equiv.refl α) = id :=
260258
by { ext, refl, }
261259

0 commit comments

Comments
 (0)