/-
Copyright (c) 2019 Scott Morrison. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Scott Morrison

! This file was ported from Lean 3 source module category_theory.sums.basic
! leanprover-community/mathlib commit 23aa88e32dcc9d2a24cca7bc23268567ed4cd7d6
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.CategoryTheory.EqToHom

/-!
# Binary disjoint unions of categories

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.

We define the category instance on `C ⊕ D` when `C` and `D` are categories.

We define:
* `inl_`      : the functor `C ⥤ C ⊕ D`
* `inr_`      : the functor `D ⥤ C ⊕ D`
* `swap`      : the functor `C ⊕ D ⥤ D ⊕ C`
    (and the fact this is an equivalence)

We further define sums of functors and natural transformations, written `F.sum G` and `α.sum β`.
-/

namespace CategoryTheory

universe v₁ u₁

-- morphism levels before object levels. See note [category_theory universes].
open Sum

section

variable (C : Type u₁) [Category.{v₁} C] (D : Type u₁) [Category.{v₁} D]

#print CategoryTheory.sum /-
/-- `sum C D` gives the direct sum of two categories.
-/
instance sum : Category.{v₁} (Sum C D)
    where
  Hom X Y :=
    match X, Y with
    | inl X, inl Y => X ⟶ Y
    | inl X, inr Y => PEmpty
    | inr X, inl Y => PEmpty
    | inr X, inr Y => X ⟶ Y
  id X :=
    match X with
    | inl X => 𝟙 X
    | inr X => 𝟙 X
  comp X Y Z f g :=
    match X, Y, Z, f, g with
    | inl X, inl Y, inl Z, f, g => f ≫ g
    | inr X, inr Y, inr Z, f, g => f ≫ g
#align category_theory.sum CategoryTheory.sum
-/

#print CategoryTheory.sum_comp_inl /-
@[simp]
theorem sum_comp_inl {P Q R : C} (f : (inl P : Sum C D) ⟶ inl Q) (g : (inl Q : Sum C D) ⟶ inl R) :
    @CategoryStruct.comp _ _ P Q R (f : P ⟶ Q) (g : Q ⟶ R) =
      @CategoryStruct.comp _ _ (inl P) (inl Q) (inl R) (f : P ⟶ Q) (g : Q ⟶ R) :=
  rfl
#align category_theory.sum_comp_inl CategoryTheory.sum_comp_inl
-/

#print CategoryTheory.sum_comp_inr /-
@[simp]
theorem sum_comp_inr {P Q R : D} (f : (inr P : Sum C D) ⟶ inr Q) (g : (inr Q : Sum C D) ⟶ inr R) :
    @CategoryStruct.comp _ _ P Q R (f : P ⟶ Q) (g : Q ⟶ R) =
      @CategoryStruct.comp _ _ (inr P) (inr Q) (inr R) (f : P ⟶ Q) (g : Q ⟶ R) :=
  rfl
#align category_theory.sum_comp_inr CategoryTheory.sum_comp_inr
-/

end

namespace Sum

variable (C : Type u₁) [Category.{v₁} C] (D : Type u₁) [Category.{v₁} D]

#print CategoryTheory.Sum.inl_ /-
-- Unfortunate naming here, suggestions welcome.
/-- `inl_` is the functor `X ↦ inl X`. -/
@[simps]
def inl_ : C ⥤ Sum C D where
  obj X := inl X
  map X Y f := f
#align category_theory.sum.inl_ CategoryTheory.Sum.inl_
-/

#print CategoryTheory.Sum.inr_ /-
/-- `inr_` is the functor `X ↦ inr X`. -/
@[simps]
def inr_ : D ⥤ Sum C D where
  obj X := inr X
  map X Y f := f
#align category_theory.sum.inr_ CategoryTheory.Sum.inr_
-/

#print CategoryTheory.Sum.swap /-
/-- The functor exchanging two direct summand categories. -/
def swap : Sum C D ⥤ Sum D C
    where
  obj X :=
    match X with
    | inl X => inr X
    | inr X => inl X
  map X Y f :=
    match X, Y, f with
    | inl X, inl Y, f => f
    | inr X, inr Y, f => f
#align category_theory.sum.swap CategoryTheory.Sum.swap
-/

