l3lab/ntp-mathlib huggingface dataset:
@[reassoc]
theorem ι_desc (j : J) : ι arrows j ≫ desc f fs w = fs _ := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
j : J
⊢ ι arrows j ≫ desc f fs w = fs j

Next tactic:
simp only [colimit.ι_desc, WidePushoutShape.mkCocone_pt, WidePushoutShape.mkCocone_ι_app]
@[reassoc]
theorem head_desc : head arrows ≫ desc f fs w = f := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
⊢ head arrows ≫ desc f fs w = f

Next tactic:
simp only [colimit.ι_desc, WidePushoutShape.mkCocone_pt, WidePushoutShape.mkCocone_ι_app]
theorem eq_desc_of_comp_eq (g : widePushout _ _ arrows ⟶ X) :
    (∀ j : J, ι arrows j ≫ g = fs j) → head arrows ≫ g = f → g = desc f fs w := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g : widePushout B (fun j => objs j) arrows ⟶ X
⊢ (∀ (j : J), ι arrows j ≫ g = fs j) → head arrows ≫ g = f → g = desc f fs w

Next tactic:
intro h1 h2
theorem eq_desc_of_comp_eq (g : widePushout _ _ arrows ⟶ X) :
    (∀ j : J, ι arrows j ≫ g = fs j) → head arrows ≫ g = f → g = desc f fs w := by
  intro h1 h2
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g : widePushout B (fun j => objs j) arrows ⟶ X
h1 : ∀ (j : J), ι arrows j ≫ g = fs j
h2 : head arrows ≫ g = f
⊢ g = desc f fs w

Next tactic:
apply
    (colimit.isColimit (WidePushoutShape.wideSpan B objs arrows)).uniq
      (WidePushoutShape.mkCocone f fs <| w)
theorem eq_desc_of_comp_eq (g : widePushout _ _ arrows ⟶ X) :
    (∀ j : J, ι arrows j ≫ g = fs j) → head arrows ≫ g = f → g = desc f fs w := by
  intro h1 h2
  apply
    (colimit.isColimit (WidePushoutShape.wideSpan B objs arrows)).uniq
      (WidePushoutShape.mkCocone f fs <| w)
  

Proof state:
case x
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g : widePushout B (fun j => objs j) arrows ⟶ X
h1 : ∀ (j : J), ι arrows j ≫ g = fs j
h2 : head arrows ≫ g = f
⊢ ∀ (j : WidePushoutShape J),
    (colimit.cocone (WidePushoutShape.wideSpan B objs arrows)).ι.app j ≫ g = (WidePushoutShape.mkCocone f fs w).ι.app j

Next tactic:
rintro (_ | _)
theorem eq_desc_of_comp_eq (g : widePushout _ _ arrows ⟶ X) :
    (∀ j : J, ι arrows j ≫ g = fs j) → head arrows ≫ g = f → g = desc f fs w := by
  intro h1 h2
  apply
    (colimit.isColimit (WidePushoutShape.wideSpan B objs arrows)).uniq
      (WidePushoutShape.mkCocone f fs <| w)
  rintro (_ | _)
  · 

Proof state:
case x.none
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g : widePushout B (fun j => objs j) arrows ⟶ X
h1 : ∀ (j : J), ι arrows j ≫ g = fs j
h2 : head arrows ≫ g = f
⊢ (colimit.cocone (WidePushoutShape.wideSpan B objs arrows)).ι.app none ≫ g =
    (WidePushoutShape.mkCocone f fs w).ι.app none

Next tactic:
apply h2
theorem eq_desc_of_comp_eq (g : widePushout _ _ arrows ⟶ X) :
    (∀ j : J, ι arrows j ≫ g = fs j) → head arrows ≫ g = f → g = desc f fs w := by
  intro h1 h2
  apply
    (colimit.isColimit (WidePushoutShape.wideSpan B objs arrows)).uniq
      (WidePushoutShape.mkCocone f fs <| w)
  rintro (_ | _)
  · apply h2
  · 

