File: Mathlib/NumberTheory/Padics/PadicVal.lean

full_name: padicValNat
code: /-- 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 q` defaults to `0`. -/
def padicValNat (p : ℕ) (n : ℕ) : ℕ 
goal: ℕ

full_name: padicValNat.zero
code: /-- `padicValNat p 0` is `0` for any `p`. -/
@[simp]
protected theorem zero : padicValNat p 0 = 0 
goal: padicValNat p 0 = 0

full_name: padicValNat.one
code: /-- `padicValNat p 1` is `0` for any `p`. -/
@[simp]
protected theorem one : padicValNat p 1 = 0 
goal: padicValNat p 1 = 0

full_name: padicValNat.self
code: /-- If `p ≠ 0` and `p ≠ 1`, then `padicValNat p p` is `1`. -/
@[simp]
theorem self (hp : 1 < p) : padicValNat p p = 1 
goal: padicValNat p p = 1

full_name: padicValNat.eq_zero_iff
code: @[simp]
theorem eq_zero_iff {n : ℕ} : padicValNat p n = 0 ↔ p = 1 ∨ n = 0 ∨ ¬p ∣ n 
goal: padicValNat p n = 0 ↔ p = 1 ∨ n = 0 ∨ ¬p ∣ n

full_name: padicValNat.eq_zero_of_not_dvd
code: theorem eq_zero_of_not_dvd {n : ℕ} (h : ¬p ∣ n) : padicValNat p n = 0 
goal: padicValNat p n = 0

full_name: padicValNat.maxPowDiv_eq_multiplicity
code: theorem maxPowDiv_eq_multiplicity {p n : ℕ} (hp : 1 < p) (hn : 0 < n) :
    p.maxPowDiv n = multiplicity p n 
goal: ↑(p.maxPowDiv n) = multiplicity p n

full_name: padicValNat.maxPowDiv_eq_multiplicity_get
code: theorem maxPowDiv_eq_multiplicity_get {p n : ℕ} (hp : 1 < p) (hn : 0 < n) (h : Finite p n) :
    p.maxPowDiv n = (multiplicity p n).get h 
goal: p.maxPowDiv n = (multiplicity p n).get h

full_name: padicValNat.padicValNat_eq_maxPowDiv
code: /-- Allows for more efficient code for `padicValNat` -/
@[csimp]
theorem padicValNat_eq_maxPowDiv : @padicValNat = @maxPowDiv 
goal: padicValNat = Nat.maxPowDiv

full_name: padicValInt
code: /-- For `p ≠ 1`, the `p`-adic valuation of an integer `z ≠ 0` is the largest natural number `k` such
that `p^k` divides `z`. If `x = 0` or `p = 1`, then `padicValInt p q` defaults to `0`. -/
def padicValInt (p : ℕ) (z : ℤ) : ℕ 
goal: ℕ

full_name: padicValInt.of_ne_one_ne_zero
code: theorem of_ne_one_ne_zero {z : ℤ} (hp : p ≠ 1) (hz : z ≠ 0) :
    padicValInt p z =
      (multiplicity (p : ℤ) z).get
        (by
          apply multiplicity.finite_int_iff.2
          simp [hp, hz]) 
goal: padicValInt p z = (multiplicity (↑p) z).get ⋯

full_name: padicValInt.zero
code: /-- `padicValInt p 0` is `0` for any `p`. -/
@[simp]
protected theorem zero : padicValInt p 0 = 0 
goal: padicValInt p 0 = 0

full_name: padicValInt.one
code: /-- `padicValInt p 1` is `0` for any `p`. -/
@[simp]
protected theorem one : padicValInt p 1 = 0 
goal: padicValInt p 1 = 0

full_name: padicValInt.of_nat
code: /-- The `p`-adic value of a natural is its `p`-adic value as an integer. -/
@[simp]
theorem of_nat {n : ℕ} : padicValInt p n = padicValNat p n 
goal: padicValInt p ↑n = padicValNat p n

full_name: padicValInt.self
code: /-- If `p ≠ 0` and `p ≠ 1`, then `padicValInt p p` is `1`. -/
theorem self (hp : 1 < p) : padicValInt p p = 1 
goal: padicValInt p ↑p = 1

full_name: padicValInt.eq_zero_of_not_dvd
code: theorem eq_zero_of_not_dvd {z : ℤ} (h : ¬(p : ℤ) ∣ z) : padicValInt p z = 0 
goal: padicValInt p z = 0

full_name: padicValRat
code: /-- `padicValRat` defines the valuation of a rational `q` to be the valuation of `q.num` minus the
valuation of `q.den`. If `q = 0` or `p = 1`, then `padicValRat p q` defaults to `0`. -/
def padicValRat (p : ℕ) (q : ℚ) : ℤ 
goal: ℤ

full_name: padicValRat_def
code: lemma padicValRat_def (p : ℕ) (q : ℚ) :
    padicValRat p q = padicValInt p q.num - padicValNat p q.den 
goal: padicValRat p q = ↑(padicValInt p q.num) - ↑(padicValNat p q.den)

full_name: padicValRat.neg
code: /-- `padicValRat p q` is symmetric in `q`. -/
@[simp]
protected theorem neg (q : ℚ) : padicValRat p (-q) = padicValRat p q 
goal: padicValRat p (-q) = padicValRat p q

full_name: padicValRat.zero
code: /-- `padicValRat p 0` is `0` for any `p`. -/
@[simp]
protected theorem zero : padicValRat p 0 = 0 
goal: padicValRat p 0 = 0

full_name: padicValRat.one
code: /-- `padicValRat p 1` is `0` for any `p`. -/
@[simp]
protected theorem one : padicValRat p 1 = 0 
goal: padicValRat p 1 = 0

full_name: padicValRat.of_int
code: /-- The `p`-adic value of an integer `z ≠ 0` is its `p`-adic_value as a rational. -/
@[simp]
theorem of_int {z : ℤ} : padicValRat p z = padicValInt p z 
goal: padicValRat p ↑z = ↑(padicValInt p z)

full_name: padicValRat.of_int_multiplicity
code: /-- The `p`-adic value of an integer `z ≠ 0` is the multiplicity of `p` in `z`. -/
theorem of_int_multiplicity {z : ℤ} (hp : p ≠ 1) (hz : z ≠ 0) :
    padicValRat p (z : ℚ) = (multiplicity (p : ℤ) z).get (finite_int_iff.2 ⟨hp, hz⟩) 
goal: padicValRat p ↑z = ↑((multiplicity (↑p) z).get ⋯)

full_name: padicValRat.multiplicity_sub_multiplicity
code: theorem multiplicity_sub_multiplicity {q : ℚ} (hp : p ≠ 1) (hq : q ≠ 0) :
    padicValRat p q =
      (multiplicity (p : ℤ) q.num).get (finite_int_iff.2 ⟨hp, Rat.num_ne_zero.2 hq⟩) -
        (multiplicity p q.den).get
          (by
            rw [← finite_iff_dom, finite_nat_iff]
            exact ⟨hp, q.pos⟩) 
goal: padicValRat p q = ↑((multiplicity (↑p) q.num).get ⋯) - ↑((multiplicity p q.den).get ⋯)

full_name: padicValRat.of_nat
code: /-- The `p`-adic value of an integer `z ≠ 0` is its `p`-adic value as a rational. -/
@[simp]
theorem of_nat {n : ℕ} : padicValRat p n = padicValNat p n 
goal: padicValRat p ↑n = ↑(padicValNat p n)

full_name: padicValRat.self
code: /-- If `p ≠ 0` and `p ≠ 1`, then `padicValRat p p` is `1`. -/
theorem self (hp : 1 < p) : padicValRat p p = 1 
goal: padicValRat p ↑p = 1

full_name: zero_le_padicValRat_of_nat
code: theorem zero_le_padicValRat_of_nat (n : ℕ) : 0 ≤ padicValRat p n 
goal: 0 ≤ padicValRat p ↑n

full_name: padicValRat_of_nat
code: /-- `padicValRat` coincides with `padicValNat`. -/
@[norm_cast]
theorem padicValRat_of_nat (n : ℕ) : ↑(padicValNat p n) = padicValRat p n 
goal: ↑(padicValNat p n) = padicValRat p ↑n

full_name: padicValNat_def
code: /-- A simplification of `padicValNat` when one input is prime, by analogy with
`padicValRat_def`. -/
theorem padicValNat_def [hp : Fact p.Prime] {n : ℕ} (hn : 0 < n) :
    padicValNat p n = (multiplicity p n).get (multiplicity.finite_nat_iff.2 ⟨hp.out.ne_one, hn⟩) 
goal: padicValNat p n = (multiplicity p n).get ⋯

full_name: padicValNat_def'
code: theorem padicValNat_def' {n : ℕ} (hp : p ≠ 1) (hn : 0 < n) :
    ↑(padicValNat p n) = multiplicity p n 
goal: ↑(padicValNat p n) = multiplicity p n

full_name: padicValNat_self
code: @[simp]
theorem padicValNat_self [Fact p.Prime] : padicValNat p p = 1 
goal: padicValNat p p = 1

full_name: one_le_padicValNat_of_dvd
code: theorem one_le_padicValNat_of_dvd {n : ℕ} [hp : Fact p.Prime] (hn : 0 < n) (div : p ∣ n) :
    1 ≤ padicValNat p n 
goal: 1 ≤ padicValNat p n

full_name: dvd_iff_padicValNat_ne_zero
code: theorem dvd_iff_padicValNat_ne_zero {p n : ℕ} [Fact p.Prime] (hn0 : n ≠ 0) :
    p ∣ n ↔ padicValNat p n ≠ 0 
goal: p ∣ n ↔ padicValNat p n ≠ 0

full_name: le_multiplicity_iff_replicate_subperm_primeFactorsList
code: theorem le_multiplicity_iff_replicate_subperm_primeFactorsList {a b : ℕ} {n : ℕ} (ha : a.Prime)
    (hb : b ≠ 0) :
    ↑n ≤ multiplicity a b ↔ replicate n a <+~ b.primeFactorsList 
goal: ↑n ≤ multiplicity a b ↔ (List.replicate n a).Subperm b.primeFactorsList

full_name: le_padicValNat_iff_replicate_subperm_primeFactorsList
code: theorem le_padicValNat_iff_replicate_subperm_primeFactorsList {a b : ℕ} {n : ℕ} (ha : a.Prime)
    (hb : b ≠ 0) :
    n ≤ padicValNat a b ↔ replicate n a <+~ b.primeFactorsList 
goal: n ≤ padicValNat a b ↔ (List.replicate n a).Subperm b.primeFactorsList

full_name: padicValRat.finite_int_prime_iff
code: /-- The multiplicity of `p : ℕ` in `a : ℤ` is finite exactly when `a ≠ 0`. -/
theorem finite_int_prime_iff {a : ℤ} : Finite (p : ℤ) a ↔ a ≠ 0 
goal: multiplicity.Finite (↑p) a ↔ a ≠ 0

full_name: padicValRat.defn
code: /-- A rewrite lemma for `padicValRat p q` when `q` is expressed in terms of `Rat.mk`. -/
protected theorem defn (p : ℕ) [hp : Fact p.Prime] {q : ℚ} {n d : ℤ} (hqz : q ≠ 0)
    (qdf : q = n /. d) :
    padicValRat p q =
      (multiplicity (p : ℤ) n).get
          (finite_int_iff.2 ⟨hp.1.ne_one, fun hn => by simp_all⟩) -
        (multiplicity (p : ℤ) d).get
          (finite_int_iff.2 ⟨hp.1.ne_one, fun hd => by simp_all⟩) 
goal: padicValRat p q = ↑((multiplicity (↑p) n).get ⋯) - ↑((multiplicity (↑p) d).get ⋯)

full_name: padicValRat.mul
code: /-- A rewrite lemma for `padicValRat p (q * r)` with conditions `q ≠ 0`, `r ≠ 0`. -/
protected theorem mul {q r : ℚ} (hq : q ≠ 0) (hr : r ≠ 0) :
    padicValRat p (q * r) = padicValRat p q + padicValRat p r 
goal: padicValRat p (q * r) = padicValRat p q + padicValRat p r

full_name: padicValRat.pow
code: /-- A rewrite lemma for `padicValRat p (q^k)` with condition `q ≠ 0`. -/
protected theorem pow {q : ℚ} (hq : q ≠ 0) {k : ℕ} :
    padicValRat p (q ^ k) = k * padicValRat p q 
goal: padicValRat p (q ^ k) = ↑k * padicValRat p q

full_name: padicValRat.inv
code: /-- A rewrite lemma for `padicValRat p (q⁻¹)` with condition `q ≠ 0`. -/
protected theorem inv (q : ℚ) : padicValRat p q⁻¹ = -padicValRat p q 
goal: padicValRat p q⁻¹ = -padicValRat p q

full_name: padicValRat.div
code: /-- A rewrite lemma for `padicValRat p (q / r)` with conditions `q ≠ 0`, `r ≠ 0`. -/
protected theorem div {q r : ℚ} (hq : q ≠ 0) (hr : r ≠ 0) :
    padicValRat p (q / r) = padicValRat p q - padicValRat p r 
goal: padicValRat p (q / r) = padicValRat p q - padicValRat p r

full_name: padicValRat.padicValRat_le_padicValRat_iff
code: /-- A condition for `padicValRat p (n₁ / d₁) ≤ padicValRat p (n₂ / d₂)`, in terms of
divisibility by `p^n`. -/
theorem padicValRat_le_padicValRat_iff {n₁ n₂ d₁ d₂ : ℤ} (hn₁ : n₁ ≠ 0) (hn₂ : n₂ ≠ 0)
    (hd₁ : d₁ ≠ 0) (hd₂ : d₂ ≠ 0) :
    padicValRat p (n₁ /. d₁) ≤ padicValRat p (n₂ /. d₂) ↔
      ∀ n : ℕ, (p : ℤ) ^ n ∣ n₁ * d₂ → (p : ℤ) ^ n ∣ n₂ * d₁ 
goal: padicValRat p (n₁ /. d₁) ≤ padicValRat p (n₂ /. d₂) ↔ ∀ (n : ℕ), ↑p ^ n ∣ n₁ * d₂ → ↑p ^ n ∣ n₂ * d₁

full_name: padicValRat.le_padicValRat_add_of_le
code: /-- Sufficient conditions to show that the `p`-adic valuation of `q` is less than or equal to the
`p`-adic valuation of `q + r`. -/
theorem le_padicValRat_add_of_le {q r : ℚ} (hqr : q + r ≠ 0)
    (h : padicValRat p q ≤ padicValRat p r) : padicValRat p q ≤ padicValRat p (q + r) 
goal: padicValRat p q ≤ padicValRat p (q + r)

full_name: padicValRat.min_le_padicValRat_add
code: /-- The minimum of the valuations of `q` and `r` is at most the valuation of `q + r`. -/
theorem min_le_padicValRat_add {q r : ℚ} (hqr : q + r ≠ 0) :
    min (padicValRat p q) (padicValRat p r) ≤ padicValRat p (q + r) 
goal: min (padicValRat p q) (padicValRat p r) ≤ padicValRat p (q + r)

full_name: padicValRat.add_eq_min
code: /-- Ultrametric property of a p-adic valuation. -/
lemma add_eq_min {q r : ℚ} (hqr : q + r ≠ 0) (hq : q ≠ 0) (hr : r ≠ 0)
    (hval : padicValRat p q ≠ padicValRat p r) :
    padicValRat p (q + r) = min (padicValRat p q) (padicValRat p r) 
goal: padicValRat p (q + r) = min (padicValRat p q) (padicValRat p r)

full_name: padicValRat.add_eq_of_lt
code: lemma add_eq_of_lt {q r : ℚ} (hqr : q + r ≠ 0)
    (hq : q ≠ 0) (hr : r ≠ 0) (hval : padicValRat p q < padicValRat p r) :
    padicValRat p (q + r) = padicValRat p q 
goal: padicValRat p (q + r) = padicValRat p q

full_name: padicValRat.lt_add_of_lt
code: lemma lt_add_of_lt {q r₁ r₂ : ℚ} (hqr : r₁ + r₂ ≠ 0)
    (hval₁ : padicValRat p q < padicValRat p r₁) (hval₂ : padicValRat p q < padicValRat p r₂) :
    padicValRat p q < padicValRat p (r₁ + r₂) 
goal: padicValRat p q < padicValRat p (r₁ + r₂)

full_name: padicValRat.self_pow_inv
code: @[simp]
lemma self_pow_inv (r : ℕ) : padicValRat p ((p : ℚ) ^ r)⁻¹ = -r 
goal: padicValRat p (↑p ^ r)⁻¹ = -↑r

full_name: padicValRat.sum_pos_of_pos
code: /-- A finite sum of rationals with positive `p`-adic valuation has positive `p`-adic valuation
(if the sum is non-zero). -/
theorem sum_pos_of_pos {n : ℕ} {F : ℕ → ℚ} (hF : ∀ i, i < n → 0 < padicValRat p (F i))
    (hn0 : ∑ i ∈ Finset.range n, F i ≠ 0) : 0 < padicValRat p (∑ i ∈ Finset.range n, F i) 
goal: 0 < padicValRat p (∑ i ∈ Finset.range n, F i)

full_name: padicValRat.lt_sum_of_lt
code: /-- If the p-adic valuation of a finite set of positive rationals is greater than a given rational
number, then the p-adic valuation of their sum is also greater than the same rational number. -/
theorem lt_sum_of_lt {p j : ℕ} [hp : Fact (Nat.Prime p)] {F : ℕ → ℚ} {S : Finset ℕ}
    (hS : S.Nonempty) (hF : ∀ i, i ∈ S → padicValRat p (F j) < padicValRat p (F i))
    (hn1 : ∀ i : ℕ, 0 < F i) : padicValRat p (F j) < padicValRat p (∑ i ∈ S, F i) 
goal: padicValRat p (F j) < padicValRat p (∑ i ∈ S, F i)

full_name: padicValNat.mul
code: /-- A rewrite lemma for `padicValNat p (a * b)` with conditions `a ≠ 0`, `b ≠ 0`. -/
protected theorem mul : a ≠ 0 → b ≠ 0 → padicValNat p (a * b) = padicValNat p a + padicValNat p b 
goal: a ≠ 0 → b ≠ 0 → padicValNat p (a * b) = padicValNat p a + padicValNat p b

full_name: padicValNat.div_of_dvd
code: protected theorem div_of_dvd (h : b ∣ a) :
    padicValNat p (a / b) = padicValNat p a - padicValNat p b 
goal: padicValNat p (a / b) = padicValNat p a - padicValNat p b

full_name: padicValNat.div
code: /-- Dividing out by a prime factor reduces the `padicValNat` by `1`. -/
protected theorem div (dvd : p ∣ b) : padicValNat p (b / p) = padicValNat p b - 1 
goal: padicValNat p (b / p) = padicValNat p b - 1

full_name: padicValNat.pow
code: /-- A version of `padicValRat.pow` for `padicValNat`. -/
protected theorem pow (n : ℕ) (ha : a ≠ 0) : padicValNat p (a ^ n) = n * padicValNat p a 
goal: padicValNat p (a ^ n) = n * padicValNat p a

full_name: padicValNat.prime_pow
code: @[simp]
protected theorem prime_pow (n : ℕ) : padicValNat p (p ^ n) = n 
goal: padicValNat p (p ^ n) = n

full_name: padicValNat.div_pow
code: protected theorem div_pow (dvd : p ^ a ∣ b) : padicValNat p (b / p ^ a) = padicValNat p b - a 
goal: padicValNat p (b / p ^ a) = padicValNat p b - a

full_name: padicValNat.div'
code: protected theorem div' {m : ℕ} (cpm : Coprime p m) {b : ℕ} (dvd : m ∣ b) :
    padicValNat p (b / m) = padicValNat p b 
goal: padicValNat p (b / m) = padicValNat p b

full_name: dvd_of_one_le_padicValNat
code: theorem dvd_of_one_le_padicValNat {n : ℕ} (hp : 1 ≤ padicValNat p n) : p ∣ n 
goal: p ∣ n

full_name: pow_padicValNat_dvd
code: theorem pow_padicValNat_dvd {n : ℕ} : p ^ padicValNat p n ∣ n 
goal: p ^ padicValNat p n ∣ n

full_name: padicValNat_dvd_iff_le
code: theorem padicValNat_dvd_iff_le [hp : Fact p.Prime] {a n : ℕ} (ha : a ≠ 0) :
    p ^ n ∣ a ↔ n ≤ padicValNat p a 
goal: p ^ n ∣ a ↔ n ≤ padicValNat p a

full_name: padicValNat_dvd_iff
code: theorem padicValNat_dvd_iff (n : ℕ) [hp : Fact p.Prime] (a : ℕ) :
    p ^ n ∣ a ↔ a = 0 ∨ n ≤ padicValNat p a 
goal: p ^ n ∣ a ↔ a = 0 ∨ n ≤ padicValNat p a

full_name: pow_succ_padicValNat_not_dvd
code: theorem pow_succ_padicValNat_not_dvd {n : ℕ} [hp : Fact p.Prime] (hn : n ≠ 0) :
    ¬p ^ (padicValNat p n + 1) ∣ n 
goal: ¬p ^ (padicValNat p n + 1) ∣ n

full_name: padicValNat_primes
code: theorem padicValNat_primes {q : ℕ} [hp : Fact p.Prime] [hq : Fact q.Prime] (neq : p ≠ q) :
    padicValNat p q = 0 
goal: padicValNat p q = 0

full_name: padicValNat_prime_prime_pow
code: theorem padicValNat_prime_prime_pow {q : ℕ} [hp : Fact p.Prime] [hq : Fact q.Prime]
    (n : ℕ) (neq : p ≠ q) : padicValNat p (q ^ n) = 0 
goal: padicValNat p (q ^ n) = 0

full_name: padicValNat_mul_pow_left
code: theorem padicValNat_mul_pow_left {q : ℕ} [hp : Fact p.Prime] [hq : Fact q.Prime]
    (n m : ℕ) (neq : p ≠ q) : padicValNat p (p^n * q^m) = n 
goal: padicValNat p (p ^ n * q ^ m) = n

full_name: padicValNat_mul_pow_right
code: theorem padicValNat_mul_pow_right {q : ℕ} [hp : Fact p.Prime] [hq : Fact q.Prime]
    (n m : ℕ) (neq : q ≠ p) : padicValNat q (p^n * q^m) = m 
goal: padicValNat q (p ^ n * q ^ m) = m

full_name: padicValNat_le_nat_log
code: /-- The p-adic valuation of `n` is less than or equal to its logarithm w.r.t `p`. -/
lemma padicValNat_le_nat_log (n : ℕ) : padicValNat p n ≤ Nat.log p n 
goal: padicValNat p n ≤ Nat.log p n

full_name: nat_log_eq_padicValNat_iff
code: /-- The p-adic valuation of `n` is equal to the logarithm w.r.t `p` iff
    `n` is less than `p` raised to one plus the p-adic valuation of `n`. -/
lemma nat_log_eq_padicValNat_iff {n : ℕ} [hp : Fact (Nat.Prime p)] (hn : 0 < n) :
    Nat.log p n = padicValNat p n ↔ n < p ^ (padicValNat p n + 1) 
goal: Nat.log p n = padicValNat p n ↔ n < p ^ (padicValNat p n + 1)

full_name: Nat.log_ne_padicValNat_succ
code: lemma Nat.log_ne_padicValNat_succ {n : ℕ} (hn : n ≠ 0) : log 2 n ≠ padicValNat 2 (n + 1) 
goal: Nat.log 2 n ≠ padicValNat 2 (n + 1)

full_name: Nat.max_log_padicValNat_succ_eq_log_succ
code: lemma Nat.max_log_padicValNat_succ_eq_log_succ (n : ℕ) :
    max (log 2 n) (padicValNat 2 (n + 1)) = log 2 (n + 1) 
goal: max (Nat.log 2 n) (padicValNat 2 (n + 1)) = Nat.log 2 (n + 1)

full_name: range_pow_padicValNat_subset_divisors
code: theorem range_pow_padicValNat_subset_divisors {n : ℕ} (hn : n ≠ 0) :
    (Finset.range (padicValNat p n + 1)).image (p ^ ·) ⊆ n.divisors 
goal: Finset.image (fun x => p ^ x) (Finset.range (padicValNat p n + 1)) ⊆ n.divisors

full_name: range_pow_padicValNat_subset_divisors'
code: theorem range_pow_padicValNat_subset_divisors' {n : ℕ} [hp : Fact p.Prime] :
    ((Finset.range (padicValNat p n)).image fun t => p ^ (t + 1)) ⊆ n.divisors.erase 1 
goal: Finset.image (fun t => p ^ (t + 1)) (Finset.range (padicValNat p n)) ⊆ n.divisors.erase 1

full_name: padicValNat_factorial_mul
code: /-- The `p`-adic valuation of `(p * n)!` is `n` more than that of `n!`. -/
theorem padicValNat_factorial_mul (n : ℕ) [hp : Fact p.Prime] :
    padicValNat p (p * n) ! = padicValNat p n ! + n 
goal: padicValNat p (p * n)! = padicValNat p n ! + n

full_name: padicValNat_eq_zero_of_mem_Ioo
code: /-- The `p`-adic valuation of `m` equals zero if it is between `p * k` and `p * (k + 1)` for
some `k`. -/
theorem padicValNat_eq_zero_of_mem_Ioo {m k : ℕ}
    (hm : m ∈ Set.Ioo (p * k) (p * (k + 1))) : padicValNat p m = 0 
goal: padicValNat p m = 0

full_name: padicValNat_factorial_mul_add
code: theorem padicValNat_factorial_mul_add {n : ℕ} (m : ℕ) [hp : Fact p.Prime] (h : n < p) :
    padicValNat p (p * m + n) ! = padicValNat p (p * m) ! 
goal: padicValNat p (p * m + n)! = padicValNat p (p * m)!

full_name: padicValNat_mul_div_factorial
code: /-- The `p`-adic valuation of `n!` is equal to the `p`-adic valuation of the factorial of the
largest multiple of `p` below `n`, i.e. `(p * ⌊n / p⌋)!`. -/
@[simp] theorem padicValNat_mul_div_factorial (n : ℕ) [hp : Fact p.Prime] :
    padicValNat p (p * (n / p))! = padicValNat p n ! 
goal: padicValNat p (p * (n / p))! = padicValNat p n !

full_name: padicValNat_factorial
code: /-- **Legendre's Theorem**

The `p`-adic valuation of `n!` is the sum of the quotients `n / p ^ i`. This sum is expressed
over the finset `Ico 1 b` where `b` is any bound greater than `log p n`. -/
theorem padicValNat_factorial {n b : ℕ} [hp : Fact p.Prime] (hnb : log p n < b) :
    padicValNat p (n !) = ∑ i ∈ Finset.Ico 1 b, n / p ^ i 
goal: padicValNat p n ! = ∑ i ∈ Finset.Ico 1 b, n / p ^ i

full_name: sub_one_mul_padicValNat_factorial
code: /-- **Legendre's Theorem**

Taking (`p - 1`) times the `p`-adic valuation of `n!` equals `n` minus the sum of base `p` digits
of `n`. -/
theorem sub_one_mul_padicValNat_factorial [hp : Fact p.Prime] (n : ℕ) :
    (p - 1) * padicValNat p (n !) = n - (p.digits n).sum 
goal: (p - 1) * padicValNat p n ! = n - (p.digits n).sum

full_name: padicValNat_choose
code: /-- **Kummer's Theorem**

The `p`-adic valuation of `n.choose k` is the number of carries when `k` and `n - k` are added
in base `p`. This sum is expressed over the finset `Ico 1 b` where `b` is any bound greater than
`log p n`. -/
theorem padicValNat_choose {n k b : ℕ} [hp : Fact p.Prime] (hkn : k ≤ n) (hnb : log p n < b) :
    padicValNat p (choose n k) =
    ((Finset.Ico 1 b).filter fun i => p ^ i ≤ k % p ^ i + (n - k) % p ^ i).card 
goal: padicValNat p (n.choose k) = (Finset.filter (fun i => p ^ i ≤ k % p ^ i + (n - k) % p ^ i) (Finset.Ico 1 b)).card

full_name: padicValNat_choose'
code: /-- **Kummer's Theorem**

The `p`-adic valuation of `(n + k).choose k` is the number of carries when `k` and `n` are added
in base `p`. This sum is expressed over the finset `Ico 1 b` where `b` is any bound greater than
`log p (n + k)`. -/
theorem padicValNat_choose' {n k b : ℕ} [hp : Fact p.Prime] (hnb : log p (n + k) < b) :
    padicValNat p (choose (n + k) k) =
    ((Finset.Ico 1 b).filter fun i => p ^ i ≤ k % p ^ i + n % p ^ i).card 
goal: padicValNat p ((n + k).choose k) = (Finset.filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Finset.Ico 1 b)).card

full_name: sub_one_mul_padicValNat_choose_eq_sub_sum_digits'
code: /-- **Kummer's Theorem**
Taking (`p - 1`) times the `p`-adic valuation of the binomial `n + k` over `k` equals the sum of the
digits of `k` plus the sum of the digits of `n` minus the sum of digits of `n + k`, all base `p`.
-/
theorem sub_one_mul_padicValNat_choose_eq_sub_sum_digits' {k n : ℕ} [hp : Fact p.Prime] :
    (p - 1) * padicValNat p (choose (n + k) k) =
    (p.digits k).sum + (p.digits n).sum - (p.digits (n + k)).sum 
goal: (p - 1) * padicValNat p ((n + k).choose k) = (p.digits k).sum + (p.digits n).sum - (p.digits (n + k)).sum

full_name: sub_one_mul_padicValNat_choose_eq_sub_sum_digits
code: /-- **Kummer's Theorem**
Taking (`p - 1`) times the `p`-adic valuation of the binomial `n` over `k` equals the sum of the
digits of `k` plus the sum of the digits of `n - k` minus the sum of digits of `n`, all base `p`.
-/
theorem sub_one_mul_padicValNat_choose_eq_sub_sum_digits {k n : ℕ} [hp : Fact p.Prime]
    (h : k ≤ n) : (p - 1) * padicValNat p (choose n k) =
    (p.digits k).sum + (p.digits (n - k)).sum - (p.digits n).sum 
goal: (p - 1) * padicValNat p (n.choose k) = (p.digits k).sum + (p.digits (n - k)).sum - (p.digits n).sum

full_name: padicValInt_dvd_iff
code: theorem padicValInt_dvd_iff (n : ℕ) (a : ℤ) : (p : ℤ) ^ n ∣ a ↔ a = 0 ∨ n ≤ padicValInt p a 
goal: ↑p ^ n ∣ a ↔ a = 0 ∨ n ≤ padicValInt p a

full_name: padicValInt_dvd
code: theorem padicValInt_dvd (a : ℤ) : (p : ℤ) ^ padicValInt p a ∣ a 
goal: ↑p ^ padicValInt p a ∣ a

full_name: padicValInt_self
code: theorem padicValInt_self : padicValInt p p = 1 
goal: padicValInt p ↑p = 1

full_name: padicValInt.mul
code: theorem padicValInt.mul {a b : ℤ} (ha : a ≠ 0) (hb : b ≠ 0) :
    padicValInt p (a * b) = padicValInt p a + padicValInt p b 
goal: padicValInt p (a * b) = padicValInt p a + padicValInt p b

full_name: padicValInt_mul_eq_succ
code: theorem padicValInt_mul_eq_succ (a : ℤ) (ha : a ≠ 0) :
    padicValInt p (a * p) = padicValInt p a + 1 
goal: padicValInt p (a * ↑p) = padicValInt p a + 1