/- warning: category_theory.sum.swap_obj_inl -> CategoryTheory.Sum.swap_obj_inl is a dubious translation:
lean 3 declaration is
  forall (C : Type.{u2}) [_inst_1 : CategoryTheory.Category.{u1, u2} C] (D : Type.{u2}) [_inst_2 : CategoryTheory.Category.{u1, u2} D] (X : C), Eq.{succ u2} (Sum.{u2, u2} D C) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2) (Sum.inl.{u2, u2} C D X)) (Sum.inr.{u2, u2} D C X)
but is expected to have type
  forall (C : Type.{u2}) [_inst_1 : CategoryTheory.Category.{u1, u2} C] (D : Type.{u2}) [_inst_2 : CategoryTheory.Category.{u1, u2} D] (X : C), Eq.{succ u2} (Sum.{u2, u2} D C) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2)) (Sum.inl.{u2, u2} C D X)) (Sum.inr.{u2, u2} D C X)
Case conversion may be inaccurate. Consider using '#align category_theory.sum.swap_obj_inl CategoryTheory.Sum.swap_obj_inlₓ'. -/
@[simp]
theorem swap_obj_inl (X : C) : (swap C D).obj (inl X) = inr X :=
  rfl
#align category_theory.sum.swap_obj_inl CategoryTheory.Sum.swap_obj_inl

/- warning: category_theory.sum.swap_obj_inr -> CategoryTheory.Sum.swap_obj_inr is a dubious translation:
lean 3 declaration is
  forall (C : Type.{u2}) [_inst_1 : CategoryTheory.Category.{u1, u2} C] (D : Type.{u2}) [_inst_2 : CategoryTheory.Category.{u1, u2} D] (X : D), Eq.{succ u2} (Sum.{u2, u2} D C) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2) (Sum.inr.{u2, u2} C D X)) (Sum.inl.{u2, u2} D C X)
but is expected to have type
  forall (C : Type.{u2}) [_inst_1 : CategoryTheory.Category.{u1, u2} C] (D : Type.{u2}) [_inst_2 : CategoryTheory.Category.{u1, u2} D] (X : D), Eq.{succ u2} (Sum.{u2, u2} D C) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2)) (Sum.inr.{u2, u2} C D X)) (Sum.inl.{u2, u2} D C X)
Case conversion may be inaccurate. Consider using '#align category_theory.sum.swap_obj_inr CategoryTheory.Sum.swap_obj_inrₓ'. -/
@[simp]
theorem swap_obj_inr (X : D) : (swap C D).obj (inr X) = inl X :=
  rfl
#align category_theory.sum.swap_obj_inr CategoryTheory.Sum.swap_obj_inr

/- warning: category_theory.sum.swap_map_inl -> CategoryTheory.Sum.swap_map_inl is a dubious translation:
lean 3 declaration is
  forall (C : Type.{u2}) [_inst_1 : CategoryTheory.Category.{u1, u2} C] (D : Type.{u2}) [_inst_2 : CategoryTheory.Category.{u1, u2} D] {X : C} {Y : C} {f : Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.inl.{u2, u2} C D X) (Sum.inl.{u2, u2} C D Y)}, Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2) (Sum.inl.{u2, u2} C D X)) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2) (Sum.inl.{u2, u2} C D Y))) (CategoryTheory.Functor.map.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2) (Sum.inl.{u2, u2} C D X) (Sum.inl.{u2, u2} C D Y) f) f
but is expected to have type
  forall (C : Type.{u2}) [_inst_1 : CategoryTheory.Category.{u1, u2} C] (D : Type.{u2}) [_inst_2 : CategoryTheory.Category.{u1, u2} D] {X : C} {Y : C} {f : Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.inl.{u2, u2} C D X) (Sum.inl.{u2, u2} C D Y)}, Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2)) (Sum.inl.{u2, u2} C D X)) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2)) (Sum.inl.{u2, u2} C D Y))) (Prefunctor.map.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2)) (Sum.inl.{u2, u2} C D X) (Sum.inl.{u2, u2} C D Y) f) f
Case conversion may be inaccurate. Consider using '#align category_theory.sum.swap_map_inl CategoryTheory.Sum.swap_map_inlₓ'. -/
@[simp]
theorem swap_map_inl {X Y : C} {f : inl X ⟶ inl Y} : (swap C D).map f = f :=
  rfl
#align category_theory.sum.swap_map_inl CategoryTheory.Sum.swap_map_inl