Proof state:
case x.some
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g : widePushout B (fun j => objs j) arrows ⟶ X
h1 : ∀ (j : J), ι arrows j ≫ g = fs j
h2 : head arrows ≫ g = f
val✝ : J
⊢ (colimit.cocone (WidePushoutShape.wideSpan B objs arrows)).ι.app (some val✝) ≫ g =
    (WidePushoutShape.mkCocone f fs w).ι.app (some val✝)

Next tactic:
apply h1
theorem hom_eq_desc (g : widePushout _ _ arrows ⟶ X) :
    g =
      desc (head arrows ≫ g) (fun j => ι arrows j ≫ g) fun j => by
        

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type ?u.206955
inst✝¹ : Category.{v₂, ?u.206955} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g : widePushout B (fun j => objs j) arrows ⟶ X
j : J
⊢ arrows j ≫ (fun j => ι arrows j ≫ g) j = head arrows ≫ g

Next tactic:
rw [← Category.assoc]
theorem hom_eq_desc (g : widePushout _ _ arrows ⟶ X) :
    g =
      desc (head arrows ≫ g) (fun j => ι arrows j ≫ g) fun j => by
        rw [← Category.assoc]
        

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type ?u.206955
inst✝¹ : Category.{v₂, ?u.206955} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g : widePushout B (fun j => objs j) arrows ⟶ X
j : J
⊢ (arrows j ≫ ι arrows j) ≫ g = head arrows ≫ g

Next tactic:
simp
theorem hom_eq_desc (g : widePushout _ _ arrows ⟶ X) :
    g =
      desc (head arrows ≫ g) (fun j => ι arrows j ≫ g) fun j => by
        rw [← Category.assoc]
        simp := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g : widePushout B (fun j => objs j) arrows ⟶ X
⊢ g =
    desc (head arrows ≫ g) (fun j => ι arrows j ≫ g)
      (_ : ∀ (j : J), arrows j ≫ (fun j => ι arrows j ≫ g) j = head arrows ≫ g)

Next tactic:
apply eq_desc_of_comp_eq
theorem hom_eq_desc (g : widePushout _ _ arrows ⟶ X) :
    g =
      desc (head arrows ≫ g) (fun j => ι arrows j ≫ g) fun j => by
        rw [← Category.assoc]
        simp := by
  apply eq_desc_of_comp_eq
  

Proof state:
case a
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g : widePushout B (fun j => objs j) arrows ⟶ X
⊢ ∀ (j : J), ι arrows j ≫ g = ι arrows j ≫ g
case a
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g : widePushout B (fun j => objs j) arrows ⟶ X
⊢ head arrows ≫ g = head arrows ≫ g

Next tactic:
aesop_cat
theorem hom_eq_desc (g : widePushout _ _ arrows ⟶ X) :
    g =
      desc (head arrows ≫ g) (fun j => ι arrows j ≫ g) fun j => by
        rw [← Category.assoc]
        simp := by
  apply eq_desc_of_comp_eq
  aesop_cat
  

Proof state:
case a
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g : widePushout B (fun j => objs j) arrows ⟶ X
⊢ head arrows ≫ g = head arrows ≫ g

Next tactic:
rfl
@[ext 1100]
theorem hom_ext (g1 g2 : widePushout _ _ arrows ⟶ X) : (∀ j : J,
    ι arrows j ≫ g1 = ι arrows j ≫ g2) → head arrows ≫ g1 = head arrows ≫ g2 → g1 = g2 := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g1 g2 : widePushout B (fun j => objs j) arrows ⟶ X
⊢ (∀ (j : J), ι arrows j ≫ g1 = ι arrows j ≫ g2) → head arrows ≫ g1 = head arrows ≫ g2 → g1 = g2

