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

Commit 2c0fa82

Browse files
committed
feat(group_theory/free_product): the 🏓-lemma (#12210)
The Ping-Pong-Lemma. If a group action of `G` on `X` so that the `H i` acts in a specific way on disjoint subsets `X i` we can prove that `lift f` is injective, and thus the image of `lift f` is isomorphic to the free product of the `H i`. Often the Ping-Pong-Lemma is stated with regard to subgroups `H i` that generate the whole group; we generalize to arbitrary group homomorphisms `f i : H i →* G` and do not require the group to be generated by the images. Usually the Ping-Pong-Lemma requires that one group `H i` has at least three elements. This condition is only needed if `# ι = 2`, and we accept `3 ≤ # ι` as an alternative.
1 parent f549c10 commit 2c0fa82

File tree

1 file changed

+338
-5
lines changed

1 file changed

+338
-5
lines changed

src/group_theory/free_product.lean

Lines changed: 338 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ Authors: David Wärn
66
import algebra.free_monoid
77
import group_theory.congruence
88
import group_theory.is_free_group
9+
import group_theory.subgroup.pointwise
910
import data.list.chain
11+
import set_theory.cardinal
1012
/-!
1113
# The free product of groups or monoids
1214
@@ -25,6 +27,11 @@ groups).
2527
- `free_product.lift : (Π {i}, M i →* N) ≃ (free_product M →* N)`: the universal property.
2628
- `free_product.word M`: the type of reduced words.
2729
- `free_product.word.equiv M : free_product M ≃ word M`.
30+
- `free_product.neword M i j`: an inductive description of non-empty words with first letter from
31+
`M i` and last letter from `M j`, together with an API (`singleton`, `append`, `head`, `tail`,
32+
`to_word`, `prod`, `inv`). Used in the proof of the Ping-Pong-lemma.
33+
- `free_product.lift_injective_of_ping_pong`: The Ping-Pong-lemma, proving injectivity of the
34+
`lift`. See the documentation of that theorem for more information.
2835
2936
## Remarks
3037
@@ -138,8 +145,8 @@ begin
138145
end
139146

140147
lemma of_left_inverse [decidable_eq ι] (i : ι) :
141-
function.left_inverse (lift $ function.update 1 i (monoid_hom.id (M i))) of :=
142-
λ x, by simp only [lift_of, function.update_same, monoid_hom.id_apply]
148+
function.left_inverse (lift $ pi.mul_single i (monoid_hom.id (M i))) of :=
149+
λ x, by simp only [lift_of, pi.mul_single_eq_same, monoid_hom.id_apply]
143150

144151
lemma of_injective (i : ι) : function.injective ⇑(of : M i →* _) :=
145152
by { classical, exact (of_left_inverse i).injective }
@@ -182,7 +189,7 @@ instance : inhabited (word M) := ⟨empty⟩
182189
def prod (w : word M) : free_product M :=
183190
list.prod (w.to_list.map $ λ l, of l.snd)
184191

185-
@[simp] lemma prod_nil : prod (empty : word M) = 1 := rfl
192+
@[simp] lemma prod_empty : prod (empty : word M) = 1 := rfl
186193

187194
/-- `fst_idx w` is `some i` if the first letter of `w` is `⟨i, m⟩` with `m : M i`. If `w` is empty
188195
then it's `none`. -/
@@ -316,10 +323,10 @@ end
316323
def equiv : free_product M ≃ word M :=
317324
{ to_fun := λ m, m • empty,
318325
inv_fun := λ w, prod w,
319-
left_inv := λ m, by dsimp only; rw [prod_smul, prod_nil, mul_one],
326+
left_inv := λ m, by dsimp only; rw [prod_smul, prod_empty, mul_one],
320327
right_inv := begin
321328
apply smul_induction,
322-
{ dsimp only, rw [prod_nil, one_smul], },
329+
{ dsimp only, rw [prod_empty, one_smul], },
323330
{ dsimp only, intros i m w ih, rw [prod_smul, mul_smul, ih], },
324331
end }
325332

@@ -328,6 +335,332 @@ instance : decidable_eq (free_product M) := word.equiv.decidable_eq
328335

329336
end word
330337

