File: Mathlib/CategoryTheory/Products/Basic.lean

full_name: CategoryTheory.prod_comp_fst
code: /-- `prod C D` gives the cartesian product of two categories.

See <https://stacks.math.columbia.edu/tag/001K>.
-/
@[simps (config := { notRecursive := [] }) Hom id_fst id_snd comp_fst comp_snd]
instance prod : Category.{max v₁ v₂} (C × D) 
goal: ∀ {X Y Z : C × D} (f : X ⟶ Y) (g : Y ⟶ Z),
  (CategoryTheory.CategoryStruct.comp f g).1 = CategoryTheory.CategoryStruct.comp f.1 g.1

full_name: CategoryTheory.prod_id_snd
code: /-- `prod C D` gives the cartesian product of two categories.

See <https://stacks.math.columbia.edu/tag/001K>.
-/
@[simps (config := { notRecursive := [] }) Hom id_fst id_snd comp_fst comp_snd]
instance prod : Category.{max v₁ v₂} (C × D) 
goal: (CategoryTheory.CategoryStruct.id X).2 = CategoryTheory.CategoryStruct.id X.2

full_name: CategoryTheory.prod_Hom
code: /-- `prod C D` gives the cartesian product of two categories.

See <https://stacks.math.columbia.edu/tag/001K>.
-/
@[simps (config := { notRecursive := [] }) Hom id_fst id_snd comp_fst comp_snd]
instance prod : Category.{max v₁ v₂} (C × D) 
goal: (X ⟶ Y) = ((X.1 ⟶ Y.1) × (X.2 ⟶ Y.2))

full_name: CategoryTheory.prod
code: /-- `prod C D` gives the cartesian product of two categories.

See <https://stacks.math.columbia.edu/tag/001K>.
-/
@[simps (config := { notRecursive := [] }) Hom id_fst id_snd comp_fst comp_snd]
instance prod : Category.{max v₁ v₂} (C × D) 
goal: CategoryTheory.Category.{max v₁ v₂, max u₂ u₁} (C × D)

full_name: CategoryTheory.prod_comp_snd
code: /-- `prod C D` gives the cartesian product of two categories.

See <https://stacks.math.columbia.edu/tag/001K>.
-/
@[simps (config := { notRecursive := [] }) Hom id_fst id_snd comp_fst comp_snd]
instance prod : Category.{max v₁ v₂} (C × D) 
goal: ∀ {X Y Z : C × D} (f : X ⟶ Y) (g : Y ⟶ Z),
  (CategoryTheory.CategoryStruct.comp f g).2 = CategoryTheory.CategoryStruct.comp f.2 g.2

full_name: CategoryTheory.prod_id_fst
code: /-- `prod C D` gives the cartesian product of two categories.

See <https://stacks.math.columbia.edu/tag/001K>.
-/
@[simps (config := { notRecursive := [] }) Hom id_fst id_snd comp_fst comp_snd]
instance prod : Category.{max v₁ v₂} (C × D) 
goal: (CategoryTheory.CategoryStruct.id X).1 = CategoryTheory.CategoryStruct.id X.1

full_name: CategoryTheory.prod_id
code: /-- Two rfl lemmas that cannot be generated by `@[simps]`. -/
@[simp]
theorem prod_id (X : C) (Y : D) : 𝟙 (X, Y) = (𝟙 X, 𝟙 Y) 
goal: CategoryTheory.CategoryStruct.id (X, Y) = (CategoryTheory.CategoryStruct.id X, CategoryTheory.CategoryStruct.id Y)

full_name: CategoryTheory.prod_comp
code: @[simp]
theorem prod_comp {P Q R : C} {S T U : D} (f : (P, S) ⟶ (Q, T)) (g : (Q, T) ⟶ (R, U)) :
    f ≫ g = (f.1 ≫ g.1, f.2 ≫ g.2) 
goal: CategoryTheory.CategoryStruct.comp f g =
  (CategoryTheory.CategoryStruct.comp f.1 g.1, CategoryTheory.CategoryStruct.comp f.2 g.2)

full_name: CategoryTheory.isIso_prod_iff
code: theorem isIso_prod_iff {P Q : C} {S T : D} {f : (P, S) ⟶ (Q, T)} :
    IsIso f ↔ IsIso f.1 ∧ IsIso f.2 
goal: CategoryTheory.IsIso f ↔ CategoryTheory.IsIso f.1 ∧ CategoryTheory.IsIso f.2

full_name: CategoryTheory.prod.etaIso
code: /-- The isomorphism between `(X.1, X.2)` and `X`. -/
@[simps]
def prod.etaIso (X : C × D) : (X.1, X.2) ≅ X 
goal: (X.1, X.2) ≅ X

full_name: CategoryTheory.prod.etaIso_hom
code: /-- The isomorphism between `(X.1, X.2)` and `X`. -/
@[simps]
def prod.etaIso (X : C × D) : (X.1, X.2) ≅ X 
goal: (CategoryTheory.prod.etaIso X).hom =
  (CategoryTheory.CategoryStruct.id (X.1, X.2).1, CategoryTheory.CategoryStruct.id (X.1, X.2).2)

full_name: CategoryTheory.prod.etaIso_inv
code: /-- The isomorphism between `(X.1, X.2)` and `X`. -/
@[simps]
def prod.etaIso (X : C × D) : (X.1, X.2) ≅ X 
goal: (CategoryTheory.prod.etaIso X).inv = (CategoryTheory.CategoryStruct.id X.1, CategoryTheory.CategoryStruct.id X.2)