Next tactic:
intro h1 h2
@[ext 1100]
theorem hom_ext (g1 g2 : widePushout _ _ arrows ⟶ X) : (∀ j : J,
    ι arrows j ≫ g1 = ι arrows j ≫ g2) → head arrows ≫ g1 = head arrows ≫ g2 → g1 = g2 := by
  intro h1 h2
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g1 g2 : widePushout B (fun j => objs j) arrows ⟶ X
h1 : ∀ (j : J), ι arrows j ≫ g1 = ι arrows j ≫ g2
h2 : head arrows ≫ g1 = head arrows ≫ g2
⊢ g1 = g2

Next tactic:
apply colimit.hom_ext
@[ext 1100]
theorem hom_ext (g1 g2 : widePushout _ _ arrows ⟶ X) : (∀ j : J,
    ι arrows j ≫ g1 = ι arrows j ≫ g2) → head arrows ≫ g1 = head arrows ≫ g2 → g1 = g2 := by
  intro h1 h2
  apply colimit.hom_ext
  

Proof state:
case w
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g1 g2 : widePushout B (fun j => objs j) arrows ⟶ X
h1 : ∀ (j : J), ι arrows j ≫ g1 = ι arrows j ≫ g2
h2 : head arrows ≫ g1 = head arrows ≫ g2
⊢ ∀ (j : WidePushoutShape J),
    colimit.ι (WidePushoutShape.wideSpan B (fun j => objs j) arrows) j ≫ g1 =
      colimit.ι (WidePushoutShape.wideSpan B (fun j => objs j) arrows) j ≫ g2

Next tactic:
rintro (_ | _)
@[ext 1100]
theorem hom_ext (g1 g2 : widePushout _ _ arrows ⟶ X) : (∀ j : J,
    ι arrows j ≫ g1 = ι arrows j ≫ g2) → head arrows ≫ g1 = head arrows ≫ g2 → g1 = g2 := by
  intro h1 h2
  apply colimit.hom_ext
  rintro (_ | _)
  · 

Proof state:
case w.none
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g1 g2 : widePushout B (fun j => objs j) arrows ⟶ X
h1 : ∀ (j : J), ι arrows j ≫ g1 = ι arrows j ≫ g2
h2 : head arrows ≫ g1 = head arrows ≫ g2
⊢ colimit.ι (WidePushoutShape.wideSpan B (fun j => objs j) arrows) none ≫ g1 =
    colimit.ι (WidePushoutShape.wideSpan B (fun j => objs j) arrows) none ≫ g2

Next tactic:
apply h2
@[ext 1100]
theorem hom_ext (g1 g2 : widePushout _ _ arrows ⟶ X) : (∀ j : J,
    ι arrows j ≫ g1 = ι arrows j ≫ g2) → head arrows ≫ g1 = head arrows ≫ g2 → g1 = g2 := by
  intro h1 h2
  apply colimit.hom_ext
  rintro (_ | _)
  · apply h2
  · 

Proof state:
case w.some
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
X : D
f : B ⟶ X
fs : (j : J) → objs j ⟶ X
w : ∀ (j : J), arrows j ≫ fs j = f
g1 g2 : widePushout B (fun j => objs j) arrows ⟶ X
h1 : ∀ (j : J), ι arrows j ≫ g1 = ι arrows j ≫ g2
h2 : head arrows ≫ g1 = head arrows ≫ g2
val✝ : J
⊢ colimit.ι (WidePushoutShape.wideSpan B (fun j => objs j) arrows) (some val✝) ≫ g1 =
    colimit.ι (WidePushoutShape.wideSpan B (fun j => objs j) arrows) (some val✝) ≫ g2

Next tactic:
apply h1
@[to_additive (attr := simp)]
theorem smul_swap : (a • x).swap = a • x.swap := by 

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝³ : SMul M α
inst✝² : SMul M β
inst✝¹ : SMul N α
inst✝ : SMul N β
a : M
b : α
c : β
x : α ⊕ β
⊢ swap (a • x) = a • swap x