/- warning: category_theory.sum.swap_map_inr -> CategoryTheory.Sum.swap_map_inr is a dubious translation:
lean 3 declaration is
  forall (C : Type.{u2}) [_inst_1 : CategoryTheory.Category.{u1, u2} C] (D : Type.{u2}) [_inst_2 : CategoryTheory.Category.{u1, u2} D] {X : D} {Y : D} {f : Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.inr.{u2, u2} C D X) (Sum.inr.{u2, u2} C D Y)}, Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2) (Sum.inr.{u2, u2} C D X)) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2) (Sum.inr.{u2, u2} C D Y))) (CategoryTheory.Functor.map.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2) (Sum.inr.{u2, u2} C D X) (Sum.inr.{u2, u2} C D Y) f) f
but is expected to have type
  forall (C : Type.{u2}) [_inst_1 : CategoryTheory.Category.{u1, u2} C] (D : Type.{u2}) [_inst_2 : CategoryTheory.Category.{u1, u2} D] {X : D} {Y : D} {f : Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.inr.{u2, u2} C D X) (Sum.inr.{u2, u2} C D Y)}, Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2)) (Sum.inr.{u2, u2} C D X)) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2)) (Sum.inr.{u2, u2} C D Y))) (Prefunctor.map.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2))) (Sum.{u2, u2} D C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1) (CategoryTheory.Sum.swap.{u1, u2} C _inst_1 D _inst_2)) (Sum.inr.{u2, u2} C D X) (Sum.inr.{u2, u2} C D Y) f) f
Case conversion may be inaccurate. Consider using '#align category_theory.sum.swap_map_inr CategoryTheory.Sum.swap_map_inrₓ'. -/
@[simp]
theorem swap_map_inr {X Y : D} {f : inr X ⟶ inr Y} : (swap C D).map f = f :=
  rfl
#align category_theory.sum.swap_map_inr CategoryTheory.Sum.swap_map_inr

namespace Swap

/- warning: category_theory.sum.swap.equivalence -> CategoryTheory.Sum.Swap.equivalence is a dubious translation:
lean 3 declaration is
  forall (C : Type.{u2}) [_inst_1 : CategoryTheory.Category.{u1, u2} C] (D : Type.{u2}) [_inst_2 : CategoryTheory.Category.{u1, u2} D], CategoryTheory.Equivalence.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1)
but is expected to have type
  forall (C : Type.{u2}) [_inst_1 : CategoryTheory.Category.{u1, u2} C] (D : Type.{u2}) [_inst_2 : CategoryTheory.Category.{u1, u2} D], CategoryTheory.Equivalence.{u1, u1, u2, u2} (Sum.{u2, u2} C D) (Sum.{u2, u2} D C) (CategoryTheory.sum.{u1, u2} C _inst_1 D _inst_2) (CategoryTheory.sum.{u1, u2} D _inst_2 C _inst_1)
Case conversion may be inaccurate. Consider using '#align category_theory.sum.swap.equivalence CategoryTheory.Sum.Swap.equivalenceₓ'. -/
/-- `swap` gives an equivalence between `C ⊕ D` and `D ⊕ C`. -/
def equivalence : Sum C D ≌ Sum D C :=
  Equivalence.mk (swap C D) (swap D C)
    (NatIso.ofComponents (fun X => eqToIso (by cases X <;> rfl)) (by tidy))
    (NatIso.ofComponents (fun X => eqToIso (by cases X <;> rfl)) (by tidy))
#align category_theory.sum.swap.equivalence CategoryTheory.Sum.Swap.equivalence

#print CategoryTheory.Sum.Swap.isEquivalence /-
instance isEquivalence : IsEquivalence (swap C D) :=
  (by infer_instance : IsEquivalence (equivalence C D).Functor)
#align category_theory.sum.swap.is_equivalence CategoryTheory.Sum.Swap.isEquivalence
-/

#print CategoryTheory.Sum.Swap.symmetry /-
/-- The double swap on `C ⊕ D` is naturally isomorphic to the identity functor. -/
def symmetry : swap C D ⋙ swap D C ≅ 𝟭 (Sum C D) :=
  (equivalence C D).unitIso.symm
#align category_theory.sum.swap.symmetry CategoryTheory.Sum.Swap.symmetry
-/

end Swap

end Sum

variable {A : Type u₁} [Category.{v₁} A] {B : Type u₁} [Category.{v₁} B] {C : Type u₁}
  [Category.{v₁} C] {D : Type u₁} [Category.{v₁} D]

namespace Functor

