l3lab/ntp-mathlib huggingface dataset:
theorem mem_support_multiset_sum [AddCommMonoid M] {s : Multiset (α →₀ M)} (a : α) :
    a ∈ s.sum.support → ∃ f ∈ s, a ∈ (f : α →₀ M).support :=
  Multiset.induction_on s (fun h => False.elim (by simp at h))
    (by
      intro f s ih ha
      

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝ : AddCommMonoid M
s✝ : Multiset (α →₀ M)
a : α
f : α →₀ M
s : Multiset (α →₀ M)
ih : a ∈ (Multiset.sum s).support → ∃ f ∈ s, a ∈ f.support
ha : a ∈ (Multiset.sum (f ::ₘ s)).support
⊢ ∃ f_1 ∈ f ::ₘ s, a ∈ f_1.support

Next tactic:
by_cases h : a ∈ f.support
theorem mem_support_multiset_sum [AddCommMonoid M] {s : Multiset (α →₀ M)} (a : α) :
    a ∈ s.sum.support → ∃ f ∈ s, a ∈ (f : α →₀ M).support :=
  Multiset.induction_on s (fun h => False.elim (by simp at h))
    (by
      intro f s ih ha
      by_cases h : a ∈ f.support
      · 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝ : AddCommMonoid M
s✝ : Multiset (α →₀ M)
a : α
f : α →₀ M
s : Multiset (α →₀ M)
ih : a ∈ (Multiset.sum s).support → ∃ f ∈ s, a ∈ f.support
ha : a ∈ (Multiset.sum (f ::ₘ s)).support
h : a ∈ f.support
⊢ ∃ f_1 ∈ f ::ₘ s, a ∈ f_1.support

Next tactic:
exact ⟨f, Multiset.mem_cons_self _ _, h⟩
theorem mem_support_multiset_sum [AddCommMonoid M] {s : Multiset (α →₀ M)} (a : α) :
    a ∈ s.sum.support → ∃ f ∈ s, a ∈ (f : α →₀ M).support :=
  Multiset.induction_on s (fun h => False.elim (by simp at h))
    (by
      intro f s ih ha
      by_cases h : a ∈ f.support
      · exact ⟨f, Multiset.mem_cons_self _ _, h⟩
      · 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝ : AddCommMonoid M
s✝ : Multiset (α →₀ M)
a : α
f : α →₀ M
s : Multiset (α →₀ M)
ih : a ∈ (Multiset.sum s).support → ∃ f ∈ s, a ∈ f.support
ha : a ∈ (Multiset.sum (f ::ₘ s)).support
h : a ∉ f.support
⊢ ∃ f_1 ∈ f ::ₘ s, a ∈ f_1.support

Next tactic:
simp only [Multiset.sum_cons, mem_support_iff, add_apply, not_mem_support_iff.1 h,
          zero_add] at ha
theorem mem_support_multiset_sum [AddCommMonoid M] {s : Multiset (α →₀ M)} (a : α) :
    a ∈ s.sum.support → ∃ f ∈ s, a ∈ (f : α →₀ M).support :=
  Multiset.induction_on s (fun h => False.elim (by simp at h))
    (by
      intro f s ih ha
      by_cases h : a ∈ f.support
      · exact ⟨f, Multiset.mem_cons_self _ _, h⟩
      · simp only [Multiset.sum_cons, mem_support_iff, add_apply, not_mem_support_iff.1 h,
          zero_add] at ha
        

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝ : AddCommMonoid M
s✝ : Multiset (α →₀ M)
a : α
f : α →₀ M
s : Multiset (α →₀ M)
ih : a ∈ (Multiset.sum s).support → ∃ f ∈ s, a ∈ f.support
h : a ∉ f.support
ha : (Multiset.sum s) a ≠ 0
⊢ ∃ f_1 ∈ f ::ₘ s, a ∈ f_1.support

Next tactic:
rcases ih (mem_support_iff.2 ha) with ⟨f', h₀, h₁⟩
theorem mem_support_multiset_sum [AddCommMonoid M] {s : Multiset (α →₀ M)} (a : α) :
    a ∈ s.sum.support → ∃ f ∈ s, a ∈ (f : α →₀ M).support :=
  Multiset.induction_on s (fun h => False.elim (by simp at h))
    (by
      intro f s ih ha
      by_cases h : a ∈ f.support
      · exact ⟨f, Multiset.mem_cons_self _ _, h⟩
      · simp only [Multiset.sum_cons, mem_support_iff, add_apply, not_mem_support_iff.1 h,
          zero_add] at ha
        rcases ih (mem_support_iff.2 ha) with ⟨f', h₀, h₁⟩
        

Proof state:
case neg.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝ : AddCommMonoid M
s✝ : Multiset (α →₀ M)
a : α
f : α →₀ M
s : Multiset (α →₀ M)
ih : a ∈ (Multiset.sum s).support → ∃ f ∈ s, a ∈ f.support
h : a ∉ f.support
ha : (Multiset.sum s) a ≠ 0
f' : α →₀ M
h₀ : f' ∈ s
h₁ : a ∈ f'.support
⊢ ∃ f_1 ∈ f ::ₘ s, a ∈ f_1.support

Next tactic:
exact ⟨f', Multiset.mem_cons_of_mem h₀, h₁⟩
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
⊢ ((Finsupp.curry f) x) y = f (x, y)

Next tactic:
classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
      split_ifs <;> simp [single_apply, *]
    rw [Finsupp.curry, sum_apply, sum_apply, sum_eq_single, this, if_pos rfl]
    · intro b _ b_ne
      rw [this b, if_neg b_ne]
    · intro _
      rw [single_zero, single_zero, coe_zero, Pi.zero_apply, coe_zero, Pi.zero_apply]
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
⊢ ((Finsupp.curry f) x) y = f (x, y)

Next tactic:
have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
      split_ifs <;> simp [single_apply, *]
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
⊢ ∀ (b : α × β), ((fun₀ | b.1 => fun₀ | b.2 => f b) x) y = if b = (x, y) then f b else 0

Next tactic:
rintro ⟨b₁, b₂⟩
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      

Proof state:
case mk
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
b₁ : α
b₂ : β
⊢ ((fun₀ | (b₁, b₂).1 => fun₀ | (b₁, b₂).2 => f (b₁, b₂)) x) y = if (b₁, b₂) = (x, y) then f (b₁, b₂) else 0

Next tactic:
simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
      

Proof state:
case mk
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
b₁ : α
b₂ : β
⊢ (if b₁ = x then fun₀ | b₂ => f (b₁, b₂) else 0) y = if b₁ = x then if b₂ = y then f (b₁, b₂) else 0 else 0

Next tactic:
split_ifs
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
      split_ifs <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
b₁ : α
b₂ : β
h✝¹ : b₁ = x
h✝ : b₂ = y
⊢ (fun₀ | b₂ => f (b₁, b₂)) y = f (b₁, b₂)

Next tactic:
simp [single_apply, *]
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
      split_ifs <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
b₁ : α
b₂ : β
h✝¹ : b₁ = x
h✝ : ¬b₂ = y
⊢ (fun₀ | b₂ => f (b₁, b₂)) y = 0

Next tactic:
simp [single_apply, *]
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
      split_ifs <;> 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
b₁ : α
b₂ : β
h✝ : ¬b₁ = x
⊢ 0 y = 0

Next tactic:
simp [single_apply, *]
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
      split_ifs <;> simp [single_apply, *]
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
this : ∀ (b : α × β), ((fun₀ | b.1 => fun₀ | b.2 => f b) x) y = if b = (x, y) then f b else 0
⊢ ((Finsupp.curry f) x) y = f (x, y)

Next tactic:
rw [Finsupp.curry, sum_apply, sum_apply, sum_eq_single, this, if_pos rfl]
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
      split_ifs <;> simp [single_apply, *]
    rw [Finsupp.curry, sum_apply, sum_apply, sum_eq_single, this, if_pos rfl]
    · 

Proof state:
case h₀
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
this : ∀ (b : α × β), ((fun₀ | b.1 => fun₀ | b.2 => f b) x) y = if b = (x, y) then f b else 0
⊢ ∀ (b : α × β), f b ≠ 0 → b ≠ (x, y) → ((fun₀ | b.1 => fun₀ | b.2 => f b) x) y = 0

Next tactic:
intro b _ b_ne
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
      split_ifs <;> simp [single_apply, *]
    rw [Finsupp.curry, sum_apply, sum_apply, sum_eq_single, this, if_pos rfl]
    · intro b _ b_ne
      

Proof state:
case h₀
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
this : ∀ (b : α × β), ((fun₀ | b.1 => fun₀ | b.2 => f b) x) y = if b = (x, y) then f b else 0
b : α × β
a✝ : f b ≠ 0
b_ne : b ≠ (x, y)
⊢ ((fun₀ | b.1 => fun₀ | b.2 => f b) x) y = 0

Next tactic:
rw [this b, if_neg b_ne]
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
      split_ifs <;> simp [single_apply, *]
    rw [Finsupp.curry, sum_apply, sum_apply, sum_eq_single, this, if_pos rfl]
    · intro b _ b_ne
      rw [this b, if_neg b_ne]
    · 

Proof state:
case h₁
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
this : ∀ (b : α × β), ((fun₀ | b.1 => fun₀ | b.2 => f b) x) y = if b = (x, y) then f b else 0
⊢ f (x, y) = 0 → ((fun₀ | (x, y).1 => fun₀ | (x, y).2 => 0) x) y = 0

Next tactic:
intro _
@[simp]
theorem curry_apply (f : α × β →₀ M) (x : α) (y : β) : f.curry x y = f (x, y) := by
  classical
    have : ∀ b : α × β, single b.fst (single b.snd (f b)) x y = if b = (x, y) then f b else 0 := by
      rintro ⟨b₁, b₂⟩
      simp only [ne_eq, single_apply, Prod.ext_iff, ite_and]
      split_ifs <;> simp [single_apply, *]
    rw [Finsupp.curry, sum_apply, sum_apply, sum_eq_single, this, if_pos rfl]
    · intro b _ b_ne
      rw [this b, if_neg b_ne]
    · intro _
      

Proof state:
case h₁
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
x : α
y : β
this : ∀ (b : α × β), ((fun₀ | b.1 => fun₀ | b.2 => f b) x) y = if b = (x, y) then f b else 0
a✝ : f (x, y) = 0
⊢ ((fun₀ | (x, y).1 => fun₀ | (x, y).2 => 0) x) y = 0

Next tactic:
rw [single_zero, single_zero, coe_zero, Pi.zero_apply, coe_zero, Pi.zero_apply]
theorem sum_curry_index (f : α × β →₀ M) (g : α → β → M → N) (hg₀ : ∀ a b, g a b 0 = 0)
    (hg₁ : ∀ a b c₀ c₁, g a b (c₀ + c₁) = g a b c₀ + g a b c₁) :
    (f.curry.sum fun a f => f.sum (g a)) = f.sum fun p c => g p.1 p.2 c := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
g : α → β → M → N
hg₀ : ∀ (a : α) (b : β), g a b 0 = 0
hg₁ : ∀ (a : α) (b : β) (c₀ c₁ : M), g a b (c₀ + c₁) = g a b c₀ + g a b c₁
⊢ (sum (Finsupp.curry f) fun a f => sum f (g a)) = sum f fun p c => g p.1 p.2 c

Next tactic:
rw [Finsupp.curry]
theorem sum_curry_index (f : α × β →₀ M) (g : α → β → M → N) (hg₀ : ∀ a b, g a b 0 = 0)
    (hg₁ : ∀ a b c₀ c₁, g a b (c₀ + c₁) = g a b c₀ + g a b c₁) :
    (f.curry.sum fun a f => f.sum (g a)) = f.sum fun p c => g p.1 p.2 c := by
  rw [Finsupp.curry]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
g : α → β → M → N
hg₀ : ∀ (a : α) (b : β), g a b 0 = 0
hg₁ : ∀ (a : α) (b : β) (c₀ c₁ : M), g a b (c₀ + c₁) = g a b c₀ + g a b c₁
⊢ (sum (sum f fun p c => fun₀ | p.1 => fun₀ | p.2 => c) fun a f => sum f (g a)) = sum f fun p c => g p.1 p.2 c

Next tactic:
trans
theorem sum_curry_index (f : α × β →₀ M) (g : α → β → M → N) (hg₀ : ∀ a b, g a b 0 = 0)
    (hg₁ : ∀ a b c₀ c₁, g a b (c₀ + c₁) = g a b c₀ + g a b c₁) :
    (f.curry.sum fun a f => f.sum (g a)) = f.sum fun p c => g p.1 p.2 c := by
  rw [Finsupp.curry]
  trans
  · 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
g : α → β → M → N
hg₀ : ∀ (a : α) (b : β), g a b 0 = 0
hg₁ : ∀ (a : α) (b : β) (c₀ c₁ : M), g a b (c₀ + c₁) = g a b c₀ + g a b c₁
⊢ (sum (sum f fun p c => fun₀ | p.1 => fun₀ | p.2 => c) fun a f => sum f (g a)) = ?m.534946

Next tactic:
exact
      sum_sum_index (fun a => sum_zero_index) fun a b₀ b₁ =>
        sum_add_index' (fun a => hg₀ _ _) fun c d₀ d₁ => hg₁ _ _ _ _
theorem sum_curry_index (f : α × β →₀ M) (g : α → β → M → N) (hg₀ : ∀ a b, g a b 0 = 0)
    (hg₁ : ∀ a b c₀ c₁, g a b (c₀ + c₁) = g a b c₀ + g a b c₁) :
    (f.curry.sum fun a f => f.sum (g a)) = f.sum fun p c => g p.1 p.2 c := by
  rw [Finsupp.curry]
  trans
  · exact
      sum_sum_index (fun a => sum_zero_index) fun a b₀ b₁ =>
        sum_add_index' (fun a => hg₀ _ _) fun c d₀ d₁ => hg₁ _ _ _ _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
g : α → β → M → N
hg₀ : ∀ (a : α) (b : β), g a b 0 = 0
hg₁ : ∀ (a : α) (b : β) (c₀ c₁ : M), g a b (c₀ + c₁) = g a b c₀ + g a b c₁
⊢ (sum f fun a b => sum (fun₀ | a.1 => fun₀ | a.2 => b) fun a f => sum f (g a)) = sum f fun p c => g p.1 p.2 c

Next tactic:
congr
theorem sum_curry_index (f : α × β →₀ M) (g : α → β → M → N) (hg₀ : ∀ a b, g a b 0 = 0)
    (hg₁ : ∀ a b c₀ c₁, g a b (c₀ + c₁) = g a b c₀ + g a b c₁) :
    (f.curry.sum fun a f => f.sum (g a)) = f.sum fun p c => g p.1 p.2 c := by
  rw [Finsupp.curry]
  trans
  · exact
      sum_sum_index (fun a => sum_zero_index) fun a b₀ b₁ =>
        sum_add_index' (fun a => hg₀ _ _) fun c d₀ d₁ => hg₁ _ _ _ _
  congr; 

Proof state:
case e_g
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
g : α → β → M → N
hg₀ : ∀ (a : α) (b : β), g a b 0 = 0
hg₁ : ∀ (a : α) (b : β) (c₀ c₁ : M), g a b (c₀ + c₁) = g a b c₀ + g a b c₁
⊢ (fun a b => sum (fun₀ | a.1 => fun₀ | a.2 => b) fun a f => sum f (g a)) = fun p c => g p.1 p.2 c

Next tactic:
funext p c
theorem sum_curry_index (f : α × β →₀ M) (g : α → β → M → N) (hg₀ : ∀ a b, g a b 0 = 0)
    (hg₁ : ∀ a b c₀ c₁, g a b (c₀ + c₁) = g a b c₀ + g a b c₁) :
    (f.curry.sum fun a f => f.sum (g a)) = f.sum fun p c => g p.1 p.2 c := by
  rw [Finsupp.curry]
  trans
  · exact
      sum_sum_index (fun a => sum_zero_index) fun a b₀ b₁ =>
        sum_add_index' (fun a => hg₀ _ _) fun c d₀ d₁ => hg₁ _ _ _ _
  congr; funext p c
  

Proof state:
case e_g.h.h
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
g : α → β → M → N
hg₀ : ∀ (a : α) (b : β), g a b 0 = 0
hg₁ : ∀ (a : α) (b : β) (c₀ c₁ : M), g a b (c₀ + c₁) = g a b c₀ + g a b c₁
p : α × β
c : M
⊢ (sum (fun₀ | p.1 => fun₀ | p.2 => c) fun a f => sum f (g a)) = g p.1 p.2 c

Next tactic:
trans
theorem sum_curry_index (f : α × β →₀ M) (g : α → β → M → N) (hg₀ : ∀ a b, g a b 0 = 0)
    (hg₁ : ∀ a b c₀ c₁, g a b (c₀ + c₁) = g a b c₀ + g a b c₁) :
    (f.curry.sum fun a f => f.sum (g a)) = f.sum fun p c => g p.1 p.2 c := by
  rw [Finsupp.curry]
  trans
  · exact
      sum_sum_index (fun a => sum_zero_index) fun a b₀ b₁ =>
        sum_add_index' (fun a => hg₀ _ _) fun c d₀ d₁ => hg₁ _ _ _ _
  congr; funext p c
  trans
  · 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
g : α → β → M → N
hg₀ : ∀ (a : α) (b : β), g a b 0 = 0
hg₁ : ∀ (a : α) (b : β) (c₀ c₁ : M), g a b (c₀ + c₁) = g a b c₀ + g a b c₁
p : α × β
c : M
⊢ (sum (fun₀ | p.1 => fun₀ | p.2 => c) fun a f => sum f (g a)) = ?m.535969

Next tactic:
exact sum_single_index sum_zero_index
theorem sum_curry_index (f : α × β →₀ M) (g : α → β → M → N) (hg₀ : ∀ a b, g a b 0 = 0)
    (hg₁ : ∀ a b c₀ c₁, g a b (c₀ + c₁) = g a b c₀ + g a b c₁) :
    (f.curry.sum fun a f => f.sum (g a)) = f.sum fun p c => g p.1 p.2 c := by
  rw [Finsupp.curry]
  trans
  · exact
      sum_sum_index (fun a => sum_zero_index) fun a b₀ b₁ =>
        sum_add_index' (fun a => hg₀ _ _) fun c d₀ d₁ => hg₁ _ _ _ _
  congr; funext p c
  trans
  · exact sum_single_index sum_zero_index
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
g : α → β → M → N
hg₀ : ∀ (a : α) (b : β), g a b 0 = 0
hg₁ : ∀ (a : α) (b : β) (c₀ c₁ : M), g a b (c₀ + c₁) = g a b c₀ + g a b c₁
p : α × β
c : M
⊢ sum (fun₀ | p.2 => c) (g p.1) = g p.1 p.2 c

Next tactic:
exact sum_single_index (hg₀ _ _)
/-- `finsuppProdEquiv` defines the `Equiv` between `((α × β) →₀ M)` and `(α →₀ (β →₀ M))` given by
currying and uncurrying. -/
def finsuppProdEquiv : (α × β →₀ M) ≃ (α →₀ β →₀ M)
    where
  toFun := Finsupp.curry
  invFun := Finsupp.uncurry
  left_inv f := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
⊢ Finsupp.uncurry (Finsupp.curry f) = f

Next tactic:
rw [Finsupp.uncurry, sum_curry_index]
/-- `finsuppProdEquiv` defines the `Equiv` between `((α × β) →₀ M)` and `(α →₀ (β →₀ M))` given by
currying and uncurrying. -/
def finsuppProdEquiv : (α × β →₀ M) ≃ (α →₀ β →₀ M)
    where
  toFun := Finsupp.curry
  invFun := Finsupp.uncurry
  left_inv f := by
    rw [Finsupp.uncurry, sum_curry_index]
    · 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
⊢ (sum f fun p c => fun₀ | (p.1, p.2) => c) = f

Next tactic:
simp_rw [Prod.mk.eta, sum_single]
/-- `finsuppProdEquiv` defines the `Equiv` between `((α × β) →₀ M)` and `(α →₀ (β →₀ M))` given by
currying and uncurrying. -/
def finsuppProdEquiv : (α × β →₀ M) ≃ (α →₀ β →₀ M)
    where
  toFun := Finsupp.curry
  invFun := Finsupp.uncurry
  left_inv f := by
    rw [Finsupp.uncurry, sum_curry_index]
    · simp_rw [Prod.mk.eta, sum_single]
    · 

Proof state:
case hg₀
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
⊢ ∀ (a : α) (b : β), (fun₀ | (a, b) => 0) = 0

Next tactic:
intros
/-- `finsuppProdEquiv` defines the `Equiv` between `((α × β) →₀ M)` and `(α →₀ (β →₀ M))` given by
currying and uncurrying. -/
def finsuppProdEquiv : (α × β →₀ M) ≃ (α →₀ β →₀ M)
    where
  toFun := Finsupp.curry
  invFun := Finsupp.uncurry
  left_inv f := by
    rw [Finsupp.uncurry, sum_curry_index]
    · simp_rw [Prod.mk.eta, sum_single]
    · intros
      

Proof state:
case hg₀
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : AddCommMonoid N
f : α × β →₀ M
a✝ : α
b✝ : β
⊢ (fun₀ | (a✝, b✝) => 0) = 0

Next tactic:
apply single_zero