Next tactic:
cases x
@[to_additive (attr := simp)]
theorem smul_swap : (a • x).swap = a • x.swap := by cases x <;> 

Proof state:
case inl
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝³ : SMul M α
inst✝² : SMul M β
inst✝¹ : SMul N α
inst✝ : SMul N β
a : M
b : α
c : β
val✝ : α
⊢ swap (a • inl val✝) = a • swap (inl val✝)

Next tactic:
rfl
@[to_additive (attr := simp)]
theorem smul_swap : (a • x).swap = a • x.swap := by cases x <;> 

Proof state:
case inr
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝³ : SMul M α
inst✝² : SMul M β
inst✝¹ : SMul N α
inst✝ : SMul N β
a : M
b : α
c val✝ : β
⊢ swap (a • inr val✝) = a • swap (inr val✝)

Next tactic:
rfl
instance [SMul M N] [IsScalarTower M N α] [IsScalarTower M N β] : IsScalarTower M N (Sum α β) :=
  ⟨fun a b x => by
    

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝⁶ : SMul M α
inst✝⁵ : SMul M β
inst✝⁴ : SMul N α
inst✝³ : SMul N β
a✝ : M
b✝ : α
c : β
x✝ : α ⊕ β
inst✝² : SMul M N
inst✝¹ : IsScalarTower M N α
inst✝ : IsScalarTower M N β
a : M
b : N
x : α ⊕ β
⊢ (a • b) • x = a • b • x

Next tactic:
cases x
instance [SMul M N] [IsScalarTower M N α] [IsScalarTower M N β] : IsScalarTower M N (Sum α β) :=
  ⟨fun a b x => by
    cases x
    

Proof state:
case inl
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝⁶ : SMul M α
inst✝⁵ : SMul M β
inst✝⁴ : SMul N α
inst✝³ : SMul N β
a✝ : M
b✝ : α
c : β
x : α ⊕ β
inst✝² : SMul M N
inst✝¹ : IsScalarTower M N α
inst✝ : IsScalarTower M N β
a : M
b : N
val✝ : α
⊢ (a • b) • inl val✝ = a • b • inl val✝
case inr
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝⁶ : SMul M α
inst✝⁵ : SMul M β
inst✝⁴ : SMul N α
inst✝³ : SMul N β
a✝ : M
b✝ : α
c : β
x : α ⊕ β
inst✝² : SMul M N
inst✝¹ : IsScalarTower M N α
inst✝ : IsScalarTower M N β
a : M
b : N
val✝ : β
⊢ (a • b) • inr val✝ = a • b • inr val✝

Next tactic:
exacts [congr_arg inl (smul_assoc _ _ _), congr_arg inr (smul_assoc _ _ _)]
@[to_additive]
instance [SMulCommClass M N α] [SMulCommClass M N β] : SMulCommClass M N (Sum α β) :=
  ⟨fun a b x => by
    

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝⁵ : SMul M α
inst✝⁴ : SMul M β
inst✝³ : SMul N α
inst✝² : SMul N β
a✝ : M
b✝ : α
c : β
x✝ : α ⊕ β
inst✝¹ : SMulCommClass M N α
inst✝ : SMulCommClass M N β
a : M
b : N
x : α ⊕ β
⊢ a • b • x = b • a • x

Next tactic:
cases x
@[to_additive]
instance [SMulCommClass M N α] [SMulCommClass M N β] : SMulCommClass M N (Sum α β) :=
  ⟨fun a b x => by
    cases x
    