#print CategoryTheory.Functor.sum /-
/-- The sum of two functors. -/
def sum (F : A ⥤ B) (G : C ⥤ D) : Sum A C ⥤ Sum B D
    where
  obj X :=
    match X with
    | inl X => inl (F.obj X)
    | inr X => inr (G.obj X)
  map X Y f :=
    match X, Y, f with
    | inl X, inl Y, f => F.map f
    | inr X, inr Y, f => G.map f
  map_id' X := by cases X <;> unfold_aux; erw [F.map_id]; rfl; erw [G.map_id]; rfl
  map_comp' X Y Z f g :=
    match X, Y, Z, f, g with
    | inl X, inl Y, inl Z, f, g => by
      unfold_aux
      erw [F.map_comp]
      rfl
    | inr X, inr Y, inr Z, f, g => by
      unfold_aux
      erw [G.map_comp]
      rfl
#align category_theory.functor.sum CategoryTheory.Functor.sum
-/

/- warning: category_theory.functor.sum_obj_inl -> CategoryTheory.Functor.sum_obj_inl is a dubious translation:
lean 3 declaration is
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] (F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (G : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (a : A), Eq.{succ u2} (Sum.{u2, u2} B D) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G) (Sum.inl.{u2, u2} A C a)) (Sum.inl.{u2, u2} B D (CategoryTheory.Functor.obj.{u1, u1, u2, u2} A _inst_1 B _inst_2 F a))
but is expected to have type
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] (F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (G : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (a : A), Eq.{succ u2} (Sum.{u2, u2} B D) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G)) (Sum.inl.{u2, u2} A C a)) (Sum.inl.{u2, u2} B D (Prefunctor.obj.{succ u1, succ u1, u2, u2} A (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} A (CategoryTheory.Category.toCategoryStruct.{u1, u2} A _inst_1)) B (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} B (CategoryTheory.Category.toCategoryStruct.{u1, u2} B _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} A _inst_1 B _inst_2 F) a))
Case conversion may be inaccurate. Consider using '#align category_theory.functor.sum_obj_inl CategoryTheory.Functor.sum_obj_inlₓ'. -/
@[simp]
theorem sum_obj_inl (F : A ⥤ B) (G : C ⥤ D) (a : A) : (F.Sum G).obj (inl a) = inl (F.obj a) :=
  rfl
#align category_theory.functor.sum_obj_inl CategoryTheory.Functor.sum_obj_inl

/- warning: category_theory.functor.sum_obj_inr -> CategoryTheory.Functor.sum_obj_inr is a dubious translation:
lean 3 declaration is
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] (F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (G : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (c : C), Eq.{succ u2} (Sum.{u2, u2} B D) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G) (Sum.inr.{u2, u2} A C c)) (Sum.inr.{u2, u2} B D (CategoryTheory.Functor.obj.{u1, u1, u2, u2} C _inst_3 D _inst_4 G c))
but is expected to have type
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] (F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (G : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (c : C), Eq.{succ u2} (Sum.{u2, u2} B D) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G)) (Sum.inr.{u2, u2} A C c)) (Sum.inr.{u2, u2} B D (Prefunctor.obj.{succ u1, succ u1, u2, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_3)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_4)) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} C _inst_3 D _inst_4 G) c))
Case conversion may be inaccurate. Consider using '#align category_theory.functor.sum_obj_inr CategoryTheory.Functor.sum_obj_inrₓ'. -/
@[simp]
theorem sum_obj_inr (F : A ⥤ B) (G : C ⥤ D) (c : C) : (F.Sum G).obj (inr c) = inr (G.obj c) :=
  rfl
#align category_theory.functor.sum_obj_inr CategoryTheory.Functor.sum_obj_inr

