# mathlibdocumentation

data.nat.factorization

# Prime factorizations #

n.factorization is the finitely supported function ℕ →₀ ℕ mapping each prime factor of n to its multiplicity in n. For example, since 2000 = 2^4 * 5^3,

• factorization 2000 2 is 4
• factorization 2000 5 is 3
• factorization 2000 k is 0 for all other k : ℕ.

## TODO #

• As discussed in this Zulip thread: https://leanprover.zulipchat.com/#narrow/stream/217875/topic/Multiplicity.20in.20the.20naturals We have lots of disparate ways of talking about the multiplicity of a prime in a natural number, including factors.count, padic_val_nat, multiplicity, and the material in data/pnat/factors. Move some of this material to this file, prove results about the relationships between these definitions, and (where appropriate) choose a uniform canonical way of expressing these ideas.

• Moreover, the results here should be generalised to an arbitrary unique factorization monoid with a normalization function, and then deduplicated. The basics of this have been started in ring_theory/unique_factorization_domain.

• Extend the inductions to any normalization_monoid with unique factorization.

noncomputable def nat.factorization (n : ) :

n.factorization is the finitely supported function ℕ →₀ ℕ mapping each prime factor of n to its multiplicity in n.

Equations

### Basic facts about factorization #

@[simp]
theorem nat.factorization_prod_pow_eq_self {n : } (hn : n 0) :
@[simp]
theorem nat.factors_count_eq {n p : } :

We can write both n.factorization p and n.factors.count p to represent the power of p in the factorization of n: we declare the former to be the simp-normal form. However, since factorization is a finsupp it's noncomputable. This theorem can also be used in reverse to compute values of factorization n p when required.

theorem nat.eq_of_factorization_eq {a b : } (ha : a 0) (hb : b 0) (h : ∀ (p : ), (a.factorization) p = (b.factorization) p) :
a = b
theorem nat.factorization_inj  :
{x : | x 0}

Every nonzero natural number has a unique prime factorization

@[simp]
@[simp]
theorem nat.factorization_one  :
@[simp]
theorem nat.support_factorization {n : } :

The support of n.factorization is exactly n.factors.to_finset

theorem nat.pos_of_mem_factorization {n p : } (hp : p n.factorization.support) :
0 < p
theorem nat.factorization_eq_zero_of_non_prime (n : ) {p : } (hp : ¬) :
theorem nat.dvd_of_factorization_pos {n p : } (hn : (n.factorization) p 0) :
p n
theorem nat.prime.factorization_pos_of_dvd {n p : } (hp : nat.prime p) (hn : n 0) (h : p n) :
theorem nat.factorization_eq_zero_iff (n : ) :
n = 0 n = 1

The only numbers with empty prime factorization are 0 and 1

@[simp]
theorem nat.factorization_mul {a b : } (ha : a 0) (hb : b 0) :

For nonzero a and b, the power of p in a * b is the sum of the powers in a and b

theorem nat.factorization_mul_support {a b : } (ha : a 0) (hb : b 0) :
@[simp]
theorem nat.factorization_pow (n k : ) :

For any p, the power of p in n^k is k times the power in n

@[simp]
theorem nat.prime.factorization {p : } (hp : nat.prime p) :

The only prime factor of prime p is p itself, with multiplicity 1

theorem nat.prime.factorization_pow {p k : } (hp : nat.prime p) :

For prime p the only prime factor of p^k is p with multiplicity k

theorem nat.eq_pow_of_factorization_eq_single {n p k : } (hn : n 0) (h : n.factorization = ) :
n = p ^ k

If the factorization of n contains just one number p then n is a power of p

theorem nat.prod_factorization_eq_prod_factors {n : } {β : Type u_1} [comm_monoid β] (f : → β) :
n.factorization.prod (λ (p k : ), f p) = n.factors.to_finset.prod (λ (p : ), f p)

If a product over n.factorization doesn't use the multiplicities of the prime factors then it's equal to the corresponding product over n.factors.to_finset

theorem nat.factorization_prod {α : Type u_1} {S : finset α} {g : α → } (hS : ∀ (x : α), x Sg x 0) :
(S.prod g).factorization = S.sum (λ (x : α), (g x).factorization)