full_name: CategoryTheory.Iso.prod_hom
code: /-- Construct an isomorphism in `C × D` out of two isomorphisms in `C` and `D`. -/
@[simps]
def Iso.prod {P Q : C} {S T : D} (f : P ≅ Q) (g : S ≅ T) : (P, S) ≅ (Q, T) 
goal: (f.prod g).hom = (f.hom, g.hom)

full_name: CategoryTheory.Iso.prod_inv
code: /-- Construct an isomorphism in `C × D` out of two isomorphisms in `C` and `D`. -/
@[simps]
def Iso.prod {P Q : C} {S T : D} (f : P ≅ Q) (g : S ≅ T) : (P, S) ≅ (Q, T) 
goal: (f.prod g).inv = (f.inv, g.inv)

full_name: CategoryTheory.Iso.prod
code: /-- Construct an isomorphism in `C × D` out of two isomorphisms in `C` and `D`. -/
@[simps]
def Iso.prod {P Q : C} {S T : D} (f : P ≅ Q) (g : S ≅ T) : (P, S) ≅ (Q, T) 
goal: (P, S) ≅ (Q, T)

full_name: CategoryTheory.uniformProd
code: /-- `Category.uniformProd C D` is an additional instance specialised so both factors have the same
universe levels. This helps typeclass resolution.
-/
instance uniformProd : Category (C × D) 
goal: CategoryTheory.Category.{v₁, u₁} (C × D)

full_name: CategoryTheory.Prod.sectl
code: /-- `sectl C Z` is the functor `C ⥤ C × D` given by `X ↦ (X, Z)`. -/
@[simps]
def sectl (C : Type u₁) [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] (Z : D) : C ⥤ C × D 
goal: CategoryTheory.Functor C (C × D)

full_name: CategoryTheory.Prod.sectl_map
code: /-- `sectl C Z` is the functor `C ⥤ C × D` given by `X ↦ (X, Z)`. -/
@[simps]
def sectl (C : Type u₁) [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] (Z : D) : C ⥤ C × D 
goal: ∀ {X Y : C} (f : X ⟶ Y), (CategoryTheory.Prod.sectl C Z).map f = (f, CategoryTheory.CategoryStruct.id Z)

full_name: CategoryTheory.Prod.sectl_obj
code: /-- `sectl C Z` is the functor `C ⥤ C × D` given by `X ↦ (X, Z)`. -/
@[simps]
def sectl (C : Type u₁) [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D] (Z : D) : C ⥤ C × D 
goal: (CategoryTheory.Prod.sectl C Z).obj X = (X, Z)

full_name: CategoryTheory.Prod.sectr
code: /-- `sectr Z D` is the functor `D ⥤ C × D` given by `Y ↦ (Z, Y)` . -/
@[simps]
def sectr {C : Type u₁} [Category.{v₁} C] (Z : C) (D : Type u₂) [Category.{v₂} D] : D ⥤ C × D 
goal: CategoryTheory.Functor D (C × D)

full_name: CategoryTheory.Prod.sectr_obj
code: /-- `sectr Z D` is the functor `D ⥤ C × D` given by `Y ↦ (Z, Y)` . -/
@[simps]
def sectr {C : Type u₁} [Category.{v₁} C] (Z : C) (D : Type u₂) [Category.{v₂} D] : D ⥤ C × D 
goal: (CategoryTheory.Prod.sectr Z D).obj X = (Z, X)

full_name: CategoryTheory.Prod.sectr_map
code: /-- `sectr Z D` is the functor `D ⥤ C × D` given by `Y ↦ (Z, Y)` . -/
@[simps]
def sectr {C : Type u₁} [Category.{v₁} C] (Z : C) (D : Type u₂) [Category.{v₂} D] : D ⥤ C × D 
goal: ∀ {X Y : D} (f : X ⟶ Y), (CategoryTheory.Prod.sectr Z D).map f = (CategoryTheory.CategoryStruct.id Z, f)

full_name: CategoryTheory.Prod.fst_map
code: /-- `fst` is the functor `(X, Y) ↦ X`. -/
@[simps]
def fst : C × D ⥤ C 
goal: ∀ {X Y : C × D} (f : X ⟶ Y), (CategoryTheory.Prod.fst C D).map f = f.1

full_name: CategoryTheory.Prod.fst
code: /-- `fst` is the functor `(X, Y) ↦ X`. -/
@[simps]
def fst : C × D ⥤ C 
goal: CategoryTheory.Functor (C × D) C

full_name: CategoryTheory.Prod.fst_obj
code: /-- `fst` is the functor `(X, Y) ↦ X`. -/
@[simps]
def fst : C × D ⥤ C 
goal: (CategoryTheory.Prod.fst C D).obj X = X.1

full_name: CategoryTheory.Prod.snd
code: /-- `snd` is the functor `(X, Y) ↦ Y`. -/
@[simps]
def snd : C × D ⥤ D 
goal: CategoryTheory.Functor (C × D) D

full_name: CategoryTheory.Prod.snd_map
code: /-- `snd` is the functor `(X, Y) ↦ Y`. -/
@[simps]
def snd : C × D ⥤ D 
goal: ∀ {X Y : C × D} (f : X ⟶ Y), (CategoryTheory.Prod.snd C D).map f = f.2

full_name: CategoryTheory.Prod.snd_obj
code: /-- `snd` is the functor `(X, Y) ↦ Y`. -/
@[simps]
def snd : C × D ⥤ D 
goal: (CategoryTheory.Prod.snd C D).obj X = X.2

