Theorem: binomial_sum_eq
File: Mathlib/Combinatorics/SetFamily/AhlswedeZhang.lean

tactic: set f : ℕ → ℚ := fun i ↦ n.choose i * (m.choose i : ℚ)⁻¹ with hf
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
⊢ ∑ i ∈ range (n + 1), ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i)) = 1
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
⊢ ∑ i ∈ range (n + 1), ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i)) = 1

tactic: suffices ∀ i ∈ range (n + 1), f i - f (i + 1) = n.choose i * (m - n) / ((m - i) * m.choose i) by
  rw [← sum_congr rfl this, sum_range_sub', hf]
  simp [choose_self, choose_zero_right, choose_eq_zero_of_lt h]
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
⊢ ∑ i ∈ range (n + 1), ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i)) = 1
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
⊢ ∀ i ∈ range (n + 1), f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: intro i h₁
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
⊢ ∀ i ∈ range (n + 1), f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁ : i ∈ range (n + 1)
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: rw [mem_range] at h₁
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁ : i ∈ range (n + 1)
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁ : i < n + 1
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: have h₁ := le_of_lt_succ h₁
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁ : i < n + 1
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: have h₂ := h₁.trans_lt h
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: have h₃ := h₂.le
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: have hi₄ : (i + 1 : ℚ) ≠ 0 := i.cast_add_one_ne_zero
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: have := congr_arg ((↑) : ℕ → ℚ) (choose_succ_right_eq m i)
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this : ↑(m.choose (i + 1) * (i + 1)) = ↑(m.choose i * (m - i))
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: push_cast at this
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this : ↑(m.choose (i + 1) * (i + 1)) = ↑(m.choose i * (m - i))
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: dsimp [f, hf]
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
⊢ f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ - ↑(n.choose (i + 1)) * (↑(m.choose (i + 1)))⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: rw [(eq_mul_inv_iff_mul_eq₀ hi₄).mpr this]
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ - ↑(n.choose (i + 1)) * (↑(m.choose (i + 1)))⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ - ↑(n.choose (i + 1)) * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: have := congr_arg ((↑) : ℕ → ℚ) (choose_succ_right_eq n i)
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ - ↑(n.choose (i + 1)) * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝ : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this : ↑(n.choose (i + 1) * (i + 1)) = ↑(n.choose i * (n - i))
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ - ↑(n.choose (i + 1)) * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: push_cast at this
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝ : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this : ↑(n.choose (i + 1) * (i + 1)) = ↑(n.choose i * (n - i))
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ - ↑(n.choose (i + 1)) * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝ : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this : ↑(n.choose (i + 1)) * (↑i + 1) = ↑(n.choose i) * ↑(n - i)
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ - ↑(n.choose (i + 1)) * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: rw [(eq_mul_inv_iff_mul_eq₀ hi₄).mpr this]
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝ : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this : ↑(n.choose (i + 1)) * (↑i + 1) = ↑(n.choose i) * ↑(n - i)
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ - ↑(n.choose (i + 1)) * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝ : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this : ↑(n.choose (i + 1)) * (↑i + 1) = ↑(n.choose i) * ↑(n - i)
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ -
      ↑(n.choose i) * ↑(n - i) * (↑i + 1)⁻¹ * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: have : (m - i : ℚ) ≠ 0 := sub_ne_zero_of_ne (cast_lt.mpr h₂).ne'
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝ : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this : ↑(n.choose (i + 1)) * (↑i + 1) = ↑(n.choose i) * ↑(n - i)
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ -
      ↑(n.choose i) * ↑(n - i) * (↑i + 1)⁻¹ * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝¹ : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this✝ : ↑(n.choose (i + 1)) * (↑i + 1) = ↑(n.choose i) * ↑(n - i)
this : ↑m - ↑i ≠ 0
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ -
      ↑(n.choose i) * ↑(n - i) * (↑i + 1)⁻¹ * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: have : (m.choose i : ℚ) ≠ 0 := cast_ne_zero.2 (choose_pos h₂.le).ne'
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝¹ : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this✝ : ↑(n.choose (i + 1)) * (↑i + 1) = ↑(n.choose i) * ↑(n - i)
this : ↑m - ↑i ≠ 0
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ -
      ↑(n.choose i) * ↑(n - i) * (↑i + 1)⁻¹ * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝² : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this✝¹ : ↑(n.choose (i + 1)) * (↑i + 1) = ↑(n.choose i) * ↑(n - i)
this✝ : ↑m - ↑i ≠ 0
this : ↑(m.choose i) ≠ 0
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ -
      ↑(n.choose i) * ↑(n - i) * (↑i + 1)⁻¹ * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))

tactic: field_simp
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝² : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this✝¹ : ↑(n.choose (i + 1)) * (↑i + 1) = ↑(n.choose i) * ↑(n - i)
this✝ : ↑m - ↑i ≠ 0
this : ↑(m.choose i) ≠ 0
⊢ ↑(n.choose i) * (↑(m.choose i))⁻¹ -
      ↑(n.choose i) * ↑(n - i) * (↑i + 1)⁻¹ * (↑(m.choose i) * ↑(m - i) * (↑i + 1)⁻¹)⁻¹ =
    ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝² : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this✝¹ : ↑(n.choose (i + 1)) * (↑i + 1) = ↑(n.choose i) * ↑(n - i)
this✝ : ↑m - ↑i ≠ 0
this : ↑(m.choose i) ≠ 0
⊢ (↑(n.choose i) * (↑(m.choose i) * (↑m - ↑i)) - ↑(m.choose i) * (↑(n.choose i) * (↑n - ↑i))) *
      ((↑m - ↑i) * ↑(m.choose i)) =
    ↑(n.choose i) * (↑m - ↑n) * (↑(m.choose i) * (↑(m.choose i) * (↑m - ↑i)))

tactic: ring
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
i : ℕ
h₁✝ : i < n + 1
h₁ : i ≤ n
h₂ : i < m
h₃ : i ≤ m
hi₄ : ↑i + 1 ≠ 0
this✝² : ↑(m.choose (i + 1)) * (↑i + 1) = ↑(m.choose i) * ↑(m - i)
this✝¹ : ↑(n.choose (i + 1)) * (↑i + 1) = ↑(n.choose i) * ↑(n - i)
this✝ : ↑m - ↑i ≠ 0
this : ↑(m.choose i) ≠ 0
⊢ (↑(n.choose i) * (↑(m.choose i) * (↑m - ↑i)) - ↑(m.choose i) * (↑(n.choose i) * (↑n - ↑i))) *
      ((↑m - ↑i) * ↑(m.choose i)) =
    ↑(n.choose i) * (↑m - ↑n) * (↑(m.choose i) * (↑(m.choose i) * (↑m - ↑i)))
state_after: no goals

tactic: rw [← sum_congr rfl this, sum_range_sub', hf]
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
this : ∀ i ∈ range (n + 1), f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
⊢ ∑ i ∈ range (n + 1), ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i)) = 1
state_after: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
this : ∀ i ∈ range (n + 1), f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
⊢ (fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹) 0 - (fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹) (n + 1) = 1

tactic: simp [choose_self, choose_zero_right, choose_eq_zero_of_lt h]
state_before: α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
m n : ℕ
h : n < m
f : ℕ → ℚ := fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
hf : f = fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹
this : ∀ i ∈ range (n + 1), f i - f (i + 1) = ↑(n.choose i) * (↑m - ↑n) / ((↑m - ↑i) * ↑(m.choose i))
⊢ (fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹) 0 - (fun i => ↑(n.choose i) * (↑(m.choose i))⁻¹) (n + 1) = 1
state_after: no goals