For any p : ℕ and any function g : α → ℕ that's non-zero on S : finset α, the power of p in S.prod g equals the sum over x ∈ S of the powers of p in g x. Generalises factorization_mul, which is the special case where S.card = 2 and g = id.

### Equivalence between ℕ+ and ℕ →₀ ℕ with support in the primes. #

theorem nat.prod_pow_factorization_eq_self {f : →₀ } (hf : ∀ (p : ), p f.support) :

Any finsupp f : ℕ →₀ ℕ whose support is in the primes is equal to the factorization of the product ∏ (a : ℕ) in f.support, a ^ f a.

theorem nat.eq_factorization_iff {n : } {f : →₀ } (hn : n 0) (hf : ∀ (p : ), p f.support) :
= n
noncomputable def nat.factorization_equiv  :
ℕ+ {f : | ∀ (p : ), p f.support

The equiv between ℕ+ and ℕ →₀ ℕ with support in the primes.

Equations
theorem nat.factorization_equiv_inv_apply {f : →₀ } (hf : ∀ (p : ), p f.support) :

### Factorization and divisibility #

theorem nat.pow_factorization_dvd (n p : ) :
theorem nat.pow_factorization_le {n : } (p : ) (hn : n 0) :
theorem nat.div_pow_factorization_ne_zero {n : } (p : ) (hn : n 0) :
n / p ^ (n.factorization) p 0
theorem nat.pow_succ_factorization_not_dvd {n p : } (hn : n 0) (hp : nat.prime p) :
¬p ^ ((n.factorization) p + 1) n
theorem nat.factorization_le_iff_dvd {d n : } (hd : d 0) (hn : n 0) :
d n
theorem nat.prime.pow_dvd_iff_le_factorization {p k n : } (pp : nat.prime p) (hn : n 0) :
p ^ k n k (n.factorization) p
theorem nat.prime.pow_dvd_iff_dvd_pow_factorization {p k n : } (pp : nat.prime p) (hn : n 0) :
p ^ k n p ^ k p ^ (n.factorization) p
theorem nat.prime.dvd_iff_one_le_factorization {p n : } (pp : nat.prime p) (hn : n 0) :
theorem nat.exists_factorization_lt_of_lt {a b : } (ha : a 0) (hab : a < b) :
∃ (p : ), (a.factorization) p < (b.factorization) p
@[simp]
theorem nat.factorization_div {d n : } (h : d n) :
theorem nat.not_dvd_div_pow_factorization {n p : } (hp : nat.prime p) (hn : n 0) :
theorem nat.dvd_iff_div_factorization_eq_tsub {d n : } (hd : d 0) (hdn : d n) :
d n (n / d).factorization =
theorem nat.dvd_iff_prime_pow_dvd_dvd (n d : ) :
d n ∀ (p k : ), p ^ k dp ^ k n
theorem nat.prod_prime_factors_dvd (n : ) :
n.factors.to_finset.prod (λ (p : ), p) n
theorem nat.factorization_gcd {a b : } (ha_pos : a 0) (hb_pos : b 0) :

### Factorization and coprimes #

For coprime a and b, the power of p in a * b is the sum of the powers in a and b

theorem nat.factorization_mul_of_coprime {a b : } (hab : a.coprime b) :

For coprime a and b, the power of p in a * b is the sum of the powers in a and b

theorem nat.factorization_eq_of_coprime_left {p a b : } (hab : a.coprime b) (hpa : p a.factors) :

If p is a prime factor of a then the power of p in a is the same that in a * b, for any b coprime to a.

theorem nat.factorization_eq_of_coprime_right {p a b : } (hab : a.coprime b) (hpb : p b.factors) :

If p is a prime factor of b then the power of p in b is the same that in a * b, for any a coprime to b.

theorem nat.factorization_disjoint_of_coprime {a b : } (hab : a.coprime b) :

The prime factorizations of coprime a and b are disjoint

For coprime a and b the prime factorization a * b is the union of those of a and b

### Induction principles involving factorizations #

def nat.rec_on_prime_pow {P : Sort u_1} (h0 : P 0) (h1 : P 1) (h : Π (a p n : ), ¬p a0 < nP aP (p ^ n * a)) (a : ) :
P a

Given P 0, P 1 and a way to extend P a to P (p ^ n * a) for prime p not dividing a, we can define P for all natural numbers.

Equations
• h1 h = λ (a : ), a.strong_rec_on (λ (n : ), nat.rec_on_prime_pow._match_1 h0 h1 h n)
• nat.rec_on_prime_pow._match_1 h0 h1 h (k + 2) = λ (hk : Π (m : ), m < k + 2P m), let p : := (k + 2).min_fac, t : := (k + 2).factors in _.mpr (h ((k + 2) / p ^ t) p t _ _ _ (hk ((k + 2) / p ^ t) _))
• nat.rec_on_prime_pow._match_1 h0 h1 h 1 = λ (_x : Π (m : ), m < 1P m), h1
• nat.rec_on_prime_pow._match_1 h0 h1 h 0 = λ (_x : Π (m : ), m < 0P m), h0
def nat.rec_on_pos_prime_pos_coprime {P : Sort u_1} (hp : Π (p n : ), 0 < nP (p ^ n)) (h0 : P 0) (h1 : P 1) (h : Π (a b : ), 1 < a1 < ba.coprime bP aP bP (a * b)) (a : ) :
P a

Given P 0, P 1, and P (p ^ n) for positive prime powers, and a way to extend P a and P b to P (a * b) when a, b are positive coprime, we can define P for all natural numbers.

Equations
• h1 h = h1 (λ (a p n : ) (hp' : (hpa : ¬p a) (hn : 0 < n) (hPa : P a), dite (a = 1) (λ (ha1 : a = 1), _.mpr (_.mpr (hp p n hp' hn))) (λ (ha1 : ¬a = 1), h (p ^ n) a _ _ _ (hp p n hp' hn) hPa))
def nat.rec_on_prime_coprime {P : Sort u_1} (h0 : P 0) (hp : Π (p n : ), P (p ^ n)) (h : Π (a b : ), 1 < a1 < ba.coprime bP aP bP (a * b)) (a : ) :
P a

Given P 0, P (p ^ n) for all prime powers, and a way to extend P a and P b to P (a * b) when a, b are positive coprime, we can define P for all natural numbers.

Equations
def nat.rec_on_mul {P : Sort u_1} (h0 : P 0) (h1 : P 1) (hp : Π (p : ), P p) (h : Π (a b : ), P aP bP (a * b)) (a : ) :
P a

Given P 0, P 1, P p for all primes, and a way to extend P a and P b to P (a * b), we can define P for all natural numbers.

Equations
• h1 hp h = let hp : Π (p n : ), P (p ^ n) := λ (p n : ) (hp' : , nat.rec_on_mul._match_1 h1 hp h p hp' n in (λ (a b : ) (_x : 1 < a) (_x : 1 < b) (_x : a.coprime b), h a b)
• nat.rec_on_mul._match_1 h1 hp h p hp' (n + 1) = h p (p ^ n.add 0) (hp p hp') (nat.rec_on_mul._match_1 h1 hp h p hp' n)
• nat.rec_on_mul._match_1 h1 hp h p hp' 0 = h1
theorem nat.multiplicative_factorization {β : Type u_1} [comm_monoid β] (f : → β) (h_mult : ∀ (x y : ), x.coprime yf (x * y) = f x * f y) (hf : f 1 = 1) {n : } :
n 0f n = n.factorization.prod (λ (p k : ), f (p ^ k))

For any multiplicative function f with f 1 = 1 and any n ≠ 0, we can evaluate f n by evaluating f at p ^ k over the factorization of n

theorem nat.multiplicative_factorization' {β : Type u_1} [comm_monoid β] (f : → β) (h_mult : ∀ (x y : ), x.coprime yf (x * y) = f x * f y) (hf0 : f 0 = 1) (hf1 : f 1 = 1) {n : } :
f n = n.factorization.prod (λ (p k : ), f (p ^ k))

For any multiplicative function f with f 1 = 1 and f 0 = 1, we can evaluate f n by evaluating f at p ^ k over the factorization of n