l3lab/ntp-mathlib huggingface dataset:
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
s : Finset α
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
⊢ ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))

Next tactic:
induction' s using Finset.induction with a s ha ih
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · 

Proof state:
case empty
α : Type u
β : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
⊢ ∏ a in ∅, ∑ b in t a, f a b = ∑ p in pi ∅ t, ∏ x in attach ∅, f (↑x) (p ↑x (_ : ↑x ∈ ∅))

Next tactic:
rw [pi_empty, sum_singleton]
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    

Proof state:
case empty
α : Type u
β : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
⊢ ∏ a in ∅, ∑ b in t a, f a b = ∏ x in attach ∅, f (↑x) (Pi.empty (fun a => δ a) ↑x (_ : ↑x ∈ ∅))

Next tactic:
rfl
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · 

Proof state:
case insert
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
⊢ ∏ a in insert a s, ∑ b in t a, f a b =
    ∑ p in pi (insert a s) t, ∏ x in attach (insert a s), f (↑x) (p ↑x (_ : ↑x ∈ insert a s))

Next tactic:
have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      simp only [disjoint_iff_ne, mem_image]
      rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq
      have : Pi.cons s a x p₂ a (mem_insert_self _ _)
              = Pi.cons s a y p₃ a (mem_insert_self _ _) := by rw [eq₂, eq₃, eq]
      rw [Pi.cons_same, Pi.cons_same] at this
      exact h this
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      

Proof state:
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
⊢ ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y → Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t))

Next tactic:
intro x _ y _ h
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      

Proof state:
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝² : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
x : δ a
a✝¹ : x ∈ t a
y : δ a
a✝ : y ∈ t a
h : x ≠ y
⊢ Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t))

Next tactic:
simp only [disjoint_iff_ne, mem_image]
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      simp only [disjoint_iff_ne, mem_image]
      