full_name: CategoryTheory.Prod.swap_obj
code: /-- The functor swapping the factors of a cartesian product of categories, `C × D ⥤ D × C`. -/
@[simps]
def swap : C × D ⥤ D × C 
goal: (CategoryTheory.Prod.swap C D).obj X = (X.2, X.1)

full_name: CategoryTheory.Prod.swap
code: /-- The functor swapping the factors of a cartesian product of categories, `C × D ⥤ D × C`. -/
@[simps]
def swap : C × D ⥤ D × C 
goal: CategoryTheory.Functor (C × D) (D × C)

full_name: CategoryTheory.Prod.swap_map
code: /-- The functor swapping the factors of a cartesian product of categories, `C × D ⥤ D × C`. -/
@[simps]
def swap : C × D ⥤ D × C 
goal: ∀ {X Y : C × D} (f : X ⟶ Y), (CategoryTheory.Prod.swap C D).map f = (f.2, f.1)

full_name: CategoryTheory.Prod.symmetry_hom_app
code: /-- Swapping the factors of a cartesian product of categories twice is naturally isomorphic
to the identity functor.
-/
@[simps]
def symmetry : swap C D ⋙ swap D C ≅ 𝟭 (C × D) 
goal: (CategoryTheory.Prod.symmetry C D).hom.app X = CategoryTheory.CategoryStruct.id X

full_name: CategoryTheory.Prod.symmetry_inv_app
code: /-- Swapping the factors of a cartesian product of categories twice is naturally isomorphic
to the identity functor.
-/
@[simps]
def symmetry : swap C D ⋙ swap D C ≅ 𝟭 (C × D) 
goal: (CategoryTheory.Prod.symmetry C D).inv.app X = CategoryTheory.CategoryStruct.id X

full_name: CategoryTheory.Prod.symmetry
code: /-- Swapping the factors of a cartesian product of categories twice is naturally isomorphic
to the identity functor.
-/
@[simps]
def symmetry : swap C D ⋙ swap D C ≅ 𝟭 (C × D) 
goal: (CategoryTheory.Prod.swap C D).comp (CategoryTheory.Prod.swap D C) ≅ CategoryTheory.Functor.id (C × D)

full_name: CategoryTheory.Prod.braiding
code: /-- The equivalence, given by swapping factors, between `C × D` and `D × C`.
-/
@[simps!]
def braiding : C × D ≌ D × C 
goal: C × D ≌ D × C

full_name: CategoryTheory.Prod.braiding_inverse_map
code: /-- The equivalence, given by swapping factors, between `C × D` and `D × C`.
-/
@[simps!]
def braiding : C × D ≌ D × C 
goal: ∀ {X Y : D × C} (f : X ⟶ Y), (CategoryTheory.Prod.braiding C D).inverse.map f = (f.2, f.1)

full_name: CategoryTheory.Prod.braiding_counitIso_hom_app
code: /-- The equivalence, given by swapping factors, between `C × D` and `D × C`.
-/
@[simps!]
def braiding : C × D ≌ D × C 
goal: (CategoryTheory.Prod.braiding C D).counitIso.hom.app X =
  (CategoryTheory.CategoryStruct.id X.1, CategoryTheory.CategoryStruct.id X.2)

full_name: CategoryTheory.Prod.braiding_unitIso_inv_app
code: /-- The equivalence, given by swapping factors, between `C × D` and `D × C`.
-/
@[simps!]
def braiding : C × D ≌ D × C 
goal: (CategoryTheory.Prod.braiding C D).unitIso.inv.app X =
  (CategoryTheory.CategoryStruct.id X.1, CategoryTheory.CategoryStruct.id X.2)

full_name: CategoryTheory.Prod.braiding_inverse_obj
code: /-- The equivalence, given by swapping factors, between `C × D` and `D × C`.
-/
@[simps!]
def braiding : C × D ≌ D × C 
goal: (CategoryTheory.Prod.braiding C D).inverse.obj X = (X.2, X.1)

full_name: CategoryTheory.Prod.braiding_counitIso_inv_app
code: /-- The equivalence, given by swapping factors, between `C × D` and `D × C`.
-/
@[simps!]
def braiding : C × D ≌ D × C 
goal: (CategoryTheory.Prod.braiding C D).counitIso.inv.app X =
  (CategoryTheory.CategoryStruct.id X.1, CategoryTheory.CategoryStruct.id X.2)

full_name: CategoryTheory.Prod.braiding_unitIso_hom_app
code: /-- The equivalence, given by swapping factors, between `C × D` and `D × C`.
-/
@[simps!]
def braiding : C × D ≌ D × C 
goal: (CategoryTheory.Prod.braiding C D).unitIso.hom.app X =
  (CategoryTheory.CategoryStruct.id X.1, CategoryTheory.CategoryStruct.id X.2)

full_name: CategoryTheory.Prod.braiding_functor_map
code: /-- The equivalence, given by swapping factors, between `C × D` and `D × C`.
-/
@[simps!]
def braiding : C × D ≌ D × C 
goal: ∀ {X Y : C × D} (f : X ⟶ Y), (CategoryTheory.Prod.braiding C D).functor.map f = (f.2, f.1)

full_name: CategoryTheory.Prod.braiding_functor_obj
code: /-- The equivalence, given by swapping factors, between `C × D` and `D × C`.
-/
@[simps!]
def braiding : C × D ≌ D × C 
goal: (CategoryTheory.Prod.braiding C D).functor.obj X = (X.2, X.1)

