1-- Core group theory2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Algebra.Group.Core8import Defs9import Set.Function1011theorem IsMagma.closed (A op x y : Set)12requires magma : IsMagma(A, op)13requires xInA : x ∈ A14requires yInA : y ∈ A15shows op(x, y) ∈ A16proof17unfold IsMagma at magma18unfold call219apply FunctionBetween.apply_closed with magma20exact product.pair with xInA, yInA2122theorem IsSemigroup.magma (A op : Set)23requires h : IsSemigroup(A, op)24shows IsMagma(A, op)25proof26simp [IsSemigroup]2728theorem IsSemigroup.associative (A op : Set)29requires h : IsSemigroup(A, op)30shows Associative(A, op)31proof32simp [IsSemigroup]3334theorem IsSemigroup.closed (A op x y : Set)35requires semigroup : IsSemigroup(A, op)36requires xInA : x ∈ A37requires yInA : y ∈ A38shows op(x, y) ∈ A39proof40have magma := IsSemigroup.magma with semigroup41exact IsMagma.closed with magma, xInA, yInA4243theorem Associative.law (A op x y z : Set)44requires associative : Associative(A, op)45requires xInA : x ∈ A46requires yInA : y ∈ A47requires zInA : z ∈ A48shows op(op(x, y), z) =49 op(x, op(y, z))50proof51exact associative with x, xInA, y, yInA, z, zInA5253theorem Commutative.law (A op x y : Set)54requires commutative : Commutative(A, op)55requires xInA : x ∈ A56requires yInA : y ∈ A57shows op(x, y) = op(y, x)58proof59exact commutative with x, xInA, y, yInA6061theorem IsMonoid.identity (A op unit : Set)62requires h : IsMonoid(A, op, unit)63shows Identity(A, op, unit)64proof65simp [IsMonoid]6667theorem IsMonoid.closed (A op unit x y : Set)68requires monoid : IsMonoid(A, op, unit)69requires xInA : x ∈ A70requires yInA : y ∈ A71shows op(x, y) ∈ A72proof73have semigroup := IsMonoid.semigroup with monoid74exact IsSemigroup.closed with semigroup, xInA, yInA7576theorem IsMonoid.associative (A op unit : Set)77requires monoid : IsMonoid(A, op, unit)78shows Associative(A, op)79proof80have semigroup := IsMonoid.semigroup with monoid81exact IsSemigroup.associative with semigroup8283theorem IsMonoid.unit_in_carrier (A op unit : Set)84requires monoid : IsMonoid(A, op, unit)85shows unit ∈ A86proof87obtain⟨unitInA, laws⟩:= IsMonoid.identity with monoid88exact unitInA8990theorem IsMonoid.left_identity (A op unit x : Set)91requires monoid : IsMonoid(A, op, unit)92requires xInA : x ∈ A93shows op(unit, x) = x94proof95obtain⟨unitInA, laws⟩:= IsMonoid.identity with monoid96obtain⟨left, right⟩:= laws with x, xInA97exactleft9899theorem IsMonoid.right_identity (A op unit x : Set)100requires monoid : IsMonoid(A, op, unit)101requires xInA : x ∈ A102shows op(x, unit) = x103proof104obtain⟨unitInA, laws⟩:= IsMonoid.identity with monoid105obtain⟨left, right⟩:= laws with x, xInA106exactright107108theorem IsCommMonoid.monoid (A op unit : Set)109requires h : IsCommMonoid(A, op, unit)110shows IsMonoid(A, op, unit)111proof112simp [IsCommMonoid]113114theorem IsCommMonoid.commutative (A op unit : Set)115requires h : IsCommMonoid(A, op, unit)116shows Commutative(A, op)117proof118simp [IsCommMonoid]119120theorem IsGroup.magma (A op unit inv : Set)121requires group : IsGroup(A, op, unit, inv)122shows IsMagma(A, op)123proof124have monoid := IsGroup.monoid with group125have semigroup := IsMonoid.semigroup with monoid126exact IsSemigroup.magma with semigroup127128theorem IsGroup.inverse (A op unit inv : Set)129requires h : IsGroup(A, op, unit, inv)130shows Inverse(A, op, unit, inv)131proof132simp [IsGroup]133134theorem IsGroup.inverse_closed (A op unit inv x : Set)135requires group : IsGroup(A, op, unit, inv)136requires xInA : x ∈ A137shows inv(x) ∈ A138proof139obtain⟨function, laws⟩:= IsGroup.inverse with group140exact FunctionBetween.apply_closed with function, xInA141142theorem IsGroup.inverse_left (A op unit inv x : Set)143requires group : IsGroup(A, op, unit, inv)144requires xInA : x ∈ A145shows op(inv(x), x) = unit146proof147obtain⟨function, laws⟩:= IsGroup.inverse with group148obtain⟨left, right⟩:= laws with x, xInA149exactleft150151theorem IsGroup.inverse_right (A op unit inv x : Set)152requires group : IsGroup(A, op, unit, inv)153requires xInA : x ∈ A154shows op(x, inv(x)) = unit155proof156obtain⟨function, laws⟩:= IsGroup.inverse with group157obtain⟨left, right⟩:= laws with x, xInA158exactright159160theorem IsAbelianGroup.group (A op unit inv : Set)161requires h : IsAbelianGroup(A, op, unit, inv)162shows IsGroup(A, op, unit, inv)163proof164simp [IsAbelianGroup]165166theorem IsAbelianGroup.commutative (A op unit inv : Set)167requires h : IsAbelianGroup(A, op, unit, inv)168shows Commutative(A, op)169proof170simp [IsAbelianGroup]171172theorem Identity.in_carrier (A op unit : Set)173requires h : Identity(A, op, unit)174shows unit ∈ A175proof176simp [Identity]177178theorem Identity.unique (A op e f : Set)179requires he : Identity(A, op, e)180requires hf : Identity(A, op, f)181shows e = f182proof183rcases he with⟨heA, heLaws⟩184rcases hf with⟨hfA, hfLaws⟩185specialize heLaws with f, hfA186rcases heLaws with⟨hef, hfe⟩187specialize hfLaws with e, heA188rcases hfLaws with⟨hfe2, hef2⟩189 rwa ← hef2190191theorem IsInverse.unique (A op unit a b c : Set)192requires monoid : IsMonoid(A, op, unit)193requires hb : IsInverse(A, op, unit, a, b)194requires hc : IsInverse(A, op, unit, a, c)195shows b = c196proof197have monoidStructure := monoid198rcases monoid with⟨semigroup, identity⟩199rcases semigroup with⟨magma, associative⟩200rcases identity with⟨unitA, identityLaws⟩201rcases hb with⟨aA, bA, hba, hab⟩202rcases hc with⟨aA2, cA, hca, hac⟩203specialize identityLaws with b, bA204rcases identityLaws with⟨unitB, bUnit⟩205obtain⟨unitA2, identityLawsC⟩:= IsMonoid.identity with monoidStructure206specialize identityLawsC with c, cA207rcases identityLawsC with⟨unitC, cUnit⟩208specialize associative with b, bA, a, aA, c, cA209rewrite← bUnit210rewrite← hac211rewrite← associative212 rwa hba213214theorem IsGroup.inverse_unit (A op unit inv : Set)215requires group : IsGroup(A, op, unit, inv)216shows inv(unit) = unit217proof218have monoid := IsGroup.monoid with group219have unitInA := IsMonoid.unit_in_carrier with monoid220have inverseUnitInA := IsGroup.inverse_closed with group, unitInA221have inverseEquation := IsGroup.inverse_left with group, unitInA222have unitEquation := IsMonoid.right_identity with monoid, inverseUnitInA223 rwa unitEquation at inverseEquation224225theorem IsGroup.inverse_involutive (A op unit inv x : Set)226requires group : IsGroup(A, op, unit, inv)227requires xInA : x ∈ A228shows inv(inv(x)) = x229proof230have monoid := IsGroup.monoid with group231have inverseXInA := IsGroup.inverse_closed with group, xInA232have inverseInverseXInA := IsGroup.inverse_closed with group, inverseXInA233have inverseLeft := IsGroup.inverse_left with group, xInA234have inverseRight := IsGroup.inverse_right with group, xInA235have twiceLeft := IsGroup.inverse_left with group, inverseXInA236have twiceRight := IsGroup.inverse_right with group, inverseXInA237have first : IsInverse(A, op, unit, inv(x), x)238unfold IsInverse239refine⟨inverseXInA, xInA, inverseRight, inverseLeft⟩240have second : IsInverse(A, op, unit,241 inv(x), inv(inv(x)))242unfold IsInverse243refine⟨inverseXInA, inverseInverseXInA, twiceLeft, twiceRight⟩244have unique := IsInverse.unique with monoid, first, second245cc246247theorem IsAbelianGroup.four_shuffle (A op unit inv a b c d : Set)248requires group : IsAbelianGroup(A, op, unit, inv)249requires aInA : a ∈ A250requires bInA : b ∈ A251requires cInA : c ∈ A252requires dInA : d ∈ A253shows op(op(a, b), op(c, d)) =254 op(op(a, c), op(b, d))255proof256have ordinary := IsAbelianGroup.group with group257have monoid := IsGroup.monoid with ordinary258have associative := IsMonoid.associative with monoid259have commutative := IsAbelianGroup.commutative with group260have cdInA := IsMonoid.closed with monoid, cInA, dInA261have bdInA := IsMonoid.closed with monoid, bInA, dInA262have outerLeft := Associative.law with associative, aInA, bInA, cdInA263have middleLeft := Associative.law with associative, bInA, cInA, dInA264have swap := commutative with b, bInA, c, cInA265have middleRight := Associative.law with associative, cInA, bInA, dInA266have outerRight := Associative.law with associative, aInA, cInA, bdInA267cc268269theorem IsAbelianGroup.inverse_op (A op unit inv x y : Set)270requires group : IsAbelianGroup(A, op, unit, inv)271requires xInA : x ∈ A272requires yInA : y ∈ A273shows inv(op(x, y)) =274 op(inv(x), inv(y))275proof276have ordinary := IsAbelianGroup.group with group277have monoid := IsGroup.monoid with ordinary278have inverseXInA := IsGroup.inverse_closed with ordinary, xInA279have inverseYInA := IsGroup.inverse_closed with ordinary, yInA280have xyInA := IsMonoid.closed with monoid, xInA, yInA281have inverseXYInA := IsGroup.inverse_closed with ordinary, xyInA282have candidateInA := IsMonoid.closed with monoid, inverseXInA, inverseYInA283have shuffle := IsAbelianGroup.four_shuffle with group, inverseXInA, inverseYInA, xInA, yInA284have inverseX := IsGroup.inverse_left with ordinary, xInA285have inverseY := IsGroup.inverse_left with ordinary, yInA286have unitInA := IsMonoid.unit_in_carrier with monoid287have unitUnit := IsMonoid.left_identity with monoid, unitInA288have candidateLeft : call2(op,289 op(inv(x), inv(y)), op(x, y)) = unit290 rwa [shuffle, inverseX, inverseY]291have commutative := IsAbelianGroup.commutative with group292have candidateSwap := commutative with293 op(inv(x), inv(y)), candidateInA,294 op(x, y), xyInA295have candidateRight : call2(op, call2(op, x, y),296 op(inv(x), inv(y))) = unit297 rwa ← candidateSwap298have canonical : IsInverse(A, op, unit,299 op(x, y), inv(op(x, y)))300unfold IsInverse301refine⟨xyInA, inverseXYInA, _, _⟩302 . exact IsGroup.inverse_left at303 A, op, unit, inv, op(x, y) with ordinary, xyInA304 . exact IsGroup.inverse_right at305 A, op, unit, inv, op(x, y) with ordinary, xyInA306have candidate : IsInverse(A, op, unit,307 op(x, y), op(inv(x), inv(y)))308unfold IsInverse309refine⟨xyInA, candidateInA, candidateLeft, candidateRight⟩310exact IsInverse.unique with monoid, canonical, candidate311312-- The inverse of a product reverses the factors.313theorem IsGroup.inverse_op (A op unit inv a b : Set)314requires group : IsGroup(A, op, unit, inv)315requires ha : a ∈ A316requires hb : b ∈ A317shows inv(op(a, b)) = op(inv(b), inv(a))318proof319have monoid := group.left320have associative := IsMonoid.associative with monoid321have product := IsMonoid.closed with monoid, ha, hb322have invA := IsGroup.inverse_closed with group, ha323have invB := IsGroup.inverse_closed with group, hb324have invProduct := IsGroup.inverse_closed with group, product325have candidate := IsMonoid.closed with monoid, invB, invA326have leftInverse := IsGroup.inverse_left with group, product327have rearranged : op(op(inv(b), inv(a)), op(a, b)) = unit328have step1 := Associative.law with associative, candidate, ha, hb329have step2 := Associative.law with associative, invB, invA, ha330have cancelA := IsGroup.inverse_left with group, ha331have unitRight := IsMonoid.right_identity with monoid, invB332have cancelB := IsGroup.inverse_left with group, hb333 rwa [← step1, step2, cancelA, unitRight]334have equalProducts : op(inv(op(a, b)), op(a, b)) = op(op(inv(b), inv(a)), op(a, b))335rw [leftInverse, rearranged]336rfl337have rightCancel : ∀ x ∈ A, ∀ y ∈ A, op(x, op(a, b)) = op(y, op(a, b)) → x = y338intros x hx y hy equal339have invProductIn := IsGroup.inverse_closed with group, product340have cancelX : op(op(x, op(a, b)), inv(op(a, b))) = x341have assoc := Associative.law with associative, hx, product, invProductIn342haveright:= IsGroup.inverse_right with group, product343have identity := IsMonoid.right_identity with monoid, hx344 rwa [assoc, right]345have cancelY : op(op(y, op(a, b)), inv(op(a, b))) = y346have assoc := Associative.law with associative, hy, product, invProductIn347haveright:= IsGroup.inverse_right with group, product348have identity := IsMonoid.right_identity with monoid, hy349 rwa [assoc, right]350rw [equal, cancelY] at cancelX351 symm at cancelX352exact cancelX353have forX := rightCancel with invProduct354have forXY := forX with candidate355exact forXY with equalProducts356