/- Copyright (c) 2016 Andrew Zipperer. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Andrew Zipperer, Jeremy Avigad Basic group theory: subgroups, homomorphisms on a set, homomorphic images, cosets, normal cosets and the normalizer, the kernel of a homomorphism, the centralizer, etc. For notation a * S and S * a for cosets, open the namespace "coset_notation". For notation a^b and S^a, open the namespace "conj_notation". TODO: homomorphisms on sets should be refactored and moved to algebra. -/ import data.set algebra.homomorphism theories.topology.basic theories.move open eq.ops set function namespace group_theory variables {A B C : Type} /- subgroups -/ structure is_one_closed [class] [has_one A] (S : set A) : Prop := (one_mem : one ∈ S) proposition one_mem [has_one A] {S : set A} [is_one_closed S] : 1 ∈ S := is_one_closed.one_mem _ S structure is_mul_closed [class] [has_mul A] (S : set A) : Prop := (mul_mem : ∀₀ a ∈ S, ∀₀ b ∈ S, a * b ∈ S) proposition mul_mem [has_mul A] {S : set A} [is_mul_closed S] {a b : A} (aS : a ∈ S) (bS : b ∈ S) : a * b ∈ S := is_mul_closed.mul_mem _ S aS bS structure is_inv_closed [class] [has_inv A] (S : set A) : Prop := (inv_mem : ∀₀ a ∈ S, a⁻¹ ∈ S) proposition inv_mem [has_inv A] {S : set A} [is_inv_closed S] {a : A} (aS : a ∈ S) : a⁻¹ ∈ S := is_inv_closed.inv_mem _ S aS structure is_subgroup [class] [group A] (S : set A) extends is_one_closed S, is_mul_closed S, is_inv_closed S : Prop section groupA variable [group A] proposition mem_of_inv_mem {a : A} {S : set A} [is_subgroup S] (H : a⁻¹ ∈ S) : a ∈ S := have (a⁻¹)⁻¹ ∈ S, from inv_mem H, by rewrite inv_inv at this; apply this proposition inv_mem_iff (a : A) (S : set A) [is_subgroup S] : a⁻¹ ∈ S ↔ a ∈ S := iff.intro mem_of_inv_mem inv_mem proposition is_subgroup_univ [instance] : is_subgroup (@univ A) := ⦃ is_subgroup, one_mem := trivial, mul_mem := λ a au b bu, trivial, inv_mem := λ a au, trivial ⦄ proposition is_subgroup_inter [instance] (G H : set A) [is_subgroup G] [is_subgroup H] : is_subgroup (G ∩ H) := ⦃ is_subgroup, one_mem := and.intro one_mem one_mem, mul_mem := λ a ai b bi, and.intro (mul_mem (and.left ai) (and.left bi)) (mul_mem (and.right ai) (and.right bi)), inv_mem := λ a ai, and.intro (inv_mem (and.left ai)) (inv_mem (and.right ai)) ⦄ end groupA /- homomorphisms on sets -/ section has_mulABC variables [has_mul A] [has_mul B] [has_mul C] -- in group theory, we can use is_hom for is_mul_hom abbreviation is_hom := @is_mul_hom definition is_hom_on [class] (f : A → B) (S : set A) : Prop := ∀₀ a₁ ∈ S, ∀₀ a₂ ∈ S, f (a₁ * a₂) = f a₁ * f a₂ proposition hom_on_mul (f : A → B) {S : set A} [H : is_hom_on f S] {a₁ a₂ : A} (a₁S : a₁ ∈ S) (a₂S : a₂ ∈ S) : f (a₁ * a₂) = (f a₁) * (f a₂) := H a₁S a₂S proposition is_hom_on_of_is_hom (f : A → B) (S : set A) [H : is_hom f] : is_hom_on f S := forallb_of_forall₂ S S (hom_mul f) proposition is_hom_of_is_hom_on_univ (f : A → B) [H : is_hom_on f univ] : is_hom f := is_mul_hom.mk (forall_of_forallb_univ₂ H) proposition is_hom_on_univ_iff (f : A → B) : is_hom_on f univ ↔ is_hom f := iff.intro (λH, is_hom_of_is_hom_on_univ f) (λ H, is_hom_on_of_is_hom f univ) proposition is_hom_on_of_subset (f : A → B) {S T : set A} (ssubt : S ⊆ T) [H : is_hom_on f T] : is_hom_on f S := forallb_of_subset₂ ssubt ssubt H proposition is_hom_on_id (S : set A) : is_hom_on id S := have H : is_hom (@id A), from is_mul_hom_id, is_hom_on_of_is_hom id S proposition is_hom_on_comp {S : set A} {T : set B} {g : B → C} {f : A → B} (H₁ : is_hom_on f S) (H₂ : is_hom_on g T) (H₃ : maps_to f S T) : is_hom_on (g ∘ f) S := take a₁, assume a₁S, take a₂, assume a₂S, have f a₁ ∈ T, from H₃ a₁S, have f a₂ ∈ T, from H₃ a₂S, show g (f (a₁ * a₂)) = g (f a₁) * g (f a₂), by rewrite [H₁ a₁S a₂S, H₂ `f a₁ ∈ T` `f a₂ ∈ T`] end has_mulABC section groupAB variables [group A] [group B] proposition hom_on_one (f : A → B) (G : set A) [is_subgroup G] [H : is_hom_on f G] : f 1 = 1 := have f 1 * f 1 = f 1 * 1, by rewrite [-H one_mem one_mem, *mul_one], eq_of_mul_eq_mul_left' this proposition hom_on_inv (f : A → B) {G : set A} [is_subgroup G] [H : is_hom_on f G] {a : A} (aG : a ∈ G) : f a⁻¹ = (f a)⁻¹ := have f a⁻¹ * f a = 1, by rewrite [-H (inv_mem aG) aG, mul.left_inv, hom_on_one f G], eq_inv_of_mul_eq_one this proposition is_subgroup_image [instance] (f : A → B) (G : set A) [is_subgroup G] [is_hom_on f G] : is_subgroup (f ' G) := ⦃ is_subgroup, one_mem := mem_image one_mem (hom_on_one f G), mul_mem := λ a afG b bfG, obtain c (cG : c ∈ G)(Hc : f c = a), from afG, obtain d (dG : d ∈ G)(Hd : f d = b), from bfG, show a * b ∈ f ' G, from mem_image (mul_mem cG dG) (by rewrite [hom_on_mul f cG dG, Hc, Hd]), inv_mem := λ a afG, obtain c (cG : c ∈ G)(Hc : f c = a), from afG, show a⁻¹ ∈ f ' G, from mem_image (inv_mem cG) (by rewrite [hom_on_inv f cG, Hc]) ⦄ end groupAB /- cosets -/ definition lcoset [has_mul A] (a : A) (N : set A) : set A := (mul a) 'N definition rcoset [has_mul A] (N : set A) (a : A) : set A := (mul^~ a) 'N -- overload multiplication namespace coset_notation infix * := lcoset infix * := rcoset end coset_notation open coset_notation section has_mulA variable [has_mul A] proposition mul_mem_lcoset {S : set A} {x : A} (a : A) (xS : x ∈ S) : a * x ∈ a * S := mem_image_of_mem (mul a) xS proposition mul_mem_rcoset [has_mul A] {S : set A} {x : A} (xS : x ∈ S) (a : A) : x * a ∈ S * a := mem_image_of_mem (mul^~ a) xS definition lcoset_equiv (S : set A) (a b : A) : Prop := a * S = b * S proposition equivalence_lcoset_equiv (S : set A) : equivalence (lcoset_equiv S) := mk_equivalence (lcoset_equiv S) (λ a, rfl) (λ a b, !eq.symm) (λ a b c, !eq.trans) proposition lcoset_subset_lcoset {S T : set A} (a : A) (H : S ⊆ T) : a * S ⊆ a * T := image_subset _ H proposition rcoset_subset_rcoset {S T : set A} (H : S ⊆ T) (a : A) : S * a ⊆ T * a := image_subset _ H proposition image_lcoset_of_is_hom_on {B : Type} [has_mul B] {f : A → B} {S : set A} {a : A} {G : set A} (SsubG : S ⊆ G) (aG : a ∈ G) [is_hom_on f G] : f ' (a * S) = f a * f ' S := ext (take x, iff.intro (assume fas : x ∈ f ' (a * S), obtain t [s (sS : s ∈ S) (seq : a * s = t)] (teq : f t = x), from fas, have x = f a * f s, by rewrite [-teq, -seq, hom_on_mul f aG (SsubG sS)], show x ∈ f a * f ' S, by rewrite this; apply mul_mem_lcoset _ (mem_image_of_mem _ sS)) (assume fafs : x ∈ f a * f ' S, obtain t [s (sS : s ∈ S) (seq : f s = t)] (teq : f a * t = x), from fafs, have x = f (a * s), by rewrite [-teq, -seq, hom_on_mul f aG (SsubG sS)], show x ∈ f ' (a * S), by rewrite this; exact mem_image_of_mem _ (mul_mem_lcoset _ sS))) proposition image_rcoset_of_is_hom_on {B : Type} [has_mul B] {f : A → B} {S : set A} {a : A} {G : set A} (SsubG : S ⊆ G) (aG : a ∈ G) [is_hom_on f G] : f ' (S * a) = f ' S * f a := ext (take x, iff.intro (assume fas : x ∈ f ' (S * a), obtain t [s (sS : s ∈ S) (seq : s * a = t)] (teq : f t = x), from fas, have x = f s * f a, by rewrite [-teq, -seq, hom_on_mul f (SsubG sS) aG], show x ∈ f ' S * f a, by rewrite this; exact mul_mem_rcoset (mem_image_of_mem _ sS) _) (assume fafs : x ∈ f ' S * f a, obtain t [s (sS : s ∈ S) (seq : f s = t)] (teq : t * f a = x), from fafs, have x = f (s * a), by rewrite [-teq, -seq, hom_on_mul f (SsubG sS) aG], show x ∈ f ' (S * a), by rewrite this; exact mem_image_of_mem _ (mul_mem_rcoset sS _))) proposition image_lcoset_of_is_hom {B : Type} [has_mul B] (f : A → B) (a : A) (S : set A) [is_hom f] : f ' (a * S) = f a * f ' S := have is_hom_on f univ, from is_hom_on_of_is_hom f univ, image_lcoset_of_is_hom_on (subset_univ S) !mem_univ proposition image_rcoset_of_is_hom {B : Type} [has_mul B] (f : A → B) (S : set A) (a : A) [is_hom f] : f ' (S * a) = f ' S * f a := have is_hom_on f univ, from is_hom_on_of_is_hom f univ, image_rcoset_of_is_hom_on (subset_univ S) !mem_univ end has_mulA section semigroupA variable [semigroup A] proposition rcoset_rcoset (S : set A) (a b : A) : S * a * b = S * (a * b) := have H : (mul^~ b) ∘ (mul^~ a) = mul^~ (a * b), from funext (take x, !mul.assoc), calc S * a * b = ((mul^~ b) ∘ (mul^~ a)) 'S : image_comp ... = S * (a * b) : by rewrite [↑rcoset, H] proposition lcoset_lcoset (S : set A) (a b : A) : a * (b * S) = (a * b) * S := have H : (mul a) ∘ (mul b) = mul (a * b), from funext (take x, !mul.assoc⁻¹), calc a * (b * S) = ((mul a) ∘ (mul b)) 'S : image_comp ... = (a * b) * S : by rewrite [↑lcoset, H] proposition lcoset_rcoset [semigroup A] (S : set A) (a b : A) : a * S * b = a * (S * b) := have H : (mul^~ b) ∘ (mul a) = (mul a) ∘ (mul^~ b), from funext (take x, !mul.assoc), calc a * S * b = ((mul^~ b) ∘ (mul a)) 'S : image_comp ... = ((mul a) ∘ (mul^~ b)) 'S : H ... = a * (S * b) : image_comp end semigroupA section monoidA variable [monoid A] proposition one_lcoset (S : set A) : 1 * S = S := ext (take x, iff.intro (suppose x ∈ 1 * S, obtain s (sS : s ∈ S) (eqx : 1 * s = x), from this, show x ∈ S, by rewrite [-eqx, one_mul]; apply sS) (suppose x ∈ S, have 1 * x ∈ 1 * S, from mem_image_of_mem (mul 1) this, show x ∈ 1 * S, by rewrite one_mul at this; apply this)) proposition rcoset_one (S : set A) : S * 1 = S := ext (take x, iff.intro (suppose x ∈ S * 1, obtain s (sS : s ∈ S) (eqx : s * 1 = x), from this, show x ∈ S, by rewrite [-eqx, mul_one]; apply sS) (suppose x ∈ S, have x * 1 ∈ S * 1, from mem_image_of_mem (mul^~ 1) this, show x ∈ S * 1, by rewrite mul_one at this; apply this)) end monoidA section groupA variable [group A] proposition lcoset_inv_lcoset (a : A) (S : set A) : a * (a⁻¹ * S) = S := by rewrite [lcoset_lcoset, mul.right_inv, one_lcoset] proposition inv_lcoset_lcoset (a : A) (S : set A) : a⁻¹ * (a * S) = S := by rewrite [lcoset_lcoset, mul.left_inv, one_lcoset] proposition rcoset_inv_rcoset (S : set A) (a : A) : (S * a⁻¹) * a = S := by rewrite [rcoset_rcoset, mul.left_inv, rcoset_one] proposition rcoset_rcoset_inv (S : set A) (a : A) : (S * a) * a⁻¹ = S := by rewrite [rcoset_rcoset, mul.right_inv, rcoset_one] proposition eq_of_lcoset_eq_lcoset {a : A} {S T : set A} (H : a * S = a * T) : S = T := by rewrite [-inv_lcoset_lcoset a S, -inv_lcoset_lcoset a T, H] proposition eq_of_rcoset_eq_rcoset {a : A} {S T : set A} (H : S * a = T * a) : S = T := by rewrite [-rcoset_rcoset_inv S a, -rcoset_rcoset_inv T a, H] proposition mem_of_mul_mem_lcoset {a b : A} {S : set A} (abaS : a * b ∈ a * S) : b ∈ S := have a⁻¹ * (a * b) ∈ a⁻¹ * (a * S), from mul_mem_lcoset _ abaS, by rewrite [inv_mul_cancel_left at this, inv_lcoset_lcoset at this]; apply this proposition mul_mem_lcoset_iff (a b : A) (S : set A) : a * b ∈ a * S ↔ b ∈ S := iff.intro !mem_of_mul_mem_lcoset !mul_mem_lcoset proposition mem_of_mul_mem_rcoset {a b : A} {S : set A} (abSb : a * b ∈ S * b) : a ∈ S := have (a * b) * b⁻¹ ∈ (S * b) * b⁻¹, from mul_mem_rcoset abSb _, by rewrite [mul_inv_cancel_right at this, rcoset_rcoset_inv at this]; apply this proposition mul_mem_rcoset_iff (a b : A) (S : set A) : a * b ∈ S * b ↔ a ∈ S := iff.intro !mem_of_mul_mem_rcoset (λ H, mul_mem_rcoset H _) proposition inv_mul_mem_of_mem_lcoset {a b : A} {S : set A} (abS : a ∈ b * S) : b⁻¹ * a ∈ S := have b⁻¹ * a ∈ b⁻¹ * (b * S), from mul_mem_lcoset b⁻¹ abS, by rewrite inv_lcoset_lcoset at this; apply this proposition mem_lcoset_of_inv_mul_mem {a b : A} {S : set A} (H : b⁻¹ * a ∈ S) : a ∈ b * S := have b * (b⁻¹ * a) ∈ b * S, from mul_mem_lcoset b H, by rewrite mul_inv_cancel_left at this; apply this proposition mem_lcoset_iff (a b : A) (S : set A) : a ∈ b * S ↔ b⁻¹ * a ∈ S := iff.intro inv_mul_mem_of_mem_lcoset mem_lcoset_of_inv_mul_mem proposition mul_inv_mem_of_mem_rcoset {a b : A} {S : set A} (aSb : a ∈ S * b) : a * b⁻¹ ∈ S := have a * b⁻¹ ∈ (S * b) * b⁻¹, from mul_mem_rcoset aSb b⁻¹, by rewrite rcoset_rcoset_inv at this; apply this proposition mem_rcoset_of_mul_inv_mem {a b : A} {S : set A} (H : a * b⁻¹ ∈ S) : a ∈ S * b := have a * b⁻¹ * b ∈ S * b, from mul_mem_rcoset H b, by rewrite inv_mul_cancel_right at this; apply this proposition mem_rcoset_iff (a b : A) (S : set A) : a ∈ S * b ↔ a * b⁻¹ ∈ S := iff.intro mul_inv_mem_of_mem_rcoset mem_rcoset_of_mul_inv_mem proposition lcoset_eq_iff_eq_inv_lcoset (a : A) (S T : set A) : (a * S = T) ↔ (S = a⁻¹ * T) := iff.intro (assume H, by rewrite [-H, inv_lcoset_lcoset]) (assume H, by rewrite [H, lcoset_inv_lcoset]) proposition rcoset_eq_iff_eq_rcoset_inv (a : A) (S T : set A) : (S * a = T) ↔ (S = T * a⁻¹) := iff.intro (assume H, by rewrite [-H, rcoset_rcoset_inv]) (assume H, by rewrite [H, rcoset_inv_rcoset]) proposition lcoset_inter (a : A) (S T : set A) [is_subgroup S] [is_subgroup T] : a * (S ∩ T) = (a * S) ∩ (a * T) := eq_of_subset_of_subset (image_inter_subset _ S T) (take b, suppose b ∈ (a * S) ∩ (a * T), obtain [s [smem (seq : a * s = b)]] [t [tmem (teq : a * t = b)]], from this, have s = t, from eq_of_mul_eq_mul_left' (eq.trans seq (eq.symm teq)), show b ∈ a * (S ∩ T), begin rewrite -seq, apply mul_mem_lcoset, apply and.intro smem, rewrite this, apply tmem end) proposition inter_rcoset (a : A) (S T : set A) [is_subgroup S] [is_subgroup T] : (S ∩ T) * a = (S * a) ∩ (T * a) := eq_of_subset_of_subset (image_inter_subset _ S T) (take b, suppose b ∈ (S * a) ∩ (T * a), obtain [s [smem (seq : s * a = b)]] [t [tmem (teq : t * a = b)]], from this, have s = t, from eq_of_mul_eq_mul_right' (eq.trans seq (eq.symm teq)), show b ∈ (S ∩ T) * a, begin rewrite -seq, apply mul_mem_rcoset, apply and.intro smem, rewrite this, apply tmem end) end groupA section subgroupG variables [group A] {G : set A} [is_subgroup G] proposition lcoset_eq_self_of_mem {a : A} (aG : a ∈ G) : a * G = G := ext (take x, iff.intro (assume xaG, obtain g [gG xeq], from xaG, show x ∈ G, by rewrite -xeq; exact (mul_mem aG gG)) (assume xG, show x ∈ a * G, from mem_image (show a⁻¹ * x ∈ G, from (mul_mem (inv_mem aG) xG)) !mul_inv_cancel_left)) proposition rcoset_eq_self_of_mem {a : A} (aG : a ∈ G) : G * a = G := ext (take x, iff.intro (assume xGa, obtain g [gG xeq], from xGa, show x ∈ G, by rewrite -xeq; exact (mul_mem gG aG)) (assume xG, show x ∈ G * a, from mem_image (show x * a⁻¹ ∈ G, from (mul_mem xG (inv_mem aG))) !inv_mul_cancel_right)) proposition mem_lcoset_self (a : A) : a ∈ a * G := by rewrite [-mul_one a at {1}]; exact mul_mem_lcoset a one_mem proposition mem_rcoset_self (a : A) : a ∈ G * a := by rewrite [-one_mul a at {1}]; exact mul_mem_rcoset one_mem a proposition mem_of_lcoset_eq_self {a : A} (H : a * G = G) : a ∈ G := by rewrite [-H]; exact mem_lcoset_self a proposition mem_of_rcoset_eq_self {a : A} (H : G * a = G) : a ∈ G := by rewrite [-H]; exact mem_rcoset_self a variable (G) proposition lcoset_eq_self_iff (a : A) : a * G = G ↔ a ∈ G := iff.intro mem_of_lcoset_eq_self lcoset_eq_self_of_mem proposition rcoset_eq_self_iff (a : A) : G * a = G ↔ a ∈ G := iff.intro mem_of_rcoset_eq_self rcoset_eq_self_of_mem variable {G} proposition lcoset_eq_lcoset {a b : A} (H : b⁻¹ * a ∈ G) : a * G = b * G := have b⁻¹ * (a * G) = b⁻¹ * (b * G), by rewrite [inv_lcoset_lcoset, lcoset_lcoset, lcoset_eq_self_of_mem H], eq_of_lcoset_eq_lcoset this proposition inv_mul_mem_of_lcoset_eq_lcoset {a b : A} (H : a * G = b * G) : b⁻¹ * a ∈ G := mem_of_lcoset_eq_self (by rewrite [-lcoset_lcoset, H, inv_lcoset_lcoset]) proposition lcoset_eq_lcoset_iff (a b : A) : a * G = b * G ↔ b⁻¹ * a ∈ G := iff.intro inv_mul_mem_of_lcoset_eq_lcoset lcoset_eq_lcoset proposition rcoset_eq_rcoset {a b : A} (H : a * b⁻¹ ∈ G) : G * a = G * b := have G * a * b⁻¹ = G * b * b⁻¹, by rewrite [rcoset_rcoset_inv, rcoset_rcoset, rcoset_eq_self_of_mem H], eq_of_rcoset_eq_rcoset this proposition mul_inv_mem_of_rcoset_eq_rcoset {a b : A} (H : G * a = G * b) : a * b⁻¹ ∈ G := mem_of_rcoset_eq_self (by rewrite [-rcoset_rcoset, H, rcoset_rcoset_inv]) proposition rcoset_eq_rcoset_iff (a b : A) : G * a = G * b ↔ a * b⁻¹ ∈ G := iff.intro mul_inv_mem_of_rcoset_eq_rcoset rcoset_eq_rcoset end subgroupG /- normal cosets and the normalizer -/ section has_mulA variable [has_mul A] abbreviation normalizes [reducible] (a : A) (S : set A) : Prop := a * S = S * a definition is_normal [class] (S : set A) : Prop := ∀ a, normalizes a S definition normalizer (S : set A) : set A := { a : A | normalizes a S } definition is_normal_in [class] (S T : set A) : Prop := T ⊆ normalizer S abbreviation normalizer_in [reducible] (S T : set A) : set A := T ∩ normalizer S proposition lcoset_eq_rcoset (a : A) (S : set A) [H : is_normal S] : a * S = S * a := H a proposition subset_normalizer (S T : set A) [H : is_normal_in T S] : S ⊆ normalizer T := H proposition lcoset_eq_rcoset_of_mem {a : A} (S : set A) {T : set A} [H : is_normal_in S T] (amemT : a ∈ T) : a * S = S * a := H amemT proposition is_normal_in_of_is_normal (S T : set A) [H : is_normal S] : is_normal_in S T := forallb_of_forall T H proposition is_normal_of_is_normal_in_univ {S : set A} (H : is_normal_in S univ) : is_normal S := forall_of_forallb_univ H proposition is_normal_in_univ_iff_is_normal (S : set A) : is_normal_in S univ ↔ is_normal S := forallb_univ_iff_forall _ proposition is_normal_in_of_subset {S T U : set A} (H : T ⊆ U) (H' : is_normal_in S U) : is_normal_in S T := forallb_of_subset H H' proposition normalizes_of_mem_normalizer {a : A} {S : set A} (H : a ∈ normalizer S) : normalizes a S := H proposition mem_normalizer_iff_normalizes (a : A) (S : set A) : a ∈ normalizer S ↔ normalizes a S := iff.refl _ proposition is_normal_in_normalizer [instance] (S : set A) : is_normal_in S (normalizer S) := subset.refl (normalizer S) end has_mulA section groupA variable [group A] proposition is_normal_in_of_forall_subset {S G : set A} [is_subgroup G] (H : ∀₀ x ∈ G, x * S ⊆ S * x) : is_normal_in S G := take x, assume xG, show x * S = S * x, from eq_of_subset_of_subset (H xG) (have x * (x⁻¹ * S) * x ⊆ x * (S * x⁻¹) * x, from rcoset_subset_rcoset (lcoset_subset_lcoset x (H (inv_mem xG))) x, show S * x ⊆ x * S, begin rewrite [lcoset_inv_lcoset at this, lcoset_rcoset at this, rcoset_inv_rcoset at this], exact this end) proposition is_normal_of_forall_subset {S : set A} (H : ∀ x, x * S ⊆ S * x) : is_normal S := begin rewrite [-is_normal_in_univ_iff_is_normal], apply is_normal_in_of_forall_subset, intro x xuniv, exact H x end proposition subset_normalizer_self (G : set A) [is_subgroup G] : G ⊆ normalizer G := take a, assume aG, show a * G = G * a, by rewrite [lcoset_eq_self_of_mem aG, rcoset_eq_self_of_mem aG] end groupA section normalG variables [group A] (G : set A) [is_normal G] proposition lcoset_equiv_mul {a₁ a₂ b₁ b₂ : A} (H₁ : lcoset_equiv G a₁ a₂) (H₂ : lcoset_equiv G b₁ b₂) : lcoset_equiv G (a₁ * b₁) (a₂ * b₂) := begin unfold lcoset_equiv at *, rewrite [-lcoset_lcoset, H₂, lcoset_eq_rcoset, -lcoset_rcoset, H₁, lcoset_rcoset, -lcoset_eq_rcoset, lcoset_lcoset] end proposition lcoset_equiv_inv {a₁ a₂ : A} (H : lcoset_equiv G a₁ a₂) : lcoset_equiv G a₁⁻¹ a₂⁻¹ := begin unfold lcoset_equiv at *, have a₁⁻¹ * G = a₂⁻¹ * (a₂ * G) * a₁⁻¹, by rewrite [inv_lcoset_lcoset, lcoset_eq_rcoset], rewrite [this, -H, lcoset_rcoset, lcoset_eq_rcoset, rcoset_rcoset_inv] end end normalG /- the normalizer is a subgroup -/ section semigroupA variable [semigroup A] proposition mul_mem_normalizer {S : set A} {a b : A} (Ha : a ∈ normalizer S) (Hb : b ∈ normalizer S) : a * b ∈ normalizer S := show a * b * S = S * (a * b), by rewrite [-lcoset_lcoset, normalizes_of_mem_normalizer Hb, -lcoset_rcoset, normalizes_of_mem_normalizer Ha, rcoset_rcoset] end semigroupA section monoidA variable [monoid A] proposition one_mem_normalizer (S : set A) : 1 ∈ normalizer S := by rewrite [↑normalizer, mem_set_of_iff, one_lcoset, rcoset_one] end monoidA section groupA variable [group A] proposition inv_mem_normalizer {S : set A} {a : A} (H : a ∈ normalizer S) : a⁻¹ ∈ normalizer S := have a⁻¹ * S = S * a⁻¹, begin apply iff.mp (rcoset_eq_iff_eq_rcoset_inv _ _ _), rewrite [lcoset_rcoset, -normalizes_of_mem_normalizer H, inv_lcoset_lcoset] end, by rewrite [↑normalizer, mem_set_of_iff, this] proposition is_subgroup_normalizer [instance] (S : set A) : is_subgroup (normalizer S) := ⦃ is_subgroup, one_mem := one_mem_normalizer S, mul_mem := λ a Ha b Hb, mul_mem_normalizer Ha Hb, inv_mem := λ a H, inv_mem_normalizer H⦄ end groupA section subgroupG variables [group A] {G : set A} [is_subgroup G] proposition normalizes_image_of_is_hom_on [group B] {a : A} (aG : a ∈ G) {S : set A} (SsubG : S ⊆ G) (H : normalizes a S) (f : A → B) [is_hom_on f G] : normalizes (f a) (f ' S) := by rewrite [-image_lcoset_of_is_hom_on SsubG aG, -image_rcoset_of_is_hom_on SsubG aG, ↑normalizes at H, H] proposition is_normal_in_image_image [group B] {S T : set A} (SsubT : S ⊆ T) [H : is_normal_in S T] (f : A → B) [is_subgroup T] [is_hom_on f T] : is_normal_in (f ' S) (f ' T) := take a, assume afT, obtain b [bT (beq : f b = a)], from afT, show normalizes a (f ' S), begin rewrite -beq, apply (normalizes_image_of_is_hom_on bT SsubT (H bT)) end proposition normalizes_image_of_is_hom [group B] {a : A} {S : set A} (H : normalizes a S) (f : A → B) [is_hom f] : normalizes (f a) (f ' S) := by rewrite [-image_lcoset_of_is_hom f a S, -image_rcoset_of_is_hom f S a, ↑normalizes at H, H] proposition is_normal_in_image_image_univ [group B] {S : set A} [H : is_normal S] (f : A → B) [is_hom f] : is_normal_in (f ' S) (f ' univ) := take a, assume afT, obtain b [buniv (beq : f b = a)], from afT, show normalizes a (f ' S), begin rewrite -beq, apply (normalizes_image_of_is_hom (H b) f) end end subgroupG /- conjugation -/ definition conj [reducible] [group A] (a b : A) : A := b⁻¹ * a * b definition set_conj [reducible] [group A] (S : set A)(a : A) : set A := a⁻¹ * S * a -- conj^~ a ' S namespace conj_notation infix `^` := conj infix `^` := set_conj end conj_notation open conj_notation section groupA variables [group A] proposition set_conj_eq_image_conj (S : set A) (a : A) : S^a = conj^~ a 'S := eq.symm !image_comp proposition set_conj_eq_self_of_normalizes {S : set A} {a : A} (H : normalizes a S) : S^a = S := by rewrite [lcoset_rcoset, ↑normalizes at H, -H, inv_lcoset_lcoset] proposition normalizes_of_set_conj_eq_self {S : set A} {a : A} (H : S^a = S) : normalizes a S := by rewrite [-H at {1}, ↑set_conj, lcoset_rcoset, lcoset_inv_lcoset] proposition set_conj_eq_self_iff_normalizes (S : set A) (a : A) : S^a = S ↔ normalizes a S := iff.intro normalizes_of_set_conj_eq_self set_conj_eq_self_of_normalizes proposition set_conj_eq_self_of_mem_normalizer {S : set A} {a : A} (H : a ∈ normalizer S) : S^a = S := set_conj_eq_self_of_normalizes H proposition mem_normalizer_of_set_conj_eq_self {S : set A} {a : A} (H : S^a = S) : a ∈ normalizer S := normalizes_of_set_conj_eq_self H proposition set_conj_eq_self_iff_mem_normalizer (S : set A) (a : A) : S^a = S ↔ a ∈ normalizer S := iff.intro mem_normalizer_of_set_conj_eq_self set_conj_eq_self_of_mem_normalizer proposition conj_one (a : A) : a ^ (1 : A) = a := by rewrite [↑conj, one_inv, one_mul, mul_one] proposition conj_conj (a b c : A) : (a^b)^c = a^(b * c) := by rewrite [↑conj, mul_inv, *mul.assoc] proposition conj_inv (a b : A) : (a^b)⁻¹ = (a⁻¹)^b := by rewrite[mul_inv, mul_inv, inv_inv, mul.assoc] proposition mul_conj (a b c : A) : (a * b)^c = a^c * b^c := by rewrite[↑conj, *mul.assoc, mul_inv_cancel_left] end groupA /- the kernel -/ definition ker [has_one B] (f : A → B) : set A := { x | f x = 1 } section hasoneB variable [has_one B] proposition eq_one_of_mem_ker {f : A → B} {a : A} (H : a ∈ ker f) : f a = 1 := H proposition mem_ker_iff (f : A → B) (a : A) : a ∈ ker f ↔ f a = 1 := iff.rfl proposition ker_eq_preimage_one (f : A → B) : ker f = f '- '{1} := ext (take x, by rewrite [mem_ker_iff, -mem_preimage_iff, mem_singleton_iff]) definition ker_in (f : A → B) (S : set A) : set A := ker f ∩ S proposition ker_in_univ (f : A → B) : ker_in f univ = ker f := !inter_univ end hasoneB section groupAB variables [group A] [group B] variable {f : A → B} proposition eq_of_mul_inv_mem_ker [is_hom f] {a₁ a₂ : A} (H : a₁ * a₂⁻¹ ∈ ker f) : f a₁ = f a₂ := eq_of_mul_inv_eq_one (by rewrite [-hom_inv f, -hom_mul f]; exact H) proposition mul_inv_mem_ker_of_eq [is_hom f] {a₁ a₂ : A} (H : f a₁ = f a₂) : a₁ * a₂⁻¹ ∈ ker f := show f (a₁ * a₂⁻¹) = 1, by rewrite [hom_mul f, hom_inv f, H, mul.right_inv] proposition eq_iff_mul_inv_mem_ker [is_hom f] (a₁ a₂ : A) : f a₁ = f a₂ ↔ a₁ * a₂⁻¹ ∈ ker f := iff.intro mul_inv_mem_ker_of_eq eq_of_mul_inv_mem_ker proposition eq_of_mul_inv_mem_ker_in {G : set A} [is_subgroup G] [is_hom_on f G] {a₁ a₂ : A} (a₁G : a₁ ∈ G) (a₂G : a₂ ∈ G) (H : a₁ * a₂⁻¹ ∈ ker_in f G) : f a₁ = f a₂ := eq_of_mul_inv_eq_one (by rewrite [-hom_on_inv f a₂G, -hom_on_mul f a₁G (inv_mem a₂G)]; exact and.left H) proposition mul_inv_mem_ker_in_of_eq {G : set A} [is_subgroup G] [is_hom_on f G] {a₁ a₂ : A} (a₁G : a₁ ∈ G) (a₂G : a₂ ∈ G) (H : f a₁ = f a₂) : a₁ * a₂⁻¹ ∈ ker_in f G := and.intro (show f (a₁ * a₂⁻¹) = 1, by rewrite [hom_on_mul f a₁G (inv_mem a₂G), hom_on_inv f a₂G, H, mul.right_inv]) (mul_mem a₁G (inv_mem a₂G)) proposition eq_iff_mul_inv_mem_ker_in {G : set A} [is_subgroup G] [is_hom_on f G] {a₁ a₂ : A} (a₁G : a₁ ∈ G) (a₂G : a₂ ∈ G) : f a₁ = f a₂ ↔ a₁ * a₂⁻¹ ∈ ker_in f G := iff.intro (mul_inv_mem_ker_in_of_eq a₁G a₂G) (eq_of_mul_inv_mem_ker_in a₁G a₂G) -- Ouch! These versions are not equivalent to the ones before. proposition eq_of_inv_mul_mem_ker [is_hom f] {a₁ a₂ : A} (H : a₁⁻¹ * a₂ ∈ ker f) : f a₁ = f a₂ := eq.symm (eq_of_inv_mul_eq_one (by rewrite [-hom_inv f, -hom_mul f]; exact H)) proposition inv_mul_mem_ker_of_eq [is_hom f] {a₁ a₂ : A} (H : f a₁ = f a₂) : a₁⁻¹ * a₂ ∈ ker f := show f (a₁⁻¹ * a₂) = 1, by rewrite [hom_mul f, hom_inv f, H, mul.left_inv] proposition eq_iff_inv_mul_mem_ker [is_hom f] (a₁ a₂ : A) : f a₁ = f a₂ ↔ a₁⁻¹ * a₂ ∈ ker f := iff.intro inv_mul_mem_ker_of_eq eq_of_inv_mul_mem_ker proposition eq_of_inv_mul_mem_ker_in {G : set A} [is_subgroup G] [is_hom_on f G] {a₁ a₂ : A} (a₁G : a₁ ∈ G) (a₂G : a₂ ∈ G) (H : a₁⁻¹ * a₂ ∈ ker_in f G) : f a₁ = f a₂ := eq.symm (eq_of_inv_mul_eq_one (by rewrite [-hom_on_inv f a₁G, -hom_on_mul f (inv_mem a₁G) a₂G]; exact and.left H)) proposition inv_mul_mem_ker_in_of_eq {G : set A} [is_subgroup G] [is_hom_on f G] {a₁ a₂ : A} (a₁G : a₁ ∈ G) (a₂G : a₂ ∈ G) (H : f a₁ = f a₂) : a₁⁻¹ * a₂ ∈ ker_in f G := and.intro (show f (a₁⁻¹ * a₂) = 1, by rewrite [hom_on_mul f (inv_mem a₁G) a₂G, hom_on_inv f a₁G, H, mul.left_inv]) (mul_mem (inv_mem a₁G) a₂G) proposition eq_iff_inv_mul_mem_ker_in {G : set A} [is_subgroup G] [is_hom_on f G] {a₁ a₂ : A} (a₁G : a₁ ∈ G) (a₂G : a₂ ∈ G) : f a₁ = f a₂ ↔ a₁⁻¹ * a₂ ∈ ker_in f G := iff.intro (inv_mul_mem_ker_in_of_eq a₁G a₂G) (eq_of_inv_mul_mem_ker_in a₁G a₂G) proposition eq_one_of_eq_one_of_injective [is_hom f] (H : injective f) {x : A} (H' : f x = 1) : x = 1 := H (by rewrite [H', hom_one f]) proposition eq_one_iff_eq_one_of_injective [is_hom f] (H : injective f) (x : A) : f x = 1 ↔ x = 1 := iff.intro (eq_one_of_eq_one_of_injective H) (λ H', by rewrite [H', hom_one f]) proposition injective_of_forall_eq_one [is_hom f] (H : ∀ x, f x = 1 → x = 1) : injective f := take a₁ a₂, assume Heq, have f (a₁ * a₂⁻¹) = 1, by rewrite [hom_mul f, hom_inv f, Heq, mul.right_inv], eq_of_mul_inv_eq_one (H _ this) proposition injective_of_ker_eq_singleton_one [is_hom f] (H : ker f = '{1}) : injective f := injective_of_forall_eq_one (take x, suppose x ∈ ker f, by rewrite [H at this]; exact eq_of_mem_singleton this) proposition ker_eq_singleton_one_of_injective [is_hom f] (H : injective f) : ker f = '{1} := ext (take x, by rewrite [mem_ker_iff, mem_singleton_iff, eq_one_iff_eq_one_of_injective H]) variable (f) proposition injective_iff_ker_eq_singleton_one [is_hom f] : injective f ↔ ker f = '{1} := iff.intro ker_eq_singleton_one_of_injective injective_of_ker_eq_singleton_one variable {f} proposition eq_one_of_eq_one_of_inj_on {G : set A} [is_subgroup G] [is_hom_on f G] (H : inj_on f G) {x : A} (xG : x ∈ G) (H' : f x = 1) : x = 1 := H xG one_mem (by rewrite [H', hom_on_one f G]) proposition eq_one_iff_eq_one_of_inj_on {G : set A} [is_subgroup G] [is_hom_on f G] (H : inj_on f G) {x : A} (xG : x ∈ G) [is_hom_on f G] : f x = 1 ↔ x = 1 := iff.intro (eq_one_of_eq_one_of_inj_on H xG) (λ H', by rewrite [H', hom_on_one f G]) proposition inj_on_of_forall_eq_one {G : set A} [is_subgroup G] [is_hom_on f G] (H : ∀₀ x ∈ G, f x = 1 → x = 1) : inj_on f G := take a₁ a₂, assume a₁G a₂G Heq, have f (a₁ * a₂⁻¹) = 1, by rewrite [hom_on_mul f a₁G (inv_mem a₂G), hom_on_inv f a₂G, Heq, mul.right_inv], eq_of_mul_inv_eq_one (H (mul_mem a₁G (inv_mem a₂G)) this) proposition inj_on_of_ker_in_eq_singleton_one {G : set A} [is_subgroup G] [is_hom_on f G] (H : ker_in f G = '{1}) : inj_on f G := inj_on_of_forall_eq_one (take x, assume xG fxone, have x ∈ ker_in f G, from and.intro fxone xG, by rewrite [H at this]; exact eq_of_mem_singleton this) proposition ker_in_eq_singleton_one_of_inj_on {G : set A} [is_subgroup G] [is_hom_on f G] (H : inj_on f G) : ker_in f G = '{1} := ext (take x, begin rewrite [↑ker_in, mem_inter_iff, mem_ker_iff, mem_singleton_iff], apply iff.intro, {intro H', cases H' with fxone xG, exact eq_one_of_eq_one_of_inj_on H xG fxone}, intro xone, rewrite xone, split, exact hom_on_one f G, exact one_mem end) variable (f) proposition inj_on_iff_ker_in_eq_singleton_one (G : set A) [is_subgroup G] [is_hom_on f G] : inj_on f G ↔ ker_in f G = '{1} := iff.intro ker_in_eq_singleton_one_of_inj_on inj_on_of_ker_in_eq_singleton_one variable {f} proposition conj_mem_ker [is_hom f] {a₁ : A} (a₂ : A) (H : a₁ ∈ ker f) : a₁^a₂ ∈ ker f := show f (a₁^a₂) = 1, by rewrite [↑conj, *(hom_mul f), hom_inv f, eq_one_of_mem_ker H, mul_one, mul.left_inv] variable (f) proposition is_subgroup_ker_in [instance] (S : set A) [is_subgroup S] [is_hom_on f S] : is_subgroup (ker_in f S) := ⦃ is_subgroup, one_mem := and.intro (hom_on_one f S) one_mem, mul_mem := λ a aker b bker, obtain (fa : f a = 1) (aS : a ∈ S), from aker, obtain (fb : f b = 1) (bS : b ∈ S), from bker, and.intro (show f (a * b) = 1, by rewrite [hom_on_mul f aS bS, fa, fb, one_mul]) (mul_mem aS bS), inv_mem := λ a aker, obtain (fa : f a = 1) (aS : a ∈ S), from aker, and.intro (show f (a⁻¹) = 1, by rewrite [hom_on_inv f aS, fa, one_inv]) (inv_mem aS) ⦄ proposition is_subgroup_ker [instance] [is_hom f] : is_subgroup (ker f) := begin rewrite [-ker_in_univ f], have is_hom_on f univ, from is_hom_on_of_is_hom f univ, apply is_subgroup_ker_in f univ end proposition is_normal_in_ker_in [instance] (G : set A) [is_subgroup G] [is_hom_on f G] : is_normal_in (ker_in f G) G := is_normal_in_of_forall_subset (take x, assume xG, take y, assume yker, obtain z [[(fz : f z = 1) zG] (yeq : x * z = y)], from yker, have y = x * z * x⁻¹ * x, by rewrite [yeq, inv_mul_cancel_right], show y ∈ ker_in f G * x, begin rewrite this, apply mul_mem_rcoset, apply and.intro, show f (x * z * x⁻¹) = 1, by rewrite [hom_on_mul f (mul_mem xG zG) (inv_mem xG), hom_on_mul f xG zG, fz, hom_on_inv f xG, mul_one, mul.right_inv], show x * z * x⁻¹ ∈ G, from mul_mem (mul_mem xG zG) (inv_mem xG) end) proposition is_normal_ker [instance] [H : is_hom f] : is_normal (ker f) := begin rewrite [-ker_in_univ, -is_normal_in_univ_iff_is_normal], apply is_normal_in_ker_in, exact is_hom_on_of_is_hom f univ end end groupAB section subgroupH variables [group A] [group B] {H : set A} [is_subgroup H] variables {f : A → B} [is_hom f] proposition subset_ker_of_forall (hyp : ∀ x y, x * H = y * H → f x = f y) : H ⊆ ker f := take h, assume hH, have h * H = 1 * H, by rewrite [lcoset_eq_self_of_mem hH, one_lcoset], have f h = f 1, from hyp h 1 this, show f h = 1, by rewrite [this, hom_one f] proposition eq_of_lcoset_eq_lcoset_of_subset_ker {x y : A} (hyp₀ : x * H = y * H) (hyp₁ : H ⊆ ker f) : f x = f y := have y⁻¹ * x ∈ H, from inv_mul_mem_of_lcoset_eq_lcoset hyp₀, eq.symm (eq_of_inv_mul_mem_ker (hyp₁ this)) variables (H f) proposition subset_ker_iff : H ⊆ ker f ↔ ∀ x y, x * H = y * H → f x = f y := iff.intro (λ h₁ x y h₀, eq_of_lcoset_eq_lcoset_of_subset_ker h₀ h₁) subset_ker_of_forall end subgroupH section subgroupGH variables [group A] [group B] {G H : set A} [is_subgroup G] [is_subgroup H] variables {f : A → B} [is_hom_on f G] proposition subset_ker_in_of_forall (hyp₀ : ∀₀ x ∈ G, ∀₀ y ∈ G, x * H = y * H → f x = f y) (hyp₁ : H ⊆ G) : H ⊆ ker_in f G := take h, assume hH, have hG : h ∈ G, from hyp₁ hH, and.intro (have h * H = 1 * H, by rewrite [lcoset_eq_self_of_mem hH, one_lcoset], have f h = f 1, from hyp₀ hG one_mem this, show f h = 1, by rewrite [this, hom_on_one f G]) hG proposition eq_of_lcoset_eq_lcoset_of_subset_ker_in {x : A} (xG : x ∈ G) {y : A} (yG : y ∈ G) (hyp₀ : x * H = y * H) (hyp₁ : H ⊆ ker_in f G) : f x = f y := have y⁻¹ * x ∈ H, from inv_mul_mem_of_lcoset_eq_lcoset hyp₀, eq.symm (eq_of_inv_mul_mem_ker_in yG xG (hyp₁ this)) variables (H f) proposition subset_ker_in_iff : H ⊆ ker_in f G ↔ (H ⊆ G ∧ ∀₀ x ∈ G, ∀₀ y ∈ G, x * H = y * H → f x = f y) := iff.intro (λ h₁, and.intro (subset.trans h₁ (inter_subset_right _ _)) (λ x xG y yG h₀, eq_of_lcoset_eq_lcoset_of_subset_ker_in xG yG h₀ h₁)) (λ h, subset_ker_in_of_forall (and.right h) (and.left h)) end subgroupGH /- the centralizer -/ section has_mulA variable [has_mul A] abbreviation centralizes [reducible] (a : A) (S : set A) : Prop := ∀₀ b ∈ S, a * b = b * a definition centralizer (S : set A) : set A := { a : A | centralizes a S } abbreviation is_centralized_by (S T : set A) : Prop := T ⊆ centralizer S abbreviation centralizer_in (S T : set A) : set A := T ∩ centralizer S proposition mem_centralizer_iff_centralizes (a : A) (S : set A) : a ∈ centralizer S ↔ centralizes a S := iff.refl _ proposition normalizes_of_centralizes {a : A} {S : set A} (H : centralizes a S) : normalizes a S := ext (take b, iff.intro (suppose b ∈ a * S, obtain s [ains (beq : a * s = b)], from this, show b ∈ S * a, by rewrite[-beq, H ains]; apply mem_image_of_mem _ ains) (suppose b ∈ S * a, obtain s [ains (beq : s * a = b)], from this, show b ∈ a * S, by rewrite[-beq, -H ains]; apply mem_image_of_mem _ ains)) proposition centralizer_subset_normalizer (S : set A) : centralizer S ⊆ normalizer S := λ a acent, normalizes_of_centralizes acent proposition centralizer_subset_centralizer {S T : set A} (ssubt : S ⊆ T) : centralizer T ⊆ centralizer S := λ x xCentT s sS, xCentT _ (ssubt sS) end has_mulA section groupA variable [group A] proposition is_subgroup_centralizer [instance] [group A] (S : set A) : is_subgroup (centralizer S) := ⦃ is_subgroup, one_mem := λ b bS, by rewrite [one_mul, mul_one], mul_mem := λ a acent b bcent c cS, by rewrite [mul.assoc, bcent cS, -*mul.assoc, acent cS], inv_mem := λ a acent c cS, eq_mul_inv_of_mul_eq (by rewrite [mul.assoc, -acent cS, inv_mul_cancel_left])⦄ end groupA /- the subgroup generated by a set -/ section groupA variable [group A] inductive subgroup_generated_by (S : set A) : A → Prop := | generators_mem : ∀ x, x ∈ S → subgroup_generated_by S x | one_mem : subgroup_generated_by S 1 | mul_mem : ∀ x y, subgroup_generated_by S x → subgroup_generated_by S y → subgroup_generated_by S (x * y) | inv_mem : ∀ x, subgroup_generated_by S x → subgroup_generated_by S (x⁻¹) theorem generators_subset_subgroup_generated_by (S : set A) : S ⊆ subgroup_generated_by S := subgroup_generated_by.generators_mem theorem is_subgroup_subgroup_generated_by [instance] (S : set A) : is_subgroup (subgroup_generated_by S) := ⦃ is_subgroup, one_mem := subgroup_generated_by.one_mem S, mul_mem := λ a amem b bmem, subgroup_generated_by.mul_mem a b amem bmem, inv_mem := λ a amem, subgroup_generated_by.inv_mem a amem ⦄ theorem subgroup_generated_by_subset {S G : set A} [is_subgroup G] (H : S ⊆ G) : subgroup_generated_by S ⊆ G := begin intro x xgenS, induction xgenS with a aS a b agen bgen aG bG a agen aG, {exact H aS}, {exact one_mem}, {exact mul_mem aG bG}, exact inv_mem aG end end groupA end group_theory