Documentation

Mathlib.Data.Nat.MaxPowDiv

The maximal power of one natural number dividing another #

Here we introduce p.maxPowDvd n which returns the maximal k : ℕ for which p ^ k ∣ n with the convention that maxPowDvd 1 n = 0 for all n.

We prove enough about maxPowDvd in this file to show equality with Nat.padicValNat in padicValNat.padicValNat_eq_maxPowDvd.

The implementation of maxPowDvd improves on the speed of padicValNat.

Find largest k : ℕ such that p ^ k ∣ n for any p : ℕ, as well as the ratio n / p ^ k.

The implementation recurses from (p, n) to (p * p, n), so the recursion depth is $$O(\log(\nu_p(n)))$$, thus it is $$O(\log(\log(n)))$$.

Equations
Instances For
    @[irreducible]
    def Nat.maxPowDvdDiv.go (n p : ) (hp : 1 < p n 0) :

    Auxiliary definition for Nat.maxPowDvdDiv.

    Equations
    Instances For
      def padicValNat (p n : ) :

      For p ≠ 1, the p-adic valuation of a natural n ≠ 0 is the largest natural number k such that p^k divides n. If n = 0 or p = 1, then padicValNat p n defaults to 0.

      Equations
      Instances For
        def Nat.divMaxPow (n p : ) :

        Divide n by the maximal power of p that divides n.

        Equations
        Instances For
          theorem Nat.maxPowDvdDiv.go_spec {n p : } (hnp : 1 < p n 0) :
          (go n p hnp).snd * p ^ (go n p hnp).fst = n ¬p (go n p hnp).snd
          theorem Nat.maxPowDvdDiv_of_base_le_one {p : } (hp : p 1) (n : ) :
          @[simp]
          @[simp]
          theorem padicValNat_zero_left (n : ) :
          @[simp]
          @[simp]
          @[simp]
          theorem padicValNat_one_left (n : ) :
          @[simp]
          theorem Nat.divMaxPow_one_right (n : ) :
          n.divMaxPow 1 = n
          @[simp]
          @[simp]
          theorem Nat.divMaxPow_zero_left (p : ) :
          divMaxPow 0 p = 0
          theorem Nat.maxPowDvdDiv_of_not_dvd {p n : } (h : ¬p n) :
          @[simp]
          @[simp]
          theorem padicValNat_one_right (p : ) :
          @[simp]
          theorem Nat.divMaxPow_one_left (p : ) :
          divMaxPow 1 p = 1
          theorem pow_padicValNat_dvd {p n : } :
          p ^ padicValNat p n n
          theorem Nat.not_dvd_divMaxPow {p n : } (hp : 1 < p) (hn : n 0) :
          theorem Nat.pow_dvd_iff_le_padicValNat {p k n : } (hp : p 1) (hn : n 0) :
          p ^ k n k padicValNat p n

          If p > 1, n > 0, then the first component of maxPowDvdDiv is the maximal power of p that divides n.

          theorem Nat.maxPowDvdDiv_of_pow_mul_eq {p n k l : } (hn : n 0) (h : p ^ k * l = n) (hl : ¬p l) :
          @[simp]
          theorem Nat.maxPowDvdDiv_base_pow_mul {p n : } (hp : 1 < p) (hn : n 0) (k : ) :
          p.maxPowDvdDiv (p ^ k * n) = (padicValNat p n + k, n.divMaxPow p)
          @[simp]
          theorem padicValNat_base_pow_mul {p n : } (hp : 1 < p) (hn : n 0) (k : ) :
          padicValNat p (p ^ k * n) = padicValNat p n + k
          @[simp]
          theorem Nat.divMaxPow_base_pow_mul {p : } (hp : p 0) (n k : ) :
          (p ^ k * n).divMaxPow p = n.divMaxPow p
          @[simp]
          theorem Nat.maxPowDvdDiv_base_mul {p n : } (hp : 1 < p) (hn : n 0) :
          @[simp]
          theorem padicValNat_base_mul {p n : } (hp : 1 < p) (hn : n 0) :
          padicValNat p (p * n) = padicValNat p n + 1
          @[simp]
          theorem Nat.divMaxPow_base_mul {p : } (hp : p 0) (n : ) :
          (p * n).divMaxPow p = n.divMaxPow p
          @[simp]
          theorem Nat.maxPowDvdDiv_base_pow {p : } (hp : 1 < p) (k : ) :
          p.maxPowDvdDiv (p ^ k) = (k, 1)
          @[simp]
          theorem padicValNat_base_pow {p : } (hp : 1 < p) (k : ) :
          padicValNat p (p ^ k) = k
          @[simp]
          theorem Nat.divMaxPow_base_pow {p : } (hp : p 0) (k : ) :
          (p ^ k).divMaxPow p = 1
          @[simp]
          theorem Nat.maxPowDvdDiv_self {p : } (hp : 1 < p) :
          @[simp]
          theorem padicValNat_base {p : } (hp : 1 < p) :
          @[simp]
          theorem Nat.divMaxPow_self {p : } (hp : p 0) :
          p.divMaxPow p = 1
          @[simp]
          @[simp]
          theorem Nat.snd_maxPowDvdDiv (p n : ) :
          @[deprecated padicValNat (since := "2026-03-15")]
          def Nat.maxPowDiv (p n : ) :

          Alias of padicValNat.


          For p ≠ 1, the p-adic valuation of a natural n ≠ 0 is the largest natural number k such that p^k divides n. If n = 0 or p = 1, then padicValNat p n defaults to 0.

          Equations
          Instances For
            @[deprecated padicValNat_base_mul (since := "2026-03-15")]
            theorem Nat.maxPowDiv.base_mul_eq_succ {p n : } (hp : 1 < p) (hn : n 0) :
            padicValNat p (p * n) = padicValNat p n + 1

            Alias of padicValNat_base_mul.

            @[deprecated padicValNat_base_pow_mul (since := "2026-03-15")]
            theorem Nat.maxPowDiv.base_pow_mul {p n : } (hp : 1 < p) (hn : n 0) (k : ) :
            padicValNat p (p ^ k * n) = padicValNat p n + k

            Alias of padicValNat_base_pow_mul.

            @[deprecated Nat.pow_dvd_iff_le_padicValNat (since := "2026-03-15")]
            theorem Nat.maxPowDiv.le_of_dvd {p k n : } (hp : p 1) (hn : n 0) :
            k padicValNat p np ^ k n

            Alias of the reverse direction of Nat.pow_dvd_iff_le_padicValNat.


            If p > 1, n > 0, then the first component of maxPowDvdDiv is the maximal power of p that divides n.

            @[deprecated pow_padicValNat_dvd (since := "2026-03-15")]
            theorem Nat.maxPowDiv.pow_dvd {p n : } :
            p ^ padicValNat p n n

            Alias of pow_padicValNat_dvd.

            @[deprecated padicValNat_zero_right (since := "2026-03-15")]
            theorem Nat.maxPowDiv.zero (p : ) :

            Alias of padicValNat_zero_right.

            @[deprecated padicValNat_zero_left (since := "2026-03-15")]

            Alias of padicValNat_zero_left.