l3lab/ntp-mathlib huggingface dataset:
/-- `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
      apply single_zero
    · 

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 : β) (c₀ c₁ : M), (fun₀ | (a, b) => c₀ + c₁) = (fun₀ | (a, b) => c₀) + fun₀ | (a, b) => c₁

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
      apply single_zero
    · 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✝ : β
c₀✝ c₁✝ : M
⊢ (fun₀ | (a✝, b✝) => c₀✝ + c₁✝) = (fun₀ | (a✝, b✝) => c₀✝) + fun₀ | (a✝, b✝) => c₁✝

Next tactic:
apply single_add
/-- `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
      apply single_zero
    · intros
      apply single_add
  right_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.curry (Finsupp.uncurry f) = f

Next tactic:
simp only [Finsupp.curry, Finsupp.uncurry, sum_sum_index, sum_zero_index, sum_add_index,
      sum_single_index, single_zero, single_add, eq_self_iff_true, forall_true_iff,
      forall₃_true_iff, (single_sum _ _ _).symm, sum_single]
theorem filter_curry (f : α × β →₀ M) (p : α → Prop) :
    (f.filter fun a : α × β => p a.1).curry = f.curry.filter p := 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
p : α → Prop
⊢ Finsupp.curry (filter (fun a => p a.1) f) = filter p (Finsupp.curry f)

Next tactic:
classical
    rw [Finsupp.curry, Finsupp.curry, Finsupp.sum, Finsupp.sum, filter_sum, support_filter,
      sum_filter]
    refine' Finset.sum_congr rfl _
    rintro ⟨a₁, a₂⟩ _
    split_ifs with h
    · rw [filter_apply_pos, filter_single_of_pos] <;> exact h
    · rwa [filter_single_of_neg]
theorem filter_curry (f : α × β →₀ M) (p : α → Prop) :
    (f.filter fun a : α × β => p a.1).curry = f.curry.filter p := 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
p : α → Prop
⊢ Finsupp.curry (filter (fun a => p a.1) f) = filter p (Finsupp.curry f)

Next tactic:
rw [Finsupp.curry, Finsupp.curry, Finsupp.sum, Finsupp.sum, filter_sum, support_filter,
      sum_filter]
theorem filter_curry (f : α × β →₀ M) (p : α → Prop) :
    (f.filter fun a : α × β => p a.1).curry = f.curry.filter p := by
  classical
    rw [Finsupp.curry, Finsupp.curry, Finsupp.sum, Finsupp.sum, filter_sum, support_filter,
      sum_filter]
    

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
p : α → Prop
⊢ (∑ a in f.support, if p a.1 then fun₀ | a.1 => fun₀ | a.2 => (filter (fun a => p a.1) f) a else 0) =
    ∑ a in f.support, filter p fun₀ | a.1 => fun₀ | a.2 => f a

Next tactic:
refine' Finset.sum_congr rfl _
theorem filter_curry (f : α × β →₀ M) (p : α → Prop) :
    (f.filter fun a : α × β => p a.1).curry = f.curry.filter p := by
  classical
    rw [Finsupp.curry, Finsupp.curry, Finsupp.sum, Finsupp.sum, filter_sum, support_filter,
      sum_filter]
    refine' Finset.sum_congr rfl _
    

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
p : α → Prop
⊢ ∀ x ∈ f.support,
    (if p x.1 then fun₀ | x.1 => fun₀ | x.2 => (filter (fun a => p a.1) f) x else 0) =
      filter p fun₀ | x.1 => fun₀ | x.2 => f x

Next tactic:
rintro ⟨a₁, a₂⟩ _
theorem filter_curry (f : α × β →₀ M) (p : α → Prop) :
    (f.filter fun a : α × β => p a.1).curry = f.curry.filter p := by
  classical
    rw [Finsupp.curry, Finsupp.curry, Finsupp.sum, Finsupp.sum, filter_sum, support_filter,
      sum_filter]
    refine' Finset.sum_congr rfl _
    rintro ⟨a₁, a₂⟩ _
    

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
p : α → Prop
a₁ : α
a₂ : β
a✝ : (a₁, a₂) ∈ f.support
⊢ (if p (a₁, a₂).1 then fun₀ | (a₁, a₂).1 => fun₀ | (a₁, a₂).2 => (filter (fun a => p a.1) f) (a₁, a₂) else 0) =
    filter p fun₀ | (a₁, a₂).1 => fun₀ | (a₁, a₂).2 => f (a₁, a₂)