Proof state:
case inl
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝⁵ : SMul M α
inst✝⁴ : SMul M β
inst✝³ : SMul N α
inst✝² : SMul N β
a✝ : M
b✝ : α
c : β
x : α ⊕ β
inst✝¹ : SMulCommClass M N α
inst✝ : SMulCommClass M N β
a : M
b : N
val✝ : α
⊢ a • b • inl val✝ = b • a • inl val✝
case inr
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝⁵ : SMul M α
inst✝⁴ : SMul M β
inst✝³ : SMul N α
inst✝² : SMul N β
a✝ : M
b✝ : α
c : β
x : α ⊕ β
inst✝¹ : SMulCommClass M N α
inst✝ : SMulCommClass M N β
a : M
b : N
val✝ : β
⊢ a • b • inr val✝ = b • a • inr val✝

Next tactic:
exacts [congr_arg inl (smul_comm _ _ _), congr_arg inr (smul_comm _ _ _)]
@[to_additive]
instance [SMul Mᵐᵒᵖ α] [SMul Mᵐᵒᵖ β] [IsCentralScalar M α] [IsCentralScalar M β] :
    IsCentralScalar M (Sum α β) :=
  ⟨fun a x => by
    

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝⁷ : SMul M α
inst✝⁶ : SMul M β
inst✝⁵ : SMul N α
inst✝⁴ : SMul N β
a✝ : M
b : α
c : β
x✝ : α ⊕ β
inst✝³ : SMul Mᵐᵒᵖ α
inst✝² : SMul Mᵐᵒᵖ β
inst✝¹ : IsCentralScalar M α
inst✝ : IsCentralScalar M β
a : M
x : α ⊕ β
⊢ MulOpposite.op a • x = a • x

Next tactic:
cases x
@[to_additive]
instance [SMul Mᵐᵒᵖ α] [SMul Mᵐᵒᵖ β] [IsCentralScalar M α] [IsCentralScalar M β] :
    IsCentralScalar M (Sum α β) :=
  ⟨fun a x => by
    cases x
    

Proof state:
case inl
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝⁷ : SMul M α
inst✝⁶ : SMul M β
inst✝⁵ : SMul N α
inst✝⁴ : SMul N β
a✝ : M
b : α
c : β
x : α ⊕ β
inst✝³ : SMul Mᵐᵒᵖ α
inst✝² : SMul Mᵐᵒᵖ β
inst✝¹ : IsCentralScalar M α
inst✝ : IsCentralScalar M β
a : M
val✝ : α
⊢ MulOpposite.op a • inl val✝ = a • inl val✝
case inr
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝⁷ : SMul M α
inst✝⁶ : SMul M β
inst✝⁵ : SMul N α
inst✝⁴ : SMul N β
a✝ : M
b : α
c : β
x : α ⊕ β
inst✝³ : SMul Mᵐᵒᵖ α
inst✝² : SMul Mᵐᵒᵖ β
inst✝¹ : IsCentralScalar M α
inst✝ : IsCentralScalar M β
a : M
val✝ : β
⊢ MulOpposite.op a • inr val✝ = a • inr val✝

Next tactic:
exacts [congr_arg inl (op_smul_eq_smul _ _), congr_arg inr (op_smul_eq_smul _ _)]
@[to_additive]
instance FaithfulSMulLeft [FaithfulSMul M α] : FaithfulSMul M (Sum α β) :=
  ⟨fun h => eq_of_smul_eq_smul fun a : α => by 

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝⁴ : SMul M α
inst✝³ : SMul M β
inst✝² : SMul N α
inst✝¹ : SMul N β
a✝ : M
b : α
c : β
x : α ⊕ β
inst✝ : FaithfulSMul M α
m₁✝ m₂✝ : M
h : ∀ (a : α ⊕ β), m₁✝ • a = m₂✝ • a
a : α
⊢ m₁✝ • a = m₂✝ • a