/- warning: category_theory.functor.sum_map_inl -> CategoryTheory.Functor.sum_map_inl is a dubious translation:
lean 3 declaration is
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] (F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (G : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) {a : A} {a' : A} (f : Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.inl.{u2, u2} A C a) (Sum.inl.{u2, u2} A C a')), Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G) (Sum.inl.{u2, u2} A C a)) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G) (Sum.inl.{u2, u2} A C a'))) (CategoryTheory.Functor.map.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G) (Sum.inl.{u2, u2} A C a) (Sum.inl.{u2, u2} A C a') f) (CategoryTheory.Functor.map.{u1, u1, u2, u2} A _inst_1 B _inst_2 F a a' f)
but is expected to have type
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] (F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (G : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) {a : A} {a' : A} (f : Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.inl.{u2, u2} A C a) (Sum.inl.{u2, u2} A C a')), Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G)) (Sum.inl.{u2, u2} A C a)) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G)) (Sum.inl.{u2, u2} A C a'))) (Prefunctor.map.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G)) (Sum.inl.{u2, u2} A C a) (Sum.inl.{u2, u2} A C a') f) (Prefunctor.map.{succ u1, succ u1, u2, u2} A (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} A (CategoryTheory.Category.toCategoryStruct.{u1, u2} A _inst_1)) B (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} B (CategoryTheory.Category.toCategoryStruct.{u1, u2} B _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} A _inst_1 B _inst_2 F) a a' f)
Case conversion may be inaccurate. Consider using '#align category_theory.functor.sum_map_inl CategoryTheory.Functor.sum_map_inlₓ'. -/
@[simp]
theorem sum_map_inl (F : A ⥤ B) (G : C ⥤ D) {a a' : A} (f : inl a ⟶ inl a') :
    (F.Sum G).map f = F.map f :=
  rfl
#align category_theory.functor.sum_map_inl CategoryTheory.Functor.sum_map_inl

/- warning: category_theory.functor.sum_map_inr -> CategoryTheory.Functor.sum_map_inr is a dubious translation:
lean 3 declaration is
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] (F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (G : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) {c : C} {c' : C} (f : Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.inr.{u2, u2} A C c) (Sum.inr.{u2, u2} A C c')), Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G) (Sum.inr.{u2, u2} A C c)) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G) (Sum.inr.{u2, u2} A C c'))) (CategoryTheory.Functor.map.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G) (Sum.inr.{u2, u2} A C c) (Sum.inr.{u2, u2} A C c') f) (CategoryTheory.Functor.map.{u1, u1, u2, u2} C _inst_3 D _inst_4 G c c' f)
but is expected to have type
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] (F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (G : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) {c : C} {c' : C} (f : Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.inr.{u2, u2} A C c) (Sum.inr.{u2, u2} A C c')), Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G)) (Sum.inr.{u2, u2} A C c)) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G)) (Sum.inr.{u2, u2} A C c'))) (Prefunctor.map.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G)) (Sum.inr.{u2, u2} A C c) (Sum.inr.{u2, u2} A C c') f) (Prefunctor.map.{succ u1, succ u1, u2, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_3)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_4)) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} C _inst_3 D _inst_4 G) c c' f)
Case conversion may be inaccurate. Consider using '#align category_theory.functor.sum_map_inr CategoryTheory.Functor.sum_map_inrₓ'. -/
@[simp]
theorem sum_map_inr (F : A ⥤ B) (G : C ⥤ D) {c c' : C} (f : inr c ⟶ inr c') :
    (F.Sum G).map f = G.map f :=
  rfl
#align category_theory.functor.sum_map_inr CategoryTheory.Functor.sum_map_inr

end Functor

namespace NatTrans

#print CategoryTheory.NatTrans.sum /-
/-- The sum of two natural transformations. -/
def sum {F G : A ⥤ B} {H I : C ⥤ D} (α : F ⟶ G) (β : H ⟶ I) : F.Sum H ⟶ G.Sum I
    where
  app X :=
    match X with
    | inl X => α.app X
    | inr X => β.app X
  naturality' X Y f :=
    match X, Y, f with
    | inl X, inl Y, f => by unfold_aux; erw [α.naturality]; rfl
    | inr X, inr Y, f => by unfold_aux; erw [β.naturality]; rfl
#align category_theory.nat_trans.sum CategoryTheory.NatTrans.sum
-/