Next tactic:
split_ifs with h
theorem filter_curry (f : α × β →₀ M) (p : α → Prop) :
    (f.filter fun a : α × β => p a.1).curry = f.curry.filter p := by
  classical
    rw [Finsupp.curry, Finsupp.curry, Finsupp.sum, Finsupp.sum, filter_sum, support_filter,
      sum_filter]
    refine' Finset.sum_congr rfl _
    rintro ⟨a₁, a₂⟩ _
    split_ifs with h
    · 

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
p : α → Prop
a₁ : α
a₂ : β
a✝ : (a₁, a₂) ∈ f.support
h : p (a₁, a₂).1
⊢ (fun₀ | (a₁, a₂).1 => fun₀ | (a₁, a₂).2 => (filter (fun a => p a.1) f) (a₁, a₂)) =
    filter p fun₀ | (a₁, a₂).1 => fun₀ | (a₁, a₂).2 => f (a₁, a₂)

Next tactic:
rw [filter_apply_pos, filter_single_of_pos]
theorem filter_curry (f : α × β →₀ M) (p : α → Prop) :
    (f.filter fun a : α × β => p a.1).curry = f.curry.filter p := by
  classical
    rw [Finsupp.curry, Finsupp.curry, Finsupp.sum, Finsupp.sum, filter_sum, support_filter,
      sum_filter]
    refine' Finset.sum_congr rfl _
    rintro ⟨a₁, a₂⟩ _
    split_ifs with h
    · rw [filter_apply_pos, filter_single_of_pos] <;> 

Proof state:
case pos.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
p : α → Prop
a₁ : α
a₂ : β
a✝ : (a₁, a₂) ∈ f.support
h : p (a₁, a₂).1
⊢ p (a₁, a₂).1

Next tactic:
exact h
theorem filter_curry (f : α × β →₀ M) (p : α → Prop) :
    (f.filter fun a : α × β => p a.1).curry = f.curry.filter p := by
  classical
    rw [Finsupp.curry, Finsupp.curry, Finsupp.sum, Finsupp.sum, filter_sum, support_filter,
      sum_filter]
    refine' Finset.sum_congr rfl _
    rintro ⟨a₁, a₂⟩ _
    split_ifs with h
    · rw [filter_apply_pos, filter_single_of_pos] <;> exact 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
inst✝ : AddCommMonoid N
f : α × β →₀ M
p : α → Prop
a₁ : α
a₂ : β
a✝ : (a₁, a₂) ∈ f.support
h : ¬p (a₁, a₂).1
⊢ 0 = filter p fun₀ | (a₁, a₂).1 => fun₀ | (a₁, a₂).2 => f (a₁, a₂)

Next tactic:
rwa [filter_single_of_neg]
theorem support_curry [DecidableEq α] (f : α × β →₀ M) :
    f.curry.support ⊆ f.support.image Prod.fst := 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
inst✝ : DecidableEq α
f : α × β →₀ M
⊢ (Finsupp.curry f).support ⊆ image Prod.fst f.support

Next tactic:
rw [← Finset.biUnion_singleton]
theorem support_curry [DecidableEq α] (f : α × β →₀ M) :
    f.curry.support ⊆ f.support.image Prod.fst := by
  rw [← Finset.biUnion_singleton]
  

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
inst✝ : DecidableEq α
f : α × β →₀ M
⊢ (Finsupp.curry f).support ⊆ Finset.biUnion f.support fun a => {a.1}

Next tactic:
refine' Finset.Subset.trans support_sum _
theorem support_curry [DecidableEq α] (f : α × β →₀ M) :
    f.curry.support ⊆ f.support.image Prod.fst := by
  rw [← Finset.biUnion_singleton]
  refine' Finset.Subset.trans support_sum _
  

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
inst✝ : DecidableEq α
f : α × β →₀ M
⊢ (Finset.biUnion f.support fun a => (fun₀ | a.1 => fun₀ | a.2 => f a).support) ⊆
    Finset.biUnion f.support fun a => {a.1}

