-- Mathlib/Analysis/Convex/SpecificFunctions/Deriv.lean
theorem int_prod_range_nonneg (m : ℤ) (n : ℕ) (hn : Even n) :
    0 ≤ ∏ k ∈ Finset.range n, (m - k)

Proof state:
case intro.succ
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
⊢ 0 ≤ ∏ k ∈ Finset.range (n + 1 + (n + 1)), (m - ↑k)

Tactic:
rw [← two_mul, mul_add, mul_one, ← one_add_one_eq_two, ← add_assoc,
  Finset.prod_range_succ, Finset.prod_range_succ, mul_assoc]

Result:
case intro.succ
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
⊢ 0 ≤ (∏ x ∈ Finset.range ((1 + 1) * n), (m - ↑x)) * ((m - ↑((1 + 1) * n)) * (m - ↑((1 + 1) * n + 1)))

Proof state:
case intro.succ.inr
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
k : ℕ
hmk : ↑k < m
⊢ 0 ≤ (m - ↑k) * (m - ↑(k + 1))

Tactic:
exact mul_nonneg (sub_nonneg_of_le hmk.le) (sub_nonneg_of_le hmk)

Result:
no goals

Proof state:
case intro.succ.inl
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
k : ℕ
hmk : m ≤ ↑k
⊢ 0 ≤ (m - ↑k) * (m - ↑(k + 1))

Tactic:
have : m ≤ k + 1 := hmk.trans (lt_add_one (k : ℤ)).le

Result:
case intro.succ.inl
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
k : ℕ
hmk : m ≤ ↑k
this : m ≤ ↑k + 1
⊢ 0 ≤ (m - ↑k) * (m - ↑(k + 1))

Proof state:
case intro.succ.inl
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
k : ℕ
hmk : m ≤ ↑k
this : m ≤ ↑k + 1
⊢ 0 ≤ (m - ↑k) * (m - ↑(k + 1))

Tactic:
convert mul_nonneg_of_nonpos_of_nonpos (sub_nonpos_of_le hmk) _

Result:
case intro.succ.inl.convert_2
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
k : ℕ
hmk : m ≤ ↑k
this : m ≤ ↑k + 1
⊢ m - ↑(k + 1) ≤ 0

Proof state:
case intro.succ
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (n + n), (m - ↑k)
⊢ 0 ≤ ∏ k ∈ Finset.range (n + 1 + (n + 1)), (m - ↑k)

Tactic:
rw [← two_mul] at ihn

Result:
case intro.succ
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
⊢ 0 ≤ ∏ k ∈ Finset.range (n + 1 + (n + 1)), (m - ↑k)

Proof state:
case intro.succ
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
k : ℕ
⊢ 0 ≤ (m - ↑k) * (m - ↑(k + 1))

Tactic:
rcases le_or_lt m k with hmk | hmk

Result:
case intro.succ.inl
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
k : ℕ
hmk : m ≤ ↑k
⊢ 0 ≤ (m - ↑k) * (m - ↑(k + 1))

case intro.succ.inr
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
k : ℕ
hmk : ↑k < m
⊢ 0 ≤ (m - ↑k) * (m - ↑(k + 1))

Proof state:
m : ℤ
n : ℕ
hn : Even n
⊢ 0 ≤ ∏ k ∈ Finset.range n, (m - ↑k)

Tactic:
rcases hn with ⟨n, rfl⟩

Result:
case intro
m : ℤ
n : ℕ
⊢ 0 ≤ ∏ k ∈ Finset.range (n + n), (m - ↑k)

Proof state:
case intro.succ
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
⊢ 0 ≤ (m - ↑((1 + 1) * n)) * (m - ↑((1 + 1) * n + 1))

Tactic:
generalize (1 + 1) * n = k

Result:
case intro.succ
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
k : ℕ
⊢ 0 ≤ (m - ↑k) * (m - ↑(k + 1))

Proof state:
case intro.succ
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
⊢ 0 ≤ (∏ x ∈ Finset.range ((1 + 1) * n), (m - ↑x)) * ((m - ↑((1 + 1) * n)) * (m - ↑((1 + 1) * n + 1)))

Tactic:
refine mul_nonneg ihn ?_

Result:
case intro.succ
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
⊢ 0 ≤ (m - ↑((1 + 1) * n)) * (m - ↑((1 + 1) * n + 1))

Proof state:
case intro.zero
m : ℤ
⊢ 0 ≤ ∏ k ∈ Finset.range (0 + 0), (m - ↑k)

Tactic:
simp

Result:
no goals

Proof state:
case intro.succ.inl.convert_2
m : ℤ
n : ℕ
ihn : 0 ≤ ∏ k ∈ Finset.range (2 * n), (m - ↑k)
k : ℕ
hmk : m ≤ ↑k
this : m ≤ ↑k + 1
⊢ m - ↑(k + 1) ≤ 0

Tactic:
convert sub_nonpos_of_le this

Result:
no goals