Theorem: Nat.superFactorial_dvd_vandermonde_det
File: Mathlib/Data/Nat/Factorial/SuperFactorial.lean

Proof steps:
state_before: n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
⊢ ↑(sf n) ∣ (Matrix.vandermonde v).det
state_after: n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
⊢ ↑(sf n) ∣ (Matrix.vandermonde v).det
tactic: let m := inf' univ ⟨0, mem_univ _⟩ v
state_before: n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
⊢ ↑(sf n) ∣ (Matrix.vandermonde v).det
state_after: n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
w' : Fin (n + 1) → ℕ := fun i => (v i - m).toNat
⊢ ↑(sf n) ∣ (Matrix.vandermonde v).det
tactic: let w' := fun i ↦ (v i - m).toNat
state_before: n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
w' : Fin (n + 1) → ℕ := fun i => (v i - m).toNat
⊢ ↑(sf n) ∣ (Matrix.vandermonde v).det
state_after: n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
w' : Fin (n + 1) → ℕ := fun i => (v i - m).toNat
hw' : ∀ (i : Fin (n + 1)), ↑(w' i) = v i - m
⊢ ↑(sf n) ∣ (Matrix.vandermonde v).det
tactic: have hw' : ∀ i, (w' i : ℤ) = v i - m := fun i ↦ Int.toNat_sub_of_le (inf'_le _ (mem_univ _))
state_before: n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
w' : Fin (n + 1) → ℕ := fun i => (v i - m).toNat
hw' : ∀ (i : Fin (n + 1)), ↑(w' i) = v i - m
⊢ ↑(sf n) ∣ (Matrix.vandermonde v).det
state_after: n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
w' : Fin (n + 1) → ℕ := fun i => (v i - m).toNat
hw' : ∀ (i : Fin (n + 1)), ↑(w' i) = v i - m
h :
  (Matrix.vandermonde fun i => ↑(w' i)).det =
    (Matrix.of fun i j => Polynomial.eval ((fun i => ↑(w' i)) i) ((fun i => descPochhammer ℤ ↑i) j)).det
⊢ ↑(sf n) ∣ (Matrix.vandermonde v).det
tactic: have h := Matrix.det_eval_matrixOfPolynomials_eq_det_vandermonde (fun i ↦ ↑(w' i))
      (fun i => descPochhammer ℤ i)
      (fun i => descPochhammer_natDegree ℤ i)
      (fun i => monic_descPochhammer ℤ i)
state_before: n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
w' : Fin (n + 1) → ℕ := fun i => (v i - m).toNat
hw' : ∀ (i : Fin (n + 1)), ↑(w' i) = v i - m
h :
  (Matrix.vandermonde fun i => ↑(w' i)).det =
    (Matrix.of fun i j => Polynomial.eval ((fun i => ↑(w' i)) i) ((fun i => descPochhammer ℤ ↑i) j)).det
⊢ ↑(sf n) ∣ (Matrix.vandermonde v).det
state_after: n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
w' : Fin (n + 1) → ℕ := fun i => (v i - m).toNat
hw' : ∀ (i : Fin (n + 1)), ↑(w' i) = v i - m
h :
  (Matrix.vandermonde v).det =
    (Matrix.of fun i j => Polynomial.eval ((fun i => ↑(w' i)) i) ((fun i => descPochhammer ℤ ↑i) j)).det
⊢ ↑(sf n) ∣ (Matrix.vandermonde v).det
tactic: conv_lhs at h => simp only [hw', Matrix.det_vandermonde_sub]
state_before: n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
w' : Fin (n + 1) → ℕ := fun i => (v i - m).toNat
hw' : ∀ (i : Fin (n + 1)), ↑(w' i) = v i - m
h :
  (Matrix.vandermonde v).det =
    (Matrix.of fun i j => Polynomial.eval ((fun i => ↑(w' i)) i) ((fun i => descPochhammer ℤ ↑i) j)).det
⊢ ↑(sf n) ∣ (Matrix.vandermonde v).det
state_after: case h
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
w' : Fin (n + 1) → ℕ := fun i => (v i - m).toNat
hw' : ∀ (i : Fin (n + 1)), ↑(w' i) = v i - m
h :
  (Matrix.vandermonde v).det =
    (Matrix.of fun i j => Polynomial.eval ((fun i => ↑(w' i)) i) ((fun i => descPochhammer ℤ ↑i) j)).det
⊢ (Matrix.vandermonde v).det = ↑(sf n) * (Matrix.of fun i j => ↑((w' i).choose ↑j)).det
tactic: use (Matrix.of (fun (i j : Fin (n + 1)) => (Nat.choose (w' i) (j : ℕ) : ℤ))).det
state_before: case h
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
n : ℕ
v : Fin (n + 1) → ℤ
m : ℤ := univ.inf' ⋯ v
w' : Fin (n + 1) → ℕ := fun i => (v i - m).toNat
hw' : ∀ (i : Fin (n + 1)), ↑(w' i) = v i - m
h :
  (Matrix.vandermonde v).det =
    (Matrix.of fun i j => Polynomial.eval ((fun i => ↑(w' i)) i) ((fun i => descPochhammer ℤ ↑i) j)).det
⊢ (Matrix.vandermonde v).det = ↑(sf n) * (Matrix.of fun i j => ↑((w' i).choose ↑j)).det
state_after: no goals
tactic: simp [h, matrixOf_eval_descPochhammer_eq_mul_matrixOf_choose w', Fin.prod_univ_eq_prod_range]