Ordered products over a prime factorisation #
n.factorization.prod f multiplies the blocks f p (n.factorization p) over the primes
dividing n. Being a Finsupp.prod it asks for a CommMonoid: a Finsupp records no order
on its support, so the product is only well defined once the factors commute.
TauCeti.Nat.primePowerProd f n multiplies the same blocks in a fixed order — least prime
first — and so asks only for One and Mul. Each step peels Nat.minFac n together with its
whole multiplicity, and recurses on ordCompl[n.minFac] n. Both n = 0 and n = 1 give the
empty product.
The ordering is not the point; the weakened typeclass is. A monoid that happens to be
commutative without carrying a CommMonoid instance — a Hecke ring whose commutativity is a
theorem rather than a structure field, say — cannot form n.factorization.prod f at all, and
this is what it forms instead. primePowerProd_eq_factorization_prod records that nothing is
lost: as soon as a CommMonoid instance is available the two agree.
Neither associativity nor a unit law enters the definition — the bracketing is fixed — so it is
stated at One plus Mul, in the same spirit as List.prod, which Lean defines at Mul plus
One. mul_one is needed once, to collapse the single block of a prime power. Associativity
enters with the multiplicativity on coprime arguments, which is stated in a Monoid under the
hypothesis it actually uses — each block of n commutes with the blocks of m at larger primes,
the pairs that merging the two increasing sequences has to exchange — so that the monoid of the
previous paragraph can use it. Only the Finsupp.prod comparison needs the full CommMonoid.
Main definitions #
TauCeti.Nat.primePowerProd: the product off p (n.factorization p)over the primes ofn, taken in increasing order of prime.
Main results #
TauCeti.Nat.primePowerProd_of_one_lt: the peeling step, as a rewriting rule.TauCeti.Nat.primePowerProd_prime_pow: on a prime power the product is a single block;TauCeti.Nat.primePowerProd_primeis the same at a bare prime.Commute.primePowerProd_right: an element commuting with every block commutes with the ordered product.TauCeti.Nat.primePowerProd_mul_of_coprime: multiplicativity on coprime arguments, given that each block ofncommutes with the blocks ofmat larger primes.TauCeti.Nat.primePowerProd_eq_factorization_prod: in aCommMonoidit isn.factorization.prod f.
Implementation notes #
The definition is Nat.recOnPrimePow, which already performs the least-prime-power
decomposition this product runs over. That recursor is @[elab_as_elim] and mathlib states no
computation rules for it, so the three equations primePowerProd_zero, primePowerProd_one
and primePowerProd_of_one_lt are proved by unfolding it and Nat.strongRec once. Everything
after them goes through those equations and never through the body again.
Coprime multiplicativity is a strong induction on m * n. The least prime of m * n lies in
exactly one of the factors, and the peeling step splits off its block. When it lies in m the
induction hypothesis and the peeling step for m already give the answer. When it lies in n
its block comes out ahead of the whole of primePowerProd f m; it sits below every prime of
m, so the commutation hypothesis moves it past that product — the one place the hypothesis is
used — and the peeling step for n reassembles primePowerProd f n.
Provenance #
Adapted from AINTLIB (see References): peelProd and its six companion lemmas, which sit in a
Hecke file inside the HeckeRing.GL2.Unified namespace. They are combinatorics about
Nat.minFac carrying no Hecke content, so they are lifted here. The source asks
Monoid/CommMonoid and writes the recursion out by hand; here the classes are weakened to
One plus Mul, the recursion is routed through mathlib's Nat.recOnPrimePow, the coprime
multiplicativity is proved in a Monoid from the commutation of the block pairs that merging
exchanges instead of being read off the Finsupp.prod comparison, and that comparison is
stated for every n rather than only for n ≠ 0. The comparison is private in the source
and is exposed here, since it is the statement tying the definition to mathlib's idiom.
References #
- C. Birkbeck, AINTLIB, Apache-2.0, commit
2baa76f742bdb4fb8ee323fabba41203bd390e08,projects/LeanModularForms/LeanModularForms/HeckeRIngs/GL2/Unified/Gamma0RingDn.lean, lines 111-184.
The product of the blocks f p (n.factorization p) over the primes p dividing n, taken
in increasing order of p: each step peels off the least prime factor of n together with its
whole multiplicity. The empty product 1 is returned at n = 1, and at n = 0 as a junk
value — 0 has no factorisation to run over.
Only One M and Mul M are asked, which is the whole point of the definition; see
primePowerProd_eq_factorization_prod for the agreement with n.factorization.prod f when M
is commutative.
Equations
- TauCeti.Nat.primePowerProd f a = Nat.recOnPrimePow 1 1 (fun (x p v : ℕ) (x_1 : Nat.Prime p) (x_2 : ¬p ∣ x) (x_3 : 0 < v) (ih : M) => f p v * ih) a
Instances For
The peeling step: for 1 < n the ordered product splits off the block at n.minFac,
leaving the ordered product over ordCompl[n.minFac] n.
On a prime power the product is a single block: primePowerProd f (p ^ v) = f p v. The
hypothesis v ≠ 0 is needed — at v = 0 the left-hand side is the empty product 1 while the
right-hand side is f p 0, and nothing forces those to agree.
At a prime the product is the single block f p 1: the case v = 1 of
primePowerProd_prime_pow, stated separately because a bare prime is not syntactically a
power, so that lemma cannot fire on it.
An element commuting with every block of n commutes with their ordered product.
Multiplicativity on coprime arguments. When m and n share no prime, the blocks of
m * n are the blocks of m together with those of n, interleaved by size; sorting them into
the blocks of m followed by those of n moves each block of n past the blocks of m at
larger primes, and those are the only pairs asked to commute. In a CommMonoid it is discharged
by fun _ _ _ _ _ ↦ Commute.all _ _.
Once the factors commute the ordering is invisible and the ordered product is the
Finsupp.prod over the factorisation. Unconditional in n, so it rewrites without a side
goal: at n = 0 both sides are 1, the left as the junk value and the right because
Nat.factorization 0 = 0 has empty support.
Splitting the assembly at a prime-power part: primePowerProd f m is its p-block
primePowerProd f (p ^ v_p(m)) times the assembly over ordCompl[p] m. At m = 0 all three
products are 1; for nonprime p its exponent is zero and the first factor is 1.