/- warning: category_theory.nat_trans.sum_app_inl -> CategoryTheory.NatTrans.sum_app_inl is a dubious translation:
lean 3 declaration is
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] {F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2} {G : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2} {H : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4} {I : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4} (α : Quiver.Hom.{succ (max u2 u1), max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u1, max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u1, max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.Functor.category.{u1, u1, u2, u2} A _inst_1 B _inst_2))) F G) (β : Quiver.Hom.{succ (max u2 u1), max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u1, max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.Category.toCategoryStruct.{max u2 u1, max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.Functor.category.{u1, u1, u2, u2} C _inst_3 D _inst_4))) H I) (a : A), Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F H) (Sum.inl.{u2, u2} A C a)) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 G I) (Sum.inl.{u2, u2} A C a))) (CategoryTheory.NatTrans.app.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F H) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 G I) (CategoryTheory.NatTrans.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G H I α β) (Sum.inl.{u2, u2} A C a)) (CategoryTheory.NatTrans.app.{u1, u1, u2, u2} A _inst_1 B _inst_2 F G α a)
but is expected to have type
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] {F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2} {G : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2} {H : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4} {I : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4} (α : Quiver.Hom.{max (succ u2) (succ u1), max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u1, max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u1, max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.Functor.category.{u1, u1, u2, u2} A _inst_1 B _inst_2))) F G) (β : Quiver.Hom.{max (succ u2) (succ u1), max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u1, max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.Category.toCategoryStruct.{max u2 u1, max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.Functor.category.{u1, u1, u2, u2} C _inst_3 D _inst_4))) H I) (a : A), Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F H)) (Sum.inl.{u2, u2} A C a)) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 G I)) (Sum.inl.{u2, u2} A C a))) (CategoryTheory.NatTrans.app.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F H) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 G I) (CategoryTheory.NatTrans.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G H I α β) (Sum.inl.{u2, u2} A C a)) (CategoryTheory.NatTrans.app.{u1, u1, u2, u2} A _inst_1 B _inst_2 F G α a)
Case conversion may be inaccurate. Consider using '#align category_theory.nat_trans.sum_app_inl CategoryTheory.NatTrans.sum_app_inlₓ'. -/
@[simp]
theorem sum_app_inl {F G : A ⥤ B} {H I : C ⥤ D} (α : F ⟶ G) (β : H ⟶ I) (a : A) :
    (sum α β).app (inl a) = α.app a :=
  rfl
#align category_theory.nat_trans.sum_app_inl CategoryTheory.NatTrans.sum_app_inl

/- warning: category_theory.nat_trans.sum_app_inr -> CategoryTheory.NatTrans.sum_app_inr is a dubious translation:
lean 3 declaration is
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] {F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2} {G : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2} {H : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4} {I : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4} (α : Quiver.Hom.{succ (max u2 u1), max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u1, max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u1, max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.Functor.category.{u1, u1, u2, u2} A _inst_1 B _inst_2))) F G) (β : Quiver.Hom.{succ (max u2 u1), max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u1, max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.Category.toCategoryStruct.{max u2 u1, max u1 u2} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.Functor.category.{u1, u1, u2, u2} C _inst_3 D _inst_4))) H I) (c : C), Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F H) (Sum.inr.{u2, u2} A C c)) (CategoryTheory.Functor.obj.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 G I) (Sum.inr.{u2, u2} A C c))) (CategoryTheory.NatTrans.app.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F H) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 G I) (CategoryTheory.NatTrans.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G H I α β) (Sum.inr.{u2, u2} A C c)) (CategoryTheory.NatTrans.app.{u1, u1, u2, u2} C _inst_3 D _inst_4 H I β c)
but is expected to have type
  forall {A : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} A] {B : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} B] {C : Type.{u2}} [_inst_3 : CategoryTheory.Category.{u1, u2} C] {D : Type.{u2}} [_inst_4 : CategoryTheory.Category.{u1, u2} D] {F : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2} {G : CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2} {H : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4} {I : CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4} (α : Quiver.Hom.{max (succ u2) (succ u1), max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u1, max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.Category.toCategoryStruct.{max u2 u1, max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} A _inst_1 B _inst_2) (CategoryTheory.Functor.category.{u1, u1, u2, u2} A _inst_1 B _inst_2))) F G) (β : Quiver.Hom.{max (succ u2) (succ u1), max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.CategoryStruct.toQuiver.{max u2 u1, max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.Category.toCategoryStruct.{max u2 u1, max u2 u1} (CategoryTheory.Functor.{u1, u1, u2, u2} C _inst_3 D _inst_4) (CategoryTheory.Functor.category.{u1, u1, u2, u2} C _inst_3 D _inst_4))) H I) (c : C), Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F H)) (Sum.inr.{u2, u2} A C c)) (Prefunctor.obj.{succ u1, succ u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3))) (Sum.{u2, u2} B D) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 G I)) (Sum.inr.{u2, u2} A C c))) (CategoryTheory.NatTrans.app.{u1, u1, u2, u2} (Sum.{u2, u2} A C) (CategoryTheory.sum.{u1, u2} A _inst_1 C _inst_3) (Sum.{u2, u2} B D) (CategoryTheory.sum.{u1, u2} B _inst_2 D _inst_4) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F H) (CategoryTheory.Functor.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 G I) (CategoryTheory.NatTrans.sum.{u1, u2} A _inst_1 B _inst_2 C _inst_3 D _inst_4 F G H I α β) (Sum.inr.{u2, u2} A C c)) (CategoryTheory.NatTrans.app.{u1, u1, u2, u2} C _inst_3 D _inst_4 H I β c)
