Theorem: Nat.Prime.multiplicity_choose'
File: Mathlib/Data/Nat/Multiplicity.lean

tactic: have h₁ :
    multiplicity p (choose (n + k) k) + multiplicity p (k ! * n !) =
      ((Finset.Ico 1 b).filter fun i => p ^ i ≤ k % p ^ i + n % p ^ i).card +
        multiplicity p (k ! * n !) := by
  rw [← hp.multiplicity_mul, ← mul_assoc]
  have := (add_tsub_cancel_right n k) ▸ choose_mul_factorial_mul_factorial (le_add_left k n)
  rw [this, hp.multiplicity_factorial hnb, hp.multiplicity_mul,
    hp.multiplicity_factorial ((log_mono_right (le_add_left k n)).trans_lt hnb),
    hp.multiplicity_factorial ((log_mono_right (le_add_left n k)).trans_lt
    (add_comm n k ▸ hnb)), multiplicity_choose_aux hp (le_add_left k n)]
  simp [add_comm]
state_before: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
⊢ multiplicity p ((n + k).choose k) = ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card
state_after: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
h₁ :
  multiplicity p ((n + k).choose k) + multiplicity p (k ! * n !) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card + multiplicity p (k ! * n !)
⊢ multiplicity p ((n + k).choose k) = ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card

tactic: refine (PartENat.add_right_cancel_iff ?_).1 h₁
state_before: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
h₁ :
  multiplicity p ((n + k).choose k) + multiplicity p (k ! * n !) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card + multiplicity p (k ! * n !)
⊢ multiplicity p ((n + k).choose k) = ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card
state_after: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
h₁ :
  multiplicity p ((n + k).choose k) + multiplicity p (k ! * n !) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card + multiplicity p (k ! * n !)
⊢ multiplicity p (k ! * n !) ≠ ⊤

tactic: apply PartENat.ne_top_iff_dom.2
state_before: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
h₁ :
  multiplicity p ((n + k).choose k) + multiplicity p (k ! * n !) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card + multiplicity p (k ! * n !)
⊢ multiplicity p (k ! * n !) ≠ ⊤
state_after: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
h₁ :
  multiplicity p ((n + k).choose k) + multiplicity p (k ! * n !) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card + multiplicity p (k ! * n !)
⊢ (multiplicity p (k ! * n !)).Dom

tactic: exact finite_nat_iff.2 ⟨hp.ne_one, mul_pos (factorial_pos k) (factorial_pos n)⟩
state_before: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
h₁ :
  multiplicity p ((n + k).choose k) + multiplicity p (k ! * n !) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card + multiplicity p (k ! * n !)
⊢ (multiplicity p (k ! * n !)).Dom
state_after: no goals

tactic: rw [← hp.multiplicity_mul, ← mul_assoc]
state_before: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
⊢ multiplicity p ((n + k).choose k) + multiplicity p (k ! * n !) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card + multiplicity p (k ! * n !)
state_after: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
⊢ multiplicity p ((n + k).choose k * k ! * n !) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card + multiplicity p (k ! * n !)

tactic: have := (add_tsub_cancel_right n k) ▸ choose_mul_factorial_mul_factorial (le_add_left k n)
state_before: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
⊢ multiplicity p ((n + k).choose k * k ! * n !) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card + multiplicity p (k ! * n !)
state_after: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
this : (n + k).choose k * k ! * n ! = (n + k)!
⊢ multiplicity p ((n + k).choose k * k ! * n !) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card + multiplicity p (k ! * n !)

tactic: rw [this, hp.multiplicity_factorial hnb, hp.multiplicity_mul,
  hp.multiplicity_factorial ((log_mono_right (le_add_left k n)).trans_lt hnb),
  hp.multiplicity_factorial ((log_mono_right (le_add_left n k)).trans_lt
  (add_comm n k ▸ hnb)), multiplicity_choose_aux hp (le_add_left k n)]
state_before: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
this : (n + k).choose k * k ! * n ! = (n + k)!
⊢ multiplicity p ((n + k).choose k * k ! * n !) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card + multiplicity p (k ! * n !)
state_after: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
this : (n + k).choose k * k ! * n ! = (n + k)!
⊢ ↑(∑ i ∈ Ico 1 b, k / p ^ i + ∑ i ∈ Ico 1 b, (n + k - k) / p ^ i +
        (filter (fun i => p ^ i ≤ k % p ^ i + (n + k - k) % p ^ i) (Ico 1 b)).card) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card +
      (↑(∑ i ∈ Ico 1 b, k / p ^ i) + ↑(∑ i ∈ Ico 1 b, n / p ^ i))

tactic: simp [add_comm]
state_before: p n k b : ℕ
hp : Prime p
hnb : log p (n + k) < b
this : (n + k).choose k * k ! * n ! = (n + k)!
⊢ ↑(∑ i ∈ Ico 1 b, k / p ^ i + ∑ i ∈ Ico 1 b, (n + k - k) / p ^ i +
        (filter (fun i => p ^ i ≤ k % p ^ i + (n + k - k) % p ^ i) (Ico 1 b)).card) =
    ↑(filter (fun i => p ^ i ≤ k % p ^ i + n % p ^ i) (Ico 1 b)).card +
      (↑(∑ i ∈ Ico 1 b, k / p ^ i) + ↑(∑ i ∈ Ico 1 b, n / p ^ i))
state_after: no goals