full_name: CategoryTheory.Prod.swapIsEquivalence
code: instance swapIsEquivalence : (swap C D).IsEquivalence 
goal: (CategoryTheory.Prod.swap C D).IsEquivalence

full_name: CategoryTheory.evaluation_map_app
code: /-- The "evaluation at `X`" functor, such that
`(evaluation.obj X).obj F = F.obj X`,
which is functorial in both `X` and `F`.
-/
@[simps]
def evaluation : C ⥤ (C ⥤ D) ⥤ D 
goal: ((CategoryTheory.evaluation C D).map f).app F = F.map f

full_name: CategoryTheory.evaluation_obj_map
code: /-- The "evaluation at `X`" functor, such that
`(evaluation.obj X).obj F = F.obj X`,
which is functorial in both `X` and `F`.
-/
@[simps]
def evaluation : C ⥤ (C ⥤ D) ⥤ D 
goal: ∀ {X_1 Y : CategoryTheory.Functor C D} (α : X_1 ⟶ Y), ((CategoryTheory.evaluation C D).obj X).map α = α.app X

full_name: CategoryTheory.evaluation_obj_obj
code: /-- The "evaluation at `X`" functor, such that
`(evaluation.obj X).obj F = F.obj X`,
which is functorial in both `X` and `F`.
-/
@[simps]
def evaluation : C ⥤ (C ⥤ D) ⥤ D 
goal: ((CategoryTheory.evaluation C D).obj X).obj F = F.obj X

full_name: CategoryTheory.evaluation
code: /-- The "evaluation at `X`" functor, such that
`(evaluation.obj X).obj F = F.obj X`,
which is functorial in both `X` and `F`.
-/
@[simps]
def evaluation : C ⥤ (C ⥤ D) ⥤ D 
goal: CategoryTheory.Functor C (CategoryTheory.Functor (CategoryTheory.Functor C D) D)

full_name: CategoryTheory.evaluationUncurried_map
code: /-- The "evaluation of `F` at `X`" functor,
as a functor `C × (C ⥤ D) ⥤ D`.
-/
@[simps]
def evaluationUncurried : C × (C ⥤ D) ⥤ D 
goal: (CategoryTheory.evaluationUncurried C D).map f = CategoryTheory.CategoryStruct.comp (x.2.map f.1) (f.2.app y.1)

full_name: CategoryTheory.evaluationUncurried_obj
code: /-- The "evaluation of `F` at `X`" functor,
as a functor `C × (C ⥤ D) ⥤ D`.
-/
@[simps]
def evaluationUncurried : C × (C ⥤ D) ⥤ D 
goal: (CategoryTheory.evaluationUncurried C D).obj p = p.2.obj p.1

full_name: CategoryTheory.evaluationUncurried
code: /-- The "evaluation of `F` at `X`" functor,
as a functor `C × (C ⥤ D) ⥤ D`.
-/
@[simps]
def evaluationUncurried : C × (C ⥤ D) ⥤ D 
goal: CategoryTheory.Functor (C × CategoryTheory.Functor C D) D

full_name: CategoryTheory.Functor.constCompEvaluationObj
code: /-- The constant functor followed by the evaluation functor is just the identity. -/
@[simps!]
def Functor.constCompEvaluationObj (X : C) : Functor.const C ⋙ (evaluation C D).obj X ≅ 𝟭 D 
goal: (CategoryTheory.Functor.const C).comp ((CategoryTheory.evaluation C D).obj X) ≅ CategoryTheory.Functor.id D

full_name: CategoryTheory.Functor.constCompEvaluationObj_hom_app
code: /-- The constant functor followed by the evaluation functor is just the identity. -/
@[simps!]
def Functor.constCompEvaluationObj (X : C) : Functor.const C ⋙ (evaluation C D).obj X ≅ 𝟭 D 
goal: ∀ (X_1 : D), (CategoryTheory.Functor.constCompEvaluationObj D X).hom.app X_1 = CategoryTheory.CategoryStruct.id X_1

full_name: CategoryTheory.Functor.constCompEvaluationObj_inv_app
code: /-- The constant functor followed by the evaluation functor is just the identity. -/
@[simps!]
def Functor.constCompEvaluationObj (X : C) : Functor.const C ⋙ (evaluation C D).obj X ≅ 𝟭 D 
goal: ∀ (X_1 : D), (CategoryTheory.Functor.constCompEvaluationObj D X).inv.app X_1 = CategoryTheory.CategoryStruct.id X_1

full_name: CategoryTheory.Functor.prod_obj
code: /-- The cartesian product of two functors. -/
@[simps]
def prod (F : A ⥤ B) (G : C ⥤ D) : A × C ⥤ B × D 
goal: (F.prod G).obj X = (F.obj X.1, G.obj X.2)

full_name: CategoryTheory.Functor.prod
code: /-- The cartesian product of two functors. -/
@[simps]
def prod (F : A ⥤ B) (G : C ⥤ D) : A × C ⥤ B × D 
goal: CategoryTheory.Functor (A × C) (B × D)

full_name: CategoryTheory.Functor.prod_map
code: /-- The cartesian product of two functors. -/
@[simps]
def prod (F : A ⥤ B) (G : C ⥤ D) : A × C ⥤ B × D 
goal: ∀ {X Y : A × C} (f : X ⟶ Y), (F.prod G).map f = (F.map f.1, G.map f.2)

