1-- Coefficient witnesses for adjoining a generator to a linear span (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.SpanInsert8import LinearSpan910def scalarExtension (f A B plus times M x : Set) : Set:=11 {y ∈ B |∃ a ∈ A, ∃ u ∈ M, y = plus(times(f(a), x), u)}1213section Algebras14variable (A add zero neg mul one B plus z minus times unit f M x : Set)15notationring R := (A, add, zero, neg, mul, one)16notationring S := (B, plus, z, minus, times, unit)17hypothesis source : IsCommRing(R)18hypothesis target : IsCommRing(S)19hypothesis hom : IsRingHom(f, R, S)20hypothesis submodule : Submodule(f, R, S, M)21hypothesis element : x ∈ S2223theorem scalarExtension.submodule24shows Submodule(f, R, S, scalarExtension(f, A, B, plus, times, M, x))25proof26have r := IsCommRing.ring with source27have s := IsCommRing.ring with target28have sourceZero := IsRing.zero_in_carrier with r29have targetZero := IsRing.zero_in_carrier with s30have zeroMem := Submodule.zero_mem with source, target, hom, submodule31have boundedM := Submodule.subset with source, target, hom, submodule32have negM := Submodule.neg_closed with source, target, hom, submodule33have addM := Submodule.add_closed with source, target, hom, submodule34have bounded : scalarExtension(f, A, B, plus, times, M, x) ⊆ S bysimp [Subset, scalarExtension]35have zeroMember : S[0] ∈ scalarExtension(f, A, B, plus, times, M, x)36apply scalarExtension.membership.backward37refine⟨targetZero, zero, sourceZero, z, zeroMem, ?_⟩38have mapped := IsRingHom.zero with hom39rw mapped40ring41have negative : ClosedUnary(scalarExtension(f, A, B, plus, times, M, x), minus)42intros y hy43obtain⟨member, a, ha, u, hu, equation⟩:= scalarExtension.membership.forward with hy44have negativeY := IsRing.neg_closed with s, member45have negativeA := IsRing.neg_closed with r, ha46have negativeU := ClosedUnary.mem with negM, hu47have inB : u ∈ S byexact boundedM with u, hu48have image := IsRingHom.closed with hom, ha49apply scalarExtension.membership.backward50refine⟨negativeY, R[-a], negativeA, S[-u], negativeU, ?_⟩51have mapped := IsRingHom.neg with hom, ha52rw [mapped, equation]53ring54have addition : ClosedBinary(scalarExtension(f, A, B, plus, times, M, x), plus)55intros y hy w hw56obtain⟨memberY, a, ha, u, hu, equationY⟩:= scalarExtension.membership.forward with hy57obtain⟨memberW, b, hb, v, hv, equationW⟩:= scalarExtension.membership.forward with hw58have sum := IsRing.add_closed with s, memberY, memberW59have coefficient := IsRing.add_closed with r, ha, hb60have remainder := ClosedBinary.mem with addM, hu, hv61have inB : u ∈ S ∧ v ∈ S62have first := boundedM with u, hu63have second := boundedM with v, hv64refine⟨first, second⟩65have memberU := inB.left66have memberV := inB.right67have imageA := IsRingHom.closed with hom, ha68have imageB := IsRingHom.closed with hom, hb69apply scalarExtension.membership.backward70refine⟨sum, R[a + b], coefficient, S[u + v], remainder, ?_⟩71have mapped := IsRingHom.add with hom, ha, hb72rw [mapped, equationY, equationW]73ring74have scalars : ∀ c ∈ R, ∀ y ∈ scalarExtension(f, A, B, plus, times, M, x), S[f(c) * y] ∈ scalarExtension(f, A, B, plus, times, M, x)75intros c hc y hy76obtain⟨member, a, ha, u, hu, equation⟩:= scalarExtension.membership.forward with hy77have imageC := IsRingHom.closed with hom, hc78have imageA := IsRingHom.closed with hom, ha79have product := IsRing.mul_closed with s, imageC, member80have coefficient := IsRing.mul_closed with r, hc, ha81have remainder := Submodule.scalar_mul_mem with source, target, hom, submodule, hc, hu82have inB : u ∈ S byexact boundedM with u, hu83apply scalarExtension.membership.backward84refine⟨product, R[c * a], coefficient, S[f(c) * u], remainder, ?_⟩85have mapped := IsRingHom.mul with hom, hc, ha86rw [mapped, equation]87ring88unfold Submodule89refine⟨bounded, zeroMember, negative, addition, scalars⟩9091theorem scalarExtension.contains92shows insert(x, M) ⊆ scalarExtension(f, A, B, plus, times, M, x)93proof94have r := IsCommRing.ring with source95have s := IsCommRing.ring with target96have zeroIn := IsRing.zero_in_carrier with r97have oneIn : R[1] ∈ R bytypecheck98have zeroMem := Submodule.zero_mem with source, target, hom, submodule99have bound := Submodule.subset with source, target, hom, submodule100intros y hy101have alternatives := insert.membership.forward with hy102cases alternatives with equal | old103 . rw equal104apply scalarExtension.membership.backward105refine⟨element, one, oneIn, z, zeroMem, ?_⟩106have mapped := IsRingHom.one with hom107rw mapped108ring109 . have member : y ∈ S110exact bound with y, old111apply scalarExtension.membership.backward112refine⟨member, zero, zeroIn, y, old, ?_⟩113have mapped := IsRingHom.zero with hom114rw mapped115ring116117end Algebras118119section Spans120variable (A add zero neg mul one B plus z minus times unit f G x : Set)121notationring R := (A, add, zero, neg, mul, one)122notationring S := (B, plus, z, minus, times, unit)123hypothesis source : IsCommRing(R)124hypothesis target : IsCommRing(S)125hypothesis hom : IsRingHom(f, R, S)126hypothesis bounded : G ⊆ S127hypothesis element : x ∈ S128129theorem linearSpan.insert130shows linearSpan(f, R, S, insert(x, G)) = scalarExtension(f, A, B, plus, times, linearSpan(f, R, S, G), x)131proof132have span := linearSpan.submodule at A, add, zero, neg, mul, one, B, plus, z, minus, times, unit, f, G with*133have extension := scalarExtension.submodule with source, target, hom, span, element134have contains := scalarExtension.contains with source, target, hom, span, element135have oldContains := linearSpan.contains with source, target, hom, bounded136have generators : insert(x, G) ⊆ scalarExtension(f, A, B, plus, times, linearSpan(f, R, S, G), x)137simp138have first := linearSpan.least with source, target, hom, extension, generators139have enlarged := linearSpan.submodule at A, add, zero, neg, mul, one, B, plus, z, minus, times, unit, f, insert(x, G) with*140have bound : insert(x, G) ⊆ S bysimp [Subset, insert.membership]141have included := linearSpan.contains with source, target, hom, bound142have xIn : x ∈ linearSpan(f, R, S, insert(x, G)) bysettlewith Subset, insert.membership143have old : G ⊆ insert(x, G) bysimp [Subset, insert.membership]144have oldSpan := linearSpan.mono with source, target, hom, bound, old145have addClosed := Submodule.add_closed with source, target, hom, enlarged146have second : scalarExtension(f, A, B, plus, times, linearSpan(f, R, S, G), x) ⊆ linearSpan(f, R, S, insert(x, G))147intros y hy148obtain⟨member, a, ha, u, hu, equation⟩:= scalarExtension.membership.forward with hy149have scalar := Submodule.scalar_mul_mem with source, target, hom, enlarged, ha, xIn150have rest : u ∈ linearSpan(f, R, S, insert(x, G)) byexact oldSpan with u, hu151rw equation152exact ClosedBinary.mem with addClosed, scalar, rest153exact Subset.antisymmetric with first, second154155theorem linearSpan.insert_membership (y : Set)156shows y ∈ linearSpan(f, R, S, insert(x, G)) ↔157 y ∈ S ∧ (∃ a ∈ R, ∃ u ∈ linearSpan(f, R, S, G), y = S[f(a) * x + u])158proof159have equation := linearSpan.insert with source, target, hom, bounded, element160rw equation161exact scalarExtension.membership162163end Spans164section EmptySpan165variable (A add zero neg mul one B plus z minus times unit f : Set)166notationring R := (A, add, zero, neg, mul, one)167notationring S := (B, plus, z, minus, times, unit)168hypothesis source : IsCommRing(R)169hypothesis target : IsCommRing(S)170hypothesis hom : IsRingHom(f, R, S)171172theorem Submodule.zero173shows Submodule(f, R, S, {S[0]})174proof175have ordinary := IsCommRing.ring with target176have zeroIn := IsRing.zero_in_carrier with ordinary177have bounded : {S[0]} ⊆ S bysimp [Subset, singleton.membership]178have zeroMember : S[0] ∈ {S[0]} bysimp [singleton.membership]179have negative : ClosedUnary({S[0]}, minus)180intros u hu181have equal := singleton.membership.forward with hu182rw equal183have value : S[-0] = S[0] byring184 rwa value185have addition : ClosedBinary({S[0]}, plus)186intros u hu v hv187have first := singleton.membership.forward with hu188have second := singleton.membership.forward with hv189rw [first, second]190have value : S[0+0] = S[0] byring191 rwa value192have scalars : ∀ a ∈ R, ∀ u ∈ {S[0]}, S[f(a) * u] ∈ {S[0]}193intros a ha u hu194have image := IsRingHom.closed with hom, ha195have equal := singleton.membership.forward with hu196rw equal197have value : S[f(a) *0] = S[0] byring198 rwa value199unfold Submodule200refine⟨bounded, zeroMember, negative, addition, scalars⟩201202theorem linearSpan.empty203shows linearSpan(f, R, S, ∅) = {S[0]}204proof205have zeroModule := Submodule.zero with*206have empty := empty.subset at {S[0]}207have first := linearSpan.least with source, target, hom, zeroModule, empty208have span := linearSpan.submodule at A, add, zero, neg, mul, one, B, plus, z, minus, times, unit, f, ∅with*209have zeroMember := Submodule.zero_mem with source, target, hom, span210have second : {S[0]} ⊆ linearSpan(f, R, S, ∅)211intros y hy212have equal := singleton.membership.forward with hy213 rwa equal214exact Subset.antisymmetric with first, second215216end EmptySpan217