1-- Actual polynomial operation graphs and their commutative-ring structure (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.Polynomial.Ring8import Associativity910defunique polynomialPairAdd (I A add zero neg mul one t : Set) (s ∈ polynomials(I, A, zero)) :=11∃ p ∈ polynomials(I, A, zero), ∃ q ∈ polynomials(I, A, zero), t = (p, q) ∧ s = coefficientAdd(monomials(I), A, add, zero, neg, mul, one, p, q)12requiresring : IsCommRing(A, add, zero, neg, mul, one)13requires pair : t ∈ polynomials(I, A, zero) × polynomials(I, A, zero)14proof15obtain⟨bound, p, hp, q, hq, shape⟩:= product.membership.forward at16 polynomials(I, A, zero), polynomials(I, A, zero), t with pair17have member := polynomials.add at I, A, add, zero, neg, mul, one, p, q with*18refine⟨coefficientAdd(monomials(I), A, add, zero, neg, mul, one, p, q), member, p, hp, q, hq, shape, rfl⟩19uniqueness20intros u hu first v hv second21obtain⟨p, hp, q, hq, shapeU, valueU⟩:= first22obtain⟨r, hr, s, hs, shapeV, valueV⟩:= second23have equal : (p, q) = (r, s)24cc25have coordinates := orderedPair.injective at p, q, r, s with equal26cc2728defgraph polynomialAdd (I A add zero neg mul one : Set) (t ∈ polynomials(I, A, zero) × polynomials(I, A, zero)) : polynomials(I, A, zero) := polynomialPairAdd(I, A, add, zero, neg, mul, one, t)29requiresring : IsCommRing(A, add, zero, neg, mul, one)30proof31have selected := polynomialPairAdd.selected at I, A, add, zero, neg, mul, one, t with*32exact selected.left3334notationscoped polynomialAdd(I, R) => polynomialAdd(I, R.carrier, R.add, R.zero, R.neg, R.mul, R.one)3536theorem polynomialAdd.apply (I A add zero neg mul one p q : Set)37requiresring : IsCommRing(A, add, zero, neg, mul, one)38requires memberP : p ∈ polynomials(I, A, zero)39requires memberQ : q ∈ polynomials(I, A, zero)40shows (polynomialAdd(I, A, add, zero, neg, mul, one))(p, q) = coefficientAdd(monomials(I), A, add, zero, neg, mul, one, p, q)41proof42have pair := product.pair at p, q, polynomials(I, A, zero), polynomials(I, A, zero) with*43have selected := polynomialPairAdd.selected at I, A, add, zero, neg, mul, one, (p, q) with*44obtain⟨r, hr, s, hs, shape, output⟩:= selected.right45have coordinates := orderedPair.injective with shape46have value := polynomialAdd.value at I, A, add, zero, neg, mul, one, (p, q) with*47unfold call248cc4950defunique polynomialPairMul (I A add zero neg mul one t : Set) (s ∈ polynomials(I, A, zero)) :=51∃ p ∈ polynomials(I, A, zero), ∃ q ∈ polynomials(I, A, zero), t = (p, q) ∧ s = polynomialProduct(I, A, add, zero, neg, mul, one, p, q)52requiresring : IsCommRing(A, add, zero, neg, mul, one)53requires pair : t ∈ polynomials(I, A, zero) × polynomials(I, A, zero)54proof55obtain⟨bound, p, hp, q, hq, shape⟩:= product.membership.forward with pair56have member := polynomialProduct.member with hp, hq57refine⟨polynomialProduct(I, A, add, zero, neg, mul, one, p, q), member, p, hp, q, hq, shape, rfl⟩58uniqueness59intros u hu first v hv second60obtain⟨p, hp, q, hq, shapeU, valueU⟩:= first61obtain⟨r, hr, s, hs, shapeV, valueV⟩:= second62have equal : (p, q) = (r, s) bycc63have coordinates := orderedPair.injective with equal64cc6566defgraph polynomialMul (I A add zero neg mul one : Set) (t ∈ polynomials(I, A, zero) × polynomials(I, A, zero)) : polynomials(I, A, zero) := polynomialPairMul(I, A, add, zero, neg, mul, one, t)67requiresring : IsCommRing(A, add, zero, neg, mul, one)68proof69have selected := polynomialPairMul.selected at I, A, add, zero, neg, mul, one, t with*70exact selected.left7172notationscoped polynomialMul(I, R) => polynomialMul(I, R.carrier, R.add, R.zero, R.neg, R.mul, R.one)7374theorem polynomialMul.apply (I A add zero neg mul one p q : Set)75requiresring : IsCommRing(A, add, zero, neg, mul, one)76requires memberP : p ∈ polynomials(I, A, zero)77requires memberQ : q ∈ polynomials(I, A, zero)78shows (polynomialMul(I, A, add, zero, neg, mul, one))(p, q) = polynomialProduct(I, A, add, zero, neg, mul, one, p, q)79proof80have pair := product.pair at p, q, polynomials(I, A, zero), polynomials(I, A, zero) with*81have selected := polynomialPairMul.selected at I, A, add, zero, neg, mul, one, (p, q) with*82obtain⟨r, hr, s, hs, shape, output⟩:= selected.right83have coordinates := orderedPair.injective with shape84have value := polynomialMul.value at I, A, add, zero, neg, mul, one, (p, q) with*85unfold call286cc8788defgraph polynomialNeg (I A add zero neg mul one : Set) (p ∈ polynomials(I, A, zero)) : polynomials(I, A, zero) := coefficientNeg(monomials(I), A, add, zero, neg, mul, one, p)89requiresring : IsCommRing(A, add, zero, neg, mul, one)90proof91exact polynomials.neg with*9293notationscoped polynomialNeg(I, R) => polynomialNeg(I, R.carrier, R.add, R.zero, R.neg, R.mul, R.one)9495theorem polynomialNeg.apply (I A add zero neg mul one p : Set)96requiresring : IsCommRing(A, add, zero, neg, mul, one)97requires member : p ∈ polynomials(I, A, zero)98shows (polynomialNeg(I, A, add, zero, neg, mul, one))(p) = coefficientNeg(monomials(I), A, add, zero, neg, mul, one, p)99proof100exact polynomialNeg.value at I, A, add, zero, neg, mul, one, p with*101102section Rings103variable (I A add zero neg mul one : Set)104hypothesisring : IsCommRing(A, add, zero, neg, mul, one)105notationring P := (polynomials(I, A, zero), polynomialAdd(I, A, add, zero, neg, mul, one), constantFunction(monomials(I), A, zero), polynomialNeg(I, A, add, zero, neg, mul, one), polynomialMul(I, A, add, zero, neg, mul, one), polynomialConstant(I, A, zero, one))106107theorem polynomials.add_commutative (p q : Set)108requires memberP : p ∈ polynomials(I, A, zero)109requires memberQ : q ∈ polynomials(I, A, zero)110shows p + q = q + p111proof112have functionP := polynomials.function with memberP113have functionQ := polynomials.function with memberQ114have member0 := polynomials.add at I, A, add, zero, neg, mul, one, p, q with*115have value0 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, p, q with*116have member1 := polynomials.add at I, A, add, zero, neg, mul, one, q, p with*117have value1 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, q, p with*118have law := coefficientAdd.commutative at monomials(I), A, add, zero, neg, mul, one, p, q with*119cc120121theorem polynomials.add_associative (p q r : Set)122requires memberP : p ∈ polynomials(I, A, zero)123requires memberQ : q ∈ polynomials(I, A, zero)124requires memberR : r ∈ polynomials(I, A, zero)125shows (p + q) + r = p + (q + r)126proof127have functionP := polynomials.function with memberP128have functionQ := polynomials.function with memberQ129have functionR := polynomials.function with memberR130have member0 := polynomials.add at I, A, add, zero, neg, mul, one, p, q with*131have value0 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, p, q with*132have member1 := polynomials.add at I, A, add, zero, neg, mul, one, q, r with*133have value1 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, q, r with*134have member2 := polynomials.add at I, A, add, zero, neg, mul, one, coefficientAdd(monomials(I), A, add, zero, neg, mul, one, p, q), r with*135have value2 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, coefficientAdd(monomials(I), A, add, zero, neg, mul, one, p, q), r with*136have member3 := polynomials.add at I, A, add, zero, neg, mul, one, p, coefficientAdd(monomials(I), A, add, zero, neg, mul, one, q, r) with*137have value3 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, p, coefficientAdd(monomials(I), A, add, zero, neg, mul, one, q, r) with*138have law := coefficientAdd.associative at monomials(I), A, add, zero, neg, mul, one, p, q, r with*139cc140141theorem polynomials.add_zero (p : Set)142requires memberP : p ∈ polynomials(I, A, zero)143shows p +0= p144proof145have functionP := polynomials.function with memberP146have zeroPolynomial := polynomials.zero at I, A, add, zero, neg, mul, one with*147have member0 := polynomials.add at I, A, add, zero, neg, mul, one, p, constantFunction(monomials(I), A, zero) with*148have value0 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, p, constantFunction(monomials(I), A, zero) with*149have law := coefficientAdd.zero with*150cc151152theorem polynomials.add_inverse (p : Set)153requires memberP : p ∈ polynomials(I, A, zero)154shows p + (-p) =0155proof156have functionP := polynomials.function with memberP157have negative := polynomials.neg with*158have negValue := polynomialNeg.apply at I, A, add, zero, neg, mul, one, p with*159have member0 := polynomials.add at I, A, add, zero, neg, mul, one, p, coefficientNeg(monomials(I), A, add, zero, neg, mul, one, p) with*160have value0 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, p, coefficientNeg(monomials(I), A, add, zero, neg, mul, one, p) with*161have law := coefficientAdd.inverse with*162cc163164theorem polynomials.mul_commutative (p q : Set)165requires memberP : p ∈ polynomials(I, A, zero)166requires memberQ : q ∈ polynomials(I, A, zero)167shows p * q = q * p168proof169have functionP := polynomials.function with memberP170have functionQ := polynomials.function with memberQ171have member0 := polynomialProduct.member at I, A, add, zero, neg, mul, one, p, q with*172have value0 := polynomialMul.apply at I, A, add, zero, neg, mul, one, p, q with*173have member1 := polynomialProduct.member at I, A, add, zero, neg, mul, one, q, p with*174have value1 := polynomialMul.apply at I, A, add, zero, neg, mul, one, q, p with*175have law := polynomialProduct.commutative at I, A, add, zero, neg, mul, one, p, q with*176cc177178theorem polynomials.mul_associative (p q r : Set)179requires memberP : p ∈ polynomials(I, A, zero)180requires memberQ : q ∈ polynomials(I, A, zero)181requires memberR : r ∈ polynomials(I, A, zero)182shows (p * q) * r = p * (q * r)183proof184have functionP := polynomials.function with memberP185have functionQ := polynomials.function with memberQ186have functionR := polynomials.function with memberR187have member0 := polynomialProduct.member at I, A, add, zero, neg, mul, one, p, q with*188have value0 := polynomialMul.apply at I, A, add, zero, neg, mul, one, p, q with*189have member1 := polynomialProduct.member at I, A, add, zero, neg, mul, one, q, r with*190have value1 := polynomialMul.apply at I, A, add, zero, neg, mul, one, q, r with*191have member2 := polynomialProduct.member at I, A, add, zero, neg, mul, one, polynomialProduct(I, A, add, zero, neg, mul, one, p, q), r with*192have value2 := polynomialMul.apply at I, A, add, zero, neg, mul, one, polynomialProduct(I, A, add, zero, neg, mul, one, p, q), r with*193have member3 := polynomialProduct.member at I, A, add, zero, neg, mul, one, p, polynomialProduct(I, A, add, zero, neg, mul, one, q, r) with*194have value3 := polynomialMul.apply at I, A, add, zero, neg, mul, one, p, polynomialProduct(I, A, add, zero, neg, mul, one, q, r) with*195have law := polynomialProduct.associative at I, A, add, zero, neg, mul, one, p, q, r with*196cc197198theorem polynomials.mul_one (p : Set)199requires memberP : p ∈ polynomials(I, A, zero)200shows p *1= p201proof202have functionP := polynomials.function with memberP203have ordinary := IsCommRing.ring withring204have zeroIn := IsRing.zero_in_carrier with ordinary205have multiplicative := IsRing.multiplicative with ordinary206have oneIn := IsMonoid.unit_in_carrier with multiplicative207have unitPolynomial := polynomialConstant.member at I, A, zero, one with*208have member0 := polynomialProduct.member at I, A, add, zero, neg, mul, one, p, polynomialConstant(I, A, zero, one) with*209have value0 := polynomialMul.apply at I, A, add, zero, neg, mul, one, p, polynomialConstant(I, A, zero, one) with*210have law := polynomialProduct.one_right at I, A, add, zero, neg, mul, one, p with*211cc212213theorem polynomials.distribute_right (p q r : Set)214requires memberP : p ∈ polynomials(I, A, zero)215requires memberQ : q ∈ polynomials(I, A, zero)216requires memberR : r ∈ polynomials(I, A, zero)217shows p * (q + r) = p * q + p * r218proof219have functionP := polynomials.function with memberP220have functionQ := polynomials.function with memberQ221have functionR := polynomials.function with memberR222have member0 := polynomials.add at I, A, add, zero, neg, mul, one, q, r with*223have value0 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, q, r with*224have member1 := polynomialProduct.member at I, A, add, zero, neg, mul, one, p, coefficientAdd(monomials(I), A, add, zero, neg, mul, one, q, r) with*225have value1 := polynomialMul.apply at I, A, add, zero, neg, mul, one, p, coefficientAdd(monomials(I), A, add, zero, neg, mul, one, q, r) with*226have member2 := polynomialProduct.member at I, A, add, zero, neg, mul, one, p, q with*227have value2 := polynomialMul.apply at I, A, add, zero, neg, mul, one, p, q with*228have member3 := polynomialProduct.member at I, A, add, zero, neg, mul, one, p, r with*229have value3 := polynomialMul.apply at I, A, add, zero, neg, mul, one, p, r with*230have member4 := polynomials.add at I, A, add, zero, neg, mul, one, polynomialProduct(I, A, add, zero, neg, mul, one, p, q), polynomialProduct(I, A, add, zero, neg, mul, one, p, r) with*231have value4 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, polynomialProduct(I, A, add, zero, neg, mul, one, p, q), polynomialProduct(I, A, add, zero, neg, mul, one, p, r) with*232have law := polynomialProduct.add_right at I, A, add, zero, neg, mul, one, p, q, r with*233cc234235theorem polynomials.distribute_left (p q r : Set)236requires memberP : p ∈ polynomials(I, A, zero)237requires memberQ : q ∈ polynomials(I, A, zero)238requires memberR : r ∈ polynomials(I, A, zero)239shows (p + q) * r = p * r + q * r240proof241have functionP := polynomials.function with memberP242have functionQ := polynomials.function with memberQ243have functionR := polynomials.function with memberR244have member0 := polynomials.add at I, A, add, zero, neg, mul, one, p, q with*245have value0 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, p, q with*246have member1 := polynomialProduct.member at I, A, add, zero, neg, mul, one, coefficientAdd(monomials(I), A, add, zero, neg, mul, one, p, q), r with*247have value1 := polynomialMul.apply at I, A, add, zero, neg, mul, one, coefficientAdd(monomials(I), A, add, zero, neg, mul, one, p, q), r with*248have member2 := polynomialProduct.member at I, A, add, zero, neg, mul, one, p, r with*249have value2 := polynomialMul.apply at I, A, add, zero, neg, mul, one, p, r with*250have member3 := polynomialProduct.member at I, A, add, zero, neg, mul, one, q, r with*251have value3 := polynomialMul.apply at I, A, add, zero, neg, mul, one, q, r with*252have member4 := polynomials.add at I, A, add, zero, neg, mul, one, polynomialProduct(I, A, add, zero, neg, mul, one, p, r), polynomialProduct(I, A, add, zero, neg, mul, one, q, r) with*253have value4 := polynomialAdd.apply at I, A, add, zero, neg, mul, one, polynomialProduct(I, A, add, zero, neg, mul, one, p, r), polynomialProduct(I, A, add, zero, neg, mul, one, q, r) with*254have law := polynomialProduct.add_left at I, A, add, zero, neg, mul, one, p, q, r with*255cc256257instance polynomials.comm_ring258shows IsCommRing(polynomials(I, A, zero), polynomialAdd(I, A, add, zero, neg, mul, one), constantFunction(monomials(I), A, zero), polynomialNeg(I, A, add, zero, neg, mul, one), polynomialMul(I, A, add, zero, neg, mul, one), polynomialConstant(I, A, zero, one))259proof260have addition := polynomialAdd.function at I, A, add, zero, neg, mul, one with*261have multiplication := polynomialMul.function at I, A, add, zero, neg, mul, one with*262have negation := polynomialNeg.function at I, A, add, zero, neg, mul, one with*263have zeroPolynomial := polynomials.zero at I, A, add, zero, neg, mul, one with*264have ordinary := IsCommRing.ring withring265have zeroIn := IsRing.zero_in_carrier with ordinary266have multiplicative := IsRing.multiplicative with ordinary267have oneIn := IsMonoid.unit_in_carrier with multiplicative268have unitPolynomial := polynomialConstant.member at I, A, zero, one with*269have addAssoc : Associative(polynomials(I, A, zero), polynomialAdd(I, A, add, zero, neg, mul, one))270intros p hp q hq r hr271exact polynomials.add_associative with*272have addComm : Commutative(polynomials(I, A, zero), polynomialAdd(I, A, add, zero, neg, mul, one))273intros p hp q hq274exact polynomials.add_commutative with*275have addIdentity : Identity(polynomials(I, A, zero), polynomialAdd(I, A, add, zero, neg, mul, one), constantFunction(monomials(I), A, zero))276constructor277 . exact zeroPolynomial278 . intros p hp279haveright:= polynomials.add_zero with hp280have comm := polynomials.add_commutative at I, A, add, zero, neg, mul, one, constantFunction(monomials(I), A, zero), p with*281constructor282 . cc283 . exactright284have inverses : Inverse(polynomials(I, A, zero), polynomialAdd(I, A, add, zero, neg, mul, one), constantFunction(monomials(I), A, zero), polynomialNeg(I, A, add, zero, neg, mul, one))285constructor286 . exact negation287 . intros p hp288have negative := polynomials.neg with hp289have value := polynomialNeg.apply with hp290haveright:= polynomials.add_inverse with hp291have comm := polynomials.add_commutative at I, A, add, zero, neg, mul, one, coefficientNeg(monomials(I), A, add, zero, neg, mul, one, p), p with*292constructor293 . cc294 . exactright295have mulAssoc : Associative(polynomials(I, A, zero), polynomialMul(I, A, add, zero, neg, mul, one))296intros p hp q hq r hr297exact polynomials.mul_associative with*298have mulComm : Commutative(polynomials(I, A, zero), polynomialMul(I, A, add, zero, neg, mul, one))299intros p hp q hq300exact polynomials.mul_commutative with*301have mulIdentity : Identity(polynomials(I, A, zero), polynomialMul(I, A, add, zero, neg, mul, one), polynomialConstant(I, A, zero, one))302constructor303 . exact unitPolynomial304 . intros p hp305haveright:= polynomials.mul_one with hp306have comm := polynomials.mul_commutative at I, A, add, zero, neg, mul, one, polynomialConstant(I, A, zero, one), p with*307constructor308 . cc309 . exactright310have distributive : Distributive(polynomials(I, A, zero), polynomialAdd(I, A, add, zero, neg, mul, one), polynomialMul(I, A, add, zero, neg, mul, one))311intros p hp q hq r hr312constructor313 . exact polynomials.distribute_right with*314 . exact polynomials.distribute_left with*315have additive : IsAbelianGroup(polynomials(I, A, zero), polynomialAdd(I, A, add, zero, neg, mul, one), constantFunction(monomials(I), A, zero), polynomialNeg(I, A, add, zero, neg, mul, one))316unfold IsAbelianGroup317refine⟨_, addComm⟩318unfold IsGroup319refine⟨_, inverses⟩320unfold IsMonoid321refine⟨_, addIdentity⟩322unfold IsSemigroup323refine⟨_, addAssoc⟩324exact addition325have multiplicativePolynomial : IsMonoid(polynomials(I, A, zero), polynomialMul(I, A, add, zero, neg, mul, one), polynomialConstant(I, A, zero, one))326unfold IsMonoid327refine⟨_, mulIdentity⟩328unfold IsSemigroup329refine⟨_, mulAssoc⟩330exact multiplication331constructor332 . unfold IsRing333refine⟨additive, multiplicativePolynomial, distributive⟩334 . exact mulComm335336end Rings337