1-- The canonical, injective coefficient-ring embedding into polynomials (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.Constants8import Ring910defgraph polynomialCoefficients (I A zero : Set) (a ∈ A) : polynomials(I, A, zero) := polynomialConstant(I, A, zero, a)11requires zeroIn : zero ∈ A12proof13exact polynomialConstant.member at I, A, zero, a with*1415notationscoped polynomialCoefficients(I, R) => polynomialCoefficients(I, R.carrier, R.zero)1617theorem polynomialConstant.value (I A zero a m : Set)18requires zeroIn : zero ∈ A19requires coefficient : a ∈ A20requires monomial : m ∈ monomials(I)21shows polynomialConstant(I, A, zero, a)(m) = singleValue(A, zero, a, monomialOne(I), m)22proof23unfold polynomialConstant24unfold polynomialTerm25exact coefficientSingle.value at monomials(I), A, zero, a, monomialOne(I), m with*2627theorem polynomialConstant.zero (I A zero : Set)28requires zeroIn : zero ∈ A29shows polynomialConstant(I, A, zero, zero) = constantFunction(monomials(I), A, zero)30proof31have member := polynomialConstant.member at I, A, zero, zero with*32have function := polynomials.function with member33have target := constantFunction.function at monomials(I), A, zero with*34apply FunctionBetween.ext with function, target35intros m hm36have value := polynomialConstant.value at I, A, zero, zero, m with*37have selected := singleValue.zero at A, zero, monomialOne(I), m with*38have constant := constantFunction.apply at monomials(I), A, m, zero with*39cc4041section Rings42variable (I A add zero neg mul one : Set)43hypothesisring : IsCommRing(A, add, zero, neg, mul, one)44notationring R := (A, add, zero, neg, mul, one)4546theorem polynomialConstant.add (a b : Set)47requires coefficientA : a ∈ A48requires coefficientB : b ∈ A49shows polynomialConstant(I, A, zero, a + b) = coefficientAdd(monomials(I), A, add, zero, neg, mul, one, polynomialConstant(I, A, zero, a), polynomialConstant(I, A, zero, b))50proof51have ordinary := IsCommRing.ring withring52have zeroIn := IsRing.zero_in_carrier with ordinary53have sumIn := IsRing.add_closed at A, add, zero, neg, mul, one, a, b with*54have memberA := polynomialConstant.member at I, A, zero, a with*55have memberB := polynomialConstant.member at I, A, zero, b with*56have memberSum := polynomialConstant.member at I, A, zero, a + b with*57have functionA := polynomials.function with memberA58have functionB := polynomials.function with memberB59have functionSum := polynomials.function with memberSum60have target := coefficientAdd.function at monomials(I), A, add, zero, neg, mul, one, polynomialConstant(I, A, zero, a), polynomialConstant(I, A, zero, b) with*61apply FunctionBetween.ext with functionSum, target62intros m hm63haveleft:= polynomialConstant.value at I, A, zero, a + b, m with*64have valueA := polynomialConstant.value at I, A, zero, a, m with*65have valueB := polynomialConstant.value at I, A, zero, b, m with*66haveright:= coefficientAdd.value at monomials(I), A, add, zero, neg, mul, one, polynomialConstant(I, A, zero, a), polynomialConstant(I, A, zero, b), m with*67have distribute := singleValue.add at A, add, zero, neg, mul, one, a, b, monomialOne(I), m with*68cc6970theorem polynomialConstant.neg (a : Set)71requires coefficient : a ∈ A72shows polynomialConstant(I, A, zero, -a) = coefficientNeg(monomials(I), A, add, zero, neg, mul, one, polynomialConstant(I, A, zero, a))73proof74have ordinary := IsCommRing.ring withring75have zeroIn := IsRing.zero_in_carrier with ordinary76have negative := IsRing.neg_closed at A, add, zero, neg, mul, one, a with*77have memberA := polynomialConstant.member at I, A, zero, a with*78have memberNeg := polynomialConstant.member at I, A, zero, -a with*79have functionA := polynomials.function with memberA80have functionNeg := polynomials.function with memberNeg81have target := coefficientNeg.function at monomials(I), A, add, zero, neg, mul, one, polynomialConstant(I, A, zero, a) with*82apply FunctionBetween.ext with functionNeg, target83intros m hm84haveleft:= polynomialConstant.value at I, A, zero, -a, m with*85have valueA := polynomialConstant.value at I, A, zero, a, m with*86haveright:= coefficientNeg.value at monomials(I), A, add, zero, neg, mul, one, polynomialConstant(I, A, zero, a), m with*87have alternatives : m = monomialOne(I) ∨ m ≠ monomialOne(I) bytauto88cases alternatives with same | different89 . have selectA := singleValue.same at A, zero, a, monomialOne(I), m with*90have selectNeg := singleValue.same at A, zero, -a, monomialOne(I), m with*91cc92 . have selectA := singleValue.other at A, zero, a, monomialOne(I), m with*93have selectNeg := singleValue.other at A, zero, -a, monomialOne(I), m with*94have negZero : -zero = zero byring95cc9697theorem polynomialConstant.mul (a b : Set)98requires coefficientA : a ∈ A99requires coefficientB : b ∈ A100shows polynomialConstant(I, A, zero, a * b) = polynomialProduct(I, A, add, zero, neg, mul, one, polynomialConstant(I, A, zero, a), polynomialConstant(I, A, zero, b))101proof102have unit := monomialOne.member at I103have terms := polynomialProduct.terms at I, A, add, zero, neg, mul, one, a, b, monomialOne(I), monomialOne(I) with*104have unitLaw := monomialProduct.one with*105unfold polynomialConstant106cc107108theorem polynomialCoefficients.hom109shows IsRingHom(polynomialCoefficients(I, A, zero), A, add, zero, neg, mul, one, 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))110proof111have ordinary := IsCommRing.ring withring112have zeroIn := IsRing.zero_in_carrier with ordinary113have multiplicative := IsRing.multiplicative with ordinary114have oneIn := IsMonoid.unit_in_carrier with multiplicative115have function := polynomialCoefficients.function at I, A, zero with*116have zeroValue := polynomialCoefficients.value at I, A, zero, zero with*117have zeroLaw := polynomialConstant.zero at I, A, zero with*118have oneValue := polynomialCoefficients.value at I, A, zero, one with*119have preservesZero : polynomialCoefficients(I, A, zero)(zero) = constantFunction(monomials(I), A, zero) bycc120have preservesNeg : ∀ x ∈ A, polynomialCoefficients(I, A, zero)(-x) = (polynomialNeg(I, A, add, zero, neg, mul, one))(polynomialCoefficients(I, A, zero)(x))121intros x hx122have negative := IsRing.neg_closed with hx123have member := polynomialConstant.member at I, A, zero, x with*124have source := polynomialCoefficients.value at I, A, zero, -x with*125have value := polynomialCoefficients.value at I, A, zero, x with*126have target := polynomialNeg.apply with*127have law := polynomialConstant.neg at I, A, add, zero, neg, mul, one, x with*128cc129have preservesAdd : ∀ x ∈ A, ∀ y ∈ A, polynomialCoefficients(I, A, zero)(x + y) = (polynomialAdd(I, A, add, zero, neg, mul, one))(polynomialCoefficients(I, A, zero)(x), polynomialCoefficients(I, A, zero)(y))130intros x hx y hy131have closed := IsRing.add_closed with hx, hy132have memberX := polynomialConstant.member at I, A, zero, x with*133have memberY := polynomialConstant.member at I, A, zero, y with*134have source := polynomialCoefficients.value at I, A, zero, x + y with*135have valueX := polynomialCoefficients.value at I, A, zero, x with*136have valueY := polynomialCoefficients.value at I, A, zero, y with*137have target := polynomialAdd.apply at I, A, add, zero, neg, mul, one, polynomialConstant(I, A, zero, x), polynomialConstant(I, A, zero, y) with*138have law := polynomialConstant.add at I, A, add, zero, neg, mul, one, x, y with*139cc140have preservesMul : ∀ x ∈ A, ∀ y ∈ A, polynomialCoefficients(I, A, zero)(x * y) = (polynomialMul(I, A, add, zero, neg, mul, one))(polynomialCoefficients(I, A, zero)(x), polynomialCoefficients(I, A, zero)(y))141intros x hx y hy142have closed := IsRing.mul_closed with hx, hy143have memberX := polynomialConstant.member at I, A, zero, x with*144have memberY := polynomialConstant.member at I, A, zero, y with*145have source := polynomialCoefficients.value at I, A, zero, x * y with*146have valueX := polynomialCoefficients.value at I, A, zero, x with*147have valueY := polynomialCoefficients.value at I, A, zero, y with*148have target := polynomialMul.apply at I, A, add, zero, neg, mul, one, polynomialConstant(I, A, zero, x), polynomialConstant(I, A, zero, y) with*149have law := polynomialConstant.mul at I, A, add, zero, neg, mul, one, x, y with*150cc151unfold IsRingHom152refine⟨function, preservesZero, oneValue, preservesNeg, preservesAdd, preservesMul⟩153154end Rings155156theorem polynomialCoefficients.injective (I A zero : Set)157requires zeroIn : zero ∈ A158shows InjectiveBetween(polynomialCoefficients(I, A, zero), A, polynomials(I, A, zero))159proof160have function := polynomialCoefficients.function at I, A, zero with*161constructor162 . exact function163 . intros x hx y hy z hz hxz hyz164have valueX := FunctionBetween.apply_value at polynomialCoefficients(I, A, zero), A, polynomials(I, A, zero), x, z with*165have valueY := FunctionBetween.apply_value at polynomialCoefficients(I, A, zero), A, polynomials(I, A, zero), y, z with*166have constantX := polynomialCoefficients.value at I, A, zero, x with*167have constantY := polynomialCoefficients.value at I, A, zero, y with*168have equal : polynomialConstant(I, A, zero, x) = polynomialConstant(I, A, zero, y) bycc169exact polynomialConstant.injective at I, A, zero, x, y with*170