1-- Multiplication by a monomial shifts coefficients without collisions (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.MonomialShift8import Ring9import Terms1011def monomialShiftCorrect (I A add z neg mul one t m : Set) : Set:=12 {p ∈ polynomials(I, A, z) | polynomialProduct(I, A, add, z, neg, mul, one, polynomialTerm(I, A, z, one, t), p)(monomialProduct(I, t, m)) = p(m)}1314section Shift15variable (I A add z neg mul one t m : Set)16notationring R := (A, add, z, neg, mul, one)17notationring P := R[I]18hypothesisring : IsCommRing(R)19hypothesis monomial : t ∈ monomials(I)20hypothesis target : m ∈ monomials(I)2122theorem monomialShiftCorrect.zero23shows P[0] ∈ monomialShiftCorrect(I, A, add, z, neg, mul, one, t, m)24proof25have zeroIn : R[0] ∈ R bytypecheck26have oneIn : R[1] ∈ R bytypecheck27have zeroPoly := polynomials.zero at I, A, add, z, neg, mul, one with*28have term := polynomialTerm.member at I, A, z, one, t with*29have shifted := monomialProduct.member at I, t, m with*30have product := polynomialProduct.zero_right at I, A, add, z, neg, mul, one, polynomialTerm(I, A, z, one, t) with*31haveleft:= constantFunction.apply at monomials(I), A, monomialProduct(I, t, m), z with*32haveright:= constantFunction.apply at monomials(I), A, m, z with*33apply monomialShiftCorrect.membership.backward34refine⟨zeroPoly, ?_⟩35cc3637theorem monomialShiftCorrect.term (a n : Set)38requires coefficient : a ∈ R39requires index : n ∈ monomials(I)40shows polynomialTerm(I, A, z, a, n) ∈ monomialShiftCorrect(I, A, add, z, neg, mul, one, t, m)41proof42have zeroIn : R[0] ∈ R bytypecheck43have oneIn : R[1] ∈ R bytypecheck44have member := polynomialTerm.member at I, A, z, a, n with*45have shifted := monomialProduct.member at I, t, m with*46have product := polynomialProduct.terms at I, A, add, z, neg, mul, one, one, a, t, n with*47have unit : R[1* a] = a byring48rw unit at product49apply monomialShiftCorrect.membership.backward50refine⟨member, ?_⟩51rw product52have alternatives : m = n ∨ m ≠ n bytauto53cases alternatives with equal | different54 . rw equal55have shiftedN := monomialProduct.member at I, t, n with*56haveleft:= polynomialTerm.same at I, A, z, a, monomialProduct(I, t, n) with*57haveright:= polynomialTerm.same at I, A, z, a, n with*58cc59 . have distinct : monomialProduct(I, t, m) ≠ monomialProduct(I, t, n)60intro equal61have cancelled := monomialProduct.cancel with*62exact different with cancelled63haveleft:= polynomialTerm.other at I, A, z, a, monomialProduct(I, t, n), monomialProduct(I, t, m) with*64haveright:= polynomialTerm.other at I, A, z, a, n, m with*65cc6667theorem monomialShiftCorrect.add (p q : Set)68requires first : p ∈ monomialShiftCorrect(I, A, add, z, neg, mul, one, t, m)69requires second : q ∈ monomialShiftCorrect(I, A, add, z, neg, mul, one, t, m)70shows coefficientAdd(monomials(I), A, add, z, neg, mul, one, p, q) ∈ monomialShiftCorrect(I, A, add, z, neg, mul, one, t, m)71proof72haveleft:= monomialShiftCorrect.membership.forward with first73haveright:= monomialShiftCorrect.membership.forward with second74have zeroIn : R[0] ∈ R bytypecheck75have oneIn : R[1] ∈ R bytypecheck76have term := polynomialTerm.member at I, A, z, one, t with*77have shifted := monomialProduct.member at I, t, m with*78have sum := polynomials.add at I, A, add, z, neg, mul, one, p, q with*79have productP := polynomialProduct.member at I, A, add, z, neg, mul, one, polynomialTerm(I, A, z, one, t), p with*80have productQ := polynomialProduct.member at I, A, add, z, neg, mul, one, polynomialTerm(I, A, z, one, t), q with*81have functionP := polynomials.function withleft.left82have functionQ := polynomials.function withright.left83have functionProductP := polynomials.function with productP84have functionProductQ := polynomials.function with productQ85have distributes := polynomialProduct.add_right at I, A, add, z, neg, mul, one, polynomialTerm(I, A, z, one, t), p, q with*86have value := coefficientAdd.value at monomials(I), A, add, z, neg, mul, one, p, q, m with*87have productValue := coefficientAdd.value at monomials(I), A, add, z, neg, mul, one, polynomialProduct(I, A, add, z, neg, mul, one, polynomialTerm(I, A, z, one, t), p), polynomialProduct(I, A, add, z, neg, mul, one, polynomialTerm(I, A, z, one, t), q), monomialProduct(I, t, m) with*88apply monomialShiftCorrect.membership.backward89refine⟨sum, ?_⟩90cc9192theorem polynomialProduct.monomial_shift (p : Set)93requires polynomial : p ∈ P94shows polynomialProduct(I, A, add, z, neg, mul, one, polynomialTerm(I, A, z, one, t), p)(monomialProduct(I, t, m)) = p(m)95proof96have base := monomialShiftCorrect.zero at I, A, add, z, neg, mul, one, t, m with*97have terms : ∀ a ∈ A, ∀ n ∈ monomials(I), polynomialTerm(I, A, z, a, n) ∈ monomialShiftCorrect(I, A, add, z, neg, mul, one, t, m)98intros a ha n hn99exact monomialShiftCorrect.term with*100have sums : ∀ u ∈ monomialShiftCorrect(I, A, add, z, neg, mul, one, t, m), ∀ v ∈ monomialShiftCorrect(I, A, add, z, neg, mul, one, t, m), coefficientAdd(monomials(I), A, add, z, neg, mul, one, u, v) ∈ monomialShiftCorrect(I, A, add, z, neg, mul, one, t, m)101intros u hu v hv102exact monomialShiftCorrect.add with*103have member := polynomials.induction with*104have data := monomialShiftCorrect.membership.forward with member105exact data.right106107end Shift108theorem polynomialProduct.monomial_outside (I A add z neg mul one t m p : Set)109requiresring : IsCommRing(A, add, z, neg, mul, one)110requires monomial : t ∈ monomials(I)111requires target : m ∈ monomials(I)112requires polynomial : p ∈ polynomials(I, A, z)113requires absent : ∀ n ∈ monomials(I), m ≠ monomialProduct(I, t, n)114shows polynomialProduct(I, A, add, z, neg, mul, one, polynomialTerm(I, A, z, one, t), p)(m) = z115proof116have ordinary := IsCommRing.ring withring117have zeroIn := IsRing.zero_in_carrier with ordinary118have multiplicative := IsRing.multiplicative with ordinary119have oneIn := IsMonoid.unit_in_carrier with multiplicative120have term := polynomialTerm.member at I, A, z, one, t with*121have bound := polynomialTerm.support at I, A, z, one, t with*122by_contra nonzero123have supported : m ∈ functionSupport(polynomialProduct(I, A, add, z, neg, mul, one, polynomialTerm(I, A, z, one, t), p), monomials(I), z)124exact functionSupport.membership.backward with⟨target, nonzero⟩125obtain⟨u, hu, n, hn, equal⟩:= polynomialProduct.support_factor at I, A, add, z, neg, mul, one, polynomialTerm(I, A, z, one, t), p, m with*126have singleton := bound with u, hu127have same := singleton.membership.forward with singleton128have data := functionSupport.membership.forward with hn129have different := absent with n, data.left130apply different131cc132133-- A variable multiple has no term with zero exponent in that variable.134theorem polynomialProduct.variable_zero (I A add z neg mul one j m p : Set)135requiresring : IsCommRing(A, add, z, neg, mul, one)136requires index : j ∈ I137requires target : m ∈ monomials(I)138requires polynomial : p ∈ polynomials(I, A, z)139requires exponent : m(j) =0140shows polynomialProduct(I, A, add, z, neg, mul, one, polynomialVariable(I, A, z, one, j), p)(m) = z141proof142havevariable:= monomialVariable.member at I, j143have absent : ∀ n ∈ monomials(I), m ≠ monomialProduct(I, monomialVariable(I, j), n)144intros n hn equal145have nNat := monomials.exponent with hn146have variableValue := monomialVariable.same at I, j with*147have productValue := monomialProduct.value at I, monomialVariable(I, j), n, j with*148have impossible : 0= succ(n(j))149have sum : 0=1+ n(j) bycc150 rwa [add, add] at sum151exact Naturals.disjoint.zero.succ at n(j) with impossible152unfold polynomialVariable153exact polynomialProduct.monomial_outside with*154