Case conversion may be inaccurate. Consider using '#align category_theory.nat_trans.sum_app_inr CategoryTheory.NatTrans.sum_app_inrₓ'. -/
@[simp]
theorem sum_app_inr {F G : A ⥤ B} {H I : C ⥤ D} (α : F ⟶ G) (β : H ⟶ I) (c : C) :
    (sum α β).app (inr c) = β.app c :=
  rfl
#align category_theory.nat_trans.sum_app_inr CategoryTheory.NatTrans.sum_app_inr

end NatTrans

end CategoryTheory


example : ∀ a b : nat, a = b → b = a :=
begin
  introv h,
  exact h.symm,
end

example : ∀ a b : nat, a = b → ∀ c, b = c → a = c :=
begin
  introv h₁ h₂,
  exact h₁.trans h₂,
end

example : ∀ a b : nat, a = b → b = a :=
begin
-- intros introduce a = b, but we want only variables, without hypotheses
  introv,
  intro h,
  exact h.symm,
end


/-
Copyright (c) 2019 Yury Kudryashov. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yury Kudryashov, Scott Morrison, Simon Hudon

Definition and basic properties of endomorphisms and automorphisms of an object in a category.
-/
import Mathlib.PrePort
import Mathlib.Lean3Lib.init.default
import Mathlib.category_theory.groupoid
import Mathlib.data.equiv.mul_add
import Mathlib.PostPort

universes v u u' v'

namespace Mathlib

namespace category_theory

/-- Endomorphisms of an object in a category. Arguments order in multiplication agrees with
`function.comp`, not with `category.comp`. -/
def End {C : Type u} [category_struct C] (X : C) :=
  X ⟶ X

namespace End

protected instance has_one {C : Type u} [category_struct C] (X : C) : HasOne (End X) :=
  { one := 𝟙 }

protected instance inhabited {C : Type u} [category_struct C] (X : C) : Inhabited (End X) :=
  { default := 𝟙 }

/-- Multiplication of endomorphisms agrees with `function.comp`, not `category_struct.comp`. -/
protected instance has_mul {C : Type u} [category_struct C] (X : C) : Mul (End X) :=
  { mul := fun (x y : End X) => y ≫ x }

@[simp] theorem one_def {C : Type u} [category_struct C] {X : C} : 1 = 𝟙 :=
  rfl

@[simp] theorem mul_def {C : Type u} [category_struct C] {X : C} (xs : End X) (ys : End X) : xs * ys = ys ≫ xs :=
  rfl

/-- Endomorphisms of an object form a monoid -/
protected instance monoid {C : Type u} [category C] {X : C} : monoid (End X) :=
  monoid.mk Mul.mul sorry 1 category.comp_id category.id_comp

/-- In a groupoid, endomorphisms form a group -/
protected instance group {C : Type u} [groupoid C] (X : C) : group (End X) :=
  group.mk monoid.mul sorry monoid.one sorry sorry groupoid.inv
    (div_inv_monoid.div._default monoid.mul sorry monoid.one sorry sorry groupoid.inv) groupoid.comp_inv

end End

/--
Automorphisms of an object in a category.

The order of arguments in multiplication agrees with
`function.comp`, not with `category.comp`.
-/
def Aut {C : Type u} [category C] (X : C) :=
  X ≅ X

namespace Aut

protected instance inhabited {C : Type u} [category C] (X : C) : Inhabited (Aut X) :=
  { default := iso.refl X }

protected instance group {C : Type u} [category C] (X : C) : group (Aut X) :=
  group.mk (flip iso.trans) sorry (iso.refl X) sorry sorry iso.symm
    (div_inv_monoid.div._default (flip iso.trans) sorry (iso.refl X) sorry sorry iso.symm) sorry