full_name: CategoryTheory.Functor.prod'_map
code: /-- Similar to `prod`, but both functors start from the same category `A` -/
@[simps]
def prod' (F : A ⥤ B) (G : A ⥤ C) : A ⥤ B × C 
goal: ∀ {X Y : A} (f : X ⟶ Y), (F.prod' G).map f = (F.map f, G.map f)

full_name: CategoryTheory.Functor.prod'
code: /-- Similar to `prod`, but both functors start from the same category `A` -/
@[simps]
def prod' (F : A ⥤ B) (G : A ⥤ C) : A ⥤ B × C 
goal: CategoryTheory.Functor A (B × C)

full_name: CategoryTheory.Functor.prod'_obj
code: /-- Similar to `prod`, but both functors start from the same category `A` -/
@[simps]
def prod' (F : A ⥤ B) (G : A ⥤ C) : A ⥤ B × C 
goal: (F.prod' G).obj a = (F.obj a, G.obj a)

full_name: CategoryTheory.Functor.prod'CompFst_hom_app
code: /-- The product `F.prod' G` followed by projection on the first component is isomorphic to `F` -/
@[simps!]
def prod'CompFst (F : A ⥤ B) (G : A ⥤ C) : F.prod' G ⋙ CategoryTheory.Prod.fst B C ≅ F 
goal: (F.prod'CompFst G).hom.app X = CategoryTheory.CategoryStruct.id (F.obj X)

full_name: CategoryTheory.Functor.prod'CompFst_inv_app
code: /-- The product `F.prod' G` followed by projection on the first component is isomorphic to `F` -/
@[simps!]
def prod'CompFst (F : A ⥤ B) (G : A ⥤ C) : F.prod' G ⋙ CategoryTheory.Prod.fst B C ≅ F 
goal: (F.prod'CompFst G).inv.app X = CategoryTheory.CategoryStruct.id (F.obj X)

full_name: CategoryTheory.Functor.prod'CompFst
code: /-- The product `F.prod' G` followed by projection on the first component is isomorphic to `F` -/
@[simps!]
def prod'CompFst (F : A ⥤ B) (G : A ⥤ C) : F.prod' G ⋙ CategoryTheory.Prod.fst B C ≅ F 
goal: (F.prod' G).comp (CategoryTheory.Prod.fst B C) ≅ F

full_name: CategoryTheory.Functor.prod'CompSnd
code: /-- The product `F.prod' G` followed by projection on the second component is isomorphic to `G` -/
@[simps!]
def prod'CompSnd (F : A ⥤ B) (G : A ⥤ C) : F.prod' G ⋙ CategoryTheory.Prod.snd B C ≅ G 
goal: (F.prod' G).comp (CategoryTheory.Prod.snd B C) ≅ G

full_name: CategoryTheory.Functor.prod'CompSnd_hom_app
code: /-- The product `F.prod' G` followed by projection on the second component is isomorphic to `G` -/
@[simps!]
def prod'CompSnd (F : A ⥤ B) (G : A ⥤ C) : F.prod' G ⋙ CategoryTheory.Prod.snd B C ≅ G 
goal: (F.prod'CompSnd G).hom.app X = CategoryTheory.CategoryStruct.id (G.obj X)

full_name: CategoryTheory.Functor.prod'CompSnd_inv_app
code: /-- The product `F.prod' G` followed by projection on the second component is isomorphic to `G` -/
@[simps!]
def prod'CompSnd (F : A ⥤ B) (G : A ⥤ C) : F.prod' G ⋙ CategoryTheory.Prod.snd B C ≅ G 
goal: (F.prod'CompSnd G).inv.app X = CategoryTheory.CategoryStruct.id (G.obj X)

full_name: CategoryTheory.Functor.diag
code: /-- The diagonal functor. -/
def diag : C ⥤ C × C 
goal: CategoryTheory.Functor C (C × C)

full_name: CategoryTheory.Functor.diag_obj
code: @[simp]
theorem diag_obj (X : C) : (diag C).obj X = (X, X) 
goal: (CategoryTheory.Functor.diag C).obj X = (X, X)

full_name: CategoryTheory.Functor.diag_map
code: @[simp]
theorem diag_map {X Y : C} (f : X ⟶ Y) : (diag C).map f = (f, f) 
goal: (CategoryTheory.Functor.diag C).map f = (f, f)

full_name: CategoryTheory.NatTrans.prod
code: /-- The cartesian product of two natural transformations. -/
@[simps]
def prod {F G : A ⥤ B} {H I : C ⥤ D} (α : F ⟶ G) (β : H ⟶ I) : F.prod H ⟶ G.prod I 
goal: F.prod H ⟶ G.prod I

full_name: CategoryTheory.NatTrans.prod_app
code: /-- The cartesian product of two natural transformations. -/
@[simps]
def prod {F G : A ⥤ B} {H I : C ⥤ D} (α : F ⟶ G) (β : H ⟶ I) : F.prod H ⟶ G.prod I 
goal: (CategoryTheory.NatTrans.prod α β).app X = (α.app X.1, β.app X.2)

full_name: CategoryTheory.NatIso.prod
code: /-- The cartesian product of two natural isomorphisms. -/
@[simps]
def prod {F F' : A ⥤ B} {G G' : C ⥤ D} (e₁ : F ≅ F') (e₂ : G ≅ G') :
    F.prod G ≅ F'.prod G' 
goal: F.prod G ≅ F'.prod G'

full_name: CategoryTheory.NatIso.prod_hom
code: /-- The cartesian product of two natural isomorphisms. -/
@[simps]
def prod {F F' : A ⥤ B} {G G' : C ⥤ D} (e₁ : F ≅ F') (e₂ : G ≅ G') :
    F.prod G ≅ F'.prod G' 
goal: (CategoryTheory.NatIso.prod e₁ e₂).hom = CategoryTheory.NatTrans.prod e₁.hom e₂.hom

full_name: CategoryTheory.NatIso.prod_inv
code: /-- The cartesian product of two natural isomorphisms. -/
@[simps]
def prod {F F' : A ⥤ B} {G G' : C ⥤ D} (e₁ : F ≅ F') (e₂ : G ≅ G') :
    F.prod G ≅ F'.prod G' 
goal: (CategoryTheory.NatIso.prod e₁ e₂).inv = CategoryTheory.NatTrans.prod e₁.inv e₂.inv

full_name: CategoryTheory.Equivalence.prod
code: /-- The cartesian product of two equivalences of categories. -/
@[simps]
def prod (E₁ : A ≌ B) (E₂ : C ≌ D) : A × C ≌ B × D 
goal: A × C ≌ B × D

full_name: CategoryTheory.Equivalence.prod_functor
code: /-- The cartesian product of two equivalences of categories. -/
@[simps]
def prod (E₁ : A ≌ B) (E₂ : C ≌ D) : A × C ≌ B × D 
goal: (E₁.prod E₂).functor = E₁.functor.prod E₂.functor

full_name: CategoryTheory.Equivalence.prod_unitIso
code: /-- The cartesian product of two equivalences of categories. -/
@[simps]
def prod (E₁ : A ≌ B) (E₂ : C ≌ D) : A × C ≌ B × D 
goal: (E₁.prod E₂).unitIso = CategoryTheory.NatIso.prod E₁.unitIso E₂.unitIso

full_name: CategoryTheory.Equivalence.prod_inverse
code: /-- The cartesian product of two equivalences of categories. -/
@[simps]
def prod (E₁ : A ≌ B) (E₂ : C ≌ D) : A × C ≌ B × D 
goal: (E₁.prod E₂).inverse = E₁.inverse.prod E₂.inverse

full_name: CategoryTheory.Equivalence.prod_counitIso
code: /-- The cartesian product of two equivalences of categories. -/
@[simps]
def prod (E₁ : A ≌ B) (E₂ : C ≌ D) : A × C ≌ B × D 
goal: (E₁.prod E₂).counitIso = CategoryTheory.NatIso.prod E₁.counitIso E₂.counitIso

full_name: CategoryTheory.flipCompEvaluation_hom_app
code: /-- `F.flip` composed with evaluation is the same as evaluating `F`. -/
@[simps!]
def flipCompEvaluation (F : A ⥤ B ⥤ C) (a) : F.flip ⋙ (evaluation _ _).obj a ≅ F.obj a 
goal: (CategoryTheory.flipCompEvaluation F a).hom.app X = CategoryTheory.CategoryStruct.id ((F.obj a).obj X)

full_name: CategoryTheory.flipCompEvaluation
code: /-- `F.flip` composed with evaluation is the same as evaluating `F`. -/
@[simps!]
def flipCompEvaluation (F : A ⥤ B ⥤ C) (a) : F.flip ⋙ (evaluation _ _).obj a ≅ F.obj a 
goal: F.flip.comp ((CategoryTheory.evaluation A C).obj a) ≅ F.obj a

full_name: CategoryTheory.flipCompEvaluation_inv_app
code: /-- `F.flip` composed with evaluation is the same as evaluating `F`. -/
@[simps!]
def flipCompEvaluation (F : A ⥤ B ⥤ C) (a) : F.flip ⋙ (evaluation _ _).obj a ≅ F.obj a 
goal: (CategoryTheory.flipCompEvaluation F a).inv.app X = CategoryTheory.CategoryStruct.id ((F.obj a).obj X)

full_name: CategoryTheory.prodFunctorToFunctorProd_map_app
code: /-- The forward direction for `functorProdFunctorEquiv` -/
@[simps]
def prodFunctorToFunctorProd : (A ⥤ B) × (A ⥤ C) ⥤ A ⥤ B × C 
goal: ∀ {X Y : CategoryTheory.Functor A B × CategoryTheory.Functor A C} (f : X ⟶ Y) (X_1 : A),
  ((CategoryTheory.prodFunctorToFunctorProd A B C).map f).app X_1 = (f.1.app X_1, f.2.app X_1)

full_name: CategoryTheory.prodFunctorToFunctorProd_obj
code: /-- The forward direction for `functorProdFunctorEquiv` -/
@[simps]
def prodFunctorToFunctorProd : (A ⥤ B) × (A ⥤ C) ⥤ A ⥤ B × C 
goal: (CategoryTheory.prodFunctorToFunctorProd A B C).obj F = F.1.prod' F.2

full_name: CategoryTheory.prodFunctorToFunctorProd
code: /-- The forward direction for `functorProdFunctorEquiv` -/
@[simps]
def prodFunctorToFunctorProd : (A ⥤ B) × (A ⥤ C) ⥤ A ⥤ B × C 
goal: CategoryTheory.Functor (CategoryTheory.Functor A B × CategoryTheory.Functor A C) (CategoryTheory.Functor A (B × C))

full_name: CategoryTheory.functorProdToProdFunctor_map
code: /-- The backward direction for `functorProdFunctorEquiv` -/
@[simps]
def functorProdToProdFunctor : (A ⥤ B × C) ⥤ (A ⥤ B) × (A ⥤ C) 
goal: ∀ {X Y : CategoryTheory.Functor A (B × C)} (α : X ⟶ Y),
  (CategoryTheory.functorProdToProdFunctor A B C).map α =
    ({ app := fun X_1 => (α.app X_1).1, naturality := ⋯ }, { app := fun X_1 => (α.app X_1).2, naturality := ⋯ })

full_name: CategoryTheory.functorProdToProdFunctor_obj
code: /-- The backward direction for `functorProdFunctorEquiv` -/
@[simps]
def functorProdToProdFunctor : (A ⥤ B × C) ⥤ (A ⥤ B) × (A ⥤ C) 
goal: (CategoryTheory.functorProdToProdFunctor A B C).obj F =
  (F.comp (CategoryTheory.Prod.fst B C), F.comp (CategoryTheory.Prod.snd B C))

full_name: CategoryTheory.functorProdToProdFunctor
code: /-- The backward direction for `functorProdFunctorEquiv` -/
@[simps]
def functorProdToProdFunctor : (A ⥤ B × C) ⥤ (A ⥤ B) × (A ⥤ C) 
goal: CategoryTheory.Functor (CategoryTheory.Functor A (B × C)) (CategoryTheory.Functor A B × CategoryTheory.Functor A C)

full_name: CategoryTheory.functorProdFunctorEquivUnitIso_inv_app
code: /-- The unit isomorphism for `functorProdFunctorEquiv` -/
@[simps!]
def functorProdFunctorEquivUnitIso :
    𝟭 _ ≅ prodFunctorToFunctorProd A B C ⋙ functorProdToProdFunctor A B C 
goal: (CategoryTheory.functorProdFunctorEquivUnitIso A B C).inv.app X =
  ((X.1.prod'CompFst X.2).hom, (X.1.prod'CompSnd X.2).hom)

full_name: CategoryTheory.functorProdFunctorEquivUnitIso_hom_app
code: /-- The unit isomorphism for `functorProdFunctorEquiv` -/
@[simps!]
def functorProdFunctorEquivUnitIso :
    𝟭 _ ≅ prodFunctorToFunctorProd A B C ⋙ functorProdToProdFunctor A B C 
goal: (CategoryTheory.functorProdFunctorEquivUnitIso A B C).hom.app X =
  ((X.1.prod'CompFst X.2).inv, (X.1.prod'CompSnd X.2).inv)

full_name: CategoryTheory.functorProdFunctorEquivUnitIso
code: /-- The unit isomorphism for `functorProdFunctorEquiv` -/
@[simps!]
def functorProdFunctorEquivUnitIso :
    𝟭 _ ≅ prodFunctorToFunctorProd A B C ⋙ functorProdToProdFunctor A B C 
goal: CategoryTheory.Functor.id (CategoryTheory.Functor A B × CategoryTheory.Functor A C) ≅
  (CategoryTheory.prodFunctorToFunctorProd A B C).comp (CategoryTheory.functorProdToProdFunctor A B C)

full_name: CategoryTheory.functorProdFunctorEquivCounitIso
code: /-- The counit isomorphism for `functorProdFunctorEquiv` -/
@[simps!]
def functorProdFunctorEquivCounitIso :
    functorProdToProdFunctor A B C ⋙ prodFunctorToFunctorProd A B C ≅ 𝟭 _ 
goal: (CategoryTheory.functorProdToProdFunctor A B C).comp (CategoryTheory.prodFunctorToFunctorProd A B C) ≅
  CategoryTheory.Functor.id (CategoryTheory.Functor A (B × C))

full_name: CategoryTheory.functorProdFunctorEquivCounitIso_hom_app_app
code: /-- The counit isomorphism for `functorProdFunctorEquiv` -/
@[simps!]
def functorProdFunctorEquivCounitIso :
    functorProdToProdFunctor A B C ⋙ prodFunctorToFunctorProd A B C ≅ 𝟭 _ 
goal: ∀ (X_1 : A),
  ((CategoryTheory.functorProdFunctorEquivCounitIso A B C).hom.app X).app X_1 =
    (CategoryTheory.CategoryStruct.id (X.obj X_1).1, CategoryTheory.CategoryStruct.id (X.obj X_1).2)

full_name: CategoryTheory.functorProdFunctorEquivCounitIso_inv_app_app
code: /-- The counit isomorphism for `functorProdFunctorEquiv` -/
@[simps!]
def functorProdFunctorEquivCounitIso :
    functorProdToProdFunctor A B C ⋙ prodFunctorToFunctorProd A B C ≅ 𝟭 _ 
goal: ∀ (X_1 : A),
  ((CategoryTheory.functorProdFunctorEquivCounitIso A B C).inv.app X).app X_1 =
    (CategoryTheory.CategoryStruct.id (X.obj X_1).1, CategoryTheory.CategoryStruct.id (X.obj X_1).2)

full_name: CategoryTheory.functorProdFunctorEquiv_functor
code: /-- The equivalence of categories between `(A ⥤ B) × (A ⥤ C)` and `A ⥤ (B × C)` -/
@[simps]
def functorProdFunctorEquiv : (A ⥤ B) × (A ⥤ C) ≌ A ⥤ B × C 
goal: (CategoryTheory.functorProdFunctorEquiv A B C).functor = CategoryTheory.prodFunctorToFunctorProd A B C

full_name: CategoryTheory.functorProdFunctorEquiv_unitIso
code: /-- The equivalence of categories between `(A ⥤ B) × (A ⥤ C)` and `A ⥤ (B × C)` -/
@[simps]
def functorProdFunctorEquiv : (A ⥤ B) × (A ⥤ C) ≌ A ⥤ B × C 
goal: (CategoryTheory.functorProdFunctorEquiv A B C).unitIso = CategoryTheory.functorProdFunctorEquivUnitIso A B C

full_name: CategoryTheory.functorProdFunctorEquiv
code: /-- The equivalence of categories between `(A ⥤ B) × (A ⥤ C)` and `A ⥤ (B × C)` -/
@[simps]
def functorProdFunctorEquiv : (A ⥤ B) × (A ⥤ C) ≌ A ⥤ B × C 
goal: CategoryTheory.Functor A B × CategoryTheory.Functor A C ≌ CategoryTheory.Functor A (B × C)

full_name: CategoryTheory.functorProdFunctorEquiv_counitIso
code: /-- The equivalence of categories between `(A ⥤ B) × (A ⥤ C)` and `A ⥤ (B × C)` -/
@[simps]
def functorProdFunctorEquiv : (A ⥤ B) × (A ⥤ C) ≌ A ⥤ B × C 
goal: (CategoryTheory.functorProdFunctorEquiv A B C).counitIso = CategoryTheory.functorProdFunctorEquivCounitIso A B C

full_name: CategoryTheory.functorProdFunctorEquiv_inverse
code: /-- The equivalence of categories between `(A ⥤ B) × (A ⥤ C)` and `A ⥤ (B × C)` -/
@[simps]
def functorProdFunctorEquiv : (A ⥤ B) × (A ⥤ C) ≌ A ⥤ B × C 
goal: (CategoryTheory.functorProdFunctorEquiv A B C).inverse = CategoryTheory.functorProdToProdFunctor A B C

full_name: CategoryTheory.prodOpEquiv_inverse_obj
code: /-- The equivalence between the opposite of a product and the product of the opposites. -/
@[simps]
def prodOpEquiv : (C × D)ᵒᵖ ≌ Cᵒᵖ × Dᵒᵖ 
goal: ∀ (x : Cᵒᵖ × Dᵒᵖ),
  (CategoryTheory.prodOpEquiv C).inverse.obj x =
    match x with
    | (X, Y) => Opposite.op (Opposite.unop X, Opposite.unop Y)

full_name: CategoryTheory.prodOpEquiv_functor_obj
code: /-- The equivalence between the opposite of a product and the product of the opposites. -/
@[simps]
def prodOpEquiv : (C × D)ᵒᵖ ≌ Cᵒᵖ × Dᵒᵖ 
goal: (CategoryTheory.prodOpEquiv C).functor.obj X = (Opposite.op (Opposite.unop X).1, Opposite.op (Opposite.unop X).2)

full_name: CategoryTheory.prodOpEquiv_functor_map
code: /-- The equivalence between the opposite of a product and the product of the opposites. -/
@[simps]
def prodOpEquiv : (C × D)ᵒᵖ ≌ Cᵒᵖ × Dᵒᵖ 
goal: ∀ {X Y : (C × D)ᵒᵖ} (f : X ⟶ Y), (CategoryTheory.prodOpEquiv C).functor.map f = (f.unop.1.op, f.unop.2.op)

full_name: CategoryTheory.prodOpEquiv_unitIso
code: /-- The equivalence between the opposite of a product and the product of the opposites. -/
@[simps]
def prodOpEquiv : (C × D)ᵒᵖ ≌ Cᵒᵖ × Dᵒᵖ 
goal: (CategoryTheory.prodOpEquiv C).unitIso = CategoryTheory.Iso.refl (CategoryTheory.Functor.id (C × D)ᵒᵖ)

full_name: CategoryTheory.prodOpEquiv_inverse_map
code: /-- The equivalence between the opposite of a product and the product of the opposites. -/
@[simps]
def prodOpEquiv : (C × D)ᵒᵖ ≌ Cᵒᵖ × Dᵒᵖ 
goal: ∀ {X Y : Cᵒᵖ × Dᵒᵖ} (x : X ⟶ Y),
  (CategoryTheory.prodOpEquiv C).inverse.map x =
    match x with
    | (f, g) => Opposite.op (f.unop, g.unop)

full_name: CategoryTheory.prodOpEquiv_counitIso
code: /-- The equivalence between the opposite of a product and the product of the opposites. -/
@[simps]
def prodOpEquiv : (C × D)ᵒᵖ ≌ Cᵒᵖ × Dᵒᵖ 
goal: (CategoryTheory.prodOpEquiv C).counitIso =
  CategoryTheory.Iso.refl
    ({
          obj := fun x =>
            match x with
            | (X, Y) => Opposite.op (Opposite.unop X, Opposite.unop Y),
          map := fun {X Y} x =>
            match x with
            | (f, g) => Opposite.op (f.unop, g.unop),
          map_id := ⋯, map_comp := ⋯ }.comp
      { obj := fun X => (Opposite.op (Opposite.unop X).1, Opposite.op (Opposite.unop X).2),
        map := fun {X Y} f => (f.unop.1.op, f.unop.2.op), map_id := ⋯, map_comp := ⋯ })

full_name: CategoryTheory.prodOpEquiv
code: /-- The equivalence between the opposite of a product and the product of the opposites. -/
@[simps]
def prodOpEquiv : (C × D)ᵒᵖ ≌ Cᵒᵖ × Dᵒᵖ 
goal: (C × D)ᵒᵖ ≌ Cᵒᵖ × Dᵒᵖ