Next tactic:
injection h (inl a)
@[to_additive]
instance FaithfulSMulRight [FaithfulSMul M β] : FaithfulSMul M (Sum α β) :=
  ⟨fun h => eq_of_smul_eq_smul fun b : β => by 

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
inst✝⁴ : SMul M α
inst✝³ : SMul M β
inst✝² : SMul N α
inst✝¹ : SMul N β
a : M
b✝ : α
c : β
x : α ⊕ β
inst✝ : FaithfulSMul M β
m₁✝ m₂✝ : M
h : ∀ (a : α ⊕ β), m₁✝ • a = m₂✝ • a
b : β
⊢ m₁✝ • b = m₂✝ • b

Next tactic:
injection h (inr b)
@[to_additive]
instance {m : Monoid M} [MulAction M α] [MulAction M β] :
    MulAction M
      (Sum α
        β) where
  mul_smul a b x := by
    cases x
    exacts [congr_arg inl (mul_smul _ _ _), congr_arg inr (mul_smul _ _ _)]
  one_smul x := by
    

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
m : Monoid M
inst✝¹ : MulAction M α
inst✝ : MulAction M β
x : α ⊕ β
⊢ 1 • x = x

Next tactic:
cases x
@[to_additive]
instance {m : Monoid M} [MulAction M α] [MulAction M β] :
    MulAction M
      (Sum α
        β) where
  mul_smul a b x := by
    cases x
    exacts [congr_arg inl (mul_smul _ _ _), congr_arg inr (mul_smul _ _ _)]
  one_smul x := by
    cases x
    

Proof state:
case inl
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
m : Monoid M
inst✝¹ : MulAction M α
inst✝ : MulAction M β
val✝ : α
⊢ 1 • inl val✝ = inl val✝
case inr
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
m : Monoid M
inst✝¹ : MulAction M α
inst✝ : MulAction M β
val✝ : β
⊢ 1 • inr val✝ = inr val✝

Next tactic:
exacts [congr_arg inl (one_smul _ _), congr_arg inr (one_smul _ _)]
@[to_additive]
instance {m : Monoid M} [MulAction M α] [MulAction M β] :
    MulAction M
      (Sum α
        β) where
  mul_smul a b x := by
    

Proof state:
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
m : Monoid M
inst✝¹ : MulAction M α
inst✝ : MulAction M β
a b : M
x : α ⊕ β
⊢ (a * b) • x = a • b • x

Next tactic:
cases x
@[to_additive]
instance {m : Monoid M} [MulAction M α] [MulAction M β] :
    MulAction M
      (Sum α
        β) where
  mul_smul a b x := by
    cases x
    

Proof state:
case inl
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
m : Monoid M
inst✝¹ : MulAction M α
inst✝ : MulAction M β
a b : M
val✝ : α
⊢ (a * b) • inl val✝ = a • b • inl val✝
case inr
M : Type u_1
N : Type u_2
P : Type u_3
α : Type u_4
β : Type u_5
γ : Type u_6
m : Monoid M
inst✝¹ : MulAction M α
inst✝ : MulAction M β
a b : M
val✝ : β
⊢ (a * b) • inr val✝ = a • b • inr val✝

Next tactic:
exacts [congr_arg inl (mul_smul _ _ _), congr_arg inr (mul_smul _ _ _)]
theorem List.trop_sum [AddMonoid R] (l : List R) : trop l.sum = List.prod (l.map trop) := by
  

Proof state:
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
l : List R
⊢ trop (sum l) = prod (map trop l)

Next tactic:
induction' l with hd tl IH
theorem List.trop_sum [AddMonoid R] (l : List R) : trop l.sum = List.prod (l.map trop) := by
  induction' l with hd tl IH
  · 

Proof state:
case nil
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
⊢ trop (sum []) = prod (map trop [])

Next tactic:
simp
theorem List.trop_sum [AddMonoid R] (l : List R) : trop l.sum = List.prod (l.map trop) := by
  induction' l with hd tl IH
  · simp
  · 

Proof state:
case cons
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
hd : R
tl : List R
IH : trop (sum tl) = prod (map trop tl)
⊢ trop (sum (hd :: tl)) = prod (map trop (hd :: tl))