Proof state:
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝² : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
x : δ a
a✝¹ : x ∈ t a
y : δ a
a✝ : y ∈ t a
h : x ≠ y
⊢ ∀ (a_1 : (a' : α) → a' ∈ insert a s → δ a'),
    (∃ a_2 ∈ pi s t, Pi.cons s a x a_2 = a_1) →
      ∀ (b : (a' : α) → a' ∈ insert a s → δ a'), (∃ a_3 ∈ pi s t, Pi.cons s a y a_3 = b) → a_1 ≠ b

Next tactic:
rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      simp only [disjoint_iff_ne, mem_image]
      rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq
      

Proof state:
case intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝³ : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
x : δ a
a✝² : x ∈ t a
y : δ a
a✝¹ : y ∈ t a
h : x ≠ y
a✝ : (a' : α) → a' ∈ insert a s → δ a'
p₂ : (a : α) → a ∈ s → δ a
left✝¹ : p₂ ∈ pi s t
eq₂ : Pi.cons s a x p₂ = a✝
b✝ : (a' : α) → a' ∈ insert a s → δ a'
p₃ : (a : α) → a ∈ s → δ a
left✝ : p₃ ∈ pi s t
eq₃ : Pi.cons s a y p₃ = b✝
eq : a✝ = b✝
⊢ False

Next tactic:
have : Pi.cons s a x p₂ a (mem_insert_self _ _)
              = Pi.cons s a y p₃ a (mem_insert_self _ _) := by rw [eq₂, eq₃, eq]
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      simp only [disjoint_iff_ne, mem_image]
      rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq
      have : Pi.cons s a x p₂ a (mem_insert_self _ _)
              = Pi.cons s a y p₃ a (mem_insert_self _ _) := by 

Proof state:
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝³ : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
x : δ a
a✝² : x ∈ t a
y : δ a
a✝¹ : y ∈ t a
h : x ≠ y
a✝ : (a' : α) → a' ∈ insert a s → δ a'
p₂ : (a : α) → a ∈ s → δ a
left✝¹ : p₂ ∈ pi s t
eq₂ : Pi.cons s a x p₂ = a✝
b✝ : (a' : α) → a' ∈ insert a s → δ a'
p₃ : (a : α) → a ∈ s → δ a
left✝ : p₃ ∈ pi s t
eq₃ : Pi.cons s a y p₃ = b✝
eq : a✝ = b✝
⊢ Pi.cons s a x p₂ a (_ : a ∈ insert a s) = Pi.cons s a y p₃ a (_ : a ∈ insert a s)

Next tactic:
rw [eq₂, eq₃, eq]
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      simp only [disjoint_iff_ne, mem_image]
      rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq
      have : Pi.cons s a x p₂ a (mem_insert_self _ _)
              = Pi.cons s a y p₃ a (mem_insert_self _ _) := by rw [eq₂, eq₃, eq]
      

Proof state:
case intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝³ : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
x : δ a
a✝² : x ∈ t a
y : δ a
a✝¹ : y ∈ t a
h : x ≠ y
a✝ : (a' : α) → a' ∈ insert a s → δ a'
p₂ : (a : α) → a ∈ s → δ a
left✝¹ : p₂ ∈ pi s t
eq₂ : Pi.cons s a x p₂ = a✝
b✝ : (a' : α) → a' ∈ insert a s → δ a'
p₃ : (a : α) → a ∈ s → δ a
left✝ : p₃ ∈ pi s t
eq₃ : Pi.cons s a y p₃ = b✝
eq : a✝ = b✝
this : Pi.cons s a x p₂ a (_ : a ∈ insert a s) = Pi.cons s a y p₃ a (_ : a ∈ insert a s)
⊢ False

Next tactic:
rw [Pi.cons_same, Pi.cons_same] at this
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      simp only [disjoint_iff_ne, mem_image]
      rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq
      have : Pi.cons s a x p₂ a (mem_insert_self _ _)
              = Pi.cons s a y p₃ a (mem_insert_self _ _) := by rw [eq₂, eq₃, eq]
      rw [Pi.cons_same, Pi.cons_same] at this
      

Proof state:
case intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝³ : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
x : δ a
a✝² : x ∈ t a
y : δ a
a✝¹ : y ∈ t a
h : x ≠ y
a✝ : (a' : α) → a' ∈ insert a s → δ a'
p₂ : (a : α) → a ∈ s → δ a
left✝¹ : p₂ ∈ pi s t
eq₂ : Pi.cons s a x p₂ = a✝
b✝ : (a' : α) → a' ∈ insert a s → δ a'
p₃ : (a : α) → a ∈ s → δ a
left✝ : p₃ ∈ pi s t
eq₃ : Pi.cons s a y p₃ = b✝
eq : a✝ = b✝
this : x = y
⊢ False

Next tactic:
exact h this
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      simp only [disjoint_iff_ne, mem_image]
      rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq
      have : Pi.cons s a x p₂ a (mem_insert_self _ _)
              = Pi.cons s a y p₃ a (mem_insert_self _ _) := by rw [eq₂, eq₃, eq]
      rw [Pi.cons_same, Pi.cons_same] at this
      exact h this
    

Proof state:
case insert
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y → Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t))
⊢ ∏ a in insert a s, ∑ b in t a, f a b =
    ∑ p in pi (insert a s) t, ∏ x in attach (insert a s), f (↑x) (p ↑x (_ : ↑x ∈ insert a s))

Next tactic:
rw [prod_insert ha, pi_insert ha, ih, sum_mul, sum_biUnion h₁]
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      simp only [disjoint_iff_ne, mem_image]
      rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq
      have : Pi.cons s a x p₂ a (mem_insert_self _ _)
              = Pi.cons s a y p₃ a (mem_insert_self _ _) := by rw [eq₂, eq₃, eq]
      rw [Pi.cons_same, Pi.cons_same] at this
      exact h this
    rw [prod_insert ha, pi_insert ha, ih, sum_mul, sum_biUnion h₁]
    

Proof state:
case insert
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
b : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y → Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t))
⊢ ∑ x in t a, f a x * ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s)) =
    ∑ x in t a, ∑ i in image (Pi.cons s a x) (pi s t), ∏ x in attach (insert a s), f (↑x) (i ↑x (_ : ↑x ∈ insert a s))

Next tactic:
refine' sum_congr rfl fun b _ => _
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      simp only [disjoint_iff_ne, mem_image]
      rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq
      have : Pi.cons s a x p₂ a (mem_insert_self _ _)
              = Pi.cons s a y p₃ a (mem_insert_self _ _) := by rw [eq₂, eq₃, eq]
      rw [Pi.cons_same, Pi.cons_same] at this
      exact h this
    rw [prod_insert ha, pi_insert ha, ih, sum_mul, sum_biUnion h₁]
    refine' sum_congr rfl fun b _ => _
    

Proof state:
case insert
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
b✝ : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y → Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t))
b : δ a
x✝ : b ∈ t a
⊢ f a b * ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s)) =
    ∑ i in image (Pi.cons s a b) (pi s t), ∏ x in attach (insert a s), f (↑x) (i ↑x (_ : ↑x ∈ insert a s))

Next tactic:
have h₂ : ∀ p₁ ∈ pi s t, ∀ p₂ ∈ pi s t, Pi.cons s a b p₁ = Pi.cons s a b p₂ → p₁ = p₂ :=
      fun p₁ _ p₂ _ eq => Pi.cons_injective ha eq
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      simp only [disjoint_iff_ne, mem_image]
      rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq
      have : Pi.cons s a x p₂ a (mem_insert_self _ _)
              = Pi.cons s a y p₃ a (mem_insert_self _ _) := by rw [eq₂, eq₃, eq]
      rw [Pi.cons_same, Pi.cons_same] at this
      exact h this
    rw [prod_insert ha, pi_insert ha, ih, sum_mul, sum_biUnion h₁]
    refine' sum_congr rfl fun b _ => _
    have h₂ : ∀ p₁ ∈ pi s t, ∀ p₂ ∈ pi s t, Pi.cons s a b p₁ = Pi.cons s a b p₂ → p₁ = p₂ :=
      fun p₁ _ p₂ _ eq => Pi.cons_injective ha eq
    

Proof state:
case insert
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
b✝ : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y → Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t))
b : δ a
x✝ : b ∈ t a
h₂ : ∀ p₁ ∈ pi s t, ∀ p₂ ∈ pi s t, Pi.cons s a b p₁ = Pi.cons s a b p₂ → p₁ = p₂
⊢ f a b * ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s)) =
    ∑ i in image (Pi.cons s a b) (pi s t), ∏ x in attach (insert a s), f (↑x) (i ↑x (_ : ↑x ∈ insert a s))

