1-- Finitely supported coefficient maps over a set-sized commutative ring (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.Coefficients8import Ring9import Cardinal.ListSupport1011def functionSupport (f I z : Set) : Set:= {i ∈ I | f(i) ≠ z}12predicate CoefficientMap (f I A z : Set) := FunctionBetween(f, I, A) ∧ Finite(functionSupport(f, I, z))13def coefficientMaps (I A z : Set) : Set:= {f ∈𝒫(I × A) | CoefficientMap(f, I, A, z)}1415theorem functionSupport.subset (f I z : Set)16shows functionSupport(f, I, z) ⊆ I17proof18simp1920theorem functionSupport.outside (f I z i : Set)21requires hi : i ∈ I22requires absent : ¬(i ∈ functionSupport(f, I, z))23shows f(i) = z24proof25ext y26simp2728theorem CoefficientMap.function (f I A z : Set)29requires map : CoefficientMap(f, I, A, z)30shows f : I → A31proof32exact map.left3334theorem CoefficientMap.finite_support (f I A z : Set)35requires map : CoefficientMap(f, I, A, z)36shows Finite(functionSupport(f, I, z))37proof38exact map.right3940theorem coefficientMaps.contains (I A z f : Set)41requires map : CoefficientMap(f, I, A, z)42shows f ∈ coefficientMaps(I, A, z)43proof44have function := CoefficientMap.function with map45have relation := FunctionBetween.relation with function46unfold RelationBetween at relation47unfold Subset at relation48have bound :=set.powerset.backward with relation49exact coefficientMaps.membership.backward with⟨bound, map⟩5051theorem CoefficientMap.ext (f g I A z : Set)52requiresleft : CoefficientMap(f, I, A, z)53requiresright : CoefficientMap(g, I, A, z)54requires values : ∀ i ∈ I, f(i) = g(i)55shows f = g56proof57have functionF := CoefficientMap.function withleft58have functionG := CoefficientMap.function withright59exact FunctionBetween.ext with functionF, functionG, values6061defgraph coefficientAdd (I A add zero neg mul one f g : Set) (i ∈ I) : A := call2(add, f(i), g(i))62requiresring : IsCommRing(A, add, zero, neg, mul, one)63requiresleft : f : I → A64requiresright : g : I → A65proof66have ordinary := IsCommRing.ring withring67have fi := FunctionBetween.apply_closed withleft, member68have gi := FunctionBetween.apply_closed withright, member69exact IsRing.add_closed with ordinary, fi, gi7071notationscoped coefficientAdd(I, R, f, g) => coefficientAdd(I, R.carrier, R.add, R.zero, R.neg, R.mul, R.one, f, g)7273defgraph coefficientNeg (I A add zero neg mul one f : Set) (i ∈ I) : A := neg(f(i))74requiresring : IsCommRing(A, add, zero, neg, mul, one)75requires function : f : I → A76proof77have ordinary := IsCommRing.ring withring78have fi := FunctionBetween.apply_closed with function, member79exact IsRing.neg_closed with ordinary, fi8081defgraph coefficientScale (I A add zero neg mul one a f : Set) (i ∈ I) : A := call2(mul, a, f(i))82requiresring : IsCommRing(A, add, zero, neg, mul, one)83requires scalar : a ∈ A84requires function : f : I → A85proof86have ordinary := IsCommRing.ring withring87have fi := FunctionBetween.apply_closed with function, member88exact IsRing.mul_closed with ordinary, scalar, fi8990notationscoped coefficientScale(I, R, a, f) => coefficientScale(I, R.carrier, R.add, R.zero, R.neg, R.mul, R.one, a, f)9192section Rings93variable (I A add zero neg mul one : Set)94hypothesisring : IsCommRing(A, add, zero, neg, mul, one)95notationring R := (A, add, zero, neg, mul, one)9697theorem CoefficientMap.zero98shows CoefficientMap(constantFunction(I, A, zero), I, A, zero)99proof100have ordinary := IsCommRing.ring withring101have zeroIn := IsRing.zero_in_carrier with ordinary102have function := constantFunction.function at I, A, zero with zeroIn103have support : functionSupport(constantFunction(I, A, zero), I, zero) =∅104ext i105constructor106 . intro member107have data := functionSupport.membership.forward with member108have value := constantFunction.apply with data.left, zeroIn109havecontradiction:= data.right with value110tauto111 . intro member112simp113unfold CoefficientMap114refine⟨function, ?_⟩115rw support116exact Finite.empty117118theorem coefficientAdd.support (f g : Set)119requiresleft : f : I → A120requiresright : g : I → A121shows functionSupport(coefficientAdd(I, A, add, zero, neg, mul, one, f, g), I, zero) ⊆ functionSupport(f, I, zero) ∪ functionSupport(g, I, zero)122proof123have ordinary := IsCommRing.ring withring124have zeroIn := IsRing.zero_in_carrier with ordinary125have zeroSum : 0+0=0byring126intros i hi127have data := functionSupport.membership.forward with hi128have value := coefficientAdd.value at I, A, add, zero, neg, mul, one, f, g, i with*129have casesF : f(i) = zero ∨ f(i) ≠ zero bytauto130have casesG : g(i) = zero ∨ g(i) ≠ zero bytauto131cases casesF with fZero | fNonzero132 . cases casesG with gZero | gNonzero133 . have equal : coefficientAdd(I, A, add, zero, neg, mul, one, f, g)(i) = zero134cc135havecontradiction:= data.right with equal136tauto137 . have member : i ∈ functionSupport(g, I, zero)138exact functionSupport.membership.backward with⟨data.left, gNonzero⟩139apply union2.membership.backward140right141exact member142 . have member : i ∈ functionSupport(f, I, zero)143exact functionSupport.membership.backward with⟨data.left, fNonzero⟩144apply union2.membership.backward145left146exact member147148theorem CoefficientMap.add (f g : Set)149requiresleft : CoefficientMap(f, I, A, zero)150requiresright : CoefficientMap(g, I, A, zero)151shows CoefficientMap(coefficientAdd(I, A, add, zero, neg, mul, one, f, g), I, A, zero)152proof153have functionF := CoefficientMap.function withleft154have functionG := CoefficientMap.function withright155have finiteF := CoefficientMap.finite_support withleft156have finiteG := CoefficientMap.finite_support withright157have finiteUnion := Finite.union with finiteF, finiteG158have support := coefficientAdd.support withring, functionF, functionG159have finite := Finite.subset with finiteUnion, support160have function := coefficientAdd.function at I, A, add, zero, neg, mul, one, f, g with*161unfold CoefficientMap162refine⟨function, finite⟩163164theorem coefficientNeg.support (f : Set)165requires function : f : I → A166shows functionSupport(coefficientNeg(I, A, add, zero, neg, mul, one, f), I, zero) ⊆ functionSupport(f, I, zero)167proof168have zeroValue : -0=0byring169intros i hi170have data := functionSupport.membership.forward with hi171have value := coefficientNeg.value at I, A, add, zero, neg, mul, one, f, i with*172have casesF : f(i) = zero ∨ f(i) ≠ zero bytauto173cases casesF with fZero | fNonzero174 . have equal : coefficientNeg(I, A, add, zero, neg, mul, one, f)(i) = zero175cc176havecontradiction:= data.right with equal177tauto178 . apply functionSupport.membership.backward at f, I, zero, i179refine⟨data.left, fNonzero⟩180181theorem CoefficientMap.neg (f : Set)182requires map : CoefficientMap(f, I, A, zero)183shows CoefficientMap(coefficientNeg(I, A, add, zero, neg, mul, one, f), I, A, zero)184proof185have functionF := CoefficientMap.function with map186have finiteF := CoefficientMap.finite_support with map187have support := coefficientNeg.support with*188have finite := Finite.subset with finiteF, support189have function := coefficientNeg.function at I, A, add, zero, neg, mul, one, f with*190unfold CoefficientMap191refine⟨function, finite⟩192193theorem coefficientScale.support (a f : Set)194requires scalar : a ∈ A195requires function : f : I → A196shows functionSupport(coefficientScale(I, A, add, zero, neg, mul, one, a, f), I, zero) ⊆ functionSupport(f, I, zero)197proof198have zeroValue : a *0=0byring199intros i hi200have data := functionSupport.membership.forward with hi201have value := coefficientScale.value at I, A, add, zero, neg, mul, one, a, f, i with*202have casesF : f(i) = zero ∨ f(i) ≠ zero bytauto203cases casesF with fZero | fNonzero204 . have equal : coefficientScale(I, A, add, zero, neg, mul, one, a, f)(i) = zero205cc206havecontradiction:= data.right with equal207tauto208 . apply functionSupport.membership.backward at f, I, zero, i209refine⟨data.left, fNonzero⟩210211theorem CoefficientMap.scale (a f : Set)212requires scalar : a ∈ A213requires map : CoefficientMap(f, I, A, zero)214shows CoefficientMap(coefficientScale(I, A, add, zero, neg, mul, one, a, f), I, A, zero)215proof216have functionF := CoefficientMap.function with map217have finiteF := CoefficientMap.finite_support with map218have support := coefficientScale.support with*219have finite := Finite.subset with finiteF, support220have function := coefficientScale.function at I, A, add, zero, neg, mul, one, a, f with*221unfold CoefficientMap222refine⟨function, finite⟩223224theorem CoefficientMap.support_list (f : Set)225requires map : CoefficientMap(f, I, A, zero)226shows∃ xs, List(I, xs) ∧ functionSupport(f, I, zero) ⊆ listSupport{I}(xs)227proof228have finite := CoefficientMap.finite_support with map229have subset := functionSupport.subset at f, I, zero230exact Finite.cover_in with finite, subset231232theorem coefficientAdd.commutative (f g : Set)233requires functionF : f : I → A234requires functionG : g : I → A235shows coefficientAdd(I, A, add, zero, neg, mul, one, f, g) = coefficientAdd(I, A, add, zero, neg, mul, one, g, f)236proof237have ordinary := IsCommRing.ring withring238have zeroIn := IsRing.zero_in_carrier with ordinary239have function0 := coefficientAdd.function at I, A, add, zero, neg, mul, one, f, g with*240have function1 := coefficientAdd.function at I, A, add, zero, neg, mul, one, g, f with*241apply FunctionBetween.ext with function0, function1242intros i hi243have fIn := FunctionBetween.apply_closed at f, I, A, i with*244have gIn := FunctionBetween.apply_closed at g, I, A, i with*245have value0 := coefficientAdd.value at I, A, add, zero, neg, mul, one, f, g, i with*246have value1 := coefficientAdd.value at I, A, add, zero, neg, mul, one, g, f, i with*247rw [value1, value0]248ring249250theorem coefficientAdd.associative (f g h : Set)251requires functionF : f : I → A252requires functionG : g : I → A253requires functionH : h : I → A254shows coefficientAdd(I, A, add, zero, neg, mul, one, coefficientAdd(I, A, add, zero, neg, mul, one, f, g), h) = coefficientAdd(I, A, add, zero, neg, mul, one, f, coefficientAdd(I, A, add, zero, neg, mul, one, g, h))255proof256have ordinary := IsCommRing.ring withring257have zeroIn := IsRing.zero_in_carrier with ordinary258have function0 := coefficientAdd.function at I, A, add, zero, neg, mul, one, f, g with*259have function1 := coefficientAdd.function at I, A, add, zero, neg, mul, one, coefficientAdd(I, A, add, zero, neg, mul, one, f, g), h with*260have function2 := coefficientAdd.function at I, A, add, zero, neg, mul, one, g, h with*261have function3 := coefficientAdd.function at I, A, add, zero, neg, mul, one, f, coefficientAdd(I, A, add, zero, neg, mul, one, g, h) with*262apply FunctionBetween.ext with function1, function3263intros i hi264have fIn := FunctionBetween.apply_closed at f, I, A, i with*265have gIn := FunctionBetween.apply_closed at g, I, A, i with*266have hIn := FunctionBetween.apply_closed at h, I, A, i with*267have value0 := coefficientAdd.value at I, A, add, zero, neg, mul, one, f, g, i with*268have value1 := coefficientAdd.value at I, A, add, zero, neg, mul, one, coefficientAdd(I, A, add, zero, neg, mul, one, f, g), h, i with*269have value2 := coefficientAdd.value at I, A, add, zero, neg, mul, one, g, h, i with*270have value3 := coefficientAdd.value at I, A, add, zero, neg, mul, one, f, coefficientAdd(I, A, add, zero, neg, mul, one, g, h), i with*271rw [value3, value2, value1, value0]272ring273274theorem coefficientAdd.zero (f : Set)275requires functionF : f : I → A276shows coefficientAdd(I, A, add, zero, neg, mul, one, f, constantFunction(I, A, zero)) = f277proof278have ordinary := IsCommRing.ring withring279have zeroIn := IsRing.zero_in_carrier with ordinary280have functionZero := constantFunction.function at I, A, zero with zeroIn281have function0 := coefficientAdd.function at I, A, add, zero, neg, mul, one, f, constantFunction(I, A, zero) with*282apply FunctionBetween.ext with function0, functionF283intros i hi284have fIn := FunctionBetween.apply_closed at f, I, A, i with*285have zeroValue := constantFunction.apply at I, A, i, zero with*286have value0 := coefficientAdd.value at I, A, add, zero, neg, mul, one, f, constantFunction(I, A, zero), i with*287rw [value0, zeroValue]288ring289290theorem coefficientAdd.inverse (f : Set)291requires functionF : f : I → A292shows coefficientAdd(I, A, add, zero, neg, mul, one, f, coefficientNeg(I, A, add, zero, neg, mul, one, f)) = constantFunction(I, A, zero)293proof294have ordinary := IsCommRing.ring withring295have zeroIn := IsRing.zero_in_carrier with ordinary296have functionZero := constantFunction.function at I, A, zero with zeroIn297have function0 := coefficientNeg.function at I, A, add, zero, neg, mul, one, f with*298have function1 := coefficientAdd.function at I, A, add, zero, neg, mul, one, f, coefficientNeg(I, A, add, zero, neg, mul, one, f) with*299apply FunctionBetween.ext with function1, functionZero300intros i hi301have fIn := FunctionBetween.apply_closed at f, I, A, i with*302have zeroValue := constantFunction.apply at I, A, i, zero with*303have value0 := coefficientNeg.value at I, A, add, zero, neg, mul, one, f, i with*304have value1 := coefficientAdd.value at I, A, add, zero, neg, mul, one, f, coefficientNeg(I, A, add, zero, neg, mul, one, f), i with*305rw [value1, value0, zeroValue]306ring307308theorem coefficientScale.one (f : Set)309requires functionF : f : I → A310shows coefficientScale(I, A, add, zero, neg, mul, one, one, f) = f311proof312have ordinary := IsCommRing.ring withring313have zeroIn := IsRing.zero_in_carrier with ordinary314have multiplicative := IsRing.multiplicative with ordinary315have oneIn := IsMonoid.unit_in_carrier with multiplicative316have function0 := coefficientScale.function at I, A, add, zero, neg, mul, one, one, f with*317apply FunctionBetween.ext with function0, functionF318intros i hi319have fIn := FunctionBetween.apply_closed at f, I, A, i with*320have value0 := coefficientScale.value at I, A, add, zero, neg, mul, one, one, f, i with*321rw value0322ring323324theorem coefficientScale.associative (a b f : Set)325requires aIn : a ∈ A326requires bIn : b ∈ A327requires functionF : f : I → A328shows coefficientScale(I, A, add, zero, neg, mul, one, a, coefficientScale(I, A, add, zero, neg, mul, one, b, f)) = coefficientScale(I, A, add, zero, neg, mul, one, call2(mul, a, b), f)329proof330have ordinary := IsCommRing.ring withring331have zeroIn := IsRing.zero_in_carrier with ordinary332have productIn := IsRing.mul_closed at A, add, zero, neg, mul, one, a,333 b with*334have function0 := coefficientScale.function at I, A, add, zero, neg, mul, one, b, f with*335have function1 := coefficientScale.function at I, A, add, zero, neg, mul, one, a, coefficientScale(I, A, add, zero, neg, mul, one, b, f) with*336have function2 := coefficientScale.function at I, A, add, zero, neg, mul, one, call2(mul, a, b), f with*337apply FunctionBetween.ext with function1, function2338intros i hi339have fIn := FunctionBetween.apply_closed at f, I, A, i with*340have value0 := coefficientScale.value at I, A, add, zero, neg, mul, one, b, f, i with*341have value1 := coefficientScale.value at I, A, add, zero, neg, mul, one, a, coefficientScale(I, A, add, zero, neg, mul, one, b, f), i with*342have value2 := coefficientScale.value at I, A, add, zero, neg, mul, one, call2(mul, a, b), f, i with*343rw [value2, value1, value0]344ring345346theorem coefficientScale.add (a f g : Set)347requires aIn : a ∈ A348requires functionF : f : I → A349requires functionG : g : I → A350shows coefficientScale(I, A, add, zero, neg, mul, one, a, coefficientAdd(I, A, add, zero, neg, mul, one, f, g)) = coefficientAdd(I, A, add, zero, neg, mul, one, coefficientScale(I, A, add, zero, neg, mul, one, a, f), coefficientScale(I, A, add, zero, neg, mul, one, a, g))351proof352have ordinary := IsCommRing.ring withring353have zeroIn := IsRing.zero_in_carrier with ordinary354have function0 := coefficientAdd.function at I, A, add, zero, neg, mul, one, f, g with*355have function1 := coefficientScale.function at I, A, add, zero, neg, mul, one, a, coefficientAdd(I, A, add, zero, neg, mul, one, f, g) with*356have function2 := coefficientScale.function at I, A, add, zero, neg, mul, one, a, f with*357have function3 := coefficientScale.function at I, A, add, zero, neg, mul, one, a, g with*358have function4 := coefficientAdd.function at I, A, add, zero, neg, mul, one, coefficientScale(I, A, add, zero, neg, mul, one, a, f), coefficientScale(I, A, add, zero, neg, mul, one, a, g) with*359apply FunctionBetween.ext with function1, function4360intros i hi361have fIn := FunctionBetween.apply_closed at f, I, A, i with*362have gIn := FunctionBetween.apply_closed at g, I, A, i with*363have value0 := coefficientAdd.value at I, A, add, zero, neg, mul, one, f, g, i with*364have value1 := coefficientScale.value at I, A, add, zero, neg, mul, one, a, coefficientAdd(I, A, add, zero, neg, mul, one, f, g), i with*365have value2 := coefficientScale.value at I, A, add, zero, neg, mul, one, a, f, i with*366have value3 := coefficientScale.value at I, A, add, zero, neg, mul, one, a, g, i with*367have value4 := coefficientAdd.value at I, A, add, zero, neg, mul, one, coefficientScale(I, A, add, zero, neg, mul, one, a, f), coefficientScale(I, A, add, zero, neg, mul, one, a, g), i with*368rw [value4, value3, value2, value1, value0]369ring370371end Rings372