1-- Evaluation of bundled polynomials: evaluationHom(R, S, I, f, v), the2-- homomorphism polynomialRing(R, I) →+* S sending the constants through3-- f : R →+* S and the variable X(R, I, j) to v(j), its universal property,4-- and evaluationAt(R, I, v) at a point of the coefficient ring; everything5-- here is ZF6-- Part of Cumulus, the Grace17 mathematics library.7-- Copyright (c) 2026 Grant Passmore.8-- Released under the Apache License 2.0. See LICENSE in the repository root.9-- Authors: Grant Passmore1011module Grace.Cumulus.Algebra.Polynomial.BundledEvaluation12import Bundled13import EvaluationOver1415-- Evaluation at an assignment v : I → S through a coefficient16-- homomorphism f, and at a point v : I → R of the coefficient ring itself.17def evaluationHom (R S I f v : Set) : Set:=18 polynomialAtOver(I, R.carrier, R.add, R.zero, R.neg, R.mul, R.one,19 S.carrier, S.add, S.zero, S.neg, S.mul, S.one, f, v)20def evaluationAt (R I v : Set) : Set:=21 polynomialAt(I, R.carrier, R.add, R.zero, R.neg, R.mul, R.one, v)2223theorem evaluationHom.graph (R S I f v : Set)24shows evaluationHom(R, S, I, f, v) =25 polynomialAtOver(I, R.carrier, R.add, R.zero, R.neg, R.mul, R.one,26 S.carrier, S.add, S.zero, S.neg, S.mul, S.one, f, v)27proof28simp [evaluationHom]2930theorem evaluationAt.graph (R I v : Set)31shows evaluationAt(R, I, v) =32 polynomialAt(I, R.carrier, R.add, R.zero, R.neg, R.mul, R.one, v)33proof34simp [evaluationAt]3536section Evaluation37variable (R S I f v : Set)38notationring K := (R.carrier, R.add, R.zero, R.neg, R.mul, R.one)39notationring L := (S.carrier, S.add, S.zero, S.neg, S.mul, S.one)40notationring P := K[I]41hypothesis source : CommRing(R)42hypothesis target : CommRing(S)43hypothesis hom : f : R→+* S44hypothesis assignment : v : I → S.carrier4546theorem evaluationHom.hom47shows evaluationHom(R, S, I, f, v) : polynomialRing(R, I) →+* S48proof49have sourceParts := CommRing.parts with source50have targetParts := CommRing.parts with target51have homParts := RingHom.parts with hom52have engine := polynomialAtOver.hom with sourceParts, targetParts,53 homParts, assignment54rw evaluationHom.graph55exact RingHom.polynomial_of_parts with source, target, engine5657instance evaluationHom.map_mem (p : polynomialRing(R, I))58shows evaluationHom(R, S, I, f, v)(p) ∈ S59proof60have evaluation := evaluationHom.hom at R, S, I, f, v with*61exact RingHom.map_mem with*6263theorem evaluationHom.map_constant (a : R)64shows evaluationHom(R, S, I, f, v)(polynomialConstant(R, I)(a)) = f(a)65proof66have sourceParts := CommRing.parts with source67have targetParts := CommRing.parts with target68have homParts := RingHom.parts with hom69have aIn : a ∈ R byassumption70have engine := polynomialAtOver.constant with sourceParts, targetParts,71 homParts, assignment, aIn72rw [polynomialConstant.apply, evaluationHom.graph]73exact engine7475theorem evaluationHom.map_X (j : Set)76requires index : j ∈ I77shows evaluationHom(R, S, I, f, v)(X(R, I, j)) = v(j)78proof79have sourceParts := CommRing.parts with source80have targetParts := CommRing.parts with target81have homParts := RingHom.parts with hom82have engine := polynomialAtOver.variable with sourceParts, targetParts,83 homParts, assignment, index84rw [X.value, evaluationHom.graph]85exact engine8687-- A homomorphism agreeing with f on the constants and with v on the88-- variables is the evaluation.89theorem evaluationHom.unique (g : Set)90requires candidate : g : polynomialRing(R, I) →+* S91requires constants : ∀ a ∈ R, g(polynomialConstant(R, I)(a)) = f(a)92requires variables : ∀ j ∈ I, g(X(R, I, j)) = v(j)93shows g = evaluationHom(R, S, I, f, v)94proof95have sourceParts := CommRing.parts with source96have targetParts := CommRing.parts with target97have homParts := RingHom.parts with hom98have engineHom := RingHom.polynomial_parts with source, target, candidate99have engineConstants : ∀ a ∈ R, g(polynomialConstant(I, K, a)) = f(a)100intros a ha101rw← polynomialConstant.apply102exact constants with a, ha103have engineVariables : ∀ j ∈ I, g(polynomialVariable(I, K, j)) = v(j)104intros j hj105rw← X.value106exact variables with j, hj107rw evaluationHom.graph108exact polynomialAtOver.unique with sourceParts, targetParts, homParts,109 assignment, engineHom, engineConstants, engineVariables110111-- The universal property of the polynomial ring: exactly one homomorphism112-- extends f along the constants and sends each variable to its value.113theorem polynomialRing.universal114shows (evaluationHom(R, S, I, f, v) : polynomialRing(R, I) →+* S) ∧115 (∀ a ∈ R,116 evaluationHom(R, S, I, f, v)(polynomialConstant(R, I)(a)) = f(a)) ∧117 (∀ j ∈ I, evaluationHom(R, S, I, f, v)(X(R, I, j)) = v(j)) ∧118 (∀ g, (g : polynomialRing(R, I) →+* S) →119 (∀ a ∈ R, g(polynomialConstant(R, I)(a)) = f(a)) →120 (∀ j ∈ I, g(X(R, I, j)) = v(j)) → g = evaluationHom(R, S, I, f, v))121proof122have evaluation := evaluationHom.hom at R, S, I, f, v with*123refine⟨evaluation, ?_, ?_, ?_⟩124 . intros a ha125exact evaluationHom.map_constant with*126 . intros j hj127exact evaluationHom.map_X with*128 . intros g candidate constants variables129exact evaluationHom.unique with*130131end Evaluation132133section Points134variable (R I v : Set)135notationring K := (R.carrier, R.add, R.zero, R.neg, R.mul, R.one)136notationring P := K[I]137hypothesis comm : CommRing(R)138hypothesis assignment : v : I → R.carrier139140theorem evaluationAt.hom141shows evaluationAt(R, I, v) : polynomialRing(R, I) →+* R142proof143have parts := CommRing.parts with comm144have engine := polynomialAt.hom with parts, assignment145rw evaluationAt.graph146exact RingHom.polynomial_of_parts with comm, comm, engine147148instance evaluationAt.map_mem (p : polynomialRing(R, I))149shows evaluationAt(R, I, v)(p) ∈ R150proof151have evaluation := evaluationAt.hom at R, I, v with*152exact RingHom.map_mem with*153154theorem evaluationAt.map_constant (a : R)155shows evaluationAt(R, I, v)(polynomialConstant(R, I)(a)) = a156proof157have parts := CommRing.parts with comm158have aIn : a ∈ R byassumption159have engine := polynomialAt.constant with parts, assignment, aIn160rw [polynomialConstant.apply, evaluationAt.graph]161exact engine162163theorem evaluationAt.map_X (j : Set)164requires index : j ∈ I165shows evaluationAt(R, I, v)(X(R, I, j)) = v(j)166proof167have parts := CommRing.parts with comm168have engine := polynomialAt.variable with parts, assignment, index169rw [X.value, evaluationAt.graph]170exact engine171172theorem evaluationAt.surjective173shows SurjectiveBetween(evaluationAt(R, I, v),174 Ring.carrier(polynomialRing(R, I)), R.carrier)175proof176have parts := CommRing.parts with comm177have engine := polynomialAt.surjective with parts, assignment178rw [evaluationAt.graph, polynomialRing.carrierOf]179exact engine180181-- Evaluation at a point is evaluation through the identity of R.182theorem evaluationAt.eq_evaluationHom183shows evaluationAt(R, I, v) = evaluationHom(R, R, I, identity(R.carrier), v)184proof185have parts := CommRing.parts with comm186have engine := polynomialAtOver.identity_coefficients with parts, assignment187rw [evaluationAt.graph, evaluationHom.graph]188 symm189exact engine190191end Points192