338+
variable (M)
339+
340+
/-- A `neword M i j` is a representation of a non-empty reduced words where the first letter comes
341+
from `M i` and the last letter comes from `M j`. It can be constructed from singletons and via
342+
concatentation, and thus provides a useful induction principle. -/
343+
@[nolint has_inhabited_instance]
344+
inductive neword : ι → ι → Type (max u_1 u_2)
345+
| singleton : ∀ {i} (x : M i) (hne1 : x ≠ 1), neword i i
346+
| append : ∀ {i j k l} (w₁ : neword i j) (hne : j ≠ k) (w₂ : neword k l), neword i l
347+
variable {M}
348+
349+
namespace neword
350+
351+
open word
352+
353+
/-- The list represented by a given `neword` -/
354+
@[simp]
355+
def to_list : Π {i j} (w : neword M i j), list (Σ i, M i)
356+
| i _ (singleton x hne1) := [⟨i, x⟩]
357+
| _ _ (append w₁ hne w₂) := w₁.to_list ++ w₂.to_list
358+
359+
lemma to_list_ne_nil {i j} (w : neword M i j) : w.to_list ≠ list.nil :=
360+
by { induction w, { rintros ⟨rfl⟩ }, { apply list.append_ne_nil_of_ne_nil_left, assumption } }
361+
362+
/-- The first letter of a `neword` -/
363+
@[simp]
364+
def head : Π {i j} (w : neword M i j), M i
365+
| i _ (singleton x hne1) := x
366+
| _ _ (append w₁ hne w₂) := w₁.head
367+
368+
/-- The last letter of a `neword` -/
369+
@[simp]
370+
def last : Π {i j} (w : neword M i j), M j
371+
| i _ (singleton x hne1) := x
372+
| _ _ (append w₁ hne w₂) := w₂.last
373+
374+
@[simp]
375+
lemma to_list_head' {i j} (w : neword M i j) :
376+
w.to_list.head' = option.some ⟨i, w.head⟩ :=
377+
begin
378+
rw ← option.mem_def,
379+
induction w,
380+
{ rw option.mem_def, reflexivity, },
381+
{ exact list.head'_append w_ih_w₁, },
382+
end
383+
384+
@[simp]
385+
lemma to_list_last' {i j} (w : neword M i j) :
386+
w.to_list.last' = option.some ⟨j, w.last⟩ :=
387+
begin
388+
rw ← option.mem_def,
389+
induction w,
390+
{ rw option.mem_def, reflexivity, },
391+
{ exact list.last'_append w_ih_w₂, },
392+
end
393+
394+
/-- The `word M` represented by a `neword M i j` -/
395+
def to_word {i j} (w : neword M i j) : word M :=
396+
{ to_list := w.to_list,
397+
ne_one :=
398+
begin
399+
induction w,
400+
{ rintros ⟨k,x⟩ ⟨rfl, rfl⟩,
401+
exact w_hne1,
402+
exfalso, apply H, },
403+
{ intros l h,
404+
simp only [to_list, list.mem_append] at h,
405+
cases h,
406+
{ exact w_ih_w₁ _ h, },
407+
{ exact w_ih_w₂ _ h, }, },
408+
end,
409+
chain_ne := begin
410+
induction w,
411+
{ exact list.chain'_singleton _, },
412+
{ apply list.chain'.append w_ih_w₁ w_ih_w₂,
413+
intros x hx y hy,
414+
rw [w_w₁.to_list_last', option.mem_some_iff] at hx,
415+
rw [w_w₂.to_list_head', option.mem_some_iff] at hy,
416+
subst hx, subst hy,
417+
exact w_hne, },
418+
end, }
419+
420+
/-- Every nonempty `word M` can be constructed as a `neword M i j` -/
421+
lemma of_word (w : word M) (h : w ≠ empty) :
422+
∃ i j (w' : neword M i j), w'.to_word = w :=
423+
begin
424+
suffices : ∃ i j (w' : neword M i j), w'.to_word.to_list = w.to_list,
425+
{ obtain ⟨i, j, w, h⟩ := this, refine ⟨i, j, w, _⟩, ext, rw h, },
426+
cases w with l hnot1 hchain,
427+
induction l with x l hi,
428+
{ contradiction, },
429+
{ rw list.forall_mem_cons at hnot1,
430+
cases l with y l,
431+
{ refine ⟨x.1, x.1, singleton x.2 hnot1.1, _ ⟩,
432+
simp [to_word], },
433+
{ rw list.chain'_cons at hchain,
434+
specialize hi hnot1.2 hchain.2 (by rintros ⟨rfl⟩),
435+
obtain ⟨i, j, w', hw' : w'.to_list = y :: l⟩ := hi,
436+
obtain rfl : y = ⟨i, w'.head⟩, by simpa [hw'] using w'.to_list_head',
437+
refine ⟨x.1, j, append (singleton x.2 hnot1.1) hchain.1 w', _⟩,
438+
{ simpa [to_word] using hw', } } }
439+
end
440+
441+
/-- A non-empty reduced word determines an element of the free product, given by multiplication. -/
442+
def prod {i j} (w : neword M i j) := w.to_word.prod
443+
444+
@[simp]
445+
lemma singleton_head {i} (x : M i) (hne_one : x ≠ 1) :
446+
(singleton x hne_one).head = x := rfl
447+
448+
@[simp]
449+
lemma singleton_last {i} (x : M i) (hne_one : x ≠ 1) :
450+
(singleton x hne_one).last = x := rfl
451+
452+
@[simp] lemma prod_singleton {i} (x : M i) (hne_one : x ≠ 1) :
453+
(singleton x hne_one).prod = of x :=
454+
by simp [to_word, prod, word.prod]
455+
456+
@[simp]
457+
lemma append_head {i j k l} {w₁ : neword M i j} {hne : j ≠ k} {w₂ : neword M k l} :
458+
(append w₁ hne w₂).head = w₁.head := rfl
459+
460+
@[simp]
461+
lemma append_last {i j k l} {w₁ : neword M i j} {hne : j ≠ k} {w₂ : neword M k l} :
462+
(append w₁ hne w₂).last = w₂.last := rfl
463+
464+
@[simp]
465+
lemma append_prod {i j k l} {w₁ : neword M i j} {hne : j ≠ k} {w₂ : neword M k l} :
466+
(append w₁ hne w₂).prod = w₁.prod * w₂.prod :=
467+
by simp [to_word, prod, word.prod]
468+
469+
/-- One can replace the first letter in a non-empty reduced word by an element of the same
470+
group -/
471+
def replace_head : Π {i j : ι} (x : M i) (hnotone : x ≠ 1) (w : neword M i j), neword M i j
472+
| _ _ x h (singleton _ _) := singleton x h
473+
| _ _ x h (append w₁ hne w₂) := append (replace_head x h w₁) hne w₂
474+
475+
@[simp]
476+
lemma replace_head_head {i j : ι} (x : M i) (hnotone : x ≠ 1) (w : neword M i j) :
477+
(replace_head x hnotone w).head = x :=
478+
by { induction w, refl, exact w_ih_w₁ _ _, }
479+
480+
/-- One can multiply an element from the left to a non-empty reduced word if it does not cancel
481+
with the first element in the word. -/
482+
def mul_head {i j : ι} (w : neword M i j) (x : M i) (hnotone : x * w.head ≠ 1) :
483+
neword M i j := replace_head (x * w.head) hnotone w
484+
485+
@[simp]
486+
lemma mul_head_head {i j : ι} (w : neword M i j) (x : M i) (hnotone : x * w.head ≠ 1) :
487+
(mul_head w x hnotone).head = x * w.head :=
488+
by { induction w, refl, exact w_ih_w₁ _ _, }
489+
490+
@[simp]
491+
lemma mul_head_prod {i j : ι} (w : neword M i j) (x : M i) (hnotone : x * w.head ≠ 1) :
492+
(mul_head w x hnotone).prod = of x * w.prod :=
493+
begin
494+
unfold mul_head,
495+
induction w,
496+
{ simp [mul_head, replace_head], },
497+
{ specialize w_ih_w₁ _ hnotone, clear w_ih_w₂,
498+
simp [replace_head, ← mul_assoc] at *,
499+
congr' 1, }
500+
end
501+
502+
section group
503+
504+
variables {G : ι → Type*} [Π i, group (G i)]
505+
506+
/-- The inverse of a non-empty reduced word -/
507+
def inv : Π {i j} (w : neword G i j), neword G j i
508+
| _ _ (singleton x h) := singleton x⁻¹ (mt inv_eq_one.mp h)
509+
| _ _ (append w₁ h w₂) := append w₂.inv h.symm w₁.inv
510+
511+
@[simp]
512+
lemma inv_prod {i j} (w : neword G i j) : w.inv.prod = w.prod⁻¹ :=
513+
by induction w; simp [inv, *]
514+
515+
@[simp]
516+
lemma inv_head {i j} (w : neword G i j) : w.inv.head = w.last⁻¹ :=
517+
by induction w; simp [inv, *]
518+
519+
@[simp]
520+
lemma inv_last {i j} (w : neword G i j) : w.inv.last = w.head⁻¹ :=
521+
by induction w; simp [inv, *]
522+
523+
end group
524+
525+
end neword
526+
527+
section ping_pong_lemma
528+
529+
open_locale pointwise
530+
open_locale cardinal
531+
532+
variables [hnontriv : nontrivial ι]
533+
variables {G : Type*} [group G]
534+
variables {H : ι → Type*} [∀ i, group (H i)]
535+
variables (f : Π i, H i →* G)
536+
537+
-- We need many groups or one group with many elements
538+
variables (hcard : 3 ≤ # ι ∨ ∃ i, 3 ≤ # (H i))
539+
540+
-- A group action on α, and the ping-pong sets
541+
variables {α : Type*} [mul_action G α]
542+
variables (X : ι → set α)
543+
variables (hXnonempty : ∀ i, (X i).nonempty)
544+
variables (hXdisj : pairwise (λ i j, disjoint (X i) (X j)))
545+
variables (hpp : pairwise (λ i j, ∀ h : H i, h ≠ 1 → f i h • X j ⊆ X i))
546+
547+
include hpp
548+
549+
lemma lift_word_ping_pong {i j k} (w : neword H i j) (hk : j ≠ k) :
550+
lift f w.prod • X k ⊆ X i :=
551+
begin
552+
rename [i → i', j → j', k → m, hk → hm],
553+
induction w with i x hne_one i j k l w₁ hne w₂ hIw₁ hIw₂ generalizing m; clear i' j',
554+
{ simpa using hpp _ _ hm _ hne_one, },
555+
{ calc lift f (neword.append w₁ hne w₂).prod • X m
556+
= lift f w₁.prod • lift f w₂.prod • X m : by simp [mul_action.mul_smul]
557+
... ⊆ lift f w₁.prod • X k : set_smul_subset_set_smul_iff.mpr (hIw₂ hm)
558+
... ⊆ X i : hIw₁ hne },
559+
end
560+
561+
include X hXnonempty hXdisj
562+
563+
lemma lift_word_prod_nontrivial_of_other_i {i j k} (w : neword H i j)
564+
(hhead : k ≠ i) (hlast : k ≠ j) : lift f w.prod ≠ 1 :=
565+
begin
566+
intro heq1,
567+
have : X k ⊆ X i,
568+
by simpa [heq1] using lift_word_ping_pong f X hpp w hlast.symm,
569+
obtain ⟨x, hx⟩ := hXnonempty k,
570+
exact hXdisj k i hhead ⟨hx, this hx⟩,
571+
end
572+
573+
include hnontriv
574+
575+
lemma lift_word_prod_nontrivial_of_head_eq_last {i} (w : neword H i i) :
576+
lift f w.prod ≠ 1 :=
577+
begin
578+
obtain ⟨k, hk⟩ := exists_ne i,
579+
exact lift_word_prod_nontrivial_of_other_i f X hXnonempty hXdisj hpp w hk hk,
580+
end
581+
582+
lemma lift_word_prod_nontrivial_of_head_card {i j} (w : neword H i j)
583+
(hcard : 3 ≤ # (H i)) (hheadtail : i ≠ j) : lift f w.prod ≠ 1 :=
584+
begin
585+
obtain ⟨h, hn1, hnh⟩ := cardinal.three_le hcard 1 (w.head⁻¹),
586+
have hnot1 : h * w.head ≠ 1, by { rw ← div_inv_eq_mul, exact div_ne_one_of_ne hnh },
587+
let w' : neword H i i := neword.append
588+
(neword.mul_head w h hnot1) hheadtail.symm
589+
(neword.singleton h⁻¹ (inv_ne_one.mpr hn1)),
590+
have hw' : lift f w'.prod ≠ 1 :=
591+
lift_word_prod_nontrivial_of_head_eq_last f X hXnonempty hXdisj hpp w',
592+
intros heq1, apply hw', simp [w', heq1]
593+
end
594+
595+
include hcard
596+
lemma lift_word_prod_nontrivial_of_not_empty {i j} (w : neword H i j) :
597+
lift f w.prod ≠ 1 :=
598+
begin
599+
classical,
600+
cases hcard,
601+
{ obtain ⟨i, h1, h2⟩ := cardinal.three_le hcard i j,
602+
exact lift_word_prod_nontrivial_of_other_i f X hXnonempty hXdisj hpp w h1 h2, },
603+
{ cases hcard with k hcard,
604+
by_cases hh : i = k; by_cases hl : j = k,
605+
{ subst hh, subst hl,
606+
exact lift_word_prod_nontrivial_of_head_eq_last f X hXnonempty hXdisj hpp w, },
607+
{ subst hh,
608+
change j ≠ i at hl,
609+
exact lift_word_prod_nontrivial_of_head_card f X hXnonempty hXdisj hpp w hcard hl.symm, },
610+
{ subst hl,
611+
change i ≠ j at hh,
612+
have : lift f w.inv.prod ≠ 1 :=
613+
lift_word_prod_nontrivial_of_head_card f X hXnonempty hXdisj hpp w.inv hcard hh.symm,
614+
intros heq, apply this, simpa using heq, },
615+
{ change i ≠ k at hh,
616+
change j ≠ k at hl,
617+
obtain ⟨h, hn1, -⟩ := cardinal.three_le hcard 1 1,
618+
let w' : neword H k k := neword.append
619+
(neword.append (neword.singleton h hn1) hh.symm w)
620+
hl (neword.singleton h⁻¹ (inv_ne_one.mpr hn1)) ,
621+
have hw' : lift f w'.prod ≠ 1 :=
622+
lift_word_prod_nontrivial_of_head_eq_last f X hXnonempty hXdisj hpp w',
623+
intros heq1, apply hw', simp [w', heq1], }, }
624+
end
625+
626+
lemma empty_of_word_prod_eq_one {w : word H} (h : lift f w.prod = 1) :
627+
w = word.empty :=
628+
begin
629+
by_contradiction hnotempty,
630+
obtain ⟨i, j, w, rfl⟩ := neword.of_word _ hnotempty,
631+
exact lift_word_prod_nontrivial_of_not_empty f hcard X hXnonempty hXdisj hpp w h,
632+
end
633+
634+
/--
635+
The Ping-Pong-Lemma.
636+
637+
Given a group action of `G` on `X` so that the `H i` acts in a specific way on disjoint subsets
638+
`X i` we can prove that `lift f` is injective, and thus the image of `lift f` is isomorphic to the
639+
direct product of the `H i`.
640+
641+
Often the Ping-Pong-Lemma is stated with regard to subgroups `H i` that generate the whole group;
642+
we generalize to arbitrary group homomorphisms `f i : H i →* G` and do not require the group to be
643+
generated by the images.
644+
645+
Usually the Ping-Pong-Lemma requires that one group `H i` has at least three elements. This
646+
condition is only needed if `# ι = 2`, and we accept `3 ≤ # ι` as an alternative.
647+
-/
648+
theorem lift_injective_of_ping_pong:
649+
function.injective (lift f) :=
650+
begin
651+
classical,
652+
apply (monoid_hom.injective_iff (lift f)).mpr,
653+
rw free_product.word.equiv.forall_congr_left',
654+
{ intros w Heq,
655+
dsimp [word.equiv] at *,
656+
{ rw empty_of_word_prod_eq_one f hcard X hXnonempty hXdisj hpp Heq,
657+
reflexivity, }, },
658+
apply_instance,
659+
apply_instance,
660+
end
661+
662+
end ping_pong_lemma
663+
331664
/-- The free product of free groups is itself a free group -/
332665
@[simps]
333666
instance {ι : Type*} (G : ι → Type*) [∀ i, group (G i)] [hG : ∀ i, is_free_group (G i)] :

0 commit comments

Comments
 (0)