Next tactic:
refine' Finset.biUnion_mono fun a _ => support_single_subset
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
⊢ Finset (α ⊕ β)

Next tactic:
haveI := Classical.decEq α
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (by
      haveI := Classical.decEq α
      

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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
this : DecidableEq α
⊢ Finset (α ⊕ β)

Next tactic:
haveI := Classical.decEq β
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (by
      haveI := Classical.decEq α
      haveI := Classical.decEq β
      

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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
this✝ : DecidableEq α
this : DecidableEq β
⊢ Finset (α ⊕ β)

Next tactic:
exact f.support.map ⟨_, Sum.inl_injective⟩ ∪ g.support.map ⟨_, Sum.inr_injective⟩
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (by
      haveI := Classical.decEq α
      haveI := Classical.decEq β
      exact f.support.map ⟨_, Sum.inl_injective⟩ ∪ g.support.map ⟨_, Sum.inr_injective⟩)
    (Sum.elim f g) fun ab h => 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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
ab : α ⊕ β
h : Sum.elim (⇑f) (⇑g) ab ≠ 0
⊢ ab ∈
    map { toFun := Sum.inl, inj' := (_ : Injective Sum.inl) } f.support ∪
      map { toFun := Sum.inr, inj' := (_ : Injective Sum.inr) } g.support

Next tactic:
cases' ab with a b
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (by
      haveI := Classical.decEq α
      haveI := Classical.decEq β
      exact f.support.map ⟨_, Sum.inl_injective⟩ ∪ g.support.map ⟨_, Sum.inr_injective⟩)
    (Sum.elim f g) fun ab h => by
    cases' ab with a b <;>
    

Proof state:
case inl
α✝ : 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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
a : α
h : Sum.elim (⇑f) (⇑g) (Sum.inl a) ≠ 0
⊢ Sum.inl a ∈
    map { toFun := Sum.inl, inj' := (_ : Injective Sum.inl) } f.support ∪
      map { toFun := Sum.inr, inj' := (_ : Injective Sum.inr) } g.support

Next tactic:
letI := Classical.decEq α
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (by
      haveI := Classical.decEq α
      haveI := Classical.decEq β
      exact f.support.map ⟨_, Sum.inl_injective⟩ ∪ g.support.map ⟨_, Sum.inr_injective⟩)
    (Sum.elim f g) fun ab h => by
    cases' ab with a b <;>
    

Proof state:
case inr
α✝ : 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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
b : β
h : Sum.elim (⇑f) (⇑g) (Sum.inr b) ≠ 0
⊢ Sum.inr b ∈
    map { toFun := Sum.inl, inj' := (_ : Injective Sum.inl) } f.support ∪
      map { toFun := Sum.inr, inj' := (_ : Injective Sum.inr) } g.support

Next tactic:
letI := Classical.decEq α
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (by
      haveI := Classical.decEq α
      haveI := Classical.decEq β
      exact f.support.map ⟨_, Sum.inl_injective⟩ ∪ g.support.map ⟨_, Sum.inr_injective⟩)
    (Sum.elim f g) fun ab h => by
    cases' ab with a b <;>
    letI := Classical.decEq α <;> 

Proof state:
case inl
α✝ : 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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
a : α
h : Sum.elim (⇑f) (⇑g) (Sum.inl a) ≠ 0
this : DecidableEq α := Classical.decEq α
⊢ Sum.inl a ∈
    map { toFun := Sum.inl, inj' := (_ : Injective Sum.inl) } f.support ∪
      map { toFun := Sum.inr, inj' := (_ : Injective Sum.inr) } g.support

Next tactic:
letI := Classical.decEq β
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (by
      haveI := Classical.decEq α
      haveI := Classical.decEq β
      exact f.support.map ⟨_, Sum.inl_injective⟩ ∪ g.support.map ⟨_, Sum.inr_injective⟩)
    (Sum.elim f g) fun ab h => by
    cases' ab with a b <;>
    letI := Classical.decEq α <;> 

Proof state:
case inr
α✝ : 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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
b : β
h : Sum.elim (⇑f) (⇑g) (Sum.inr b) ≠ 0
this : DecidableEq α := Classical.decEq α
⊢ Sum.inr b ∈
    map { toFun := Sum.inl, inj' := (_ : Injective Sum.inl) } f.support ∪
      map { toFun := Sum.inr, inj' := (_ : Injective Sum.inr) } g.support

Next tactic:
letI := Classical.decEq β
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (by
      haveI := Classical.decEq α
      haveI := Classical.decEq β
      exact f.support.map ⟨_, Sum.inl_injective⟩ ∪ g.support.map ⟨_, Sum.inr_injective⟩)
    (Sum.elim f g) fun ab h => by
    cases' ab with a b <;>
    letI := Classical.decEq α <;> letI := Classical.decEq β <;>
    -- porting note: had to add these `DecidableEq` instances
    

Proof state:
case inl
α✝ : 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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
a : α
h : Sum.elim (⇑f) (⇑g) (Sum.inl a) ≠ 0
this✝ : DecidableEq α := Classical.decEq α
this : DecidableEq β := Classical.decEq β
⊢ Sum.inl a ∈
    map { toFun := Sum.inl, inj' := (_ : Injective Sum.inl) } f.support ∪
      map { toFun := Sum.inr, inj' := (_ : Injective Sum.inr) } g.support

Next tactic:
simp only [Sum.elim_inl, Sum.elim_inr] at h
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (by
      haveI := Classical.decEq α
      haveI := Classical.decEq β
      exact f.support.map ⟨_, Sum.inl_injective⟩ ∪ g.support.map ⟨_, Sum.inr_injective⟩)
    (Sum.elim f g) fun ab h => by
    cases' ab with a b <;>
    letI := Classical.decEq α <;> letI := Classical.decEq β <;>
    -- porting note: had to add these `DecidableEq` instances
    

Proof state:
case inr
α✝ : 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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
b : β
h : Sum.elim (⇑f) (⇑g) (Sum.inr b) ≠ 0
this✝ : DecidableEq α := Classical.decEq α
this : DecidableEq β := Classical.decEq β
⊢ Sum.inr b ∈
    map { toFun := Sum.inl, inj' := (_ : Injective Sum.inl) } f.support ∪
      map { toFun := Sum.inr, inj' := (_ : Injective Sum.inr) } g.support

Next tactic:
simp only [Sum.elim_inl, Sum.elim_inr] at h
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (by
      haveI := Classical.decEq α
      haveI := Classical.decEq β
      exact f.support.map ⟨_, Sum.inl_injective⟩ ∪ g.support.map ⟨_, Sum.inr_injective⟩)
    (Sum.elim f g) fun ab h => by
    cases' ab with a b <;>
    letI := Classical.decEq α <;> letI := Classical.decEq β <;>
    -- porting note: had to add these `DecidableEq` instances
    simp only [Sum.elim_inl, Sum.elim_inr] at h <;>
    

Proof state:
case inl
α✝ : 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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
a : α
h : f a ≠ 0
this✝ : DecidableEq α := Classical.decEq α
this : DecidableEq β := Classical.decEq β
⊢ Sum.inl a ∈
    map { toFun := Sum.inl, inj' := (_ : Injective Sum.inl) } f.support ∪
      map { toFun := Sum.inr, inj' := (_ : Injective Sum.inr) } g.support

Next tactic:
simpa
/-- `Finsupp.sumElim f g` maps `inl x` to `f x` and `inr y` to `g y`. -/
def sumElim {α β γ : Type*} [Zero γ] (f : α →₀ γ) (g : β →₀ γ) : Sum α β →₀ γ :=
  onFinset
    (by
      haveI := Classical.decEq α
      haveI := Classical.decEq β
      exact f.support.map ⟨_, Sum.inl_injective⟩ ∪ g.support.map ⟨_, Sum.inr_injective⟩)
    (Sum.elim f g) fun ab h => by
    cases' ab with a b <;>
    letI := Classical.decEq α <;> letI := Classical.decEq β <;>
    -- porting note: had to add these `DecidableEq` instances
    simp only [Sum.elim_inl, Sum.elim_inr] at h <;>
    

Proof state:
case inr
α✝ : 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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α →₀ γ
g : β →₀ γ
b : β
h : g b ≠ 0
this✝ : DecidableEq α := Classical.decEq α
this : DecidableEq β := Classical.decEq β
⊢ Sum.inr b ∈
    map { toFun := Sum.inl, inj' := (_ : Injective Sum.inl) } f.support ∪
      map { toFun := Sum.inr, inj' := (_ : Injective Sum.inr) } g.support

Next tactic:
simpa
/-- The equivalence between `(α ⊕ β) →₀ γ` and `(α →₀ γ) × (β →₀ γ)`.

This is the `Finsupp` version of `Equiv.sum_arrow_equiv_prod_arrow`. -/
@[simps apply symm_apply]
def sumFinsuppEquivProdFinsupp {α β γ : Type*} [Zero γ] : (Sum α β →₀ γ) ≃ (α →₀ γ) × (β →₀ γ)
    where
  toFun f :=
    ⟨f.comapDomain Sum.inl (Sum.inl_injective.injOn _),
      f.comapDomain Sum.inr (Sum.inr_injective.injOn _)⟩
  invFun fg := sumElim fg.1 fg.2
  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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α ⊕ β →₀ γ
⊢ (fun fg => sumElim fg.1 fg.2)
      ((fun f =>
          (comapDomain Sum.inl f (_ : Set.InjOn Sum.inl (Sum.inl ⁻¹' ↑f.support)),
            comapDomain Sum.inr f (_ : Set.InjOn Sum.inr (Sum.inr ⁻¹' ↑f.support))))
        f) =
    f

Next tactic:
ext ab
/-- The equivalence between `(α ⊕ β) →₀ γ` and `(α →₀ γ) × (β →₀ γ)`.

This is the `Finsupp` version of `Equiv.sum_arrow_equiv_prod_arrow`. -/
@[simps apply symm_apply]
def sumFinsuppEquivProdFinsupp {α β γ : Type*} [Zero γ] : (Sum α β →₀ γ) ≃ (α →₀ γ) × (β →₀ γ)
    where
  toFun f :=
    ⟨f.comapDomain Sum.inl (Sum.inl_injective.injOn _),
      f.comapDomain Sum.inr (Sum.inr_injective.injOn _)⟩
  invFun fg := sumElim fg.1 fg.2
  left_inv f := by
    ext ab
    

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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α ⊕ β →₀ γ
ab : α ⊕ β
⊢ ((fun fg => sumElim fg.1 fg.2)
        ((fun f =>
            (comapDomain Sum.inl f (_ : Set.InjOn Sum.inl (Sum.inl ⁻¹' ↑f.support)),
              comapDomain Sum.inr f (_ : Set.InjOn Sum.inr (Sum.inr ⁻¹' ↑f.support))))
          f))
      ab =
    f ab

Next tactic:
cases' ab with a b
/-- The equivalence between `(α ⊕ β) →₀ γ` and `(α →₀ γ) × (β →₀ γ)`.

This is the `Finsupp` version of `Equiv.sum_arrow_equiv_prod_arrow`. -/
@[simps apply symm_apply]
def sumFinsuppEquivProdFinsupp {α β γ : Type*} [Zero γ] : (Sum α β →₀ γ) ≃ (α →₀ γ) × (β →₀ γ)
    where
  toFun f :=
    ⟨f.comapDomain Sum.inl (Sum.inl_injective.injOn _),
      f.comapDomain Sum.inr (Sum.inr_injective.injOn _)⟩
  invFun fg := sumElim fg.1 fg.2
  left_inv f := by
    ext ab
    cases' ab with a b <;> 

Proof state:
case h.inl
α✝ : 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
α : Type u_13
β : Type u_14
γ : Type u_15
inst✝ : Zero γ
f : α ⊕ β →₀ γ
a : α
⊢ ((fun fg => sumElim fg.1 fg.2)
        ((fun f =>
            (comapDomain Sum.inl f (_ : Set.InjOn Sum.inl (Sum.inl ⁻¹' ↑f.support)),
              comapDomain Sum.inr f (_ : Set.InjOn Sum.inr (Sum.inr ⁻¹' ↑f.support))))
          f))
      (Sum.inl a) =
    f (Sum.inl a)

Next tactic:
simp