Theorem: sq_dvd_add_pow_sub_sub
File: Mathlib/NumberTheory/Multiplicity.lean

tactic: cases' n with n n
state_before: R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * ↑n - x ^ n
state_after: case zero
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
⊢ p ^ 2 ∣ (x + p) ^ 0 - x ^ (0 - 1) * p * ↑0 - x ^ 0

case succ
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ p ^ 2 ∣ (x + p) ^ (n + 1) - x ^ (n + 1 - 1) * p * ↑(n + 1) - x ^ (n + 1)

tactic: simp only [pow_zero, Nat.cast_zero, sub_zero, sub_self, dvd_zero, Nat.zero_eq, mul_zero]
state_before: case zero
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
⊢ p ^ 2 ∣ (x + p) ^ 0 - x ^ (0 - 1) * p * ↑0 - x ^ 0
state_after: no goals

tactic: simp only [Nat.succ_sub_succ_eq_sub, tsub_zero, Nat.cast_succ, add_pow, Finset.sum_range_succ,
  Nat.choose_self, Nat.succ_sub _, tsub_self, pow_one, Nat.choose_succ_self_right, pow_zero,
  mul_one, Nat.cast_zero, zero_add, Nat.succ_eq_add_one, add_tsub_cancel_left]
state_before: case succ
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ p ^ 2 ∣ (x + p) ^ (n + 1) - x ^ (n + 1 - 1) * p * ↑(n + 1) - x ^ (n + 1)
state_after: case succ
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ p ^ 2 ∣
    ∑ m ∈ range n, x ^ m * p ^ (n + 1 - m) * ↑((n + 1).choose m) + x ^ n * p * (↑n + 1) + x ^ (n + 1) -
        x ^ n * p * (↑n + 1) -
      x ^ (n + 1)

tactic: suffices p ^ 2 ∣ ∑ i ∈ range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i) by
  convert this; abel
state_before: case succ
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ p ^ 2 ∣
    ∑ m ∈ range n, x ^ m * p ^ (n + 1 - m) * ↑((n + 1).choose m) + x ^ n * p * (↑n + 1) + x ^ (n + 1) -
        x ^ n * p * (↑n + 1) -
      x ^ (n + 1)
state_after: case succ
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ p ^ 2 ∣ ∑ i ∈ range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i)

tactic: apply Finset.dvd_sum
state_before: case succ
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ p ^ 2 ∣ ∑ i ∈ range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i)
state_after: case succ.h
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ ∀ i ∈ range n, p ^ 2 ∣ x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i)

tactic: intro y hy
state_before: case succ.h
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ ∀ i ∈ range n, p ^ 2 ∣ x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i)
state_after: case succ.h
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y✝ p x : R
n y : ℕ
hy : y ∈ range n
⊢ p ^ 2 ∣ x ^ y * p ^ (n + 1 - y) * ↑((n + 1).choose y)

tactic: calc
  p ^ 2 ∣ p ^ (n + 1 - y) :=
    pow_dvd_pow p (le_tsub_of_add_le_left (by linarith [Finset.mem_range.mp hy]))
  _ ∣ x ^ y * p ^ (n + 1 - y) * ↑((n + 1).choose y) :=
    dvd_mul_of_dvd_left (dvd_mul_left _ _) _
state_before: case succ.h
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y✝ p x : R
n y : ℕ
hy : y ∈ range n
⊢ p ^ 2 ∣ x ^ y * p ^ (n + 1 - y) * ↑((n + 1).choose y)
state_after: no goals

tactic: convert this
state_before: R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
this : p ^ 2 ∣ ∑ i ∈ range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i)
⊢ p ^ 2 ∣
    ∑ m ∈ range n, x ^ m * p ^ (n + 1 - m) * ↑((n + 1).choose m) + x ^ n * p * (↑n + 1) + x ^ (n + 1) -
        x ^ n * p * (↑n + 1) -
      x ^ (n + 1)
state_after: case h.e'_4
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
this : p ^ 2 ∣ ∑ i ∈ range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i)
⊢ ∑ m ∈ range n, x ^ m * p ^ (n + 1 - m) * ↑((n + 1).choose m) + x ^ n * p * (↑n + 1) + x ^ (n + 1) -
        x ^ n * p * (↑n + 1) -
      x ^ (n + 1) =
    ∑ i ∈ range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i)

tactic: abel
state_before: case h.e'_4
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
this : p ^ 2 ∣ ∑ i ∈ range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i)
⊢ ∑ m ∈ range n, x ^ m * p ^ (n + 1 - m) * ↑((n + 1).choose m) + x ^ n * p * (↑n + 1) + x ^ (n + 1) -
        x ^ n * p * (↑n + 1) -
      x ^ (n + 1) =
    ∑ i ∈ range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i)
state_after: no goals

tactic: linarith [Finset.mem_range.mp hy]
state_before: R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y✝ p x : R
n y : ℕ
hy : y ∈ range n
⊢ y + 2 ≤ n + 1
state_after: no goals