Theorem: Finset.prod_antidiagonal_pow_choose_succ
File: Mathlib/Data/Nat/Choose/Sum.lean

tactic: simp only [Nat.prod_antidiagonal_eq_prod_range_succ_mk, prod_pow_choose_succ]
state_before: R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
⊢ ∏ ij ∈ antidiagonal (n + 1), f ij.1 ij.2 ^ (n + 1).choose ij.1 =
    (∏ ij ∈ antidiagonal n, f ij.1 (ij.2 + 1) ^ n.choose ij.1) *
      ∏ ij ∈ antidiagonal n, f (ij.1 + 1) ij.2 ^ n.choose ij.2
state_after: R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
⊢ (∏ i ∈ range (n + 1), f i (n + 1 - i) ^ n.choose i) * ∏ i ∈ range (n + 1), f (i + 1) (n - i) ^ n.choose i =
    (∏ x ∈ range n.succ, f x (n - x + 1) ^ n.choose x) * ∏ x ∈ range n.succ, f (x + 1) (n - x) ^ n.choose (n - x)

tactic: have : ∀ i ∈ range (n + 1), i ≤ n := fun i hi ↦ by simpa [Nat.lt_succ_iff] using hi
state_before: R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
⊢ (∏ i ∈ range (n + 1), f i (n + 1 - i) ^ n.choose i) * ∏ i ∈ range (n + 1), f (i + 1) (n - i) ^ n.choose i =
    (∏ x ∈ range n.succ, f x (n - x + 1) ^ n.choose x) * ∏ x ∈ range n.succ, f (x + 1) (n - x) ^ n.choose (n - x)
state_after: R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
this : ∀ i ∈ range (n + 1), i ≤ n
⊢ (∏ i ∈ range (n + 1), f i (n + 1 - i) ^ n.choose i) * ∏ i ∈ range (n + 1), f (i + 1) (n - i) ^ n.choose i =
    (∏ x ∈ range n.succ, f x (n - x + 1) ^ n.choose x) * ∏ x ∈ range n.succ, f (x + 1) (n - x) ^ n.choose (n - x)

tactic: congr 1
state_before: R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
this : ∀ i ∈ range (n + 1), i ≤ n
⊢ (∏ i ∈ range (n + 1), f i (n + 1 - i) ^ n.choose i) * ∏ i ∈ range (n + 1), f (i + 1) (n - i) ^ n.choose i =
    (∏ x ∈ range n.succ, f x (n - x + 1) ^ n.choose x) * ∏ x ∈ range n.succ, f (x + 1) (n - x) ^ n.choose (n - x)
state_after: case e_a
R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
this : ∀ i ∈ range (n + 1), i ≤ n
⊢ ∏ i ∈ range (n + 1), f i (n + 1 - i) ^ n.choose i = ∏ x ∈ range n.succ, f x (n - x + 1) ^ n.choose x

case e_a
R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
this : ∀ i ∈ range (n + 1), i ≤ n
⊢ ∏ i ∈ range (n + 1), f (i + 1) (n - i) ^ n.choose i = ∏ x ∈ range n.succ, f (x + 1) (n - x) ^ n.choose (n - x)

tactic: simpa [Nat.lt_succ_iff] using hi
state_before: R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n i : ℕ
hi : i ∈ range (n + 1)
⊢ i ≤ n
state_after: no goals

tactic: refine prod_congr rfl fun i hi ↦ ?_
state_before: case e_a
R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
this : ∀ i ∈ range (n + 1), i ≤ n
⊢ ∏ i ∈ range (n + 1), f i (n + 1 - i) ^ n.choose i = ∏ x ∈ range n.succ, f x (n - x + 1) ^ n.choose x
state_after: case e_a
R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
this : ∀ i ∈ range (n + 1), i ≤ n
i : ℕ
hi : i ∈ range n.succ
⊢ f i (n + 1 - i) ^ n.choose i = f i (n - i + 1) ^ n.choose i

tactic: rw [tsub_add_eq_add_tsub (this _ hi)]
state_before: case e_a
R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
this : ∀ i ∈ range (n + 1), i ≤ n
i : ℕ
hi : i ∈ range n.succ
⊢ f i (n + 1 - i) ^ n.choose i = f i (n - i + 1) ^ n.choose i
state_after: no goals

tactic: refine prod_congr rfl fun i hi ↦ ?_
state_before: case e_a
R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
this : ∀ i ∈ range (n + 1), i ≤ n
⊢ ∏ i ∈ range (n + 1), f (i + 1) (n - i) ^ n.choose i = ∏ x ∈ range n.succ, f (x + 1) (n - x) ^ n.choose (n - x)
state_after: case e_a
R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
this : ∀ i ∈ range (n + 1), i ≤ n
i : ℕ
hi : i ∈ range n.succ
⊢ f (i + 1) (n - i) ^ n.choose i = f (i + 1) (n - i) ^ n.choose (n - i)

tactic: rw [Nat.choose_symm (this _ hi)]
state_before: case e_a
R✝ : Type u_1
M✝ : Type u_2
R : Type u_3
inst✝² : CommMonoid M✝
inst✝¹ : NonAssocSemiring R
M : Type u_4
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
this : ∀ i ∈ range (n + 1), i ≤ n
i : ℕ
hi : i ∈ range n.succ
⊢ f (i + 1) (n - i) ^ n.choose i = f (i + 1) (n - i) ^ n.choose (n - i)
state_after: no goals