1-- Image subrings and the general first isomorphism theorem in ZF.2-- 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.Ring.Image8import FirstIsomorphism9import Subring1011theorem IsRingHom.image_subring (f A add zero neg mul one B plus z minus times unit : Set)12requires source : IsCommRing(A, add, zero, neg, mul, one)13requires target : IsCommRing(B, plus, z, minus, times, unit)14requires hom : IsRingHom(f, A, add, zero, neg, mul, one, B, plus, z, minus, times, unit)15shows IsSubring(B, plus, z, minus, times, unit, functionImage(f, A, B))16proof17have function := IsRingHom.function with hom18havering:= IsCommRing.ring with source19have zeroIn := IsRing.zero_in_carrier withring20have oneIn : one ∈ A bysimp [IsCommRing, IsRing, IsMonoid, Identity]21have zeroValue := IsRingHom.zero with hom22have oneValue := IsRingHom.one with hom23have zeroImage := functionImage.value at f, A, B, zero with*24have oneImage := functionImage.value at f, A, B, one with*25have subset := functionImage.subset at f, A, B26unfold IsSubring27refine⟨subset, ⟨?_, ⟨?_, ⟨?_, ⟨?_, ?_⟩⟩⟩⟩⟩28 . cc29 . cc30intros y hy31obtain⟨yIn, x, hx, shape⟩:= functionImage.membership.forward with hy32have negative := IsRing.neg_closed at A, add, zero, neg, mul, one, x with*33have mapped := IsRingHom.neg at f, A, add, zero, neg, mul, one, B, plus, z, minus, times, unit, x with*34have output := functionImage.value at f, A, B, neg(x) with*35cc36intros y hy w hw37obtain⟨yIn, a, ha, sy⟩:= functionImage.membership.forward with hy38obtain⟨wIn, b, hb, sw⟩:= functionImage.membership.forward with hw39have closed := IsRing.add_closed at A, add, zero, neg, mul, one, a, b with*40have mapped := IsRingHom.add at f, A, add, zero, neg, mul, one, B, plus, z, minus, times, unit, a, b with*41have output := functionImage.value at f, A, B, call2(add, a, b) with*42cc43intros y hy w hw44obtain⟨yIn, c, hc, sy⟩:= functionImage.membership.forward with hy45obtain⟨wIn, d, hd, sw⟩:= functionImage.membership.forward with hw46have closed := IsRing.mul_closed at A, add, zero, neg, mul, one, c, d with*47have mapped := IsRingHom.mul at f, A, add, zero, neg, mul, one, B, plus, z, minus, times, unit, c, d with*48have output := functionImage.value at f, A, B, call2(mul, c, d) with*49cc5051theorem IsRingHom.image_comm_ring (f A add zero neg mul one B plus z minus times unit : Set)52requires source : IsCommRing(A, add, zero, neg, mul, one)53requires target : IsCommRing(B, plus, z, minus, times, unit)54requires hom : IsRingHom(f, A, add, zero, neg, mul, one, B, plus, z, minus, times, unit)55shows IsCommRing(functionImage(f, A, B), restrict(plus, functionImage(f, A, B) × functionImage(f, A, B)), z, restrict(minus, functionImage(f, A, B)), restrict(times, functionImage(f, A, B) × functionImage(f, A, B)), unit)56proof57have subring := IsRingHom.image_subring with source, target, hom58exact IsSubring.comm_ring with target, subring5960theorem IsRingHom.corestrict (f A add zero neg mul one B plus z minus times unit : Set)61requires source : IsCommRing(A, add, zero, neg, mul, one)62requires target : IsCommRing(B, plus, z, minus, times, unit)63requires hom : IsRingHom(f, A, add, zero, neg, mul, one, B, plus, z, minus, times, unit)64shows IsRingHom(f, A, add, zero, neg, mul, one, functionImage(f, A, B), restrict(plus, functionImage(f, A, B) × functionImage(f, A, B)), z, restrict(minus, functionImage(f, A, B)), restrict(times, functionImage(f, A, B) × functionImage(f, A, B)), unit)65proof66have function := IsRingHom.function with hom67have corestricted := functionImage.corestrict with*68have imageRing := IsRingHom.image_comm_ring with source, target, hom69have subring := IsRingHom.image_subring with source, target, hom70have subset := functionImage.subset at f, A, B71have addClosed := IsSubring.add_closed with*72have mulClosed := IsSubring.mul_closed with*73have addition : IsMagma(B, plus) bysimp [IsCommRing, IsRing, IsAbelianGroup, IsGroup, IsMonoid, IsSemigroup]74have multiplication : IsMagma(B, times) bysimp [IsCommRing, IsRing, IsMonoid, IsSemigroup]75apply IsRingHom.of_add_mul_one with source, imageRing, corestricted76 . intros x hx y hy77have fx := functionImage.value with function, hx78have fy := functionImage.value with function, hx79have mapped := IsRingHom.add with hx, hy80have restricted := restrictBinary.value at B, functionImage(f, A, B), plus, f(x), f(y) with*81cc82 . intros x hx y hy83have fx := functionImage.value with function, hx84have fy := functionImage.value with function, hx85have mapped := IsRingHom.mul with hx, hy86have restricted := restrictBinary.value at B, functionImage(f, A, B), times, f(x), f(y) with*87cc88 . exact IsRingHom.one with hom8990-- No surjectivity hypothesis: the target is the image subring.91theorem IsRingHom.first_isomorphism_image (f A add zero neg mul one B plus z minus times unit : Set)92requires source : IsCommRing(A, add, zero, neg, mul, one)93requires target : IsCommRing(B, plus, z, minus, times, unit)94requires hom : IsRingHom(f, A, add, zero, neg, mul, one, B, plus, z, minus, times, unit)95shows IsRingIso(quotientMap(f, A, functionImage(f, A, B), idealRelation(A, add, neg, ringKernel(f, A, z))), (A ⧸ idealRelation(A, add, neg, ringKernel(f, A, z))),96 quotientBinary(A, idealRelation(A, add, neg, ringKernel(f, A, z)), add), ⟦zero⟧[A, idealRelation(A, add, neg, ringKernel(f, A, z))],97 quotientUnary(A, idealRelation(A, add, neg, ringKernel(f, A, z)), neg), quotientBinary(A, idealRelation(A, add, neg, ringKernel(f, A, z)), mul), ⟦one⟧[A, idealRelation(A, add, neg, ringKernel(f, A, z))],98 functionImage(f, A, B), restrict(plus, functionImage(f, A, B) × functionImage(f, A, B)), z, restrict(minus, functionImage(f, A, B)), restrict(times, functionImage(f, A, B) × functionImage(f, A, B)), unit)99proof100have function := IsRingHom.function with hom101have imageRing := IsRingHom.image_comm_ring with source, target, hom102have corestricted := IsRingHom.corestrict with source, target, hom103have onto := functionImage.surjective with*104exact idealQuotient.first_isomorphism with source, imageRing, corestricted, onto105106-- Every homomorphism factors as a surjection followed by an inclusion.107theorem IsRingHom.image_factorization (f A add zero neg mul one B plus z minus times unit : Set)108requires source : IsCommRing(A, add, zero, neg, mul, one)109requires target : IsCommRing(B, plus, z, minus, times, unit)110requires hom : IsRingHom(f, A, add, zero, neg, mul, one, B, plus, z, minus, times, unit)111shows compose(identity(functionImage(f, A, B)), f, A, functionImage(f, A, B), B) = f112proof113have function := IsRingHom.function with hom114have corestricted := functionImage.corestrict with function115have subring := IsRingHom.image_subring with source, target, hom116have inclusion := IsSubring.inclusion_function with subring117have composed := compose.function at identity(functionImage(f, A, B)), f, A, functionImage(f, A, B), B with*118apply FunctionBetween.ext with composed, function119intros x hx120have fx := functionImage.value with function, hx121have value := compose.apply at identity(functionImage(f, A, B)), f, A, functionImage(f, A, B), B, x with*122have included := identity.apply with fx123cc124