1-- Group isomorphisms f : G ≃* H and automorphisms: inverses and composites2-- of isomorphisms, isomorphism as an equivalence between groups, transfer3-- of commutativity, and conjugation as an inner automorphism4-- 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.Isomorphism10import Restricted11import Cardinal.Finite1213-- f : G ≃* H: a bijective homomorphism. G ≃* H: some isomorphism exists.14predicate GroupIso (f G H : Set) :=15 GroupHom(f, G, H) ∧ BijectiveBetween(f, G.carrier, H.carrier)1617predicate IsomorphicGroups (G H : Set) :=∃ f, GroupIso(f, G, H)1819predicate GroupAutomorphism (f G : Set) := GroupIso(f, G, G)2021notationguard"_ : _ ≃* _"=> GroupIso22notationinfix50"≃*"=> IsomorphicGroups2324theorem GroupIso.mk (f G H : Set)25requires hom : f : G →* H26requires bijective : BijectiveBetween(f, G.carrier, H.carrier)27shows f : G ≃* H28proof29unfold GroupIso30exact⟨hom, bijective⟩3132section IsoLaws33variable (f G H : Set)34hypothesis iso : f : G ≃* H3536theorem GroupIso.hom37shows f : G →* H38proof39obtain⟨hom, bijective⟩:= iso40exact hom4142theorem GroupIso.bijective43shows BijectiveBetween(f, G.carrier, H.carrier)44proof45obtain⟨hom, bijective⟩:= iso46exact bijective4748theorem GroupIso.function49shows f : G.carrier → H.carrier50proof51have hom := GroupIso.hom with iso52exact GroupHom.function with hom5354theorem GroupIso.injective55shows InjectiveBetween(f, G.carrier, H.carrier)56proof57have bijective := GroupIso.bijective with iso58exact Bijective.injective with bijective5960theorem GroupIso.surjective61shows SurjectiveBetween(f, G.carrier, H.carrier)62proof63have bijective := GroupIso.bijective with iso64exact Bijective.surjective with bijective6566theorem GroupIso.map_mul (a b : G)67shows f(a * b) = f(a) * f(b)68proof69have hom := GroupIso.hom with iso70exact GroupHom.map_mul with*7172theorem GroupIso.equipotent73shows G.carrier ≃ H.carrier74proof75have bijective := GroupIso.bijective with iso76witness f77exact bijective7879theorem GroupIso.kernel_trivial80shows ker(f) = {G.one}81proof82have hom := GroupIso.hom with iso83have injective := GroupIso.injective with iso84have criterion := GroupHom.injective_iff_kernel_trivial with hom85exact criterion.forward with injective8687theorem GroupIso.range88shows functionImage(f, G.carrier, H.carrier) = H.carrier89proof90have hom := GroupIso.hom with iso91have surjective := GroupIso.surjective with iso92have criterion := GroupHom.surjective_iff_range with hom93exact criterion.forward with surjective9495-- The inverse of an isomorphism is an isomorphism.96theorem GroupIso.symm97shows converse(f, G.carrier, H.carrier) : H ≃* G98proof99have hom := GroupIso.hom with iso100have group := GroupHom.source with hom101have target := GroupHom.target with hom102have bijective := GroupIso.bijective with iso103have inverse := converse.function_of_bijective with bijective104have inverseBijective := converse.bijective with bijective105have inverseHom : converse(f, G.carrier, H.carrier) : H →* G106apply GroupHom.mk with target, group, inverse107intros y hy w hw108have py := FunctionBetween.apply_closed with inverse, hy109have pw := FunctionBetween.apply_closed with inverse, hw110have fy := Bijective.apply_inverse with bijective, hy111have fw := Bijective.apply_inverse with bijective, hw112have closed : converse(f, G.carrier, H.carrier)(y) * converse(f, G.carrier, H.carrier)(w) ∈ G.carrier bytypecheck113have mapped : f(converse(f, G.carrier, H.carrier)(y) * converse(f, G.carrier, H.carrier)(w)) =114 f(converse(f, G.carrier, H.carrier)(y)) * f(converse(f, G.carrier, H.carrier)(w)) :=115 GroupHom.map_mul with*116have recovered := Bijective.inverse_apply with bijective, closed117cc118exact GroupIso.mk with inverseHom, inverseBijective119120-- Commutativity transfers along an isomorphism.121theorem GroupIso.commutative122requires commutative : Commutative(G.carrier, G.mul)123shows Commutative(H.carrier, H.mul)124proof125have function := GroupIso.function with iso126have surjective := GroupIso.surjective with iso127intros y hy w hw128obtain⟨x, hx, xEdge⟩:= surjective.right with y, hy129obtain⟨u, hu, uEdge⟩:= surjective.right with w, hw130have yEq := FunctionBetween.apply_value with function, hx, xEdge131have wEq := FunctionBetween.apply_value with function, hu, uEdge132have first : f(x * u) = f(x) * f(u) := GroupIso.map_mul with*133have second : f(u * x) = f(u) * f(x) := GroupIso.map_mul with*134have swap := Commutative.law with commutative, hx, hu135cc136137theorem GroupIso.abelian138requires abelian : AbelianGroup(G)139shows AbelianGroup(H)140proof141have hom := GroupIso.hom with iso142have target := GroupHom.target with hom143have commutative := IsAbelianGroup.commutative with (AbelianGroup.parts with abelian)144have transferred := GroupIso.commutative with iso, commutative145unfold Basic.AbelianGroup146exact⟨target, transferred⟩147148end IsoLaws149150theorem GroupIso.id (G : Set)151requires group : Group(G)152shows identity(G.carrier) : G ≃* G153proof154have hom := GroupHom.id with group155have bijective := identity.bijective at G.carrier156exact GroupIso.mk with hom, bijective157158theorem GroupIso.trans (f g G H K : Set)159requires first : f : G ≃* H160requires second : g : H ≃* K161shows compose(g, f, G.carrier, H.carrier, K.carrier) : G ≃* K162proof163have hom := GroupHom.comp with (GroupIso.hom with first), (GroupIso.hom with second)164have bijective := compose.bijective with (GroupIso.bijective with first), (GroupIso.bijective with second)165exact GroupIso.mk with hom, bijective166167-- An injective homomorphism is an isomorphism onto its image.168theorem GroupHom.iso_onto_range (f G H : Set)169requires hom : f : G →* H170requires injective : InjectiveBetween(f, G.carrier, H.carrier)171shows f : G ≃* subgroupGroup(H, functionImage(f, G.carrier, H.carrier))172proof173have corestricted := GroupHom.corestrict with hom174have injectiveImage := Injective.corestrict with injective175have surjectiveImage := GroupHom.corestrict_surjective with hom176have bijective : BijectiveBetween(f, G.carrier, Group.carrier(subgroupGroup(H, functionImage(f, G.carrier, H.carrier))))177rw subgroupGroup.carrierOf178exact⟨injectiveImage, surjectiveImage⟩179exact GroupIso.mk with corestricted, bijective180181theorem IsomorphicGroups.refl (G : Set)182requires group : Group(G)183shows G ≃* G184proof185have iso := GroupIso.id with group186witness identity(G.carrier)187exact iso188189theorem IsomorphicGroups.symm (G H : Set)190requires isomorphic : G ≃* H191shows H ≃* G192proof193obtain⟨f, iso⟩:= isomorphic194have inverse := GroupIso.symm with iso195witness converse(f, G.carrier, H.carrier)196exact inverse197198theorem IsomorphicGroups.trans (G H K : Set)199requires first : G ≃* H200requires second : H ≃* K201shows G ≃* K202proof203obtain⟨f, isoF⟩:= first204obtain⟨g, isoG⟩:= second205have composed := GroupIso.trans with isoF, isoG206witness compose(g, f, G.carrier, H.carrier, K.carrier)207exact composed208209theorem IsomorphicGroups.equipotent (G H : Set)210requires isomorphic : G ≃* H211shows G.carrier ≃ H.carrier212proof213obtain⟨f, iso⟩:= isomorphic214exact GroupIso.equipotent with iso215216theorem IsomorphicGroups.abelian (G H : Set)217requires isomorphic : G ≃* H218requires abelian : AbelianGroup(G)219shows AbelianGroup(H)220proof221obtain⟨f, iso⟩:= isomorphic222exact GroupIso.abelian with iso, abelian223224-- Automorphisms.225theorem GroupAutomorphism.iso (f G : Set)226requires automorphism : GroupAutomorphism(f, G)227shows f : G ≃* G228proof229exact automorphism230231theorem GroupAutomorphism.id (G : Set)232requires group : Group(G)233shows GroupAutomorphism(identity(G.carrier), G)234proof235unfold GroupAutomorphism236exact GroupIso.id with group237238theorem GroupAutomorphism.symm (f G : Set)239requires automorphism : GroupAutomorphism(f, G)240shows GroupAutomorphism(converse(f, G.carrier, G.carrier), G)241proof242have iso := GroupAutomorphism.iso with automorphism243unfold GroupAutomorphism244exact GroupIso.symm with iso245246theorem GroupAutomorphism.trans (f g G : Set)247requires first : GroupAutomorphism(f, G)248requires second : GroupAutomorphism(g, G)249shows GroupAutomorphism(compose(g, f, G.carrier, G.carrier, G.carrier), G)250proof251have isoF := GroupAutomorphism.iso with first252have isoG := GroupAutomorphism.iso with second253unfold GroupAutomorphism254exact GroupIso.trans with isoF, isoG255256section Automorphisms257variable (G : Set)258hypothesis group : Group(G)259260theorem conjugation.automorphism (g : G)261shows GroupAutomorphism(conjugation(G, g), G)262proof263have hom := conjugation.hom with*264have bijective := conjugation.bijective with*265unfold GroupAutomorphism266exact GroupIso.mk with hom, bijective267268theorem GroupAutomorphism.map_one (f : Set)269requires automorphism : GroupAutomorphism(f, G)270shows f(G.one) = G.one271proof272have hom := GroupIso.hom with (GroupAutomorphism.iso with automorphism)273exact GroupHom.map_one with hom274275theorem GroupAutomorphism.image_subgroup (f H : Set)276requires automorphism : GroupAutomorphism(f, G)277requires subgroup : Subgroup(H, G)278shows Subgroup(functionImage(f, H, G.carrier), G)279proof280have hom := GroupIso.hom with (GroupAutomorphism.iso with automorphism)281exact GroupHom.image_subgroup with hom, subgroup282283theorem GroupAutomorphism.image_normal (f N : Set)284requires automorphism : GroupAutomorphism(f, G)285requires normal : NormalSubgroup(N, G)286shows NormalSubgroup(functionImage(f, N, G.carrier), G)287proof288have iso := GroupAutomorphism.iso with automorphism289have hom := GroupIso.hom with iso290have surjective := GroupIso.surjective with iso291exact NormalSubgroup.image_of_surjective with hom, surjective, normal292293end Automorphisms294