1-- A subgroup as a group of its own, with the operations restricted to it;2-- the inclusion of a subgroup is a homomorphism, and homomorphisms restrict3-- to subgroups and corestrict to their images4-- 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.Restricted10import Normal11import Algebra.Restriction1213-- The group on a subgroup H of G: the carrier H with the operation and14-- inverse of G restricted to it.15def subgroupGroup (G H : Set) : Set:=16 Group.mk(H, restrict(G.mul, H × H), G.one, restrict(G.inv, H))1718theorem subgroupGroup.carrierOf (G H : Set)19shows Group.carrier(subgroupGroup(G, H)) = H20proof21simp [subgroupGroup, Group.mk.carrier]2223theorem subgroupGroup.operation (G H : Set)24shows Group.mul(subgroupGroup(G, H)) = restrict(G.mul, H × H)25proof26simp [subgroupGroup, Group.mk.mul]2728theorem subgroupGroup.unit (G H : Set)29shows Group.one(subgroupGroup(G, H)) = G.one30proof31simp [subgroupGroup, Group.mk.one]3233theorem subgroupGroup.inverse (G H : Set)34shows Group.inv(subgroupGroup(G, H)) = restrict(G.inv, H)35proof36simp [subgroupGroup, Group.mk.inv]3738section Restricted39variable (G H : Set)40hypothesis group : Group(G)41hypothesis subgroup : Subgroup(H, G)4243theorem Subgroup.closed_binary44shows ClosedBinary(H, G.mul)45proof46intros x hx y hy47exact Subgroup.mul_mem with*4849theorem Subgroup.closed_unary50shows ClosedUnary(H, G.inv)51proof52intros x hx53exact Subgroup.inv_mem with*5455theorem subgroupGroup.mul (h k : H)56shows Group.mul(subgroupGroup(G, H))(h, k) = h * k57proof58have magma := IsGroup.magma with (Group.parts with group)59have subset := Subgroup.subset with subgroup60have closed := Subgroup.closed_binary with group, subgroup61rw subgroupGroup.operation62exact restrictBinary.value with magma, subset, closed, *6364theorem subgroupGroup.inverse_value (h : H)65shows Group.inv(subgroupGroup(G, H))(h) = h⁻¹66proof67have function := Group.inverse_function with group68have subset := Subgroup.subset with subgroup69have closed := Subgroup.closed_unary with group, subgroup70rw subgroupGroup.inverse71exact restrictUnary.value with function, subset, closed, *7273theorem Subgroup.restricted_group74shows IsGroup(H, restrict(G.mul, H × H), G.one, restrict(G.inv, H))75proof76have parts := Group.parts with group77have magma := IsGroup.magma with parts78have monoid := IsGroup.monoid with parts79have associative := IsMonoid.associative with monoid80have identity := IsMonoid.identity with monoid81have inverse := IsGroup.inverse with parts82have negation := inverse.left83have subset := Subgroup.subset with subgroup84have unitIn : G.one ∈ H := Subgroup.one_mem with*85have opClosed := Subgroup.closed_binary with group, subgroup86have invClosed := Subgroup.closed_unary with group, subgroup87have function := restrictBinary.function with magma, subset, opClosed88have rMagma : IsMagma(H, restrict(G.mul, H × H)) byexact function89have rAssociative := restrictBinary.associative with magma, subset, opClosed, associative90have rIdentity := restrictBinary.identity with magma, subset, opClosed, identity, unitIn91have rInverse := restrictUnary.inverse with magma, negation, subset, opClosed, invClosed, inverse92simp [IsGroup, IsMonoid, IsSemigroup]9394theorem subgroupGroup.group95shows Group(subgroupGroup(G, H))96proof97have restricted := Subgroup.restricted_group with group, subgroup98unfold subgroupGroup99exact Group.of_parts with restricted100101theorem subgroupGroup.abelian102requires abelian : AbelianGroup(G)103shows AbelianGroup(subgroupGroup(G, H))104proof105have commutative := IsAbelianGroup.commutative with (AbelianGroup.parts with abelian)106have magma := IsGroup.magma with (Group.parts with group)107have subset := Subgroup.subset with subgroup108have opClosed := Subgroup.closed_binary with group, subgroup109have restricted := Subgroup.restricted_group with group, subgroup110have rCommutative := restrictBinary.commutative with magma, subset, opClosed, commutative111unfold subgroupGroup112apply AbelianGroup.of_parts113unfold IsAbelianGroup114exact⟨restricted, rCommutative⟩115116-- The inclusion of a subgroup is an injective homomorphism.117theorem Subgroup.inclusion_hom118shows identity(H) : subgroupGroup(G, H) →* G119proof120have subgroupGroupIs := subgroupGroup.group with group, subgroup121have subset := Subgroup.subset with subgroup122have function : identity(H) : Group.carrier(subgroupGroup(G, H)) → G.carrier123rw subgroupGroup.carrierOf124exact identity.inclusion with subset125apply GroupHom.mk with subgroupGroupIs, group, function126intros x hx y hy127rw subgroupGroup.carrierOf at hx128rw subgroupGroup.carrierOf at hy129have restricted : Group.mul(subgroupGroup(G, H))(x, y) = G.mul(x, y) := subgroupGroup.mul with*130have vx := identity.apply with hx131have vy := identity.apply with hy132have closed : G.mul(x, y) ∈ H := Subgroup.mul_mem with*133have output := identity.apply with closed134rw [restricted, output, vx, vy]135rfl136137theorem Subgroup.inclusion_injective138shows InjectiveBetween(identity(H), H, G.carrier)139proof140have subset := Subgroup.subset with subgroup141have function := identity.inclusion with subset142constructor143 . exact function144 . intros x hx y hy z hz hxz hyz145have vx := identity.apply with hx146have vy := identity.apply with hy147have ex := FunctionBetween.apply_value with function, hx, hxz148have ey := FunctionBetween.apply_value with function, hy, hyz149cc150151end Restricted152153section RestrictedHoms154variable (f G H : Set)155hypothesis hom : f : G →* H156157-- A homomorphism restricted to a subgroup, as a homomorphism out of the158-- subgroup's group.159theorem GroupHom.restrict (K : Set)160requires subgroup : Subgroup(K, G)161shows restrict(f, K) : subgroupGroup(G, K) →* H162proof163have group := GroupHom.source with hom164have target := GroupHom.target with hom165have function := GroupHom.function with hom166have subset := Subgroup.subset with subgroup167have subgroupGroupIs := subgroupGroup.group with group, subgroup168have restricted := restrict.domain_function with function, subset169have restrictedFunction : restrict(f, K) : Group.carrier(subgroupGroup(G, K)) → H.carrier170rw subgroupGroup.carrierOf171exact restricted172apply GroupHom.mk with subgroupGroupIs, target, restrictedFunction173intros x hx y hy174rw subgroupGroup.carrierOf at hx175rw subgroupGroup.carrierOf at hy176have xIn : x ∈ G := Subgroup.mem_carrier with*177have yIn : y ∈ G := Subgroup.mem_carrier with*178have closed : G.mul(x, y) ∈ K := Subgroup.mul_mem with*179have mulValue : Group.mul(subgroupGroup(G, K))(x, y) = G.mul(x, y) := subgroupGroup.mul with*180have vx := restrict.domain_apply with function, subset, hx181have vy := restrict.domain_apply with function, subset, hy182have output := restrict.domain_apply with function, subset, closed183have preserved : f(G.mul(x, y)) = f(x) * f(y) := GroupHom.map_mul with*184rw [mulValue, output, vx, vy]185exact preserved186187-- The corestriction of a homomorphism to its image.188theorem GroupHom.corestrict189shows f : G →* subgroupGroup(H, functionImage(f, G.carrier, H.carrier))190proof191have group := GroupHom.source with hom192have target := GroupHom.target with hom193have function := GroupHom.function with hom194have rangeSubgroup := GroupHom.range_subgroup with hom195have rangeGroup := subgroupGroup.group with target, rangeSubgroup196have corestricted : f : G.carrier → Group.carrier(subgroupGroup(H, functionImage(f, G.carrier, H.carrier)))197rw subgroupGroup.carrierOf198exact functionImage.corestrict with function199apply GroupHom.mk with group, rangeGroup, corestricted200intros x hx y hy201have fx := functionImage.value with function, hx202have fy := functionImage.value with function, hy203have mulValue : Group.mul(subgroupGroup(H, functionImage(f, G.carrier, H.carrier)))(f(x), f(y)) =204 H.mul(f(x), f(y)) := subgroupGroup.mul with*205have preserved : f(x * y) = H.mul(f(x), f(y)) := GroupHom.map_mul with*206rw mulValue207exact preserved208209theorem GroupHom.range_group210shows Group(subgroupGroup(H, functionImage(f, G.carrier, H.carrier)))211proof212have target := GroupHom.target with hom213have rangeSubgroup := GroupHom.range_subgroup with hom214exact subgroupGroup.group with target, rangeSubgroup215216theorem GroupHom.image_factorization217shows compose(identity(functionImage(f, G.carrier, H.carrier)), f, G.carrier,218 functionImage(f, G.carrier, H.carrier), H.carrier) = f219proof220have function := GroupHom.function with hom221have corestricted := functionImage.corestrict with function222have subset := functionImage.subset at f, G.carrier, H.carrier223have inclusion := identity.inclusion with subset224have composed := compose.function with corestricted, inclusion225apply FunctionBetween.ext with composed, function226intros x hx227have fx := functionImage.value with function, hx228have value := compose.apply at identity(functionImage(f, G.carrier, H.carrier)), f, G.carrier, functionImage(f, G.carrier, H.carrier), H.carrier, x with*229have included := identity.apply with fx230cc231232-- The kernel of a restricted homomorphism is the restricted kernel.233theorem GroupHom.kernel_restrict (K : Set)234requires subgroup : Subgroup(K, G)235shows kernel(restrict(f, K), subgroupGroup(G, K), H) = ker(f) ∩ K236proof237have function := GroupHom.function with hom238have subset := Subgroup.subset with subgroup239ext x240constructor241 . intro hx242obtain⟨xK, vx⟩:= kernel.membership.forward with hx243rw subgroupGroup.carrierOf at xK244have xIn := subset with x, xK245have restricted := restrict.domain_apply with function, subset, xK246have vanishes : f(x) = H.one bycc247have inKernel := kernel.of_value with xIn, vanishes248exact intersection.membership.backward with⟨inKernel, xK⟩249 . intro hx250obtain⟨inKernel, xK⟩:= intersection.membership.forward with hx251have vx := kernel.value with inKernel252have restricted := restrict.domain_apply with function, subset, xK253have vanishes : restrict(f, K)(x) = H.one bycc254have xIn : x ∈ Group.carrier(subgroupGroup(G, K))255rw subgroupGroup.carrierOf256exact xK257exact kernel.of_value with xIn, vanishes258259end RestrictedHoms260