decide_zmod: deciding ground ring identities over ZMod m by bounded residue computation #
HexDecide transfers a single ZMod m multiplication to an integer
multiply-then-%m (residueMulReal). A ground ring identity — one built from
+, *, -, neg, ^ over concrete ZMod m numerals — is a whole expression
tree. This module lifts that single-op transfer to the tree (the
ReprTransferExpr.OpExpr.denote_commutes idea, for the full ring signature), and
reduces mod m after every node so intermediates stay in [0, m). That
bounded-residue discipline keeps the final check on the GMP Int fast path, so
decide_zmod closes by kernel decide — axiom-free ([propext, Classical.choice, Quot.sound], no Lean.ofReduceBool) — where computing inside
ZMod/Fin, or over unreduced ℤ, either stalls the kernel or blows the
coefficients up.
Main results #
RingExpr— the ground ring-expression algebra.RingExpr.denoteA/denoteR— its meaning inZMod m, and the bounded integer-residue computation (% mafter every operation).RingExpr.denoteR_cast— the abstraction theorem (the homomorphism square lifted over the tree by induction).RingExpr.decide_transfer— the backward transfer adecideon the residues proves the abstract identity.decide_zmod— the tactic front: reifies aZMod mequality goal intoRingExprand closes it viadecide_transfer+ kerneldecide.
Scope and extensions #
- Ground identities only: every leaf must be a
ZMod mnumeral. A goal with a freeZMod mvariable is not decidable and is out of scope (usering/reduce_mod_charthere). - Exponents are literal
ℕ.denoteRcomputesbase ^ nbefore reducing, so a huge exponent can build a large intermediate; a binarypowModindenoteRremoves that (future). - A polynomial identity
∀ x, p x = q xreduces to coefficient equality (theseqpolyrefinement,HexSeqPoly) — a separatedecide_zmod_polyon top of this core.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
The abstract meaning of a RingExpr in ZMod m.
Equations
- Transfer.ZModDecide.RingExpr.denoteA m (Transfer.ZModDecide.RingExpr.lit z) = ↑z
- Transfer.ZModDecide.RingExpr.denoteA m (a.add b) = Transfer.ZModDecide.RingExpr.denoteA m a + Transfer.ZModDecide.RingExpr.denoteA m b
- Transfer.ZModDecide.RingExpr.denoteA m (a.sub b) = Transfer.ZModDecide.RingExpr.denoteA m a - Transfer.ZModDecide.RingExpr.denoteA m b
- Transfer.ZModDecide.RingExpr.denoteA m (a.mul b) = Transfer.ZModDecide.RingExpr.denoteA m a * Transfer.ZModDecide.RingExpr.denoteA m b
- Transfer.ZModDecide.RingExpr.denoteA m a.neg = -Transfer.ZModDecide.RingExpr.denoteA m a
- Transfer.ZModDecide.RingExpr.denoteA m (a.pow n) = Transfer.ZModDecide.RingExpr.denoteA m a ^ n
Instances For
The bounded integer-residue computation: % m after every operation, so every
intermediate stays in [0, m) (bar a single pow, reduced immediately). This
is what decide evaluates — Int arithmetic on the GMP fast path.
Equations
- Transfer.ZModDecide.RingExpr.denoteR m (Transfer.ZModDecide.RingExpr.lit z) = z % m
- Transfer.ZModDecide.RingExpr.denoteR m (a.add b) = (Transfer.ZModDecide.RingExpr.denoteR m a + Transfer.ZModDecide.RingExpr.denoteR m b) % m
- Transfer.ZModDecide.RingExpr.denoteR m (a.sub b) = (Transfer.ZModDecide.RingExpr.denoteR m a - Transfer.ZModDecide.RingExpr.denoteR m b) % m
- Transfer.ZModDecide.RingExpr.denoteR m (a.mul b) = Transfer.ZModDecide.RingExpr.denoteR m a * Transfer.ZModDecide.RingExpr.denoteR m b % m
- Transfer.ZModDecide.RingExpr.denoteR m a.neg = -Transfer.ZModDecide.RingExpr.denoteR m a % m
- Transfer.ZModDecide.RingExpr.denoteR m (a.pow n) = Transfer.ZModDecide.RingExpr.denoteR m a ^ n % m
Instances For
The abstraction theorem. The residue computation, cast back into ZMod m,
equals the abstract value: the single-op commuting square (% m invisible under
Int.cast, ZMod.intCast_mod) lifted over the tree by induction.
The backward transfer. A decidable equality of the two bounded residue
computations proves the abstract ZMod m identity — decide on the residues,
underwritten by denoteR_cast rather than trusted.
The decide_zmod tactic #
Close a ground ring identity over ZMod m by bounded residue computation:
reify both sides, then discharge via RingExpr.decide_transfer and a kernel
decide on the reduced integer residues. Axiom-free (no Lean.ofReduceBool).
Every leaf must be a numeral; a free ZMod m variable is rejected.
Equations
- Transfer.ZModDecide.tacticDecide_zmod = Lean.ParserDescr.node `Transfer.ZModDecide.tacticDecide_zmod 1024 (Lean.ParserDescr.nonReservedSymbol "decide_zmod" false)