decide_zmod_poly: deciding univariate polynomial identities over ZMod m #
ZModDecide.decide_zmod decides a ground ZMod m equation — every leaf a
numeral — by bounded integer-residue computation. This module lifts that to a
∀ x : ZMod m polynomial identity p x = q x, where p/q are built from
the variable x, +, -, *, ^, neg, and ZMod m numerals.
The mathematics is the seqpoly change of representation (HexSeqPoly): a
polynomial is a dense coefficient list (HexPoly = List ℤ), evaluation is Horner
form (evalC), and two Horner polynomials agree at every point of ZMod m once
their coefficient lists are congruent mod m (evalC_congr_of_dvd). The variable
is carried symbolically through the whole expression tree by the coefficient
homomorphism lemmas evalC_cAdd / cScale / cMul / cPow, proved once over a generic
commutative ring.
Boundedness #
denoteC reduces % m after every coefficient operation (cAddMod,
cMulMod, cPowMod, …), so a coefficient is at most m² transiently and < m
between steps. A degree-d identity produces two lists of about d + 1
coefficients, each below m; the closing divisibility check runs on those small
integers. Unreduced convolution — repeated cMul inside cPow — would grow a
coefficient's bit width additively per multiply, the blow-up that makes ring
and native_decide over ZMod m diverge on a high-degree identity.
Main results #
PolyExpr— univariate polynomial expressions with avarleaf.PolyExpr.denoteA— the abstract meaningZMod m → ZMod m.PolyExpr.denoteC— the bounded coefficient-list normalizer (% mafter every operation), landing inHexPoly.PolyExpr.denoteC_correct— the refinementdenoteA m e x = evalC (denoteC e) x.PolyExpr.decide_transfer_poly— the backward transfer: a coefficient-list divisibility check proves the abstract identity at every point.decide_zmod_poly— the tactic front: reifies a∀ x : ZMod m, _ = _goal and closes it bydecide_transfer_polyplus a kerneldecideon the reduced coefficient lists. Axiom-free ([propext, Classical.choice, Quot.sound], noLean.ofReduceBool).
Scope #
- One variable. Every numeral is a
ZMod mconstant; a second free variable is out of scope. - Exponents are literal
ℕ.
The integer-coefficient Horner evaluator (the seqpoly read-out) #
Horner evaluation of an integer-coefficient list (low degree first) at x : R,
coefficients cast in through Int.cast. This is the List ℤ (HexPoly)
representation of a polynomial read out over R.
Equations
- Transfer.ZModPolyDecide.evalC [] x✝ = 0
- Transfer.ZModPolyDecide.evalC (c :: cs) x✝ = ↑c + x✝ * Transfer.ZModPolyDecide.evalC cs x✝
Instances For
Coefficient-wise addition.
Equations
- Transfer.ZModPolyDecide.cAdd [] x✝ = x✝
- Transfer.ZModPolyDecide.cAdd x✝ [] = x✝
- Transfer.ZModPolyDecide.cAdd (a :: p) (b :: q) = (a + b) :: Transfer.ZModPolyDecide.cAdd p q
Instances For
Scalar multiplication of a coefficient list.
Equations
- Transfer.ZModPolyDecide.cScale a [] = []
- Transfer.ZModPolyDecide.cScale a (b :: q) = a * b :: Transfer.ZModPolyDecide.cScale a q
Instances For
Coefficient-wise (convolution) product.
Equations
Instances For
Coefficient-wise subtraction.
Equations
Instances For
Coefficient homomorphism lemmas — proved once, generically over R #
Two Horner polynomials are equal at every point of ZMod m once every
coefficient of their difference cSub p q is divisible by m — a decidable
integer predicate. This is HexDecide.residueMulReal's
eq_transfer_backward step lifted from a single binop to a whole polynomial.
The bounded coefficient operations (% m after every step) #
Coefficient-wise addition, reduced mod m.
Equations
Instances For
Coefficient-wise subtraction, reduced mod m.
Equations
Instances For
Convolution product, reduced mod m.
Equations
Instances For
Coefficient-wise negation, reduced mod m.
Equations
Instances For
Power by repeated reduced multiplication, so coefficients stay < m.
Equations
Instances For
The polynomial-expression front #
Univariate polynomial expressions over ZMod m: a variable leaf, integer-
numeral constants, and the ring operations.
- var : PolyExpr
- lit : ℤ → PolyExpr
- add : PolyExpr → PolyExpr → PolyExpr
- sub : PolyExpr → PolyExpr → PolyExpr
- mul : PolyExpr → PolyExpr → PolyExpr
- neg : PolyExpr → PolyExpr
- pow : PolyExpr → ℕ → PolyExpr
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
The abstract meaning of a PolyExpr as a function ZMod m → ZMod m.
Equations
- Transfer.ZModPolyDecide.PolyExpr.denoteA m Transfer.ZModPolyDecide.PolyExpr.var = fun (x : ZMod m) => x
- Transfer.ZModPolyDecide.PolyExpr.denoteA m (Transfer.ZModPolyDecide.PolyExpr.lit z) = fun (x : ZMod m) => ↑z
- Transfer.ZModPolyDecide.PolyExpr.denoteA m (a.add b) = fun (x : ZMod m) => Transfer.ZModPolyDecide.PolyExpr.denoteA m a x + Transfer.ZModPolyDecide.PolyExpr.denoteA m b x
- Transfer.ZModPolyDecide.PolyExpr.denoteA m (a.sub b) = fun (x : ZMod m) => Transfer.ZModPolyDecide.PolyExpr.denoteA m a x - Transfer.ZModPolyDecide.PolyExpr.denoteA m b x
- Transfer.ZModPolyDecide.PolyExpr.denoteA m (a.mul b) = fun (x : ZMod m) => Transfer.ZModPolyDecide.PolyExpr.denoteA m a x * Transfer.ZModPolyDecide.PolyExpr.denoteA m b x
- Transfer.ZModPolyDecide.PolyExpr.denoteA m a.neg = fun (x : ZMod m) => -Transfer.ZModPolyDecide.PolyExpr.denoteA m a x
- Transfer.ZModPolyDecide.PolyExpr.denoteA m (a.pow n) = fun (x : ZMod m) => Transfer.ZModPolyDecide.PolyExpr.denoteA m a x ^ n
Instances For
The bounded coefficient-list normalizer: the polynomial's dense coefficient
list (HexPoly), reduced mod m after every operation.
Equations
- Transfer.ZModPolyDecide.PolyExpr.denoteC m Transfer.ZModPolyDecide.PolyExpr.var = Transfer.ZModPolyDecide.cReduce m [0, 1]
- Transfer.ZModPolyDecide.PolyExpr.denoteC m (Transfer.ZModPolyDecide.PolyExpr.lit z) = Transfer.ZModPolyDecide.cReduce m [z]
- Transfer.ZModPolyDecide.PolyExpr.denoteC m (a.add b) = Transfer.ZModPolyDecide.cAddMod m (Transfer.ZModPolyDecide.PolyExpr.denoteC m a) (Transfer.ZModPolyDecide.PolyExpr.denoteC m b)
- Transfer.ZModPolyDecide.PolyExpr.denoteC m (a.sub b) = Transfer.ZModPolyDecide.cSubMod m (Transfer.ZModPolyDecide.PolyExpr.denoteC m a) (Transfer.ZModPolyDecide.PolyExpr.denoteC m b)
- Transfer.ZModPolyDecide.PolyExpr.denoteC m (a.mul b) = Transfer.ZModPolyDecide.cMulMod m (Transfer.ZModPolyDecide.PolyExpr.denoteC m a) (Transfer.ZModPolyDecide.PolyExpr.denoteC m b)
- Transfer.ZModPolyDecide.PolyExpr.denoteC m a.neg = Transfer.ZModPolyDecide.cNegMod m (Transfer.ZModPolyDecide.PolyExpr.denoteC m a)
- Transfer.ZModPolyDecide.PolyExpr.denoteC m (a.pow n) = Transfer.ZModPolyDecide.cPowMod m (Transfer.ZModPolyDecide.PolyExpr.denoteC m a) n
Instances For
The refinement. The abstract value at x equals the Horner evaluation of
the bounded coefficient list at x: the coefficient homomorphism lifted over
the expression tree, with every reduction step invisible over ZMod m.
The reflective coefficient check: every coefficient of the normalized
difference is divisible by m.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The backward transfer. When the coefficient check passes, the two abstract
polynomials agree at every point of ZMod m. Underwritten by denoteC_correct
and evalC_congr_of_dvd, so the decide on the reduced coefficients is proof,
not trust.
The decide_zmod_poly tactic #
Reify a ZMod m expression into a PolyExpr, mapping the free variable
xvar to PolyExpr.var. Fails on any leaf that is neither the variable nor a
numeral.
Close a univariate polynomial identity ∀ x : ZMod m, p x = q x by bounded
coefficient-list computation: introduce x, reify both sides into PolyExpr,
then discharge via PolyExpr.decide_transfer_poly and a kernel decide on the
reduced coefficient lists. Axiom-free (no Lean.ofReduceBool). Every leaf must
be the variable or a numeral.
Equations
- Transfer.ZModPolyDecide.tacticDecide_zmod_poly = Lean.ParserDescr.node `Transfer.ZModPolyDecide.tacticDecide_zmod_poly 1024 (Lean.ParserDescr.nonReservedSymbol "decide_zmod_poly" false)