/--
Units in the monoid of endomorphisms of an object
are (multiplicatively) equivalent to automorphisms of that object.
-/
def units_End_equiv_Aut {C : Type u} [category C] (X : C) : units (End X) ≃* Aut X :=
  mul_equiv.mk (fun (f : units (End X)) => iso.mk (units.val f) (units.inv f))
    (fun (f : Aut X) => units.mk (iso.hom f) (iso.inv f) (iso.inv_hom_id' f) (iso.hom_inv_id' f)) sorry sorry sorry

end Aut

namespace functor

/-- `f.map` as a monoid hom between endomorphism monoids. -/
def map_End {C : Type u} [category C] (X : C) {D : Type u'} [category D] (f : C ⥤ D) : End X →* End (obj f X) :=
  monoid_hom.mk (map f) (map_id f X) sorry

/-- `f.map_iso` as a group hom between automorphism groups. -/
def map_Aut {C : Type u} [category C] (X : C) {D : Type u'} [category D] (f : C ⥤ D) : Aut X →* Aut (obj f X) :=
  monoid_hom.mk (map_iso f) (map_iso_refl f X) sorry


import HOLFloat.Common
import HOLFloat.Fixed
import Mathlib
import Aesop
--set_option pp.all true
@[aesop safe]
def is_valid_flformat (fmt : format): Prop :=
    1 < fmt.r
  ∧ fmt.r % 2 = 0
  ∧ 1 < fmt.p

@[aesop safe]
abbrev flformat : Type :=
  {fmt : format // is_valid_flformat fmt}

@[aesop safe]
def flformat.pnat : flformat → ℕ
| { val := { r := _, p := p, e := _}, property := _ } => p.toNat
  /-
  \ in an flformat, the 'p' is always > 0, and is thus
  a natural number
  -/

@[aesop safe, simp]
def is_frac_and_exp (fmt: flformat)(x : ℝ)(f : ℤ)(e : ℤ): Prop:=
  0 < f
  ∧ f < fmt.val.r  ^ fmt.pnat
  ∧ |x| = f * ((fmt.val.r ^ (e - fmt.pnat + 1)) : ℝ)

@[aesop safe, simp]
def is_float (fmt: flformat) (x : ℝ): Prop :=
  ∃(f: ℤ)(e : ℤ), is_frac_and_exp fmt x f e

@[simp]
theorem flformat_to_fformat {float : flformat} : is_valid_fformat float.val := by
  apply And.intro
  case left =>
    exact float.prop.left
  case right =>
    apply And.intro
    case left  =>
      exact float.prop.right.left
    case right =>
      apply Int.one_lt_zero_lt
      exact float.prop.right.right

@[aesop unsafe]
def to_fformat (fmt : flformat): fformat :=
  ⟨fmt.val, by simp [flformat_to_fformat]⟩

instance : Coe flformat fformat where
  coe fmt := to_fformat fmt

-- Normalization
@[aesop unsafe]
noncomputable def greatest_e (fmt : flformat) (x : ℝ): ℤ :=
  supₛ {z : ℤ | (fmt.val.r : ℝ) ^ z  ≤ |x|}

@[aesop unsafe]
noncomputable def greatest_m (fmt : flformat) (x : ℝ) : ℝ :=
  supₛ {m : ℝ | m * (fmt.val.r ^ greatest_e fmt x : ℝ) ≤ |x|}

@[aesop unsafe]
noncomputable def greatest_r ( fmt : flformat ) (x : ℝ) : ℝ :=
  if (0 ≤ x) then
    (x - greatest_m fmt x) * ((fmt.val.r) ^ (greatest_e fmt x) : ℝ)
  else
    (x + greatest_m fmt x) * ((fmt.val.r) ^ (greatest_e fmt x) : ℝ)

-- Rounding
--
@[aesop unsafe]
noncomputable def flround (fmt : flformat) (mode : roundmode)( x : Real) : Real :=
  let (m : ℝ) := greatest_m fmt x
  let (e : ℤ) := greatest_e fmt x
  let (r : ℝ) := greatest_r fmt x
  if (0 ≤ x) then
    m * (fmt.val.r ^ e : ℝ) + (fround (Coe.coe fmt) mode r)
  else
    - ((m * (fmt.val.r ^ e : ℝ)) + fround (Coe.coe fmt) mode r)

-- Machine Epsilon
--
-- fl_eps = r ^ (-p + 1) / 2
@[aesop unsafe]
def fl_eps (fmt : flformat) : ℤ :=
  fmt.val.r ^ (1 - fmt.pnat) / (2 : ℤ)