1-- Moving a polynomial between variable sets, preserving supported evaluations (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.Transfer8import EvaluationSupport910defgraph polynomialTransferVariables (I J A z one : Set) (i ∈ I) : polynomials(J, A, z) := polynomialVariable(J, A, z, one, i)11requires zeroIn : z ∈ A12requires oneIn : one ∈ A13proof14exact polynomialVariable.member with*1516def polynomialTransfer (I J A add z neg mul one : Set) : Set:=17 polynomialAtOver(I, A, add, z, neg, mul, one, polynomials(J, A, z), polynomialAdd(J, A, add, z, neg, mul, one), constantFunction(monomials(J), A, z), polynomialNeg(J, A, add, z, neg, mul, one), polynomialMul(J, A, add, z, neg, mul, one), polynomialConstant(J, A, z, one), polynomialCoefficients(J, A, z), polynomialTransferVariables(I, J, A, z, one))1819notationscoped polynomialTransfer(I, J, R) => polynomialTransfer(I, J, R.carrier, R.add, R.zero, R.neg, R.mul, R.one)2021section Rings22variable (I J A add z neg mul one : Set)23notationring R := (A, add, z, neg, mul, one)24notationring P := R[I]25notationring Q := R[J]26hypothesisring : IsCommRing(R)2728theorem polynomialTransfer.hom29shows IsRingHom(polynomialTransfer(I, J, R), P, Q)30proof31have target : IsCommRing(Q)32exact polynomials.comm_ring with*33have coefficients : IsRingHom(polynomialCoefficients(J, R), R, Q)34exact polynomialCoefficients.hom with*35have zeroIn : R[0] ∈ R bytypecheck36have oneIn : R[1] ∈ R bytypecheck37have assignment := polynomialTransferVariables.function at I, J, A, z, one with*38unfold polynomialTransfer39exact polynomialAtOver.hom with*4041theorem polynomialTransfer.constant (a : Set)42requires coefficient : a ∈ R43shows polynomialTransfer(I, J, R)(polynomialConstant(I, R, a)) = polynomialConstant(J, R, a)44proof45have target : IsCommRing(Q)46exact polynomials.comm_ring with*47have coefficients : IsRingHom(polynomialCoefficients(J, R), R, Q)48exact polynomialCoefficients.hom with*49have zeroIn : R[0] ∈ R bytypecheck50have oneIn : R[1] ∈ R bytypecheck51have assignment := polynomialTransferVariables.function at I, J, A, z, one with*52have value := polynomialCoefficients.value at J, A, z, a with*53unfold polynomialTransfer54 rwa polynomialAtOver.constant5556theorem polynomialTransfer.variable (i : Set)57requires index : i ∈ I58shows polynomialTransfer(I, J, R)(polynomialVariable(I, R, i)) = polynomialVariable(J, R, i)59proof60have target : IsCommRing(Q)61exact polynomials.comm_ring with*62have coefficients : IsRingHom(polynomialCoefficients(J, R), R, Q)63exact polynomialCoefficients.hom with*64have zeroIn : R[0] ∈ R bytypecheck65have oneIn : R[1] ∈ R bytypecheck66have assignment := polynomialTransferVariables.function at I, J, A, z, one with*67have value := polynomialTransferVariables.value at I, J, A, z, one, i with*68unfold polynomialTransfer69 rwa polynomialAtOver.variable7071theorem polynomialTransfer.outside_variable (i : Set)72requires index : i ∈ I73requires outside : ¬(i ∈ J)74shows polynomialTransfer(I, J, R)(polynomialVariable(I, R, i)) = Q[1]75proof76have mapped := polynomialTransfer.variable at I, J, A, add, z, neg, mul, one, i with*77have monomial := monomialVariable.member at J, i78have unit := monomialOne.member at J79have same : monomialVariable(J, i) = monomialOne(J)80apply monomials.ext with monomial, unit81intros k member82have distinct : k ≠ i83intro equal84rw equal at member85exact outside with member86have value := coefficientSingle.other at J, ℕ, (0:Nat), (1:Nat), i, k with*87have zero := monomialOne.value at J, k with*88unfold monomialVariable89cc90rw mapped91simp [polynomialVariable, polynomialConstant]9293section Evaluation94variable (B plus o minus times unit f v w : Set)95notationring S := (B, plus, o, minus, times, unit)96hypothesis target : IsCommRing(S)97hypothesis hom : IsRingHom(f, R, S)98hypothesis first : v : I → S99hypothesis second : w : J → S100101theorem polynomialTransfer.evaluate_supported (p : Set)102requires polynomial : p ∈ P103requires supported : polynomialVariablesUsed(I, R, p) ⊆ J104requires agreement : ∀ i ∈ polynomialVariablesUsed(I, R, p), v(i) = w(i)105shows polynomialAtOver(J, R, S, f, w)(polynomialTransfer(I, J, R)(p)) = polynomialAtOver(I, R, S, f, v)(p)106proof107have transfer : IsRingHom(polynomialTransfer(I, J, R), P, Q)108exact polynomialTransfer.hom with*109have evaluationI : IsRingHom(polynomialAtOver(I, R, S, f, v), P, S)110exact polynomialAtOver.hom with*111have evaluationJ : IsRingHom(polynomialAtOver(J, R, S, f, w), Q, S)112exact polynomialAtOver.hom with*113have sourceRing : IsCommRing(P)114exact polynomials.comm_ring with*115have combined := IsRingHom.compose with sourceRing, transfer, evaluationJ116have functionT := IsRingHom.function with transfer117have functionJ := IsRingHom.function with evaluationJ118have zeroIn : R[0] ∈ R bytypecheck119have oneIn : R[1] ∈ R bytypecheck120have constants : ∀ a ∈ R, compose(polynomialAtOver(J, R, S, f, w), polynomialTransfer(I, J, R), P, Q, S)(polynomialConstant(I, R, a)) = f(a)121intros a coefficient122have member := polynomialConstant.member at I, A, z, a with*123have composed := compose.apply at polynomialAtOver(J, R, S, f, w), polynomialTransfer(I, J, R), P, Q, S, polynomialConstant(I, R, a) with*124have mapped := polynomialTransfer.constant at I, J, A, add, z, neg, mul, one, a with*125have evaluated := polynomialAtOver.constant at J, A, add, z, neg, mul, one, B, plus, o, minus, times, unit, f, w, a with*126cc127have originals : ∀ a ∈ R, polynomialAtOver(I, R, S, f, v)(polynomialConstant(I, R, a)) = f(a)128intros a coefficient129exact polynomialAtOver.constant with*130have variables : ∀ i ∈ polynomialVariablesUsed(I, R, p), compose(polynomialAtOver(J, R, S, f, w), polynomialTransfer(I, J, R), P, Q, S)(polynomialVariable(I, R, i)) = polynomialAtOver(I, R, S, f, v)(polynomialVariable(I, R, i))131intros i used132have subset := polynomialVariablesUsed.subset at I, A, z, p133have inI := subset with i, used134have inJ := supported with i, used135have member := polynomialVariable.member at I, A, z, one, i with*136have composed := compose.apply at polynomialAtOver(J, R, S, f, w), polynomialTransfer(I, J, R), P, Q, S, polynomialVariable(I, R, i) with*137have mapped := polynomialTransfer.variable at I, J, A, add, z, neg, mul, one, i with*138have evaluated := polynomialAtOver.variable at J, A, add, z, neg, mul, one, B, plus, o, minus, times, unit, f, w, i with*139have original := polynomialAtOver.variable at I, A, add, z, neg, mul, one, B, plus, o, minus, times, unit, f, v, i with*140have same := agreement with i, used141cc142have equal := IsRingHom.polynomial_local_ext with*143have value := compose.apply at polynomialAtOver(J, R, S, f, w), polynomialTransfer(I, J, R), P, Q, S, p with*144cc145146end Evaluation147148theorem polynomialTransfer.roundtrip (p : Set)149requires polynomial : p ∈ P150requires supported : polynomialVariablesUsed(I, R, p) ⊆ J151shows polynomialTransfer(J, I, R)(polynomialTransfer(I, J, R)(p)) = p152proof153have target : IsCommRing(P)154exact polynomials.comm_ring with*155have coefficients : IsRingHom(polynomialCoefficients(I, R), R, P)156exact polynomialCoefficients.hom with*157have zeroIn : R[0] ∈ R bytypecheck158have oneIn : R[1] ∈ R bytypecheck159have first := polynomialVariables.function at I, A, z, one with*160have second := polynomialTransferVariables.function at J, I, A, z, one with*161have agreement : ∀ i ∈ polynomialVariablesUsed(I, R, p), polynomialVariables(I, R)(i) = polynomialTransferVariables(J, I, A, z, one)(i)162intros i used163have subset := polynomialVariablesUsed.subset at I, A, z, p164have inI := subset with i, used165have included := supported166have inJ := included with i, used167haveleft:= polynomialVariables.value at I, A, z, one, i with*168haveright:= polynomialTransferVariables.value at J, I, A, z, one, i with*169cc170have equal : polynomialAtOver(J, R, P, polynomialCoefficients(I, R), polynomialTransferVariables(J, I, A, z, one))(polynomialTransfer(I, J, R)(p)) = polynomialAtOver(I, R, P, polynomialCoefficients(I, R), polynomialVariables(I, R))(p)171exact polynomialTransfer.evaluate_supported with*172have canonical := polynomialAtOver.canonical_variables at I, A, add, z, neg, mul, one with*173rw canonical at equal174have identity := identity.apply at p, P with*175unfold polynomialTransfer at equal176unfold polynomialTransfer177cc178179theorem polynomialTransfer.nonzero_supported (p : Set)180requires polynomial : p ∈ P181requires supported : polynomialVariablesUsed(I, R, p) ⊆ J182requires nonzero : p ≠ P[0]183shows polynomialTransfer(I, J, R)(p) ≠ Q[0]184proof185have reverse : IsRingHom(polynomialTransfer(J, I, R), Q, P)186exact polynomialTransfer.hom with*187have zero := IsRingHom.zero with reverse188have recovered := polynomialTransfer.roundtrip with*189intro vanishes190apply nonzero191cc192193theorem polynomialTransfer.injective194requires subset : I ⊆ J195shows InjectiveBetween(polynomialTransfer(I, J, R), P, Q)196proof197have hom : IsRingHom(polynomialTransfer(I, J, R), P, Q)198exact polynomialTransfer.hom with*199have function := IsRingHom.function with hom200unfold InjectiveBetween201refine⟨function, ?_⟩202intros p hp q hq y hy first second203have valueP := FunctionBetween.apply_value at polynomialTransfer(I, J, R), P, Q, p, y with*204have valueQ := FunctionBetween.apply_value at polynomialTransfer(I, J, R), P, Q, q, y with*205have usedP := polynomialVariablesUsed.subset at I, A, z, p206have usedQ := polynomialVariablesUsed.subset at I, A, z, q207have supportedP := Subset.transitive with usedP, subset208have supportedQ := Subset.transitive with usedQ, subset209have recoveredP := polynomialTransfer.roundtrip at I, J, A, add, z, neg, mul, one, p with*210have recoveredQ := polynomialTransfer.roundtrip at I, J, A, add, z, neg, mul, one, q with*211cc212213end Rings214