1-- Abelian groups: powers distribute over products, the elements killed2-- by a fixed exponent form a subgroup, and so do the elements of finite3-- order4-- Part of Cumulus, the Grace17 mathematics library.5-- Copyright (c) 2026 Grant Passmore.6-- Released under the Apache License 2.0. See LICENSE in the repository root.7-- Authors: Grant Passmore89module Grace.Cumulus.Algebra.Group.Abelian10import Cyclic1112-- The elements killed by the exponent n, and the elements of finite order.13def exponentKernel (G : Set, n : Nat) : Set:= { x ∈ G.carrier | groupPow(G, x, n) = G.one }14def torsion (G : Set) : Set:= { x ∈ G.carrier | HasFiniteOrder(G, x) }1516theorem exponentKernel.subset (G : Set, n : Nat)17shows exponentKernel(G, n) ⊆ G.carrier18proof19intros x hx20have parts := exponentKernel.membership.forward with hx21exact parts.left2223theorem torsion.subset (G : Set)24shows torsion(G) ⊆ G.carrier25proof26intros x hx27have parts := torsion.membership.forward with hx28exact parts.left2930-- In an abelian group, raising to a fixed power is an endomorphism.31defgraph powerEndomorphism (G : Set, n : Nat) (x ∈ G.carrier) : G.carrier := groupPow(G, x, n)32requires group : Group(G)33proof34exact Group.pow_mem with*3536section Torsion37variable (G : Set)38hypothesis group : Group(G)3940theorem HasFiniteOrder.inv (x : G)41requires finite : HasFiniteOrder(G, x)42shows HasFiniteOrder(G, x⁻¹)43proof44obtain⟨n, nNat, positive, vanishes⟩:= finite45have inverted : x⁻¹ ^ n = (x ^ n)⁻¹ := inv_pow with*46have inverseVanishes : x⁻¹ ^ n = G.one47rw [inverted, vanishes, inv_one]48rfl49exact HasFiniteOrder.of_pow with positive, inverseVanishes5051theorem exponentKernel.of_order_dvd (x : G) (n : Nat)52requires finite : HasFiniteOrder(G, x)53requires divides : elementOrder(G, x) ∣ n54shows x ∈ exponentKernel(G, n)55proof56have vanishes : x ^ n = G.one := elementOrder.pow_eq_one_of_dvd with*57have xIn : x ∈ G byassumption58exact exponentKernel.membership.backward with⟨xIn, vanishes⟩5960theorem exponentKernel.subset_torsion (n : Nat)61requires positive : 0 < n62shows exponentKernel(G, n) ⊆ torsion(G)63proof64intros x hx65obtain⟨xIn, vx⟩:= exponentKernel.membership.forward with hx66have finite := HasFiniteOrder.of_pow with positive, vx67exact torsion.membership.backward with⟨xIn, finite⟩6869end Torsion7071section AbelianPowers72variable (G : Set)73hypothesis abelian : AbelianGroup(G)7475theorem AbelianGroup.mul_pow (x y : G) (n : Nat)76shows (x * y) ^ n = x ^ n * y ^ n77proof78have group := AbelianGroup.to_group with abelian79induction n80| zero =>81rw [pow_zero, pow_zero, pow_zero, one_mul]82rfl83| succ(k) using ih =>84have shuffle : x ^ k * y ^ k * (x * y) = x ^ k * x * (y ^ k * y) := mul_mul_mul_comm with*85rw [← add.right_one, pow_succ, pow_succ, pow_succ, ih, shuffle]86rfl8788theorem exponentKernel.subgroup (n : Nat)89shows Subgroup(exponentKernel(G, n), G)90proof91have group := AbelianGroup.to_group with abelian92have unitIn : G.one ∈ exponentKernel(G, n)93have unitPower : G.one ^ n = G.one := one_pow with*94exact exponentKernel.membership.backward with⟨(Group.one_mem with group), unitPower⟩95apply Subgroup.mk with group, (exponentKernel.subset at G, n), unitIn96 . intros x hx y hy97obtain⟨xIn, vx⟩:= exponentKernel.membership.forward with hx98obtain⟨yIn, vy⟩:= exponentKernel.membership.forward with hy99have vanishes : (x * y) ^ n = G.one100rw [AbelianGroup.mul_pow, vx, vy, one_mul]101rfl102exact exponentKernel.membership.backward with⟨(Group.mul_mem with*), vanishes⟩103 . intros x hx104obtain⟨xIn, vx⟩:= exponentKernel.membership.forward with hx105have vanishes : x⁻¹ ^ n = G.one106rw [inv_pow, vx, inv_one]107rfl108exact exponentKernel.membership.backward with⟨(Group.inv_mem with*), vanishes⟩109110theorem exponentKernel.normal (n : Nat)111shows NormalSubgroup(exponentKernel(G, n), G)112proof113have subgroup := exponentKernel.subgroup with*114exact NormalSubgroup.of_abelian with abelian, subgroup115116theorem AbelianGroup.finite_order_mul (x y : G)117requires finiteX : HasFiniteOrder(G, x)118requires finiteY : HasFiniteOrder(G, y)119shows HasFiniteOrder(G, x * y)120proof121have group := AbelianGroup.to_group with abelian122obtain⟨m, mNat, mPositive, mVanishes⟩:= finiteX123obtain⟨n, nNat, nPositive, nVanishes⟩:= finiteY124have distributed : (x * y) ^ (m * n) = x ^ (m * n) * y ^ (m * n) := AbelianGroup.mul_pow with*125have xPower : x ^ (m * n) = (x ^ m) ^ n := pow_mul with*126have swap := mul.commutative at n, m127have yPower : y ^ (n * m) = (y ^ n) ^ m := pow_mul with*128have unitM : G.one ^ m = G.one := one_pow with*129have unitN : G.one ^ n = G.one := one_pow with*130have mNonzero : m ≠0131intro zero132rw zero at mPositive133exact Less.irreflexive at0with mPositive134have nNonzero : n ≠0135intro zero136rw zero at nPositive137exact Less.irreflexive at0with nPositive138have productNonzero := mul.nonzero with mNonzero, nNonzero139have productPositive := Less.add_positive at0, m * n with productNonzero140have zeroAdd : 0+ m * n = m * n byring141rw zeroAdd at productPositive142have vanishes : (x * y) ^ (m * n) = G.one143rw [distributed, xPower, mVanishes, unitN, swap, yPower, nVanishes, unitM, one_mul]144rfl145exact HasFiniteOrder.of_pow with productPositive, vanishes146147theorem torsion.subgroup148shows Subgroup(torsion(G), G)149proof150have group := AbelianGroup.to_group with abelian151have unitFinite := HasFiniteOrder.one with group152have unitIn : G.one ∈ torsion(G) := torsion.membership.backward with⟨(Group.one_mem with group), unitFinite⟩153apply Subgroup.mk with group, (torsion.subset at G), unitIn154 . intros x hx y hy155obtain⟨xIn, finiteX⟩:= torsion.membership.forward with hx156obtain⟨yIn, finiteY⟩:= torsion.membership.forward with hy157have finite : HasFiniteOrder(G, x * y) := AbelianGroup.finite_order_mul with*158exact torsion.membership.backward with⟨(Group.mul_mem with*), finite⟩159 . intros x hx160obtain⟨xIn, finiteX⟩:= torsion.membership.forward with hx161have finite : HasFiniteOrder(G, x⁻¹) := HasFiniteOrder.inv with*162exact torsion.membership.backward with⟨(Group.inv_mem with*), finite⟩163164theorem torsion.normal165shows NormalSubgroup(torsion(G), G)166proof167have subgroup := torsion.subgroup with abelian168exact NormalSubgroup.of_abelian with abelian, subgroup169170theorem powerEndomorphism.hom (n : Nat)171shows powerEndomorphism(G, n) : G →* G172proof173have group := AbelianGroup.to_group with abelian174have function := powerEndomorphism.function at G, n with*175apply GroupHom.mk with group, group, function176intros x hx y hy177have closed : x * y ∈ G bytypecheck178have vx := powerEndomorphism.value at G, n, x with*179have vy := powerEndomorphism.value at G, n, y with*180have output := powerEndomorphism.value at G, n, x * y with*181have distributed : (x * y) ^ n = x ^ n * y ^ n := AbelianGroup.mul_pow with*182cc183184theorem powerEndomorphism.kernel (n : Nat)185shows kernel(powerEndomorphism(G, n), G, G) = exponentKernel(G, n)186proof187have group := AbelianGroup.to_group with abelian188ext x189constructor190 . intro hx191obtain⟨xIn, vx⟩:= kernel.membership.forward with hx192have value := powerEndomorphism.value at G, n, x with*193have vanishes : x ^ n = G.one bycc194exact exponentKernel.membership.backward with⟨xIn, vanishes⟩195 . intro hx196obtain⟨xIn, vx⟩:= exponentKernel.membership.forward with hx197have value := powerEndomorphism.value at G, n, x with*198have vanishes : powerEndomorphism(G, n)(x) = G.one bycc199exact kernel.of_value with xIn, vanishes200201end AbelianPowers202