1-- Group homomorphisms f : G →* H: maps preserving the operation, hence the2-- unit, inverses, and powers; identity, constant, and composite3-- homomorphisms4-- 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.Homomorphism10import Pow1112-- f : G →* H: a function between the carriers preserving the operation;13-- the unit and inverse laws follow. The form is a transparent guard, so a14-- hypothesis f : G →* H also supplies the groups G and H, their operations15-- a * b, and the binders (a : G) and (b : H).16predicate GroupHom (f G H : Set) :=17 Group(G) ∧ Group(H) ∧ (f : G.carrier → H.carrier) ∧18 (∀ x y ∈ G.carrier, f(x * y) = f(x) * f(y))1920notationguard"_ : _ →* _"=> GroupHom2122theorem GroupHom.mk (f G H : Set)23requires source : Group(G)24requires target : Group(H)25requires function : f : G.carrier → H.carrier26requires preserves : ∀ x y ∈ G.carrier, f(x * y) = f(x) * f(y)27shows f : G →* H28proof29unfold GroupHom30refine⟨source, target, function, preserves⟩3132section HomLaws33variable (f G H : Set)34hypothesis hom : f : G →* H3536theorem GroupHom.source37shows Group(G)38proof39obtain⟨source, rest⟩:= hom40exact source4142theorem GroupHom.target43shows Group(H)44proof45obtain⟨source, target, rest⟩:= hom46exact target4748theorem GroupHom.function49shows f : G.carrier → H.carrier50proof51obtain⟨source, target, function, preserves⟩:= hom52exact function5354theorem GroupHom.map_mul (a b : G)55shows f(a * b) = f(a) * f(b)56proof57obtain⟨source, target, function, preserves⟩:= hom58have aIn : a ∈ G byassumption59have bIn : b ∈ G byassumption60exact preserves with a, aIn, b, bIn6162instance GroupHom.map_mem (a : G)63shows f(a) ∈ H64proof65have function := GroupHom.function with hom66exact FunctionBetween.apply_closed with function, *6768theorem GroupHom.map_one69shows f(G.one) = H.one70proof71have group := GroupHom.source with hom72have target := GroupHom.target with hom73have preserved : f(G.one * G.one) = f(G.one) * f(G.one) := GroupHom.map_mul with*74rw mul_one at preserved75have criterion : f(G.one) * f(G.one) = f(G.one) ↔ f(G.one) = H.one := mul_self_eq_self with*76 symm at preserved77exact criterion.forward with preserved7879theorem GroupHom.map_inv (a : G)80shows f(a⁻¹) = f(a)⁻¹81proof82have product : f(a) * f(a⁻¹) = H.one83rw [← GroupHom.map_mul, Group.mul_inv, GroupHom.map_one]84rfl85exact eq_inv_of_mul_eq_one_right with*8687theorem GroupHom.map_mul_inv (a b : G)88shows f(a * b⁻¹) = f(a) * f(b)⁻¹89proof90rw [GroupHom.map_mul, GroupHom.map_inv]91rfl9293theorem GroupHom.map_inv_mul (a b : G)94shows f(a⁻¹ * b) = f(a)⁻¹ * f(b)95proof96rw [GroupHom.map_mul, GroupHom.map_inv]97rfl9899theorem GroupHom.map_pow (a : G) (n : Nat)100shows f(a ^ n) = f(a) ^ n101proof102have group := GroupHom.source with hom103have target := GroupHom.target with hom104induction n105| zero =>106rw [pow_zero, pow_zero, GroupHom.map_one]107rfl108| succ(k) using ih =>109rw [← add.right_one, pow_succ, pow_succ, GroupHom.map_mul, ih]110rfl111112theorem GroupHom.map_inv_eq_one (a : G)113requires vanishes : f(a) = H.one114shows f(a⁻¹) = H.one115proof116rw [GroupHom.map_inv, vanishes, inv_one]117rfl118119theorem GroupHom.ext (g : Set)120requires hom2 : g : G →* H121requires same : ∀ x ∈ G, f(x) = g(x)122shows f = g123proof124have fFunction := GroupHom.function with hom125have gFunction := GroupHom.function with hom2126exact FunctionBetween.ext with fFunction, gFunction, same127128theorem GroupHom.id_comp129shows compose(identity(H.carrier), f, G.carrier, H.carrier, H.carrier) = f130proof131have function := GroupHom.function with hom132exact compose.identity_left with function133134theorem GroupHom.comp_id135shows compose(f, identity(G.carrier), G.carrier, G.carrier, H.carrier) = f136proof137have function := GroupHom.function with hom138exact compose.identity_right with function139140end HomLaws141142theorem GroupHom.id (G : Set)143requires group : Group(G)144shows identity(G.carrier) : G →* G145proof146have function := identity.function at G.carrier147apply GroupHom.mk with group, group, function148intros x hx y hy149have vx := identity.apply with hx150have vy := identity.apply with hy151have closed : x * y ∈ G.carrier bytypecheck152have output := identity.apply with closed153rw [vx, vy]154exact output155156theorem GroupHom.const (G H : Set)157requires group : Group(G)158requires target : Group(H)159shows constantFunction(G.carrier, H.carrier, H.one) : G →* H160proof161have unitIn : H.one ∈ H.carrier := Group.one_mem with*162have function := constantFunction.function at G.carrier, H.carrier, H.one with unitIn163apply GroupHom.mk with group, target, function164intros x hx y hy165have vx := constantFunction.apply with hx, unitIn166have vy := constantFunction.apply with hy, unitIn167have closed : x * y ∈ G.carrier bytypecheck168have output := constantFunction.apply with closed, unitIn169rw [vx, vy, output, one_mul]170rfl171172theorem GroupHom.comp (f g G H K : Set)173requires first : f : G →* H174requires second : g : H →* K175shows compose(g, f, G.carrier, H.carrier, K.carrier) : G →* K176proof177have source := GroupHom.source with first178have target := GroupHom.target with second179have fFunction := GroupHom.function with first180have gFunction := GroupHom.function with second181have function := compose.function with fFunction, gFunction182apply GroupHom.mk with source, target, function183intros x hx y hy184have fx : f(x) ∈ H.carrier bytypecheck185have fy : f(y) ∈ H.carrier bytypecheck186have fMul : f(x * y) = f(x) * f(y) := GroupHom.map_mul with*187have gMul : g(f(x) * f(y)) = g(f(x)) * g(f(y)) := GroupHom.map_mul with*188have vx := compose.apply at g, f, G.carrier, H.carrier, K.carrier, x with*189have vy := compose.apply at g, f, G.carrier, H.carrier, K.carrier, y with*190have closed : x * y ∈ G.carrier bytypecheck191have output := compose.apply at g, f, G.carrier, H.carrier, K.carrier, x * y with*192cc193