Next tactic:
rw [sum_image h₂, mul_sum]
/-- The product over a sum can be written as a sum over the product of sets, `Finset.Pi`.
  `Finset.prod_univ_sum` is an alternative statement when the product is over `univ`. -/
theorem prod_sum {δ : α → Type*} [DecidableEq α] [∀ a, DecidableEq (δ a)] {s : Finset α}
    {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a → β} :
    (∏ a in s, ∑ b in t a, f a b) = ∑ p in s.pi t, ∏ x in s.attach, f x.1 (p x.1 x.2) := by
  induction' s using Finset.induction with a s ha ih
  · rw [pi_empty, sum_singleton]
    rfl
  · have h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y →
      Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t)) := by
      intro x _ y _ h
      simp only [disjoint_iff_ne, mem_image]
      rintro _ ⟨p₂, _, eq₂⟩ _ ⟨p₃, _, eq₃⟩ eq
      have : Pi.cons s a x p₂ a (mem_insert_self _ _)
              = Pi.cons s a y p₃ a (mem_insert_self _ _) := by rw [eq₂, eq₃, eq]
      rw [Pi.cons_same, Pi.cons_same] at this
      exact h this
    rw [prod_insert ha, pi_insert ha, ih, sum_mul, sum_biUnion h₁]
    refine' sum_congr rfl fun b _ => _
    have h₂ : ∀ p₁ ∈ pi s t, ∀ p₂ ∈ pi s t, Pi.cons s a b p₁ = Pi.cons s a b p₂ → p₁ = p₂ :=
      fun p₁ _ p₂ _ eq => Pi.cons_injective ha eq
    rw [sum_image h₂, mul_sum]
    

Proof state:
case insert
α : Type u
β : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
b✝ : β
f✝ g : α → β
inst✝² : CommSemiring β
δ : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (δ a)
t : (a : α) → Finset (δ a)
f : (a : α) → δ a → β
a : α
s : Finset α
ha : a ∉ s
ih : ∏ a in s, ∑ b in t a, f a b = ∑ p in pi s t, ∏ x in attach s, f (↑x) (p ↑x (_ : ↑x ∈ s))
h₁ : ∀ x ∈ t a, ∀ y ∈ t a, x ≠ y → Disjoint (image (Pi.cons s a x) (pi s t)) (image (Pi.cons s a y) (pi s t))
b : δ a
x✝ : b ∈ t a
h₂ : ∀ p₁ ∈ pi s t, ∀ p₂ ∈ pi s t, Pi.cons s a b p₁ = Pi.cons s a b p₂ → p₁ = p₂
⊢ ∑ x in pi s t, f a b * ∏ x_1 in attach s, f (↑x_1) (x ↑x_1 (_ : ↑x_1 ∈ s)) =
    ∑ x in pi s t, ∏ x_1 in attach (insert a s), f (↑x_1) (Pi.cons s a b x ↑x_1 (_ : ↑x_1 ∈ insert a s))

Next tactic:
refine' sum_congr rfl fun g _ => _