Next tactic:
simp [← IH]
theorem Multiset.trop_sum [AddCommMonoid R] (s : Multiset R) :
    trop s.sum = Multiset.prod (s.map trop) :=
  Quotient.inductionOn s (by 

Proof state:
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Multiset R
⊢ ∀ (a : List R), trop (sum ⟦a⟧) = prod (map trop ⟦a⟧)

Next tactic:
simpa using List.trop_sum
theorem trop_sum [AddCommMonoid R] (s : Finset S) (f : S → R) :
    trop (∑ i in s, f i) = ∏ i in s, trop (f i) := by
  

Proof state:
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Finset S
f : S → R
⊢ trop (∑ i in s, f i) = ∏ i in s, trop (f i)

Next tactic:
convert Multiset.trop_sum (s.val.map f)
theorem trop_sum [AddCommMonoid R] (s : Finset S) (f : S → R) :
    trop (∑ i in s, f i) = ∏ i in s, trop (f i) := by
  convert Multiset.trop_sum (s.val.map f)
  

Proof state:
case h.e'_3
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Finset S
f : S → R
⊢ ∏ i in s, trop (f i) = Multiset.prod (Multiset.map trop (Multiset.map f s.val))

Next tactic:
simp only [Multiset.map_map, Function.comp_apply]
theorem trop_sum [AddCommMonoid R] (s : Finset S) (f : S → R) :
    trop (∑ i in s, f i) = ∏ i in s, trop (f i) := by
  convert Multiset.trop_sum (s.val.map f)
  simp only [Multiset.map_map, Function.comp_apply]
  

Proof state:
case h.e'_3
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Finset S
f : S → R
⊢ ∏ i in s, trop (f i) = Multiset.prod (Multiset.map (fun i => trop (f i)) s.val)

Next tactic:
rfl
theorem List.untrop_prod [AddMonoid R] (l : List (Tropical R)) :
    untrop l.prod = List.sum (l.map untrop) := by
  

Proof state:
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
l : List (Tropical R)
⊢ untrop (prod l) = sum (map untrop l)

Next tactic:
induction' l with hd tl IH
theorem List.untrop_prod [AddMonoid R] (l : List (Tropical R)) :
    untrop l.prod = List.sum (l.map untrop) := by
  induction' l with hd tl IH
  · 

Proof state:
case nil
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
⊢ untrop (prod []) = sum (map untrop [])

Next tactic:
simp
theorem List.untrop_prod [AddMonoid R] (l : List (Tropical R)) :
    untrop l.prod = List.sum (l.map untrop) := by
  induction' l with hd tl IH
  · simp
  · 

Proof state:
case cons
R : Type u_1
S : Type u_2
inst✝ : AddMonoid R
hd : Tropical R
tl : List (Tropical R)
IH : untrop (prod tl) = sum (map untrop tl)
⊢ untrop (prod (hd :: tl)) = sum (map untrop (hd :: tl))

Next tactic:
simp [← IH]
theorem Multiset.untrop_prod [AddCommMonoid R] (s : Multiset (Tropical R)) :
    untrop s.prod = Multiset.sum (s.map untrop) :=
  Quotient.inductionOn s (by 

Proof state:
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Multiset (Tropical R)
⊢ ∀ (a : List (Tropical R)), untrop (prod ⟦a⟧) = sum (map untrop ⟦a⟧)

Next tactic:
simpa using List.untrop_prod
theorem untrop_prod [AddCommMonoid R] (s : Finset S) (f : S → Tropical R) :
    untrop (∏ i in s, f i) = ∑ i in s, untrop (f i) := by
  

Proof state:
R : Type u_1
S : Type u_2
inst✝ : AddCommMonoid R
s : Finset S
f : S → Tropical R
⊢ untrop (∏ i in s, f i) = ∑ i in s, untrop (f i)

Next tactic:
convert Multiset.untrop_prod (s.val.map f)