File: Mathlib/CategoryTheory/Adjunction/Basic.lean

full_name: CategoryTheory.Adjunction
code: /-- `F ⊣ G` represents the data of an adjunction between two functors
`F : C ⥤ D` and `G : D ⥤ C`. `F` is the left adjoint and `G` is the right adjoint.

To construct an `adjunction` between two functors, it's often easier to instead use the
constructors `mkOfHomEquiv` or `mkOfUnitCounit`. To construct a left adjoint,
there are also constructors `leftAdjointOfEquiv` and `adjunctionOfEquivLeft` (as
well as their duals) which can be simpler in practice.

Uniqueness of adjoints is shown in `CategoryTheory.Adjunction.Opposites`.

See <https://stacks.math.columbia.edu/tag/0037>.
-/
structure Adjunction (F : C ⥤ D) (G : D ⥤ C) where
  /-- The equivalence between `Hom (F X) Y` and `Hom X (G Y)` coming from an adjunction -/
  homEquiv : ∀ X Y, (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)
  /-- The unit of an adjunction -/
  unit : 𝟭 C ⟶ F.comp G
  /-- The counit of an adjunction -/
  counit : G.comp F ⟶ 𝟭 D
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the unit of an adjunction -/
  homEquiv_unit : ∀ {X Y f}, (homEquiv X Y) f = (unit : _ ⟶ _).app X ≫ G.map f := by aesop_cat
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the counit of an adjunction -/
  homEquiv_counit : ∀ {X Y g}, (homEquiv X Y).symm g = F.map g ≫ counit.app Y := by aesop_cat
goal: Type (max (max (max u₁ u₂) v₁) v₂)

full_name: CategoryTheory.Adjunction.unit
code: /-- `F ⊣ G` represents the data of an adjunction between two functors
`F : C ⥤ D` and `G : D ⥤ C`. `F` is the left adjoint and `G` is the right adjoint.

To construct an `adjunction` between two functors, it's often easier to instead use the
constructors `mkOfHomEquiv` or `mkOfUnitCounit`. To construct a left adjoint,
there are also constructors `leftAdjointOfEquiv` and `adjunctionOfEquivLeft` (as
well as their duals) which can be simpler in practice.

Uniqueness of adjoints is shown in `CategoryTheory.Adjunction.Opposites`.

See <https://stacks.math.columbia.edu/tag/0037>.
-/
structure Adjunction (F : C ⥤ D) (G : D ⥤ C) where
  /-- The equivalence between `Hom (F X) Y` and `Hom X (G Y)` coming from an adjunction -/
  homEquiv : ∀ X Y, (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)
  /-- The unit of an adjunction -/
  unit : 𝟭 C ⟶ F.comp G
  /-- The counit of an adjunction -/
  counit : G.comp F ⟶ 𝟭 D
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the unit of an adjunction -/
  homEquiv_unit : ∀ {X Y f}, (homEquiv X Y) f = (unit : _ ⟶ _).app X ≫ G.map f := by aesop_cat
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the counit of an adjunction -/
  homEquiv_counit : ∀ {X Y g}, (homEquiv X Y).symm g = F.map g ≫ counit.app Y := by aesop_cat
goal: CategoryTheory.Functor.id C ⟶ F.comp G

full_name: CategoryTheory.Adjunction.homEquiv_counit
code: /-- `F ⊣ G` represents the data of an adjunction between two functors
`F : C ⥤ D` and `G : D ⥤ C`. `F` is the left adjoint and `G` is the right adjoint.

To construct an `adjunction` between two functors, it's often easier to instead use the
constructors `mkOfHomEquiv` or `mkOfUnitCounit`. To construct a left adjoint,
there are also constructors `leftAdjointOfEquiv` and `adjunctionOfEquivLeft` (as
well as their duals) which can be simpler in practice.

Uniqueness of adjoints is shown in `CategoryTheory.Adjunction.Opposites`.

See <https://stacks.math.columbia.edu/tag/0037>.
-/
structure Adjunction (F : C ⥤ D) (G : D ⥤ C) where
  /-- The equivalence between `Hom (F X) Y` and `Hom X (G Y)` coming from an adjunction -/
  homEquiv : ∀ X Y, (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)
  /-- The unit of an adjunction -/
  unit : 𝟭 C ⟶ F.comp G
  /-- The counit of an adjunction -/
  counit : G.comp F ⟶ 𝟭 D
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the unit of an adjunction -/
  homEquiv_unit : ∀ {X Y f}, (homEquiv X Y) f = (unit : _ ⟶ _).app X ≫ G.map f := by aesop_cat
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the counit of an adjunction -/
  homEquiv_counit : ∀ {X Y g}, (homEquiv X Y).symm g = F.map g ≫ counit.app Y := by aesop_cat
goal: (self.homEquiv X Y).symm g = CategoryTheory.CategoryStruct.comp (F.map g) (self.counit.app Y)

full_name: CategoryTheory.Adjunction.counit
code: /-- `F ⊣ G` represents the data of an adjunction between two functors
`F : C ⥤ D` and `G : D ⥤ C`. `F` is the left adjoint and `G` is the right adjoint.

To construct an `adjunction` between two functors, it's often easier to instead use the
constructors `mkOfHomEquiv` or `mkOfUnitCounit`. To construct a left adjoint,
there are also constructors `leftAdjointOfEquiv` and `adjunctionOfEquivLeft` (as
well as their duals) which can be simpler in practice.

Uniqueness of adjoints is shown in `CategoryTheory.Adjunction.Opposites`.

See <https://stacks.math.columbia.edu/tag/0037>.
-/
structure Adjunction (F : C ⥤ D) (G : D ⥤ C) where
  /-- The equivalence between `Hom (F X) Y` and `Hom X (G Y)` coming from an adjunction -/
  homEquiv : ∀ X Y, (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)
  /-- The unit of an adjunction -/
  unit : 𝟭 C ⟶ F.comp G
  /-- The counit of an adjunction -/
  counit : G.comp F ⟶ 𝟭 D
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the unit of an adjunction -/
  homEquiv_unit : ∀ {X Y f}, (homEquiv X Y) f = (unit : _ ⟶ _).app X ≫ G.map f := by aesop_cat
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the counit of an adjunction -/
  homEquiv_counit : ∀ {X Y g}, (homEquiv X Y).symm g = F.map g ≫ counit.app Y := by aesop_cat
goal: G.comp F ⟶ CategoryTheory.Functor.id D

full_name: CategoryTheory.Adjunction.homEquiv_unit
code: /-- `F ⊣ G` represents the data of an adjunction between two functors
`F : C ⥤ D` and `G : D ⥤ C`. `F` is the left adjoint and `G` is the right adjoint.

To construct an `adjunction` between two functors, it's often easier to instead use the
constructors `mkOfHomEquiv` or `mkOfUnitCounit`. To construct a left adjoint,
there are also constructors `leftAdjointOfEquiv` and `adjunctionOfEquivLeft` (as
well as their duals) which can be simpler in practice.

Uniqueness of adjoints is shown in `CategoryTheory.Adjunction.Opposites`.

See <https://stacks.math.columbia.edu/tag/0037>.
-/
structure Adjunction (F : C ⥤ D) (G : D ⥤ C) where
  /-- The equivalence between `Hom (F X) Y` and `Hom X (G Y)` coming from an adjunction -/
  homEquiv : ∀ X Y, (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)
  /-- The unit of an adjunction -/
  unit : 𝟭 C ⟶ F.comp G
  /-- The counit of an adjunction -/
  counit : G.comp F ⟶ 𝟭 D
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the unit of an adjunction -/
  homEquiv_unit : ∀ {X Y f}, (homEquiv X Y) f = (unit : _ ⟶ _).app X ≫ G.map f := by aesop_cat
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the counit of an adjunction -/
  homEquiv_counit : ∀ {X Y g}, (homEquiv X Y).symm g = F.map g ≫ counit.app Y := by aesop_cat
goal: (self.homEquiv X Y) f = CategoryTheory.CategoryStruct.comp (self.unit.app X) (G.map f)

full_name: CategoryTheory.Adjunction.homEquiv
code: /-- `F ⊣ G` represents the data of an adjunction between two functors
`F : C ⥤ D` and `G : D ⥤ C`. `F` is the left adjoint and `G` is the right adjoint.

To construct an `adjunction` between two functors, it's often easier to instead use the
constructors `mkOfHomEquiv` or `mkOfUnitCounit`. To construct a left adjoint,
there are also constructors `leftAdjointOfEquiv` and `adjunctionOfEquivLeft` (as
well as their duals) which can be simpler in practice.

Uniqueness of adjoints is shown in `CategoryTheory.Adjunction.Opposites`.

See <https://stacks.math.columbia.edu/tag/0037>.
-/
structure Adjunction (F : C ⥤ D) (G : D ⥤ C) where
  /-- The equivalence between `Hom (F X) Y` and `Hom X (G Y)` coming from an adjunction -/
  homEquiv : ∀ X Y, (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)
  /-- The unit of an adjunction -/
  unit : 𝟭 C ⟶ F.comp G
  /-- The counit of an adjunction -/
  counit : G.comp F ⟶ 𝟭 D
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the unit of an adjunction -/
  homEquiv_unit : ∀ {X Y f}, (homEquiv X Y) f = (unit : _ ⟶ _).app X ≫ G.map f := by aesop_cat
  -- Porting note: It's strange that this `Prop` is being flagged by the `docBlame` linter
  /-- Naturality of the counit of an adjunction -/
  homEquiv_counit : ∀ {X Y g}, (homEquiv X Y).symm g = F.map g ≫ counit.app Y := by aesop_cat
goal: (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)

full_name: CategoryTheory.«_aux_Mathlib_CategoryTheory_Adjunction_Basic___macroRules_CategoryTheory_term_⊣__1»
code: /-- The notation `F ⊣ G` stands for `Adjunction F G` representing that `F` is left adjoint to `G` -/
infixl:15 " ⊣ " => Adjunction
goal: Lean.Macro

full_name: CategoryTheory._aux_Mathlib_CategoryTheory_Adjunction_Basic___unexpand_CategoryTheory_Adjunction_1
code: /-- The notation `F ⊣ G` stands for `Adjunction F G` representing that `F` is left adjoint to `G` -/
infixl:15 " ⊣ " => Adjunction
goal: Lean.PrettyPrinter.Unexpander

full_name: CategoryTheory.Functor.IsLeftAdjoint
code: /-- A class asserting the existence of a right adjoint. -/
class IsLeftAdjoint (left : C ⥤ D) : Prop where
  exists_rightAdjoint : ∃ (right : D ⥤ C), Nonempty (left ⊣ right)
goal: Prop

full_name: CategoryTheory.Functor.IsLeftAdjoint.exists_rightAdjoint
code: /-- A class asserting the existence of a right adjoint. -/
class IsLeftAdjoint (left : C ⥤ D) : Prop where
  exists_rightAdjoint : ∃ (right : D ⥤ C), Nonempty (left ⊣ right)
goal: ∃ right, Nonempty (left ⊣ right)

full_name: CategoryTheory.Functor.IsRightAdjoint.exists_leftAdjoint
code: /-- A class asserting the existence of a left adjoint. -/
class IsRightAdjoint (right : D ⥤ C) : Prop where
  exists_leftAdjoint : ∃ (left : C ⥤ D), Nonempty (left ⊣ right)
goal: ∃ left, Nonempty (left ⊣ right)

full_name: CategoryTheory.Functor.IsRightAdjoint
code: /-- A class asserting the existence of a left adjoint. -/
class IsRightAdjoint (right : D ⥤ C) : Prop where
  exists_leftAdjoint : ∃ (left : C ⥤ D), Nonempty (left ⊣ right)
goal: Prop

full_name: CategoryTheory.Functor.leftAdjoint
code: /-- A chosen left adjoint to a functor that is a right adjoint. -/
noncomputable def leftAdjoint (R : D ⥤ C) [IsRightAdjoint R] : C ⥤ D 
goal: CategoryTheory.Functor C D

full_name: CategoryTheory.Functor.rightAdjoint
code: /-- A chosen right adjoint to a functor that is a left adjoint. -/
noncomputable def rightAdjoint (L : C ⥤ D) [IsLeftAdjoint L] : D ⥤ C 
goal: CategoryTheory.Functor D C

full_name: CategoryTheory.Adjunction.ofIsLeftAdjoint
code: /-- The adjunction associated to a functor known to be a left adjoint. -/
noncomputable def Adjunction.ofIsLeftAdjoint (left : C ⥤ D) [left.IsLeftAdjoint] :
    left ⊣ left.rightAdjoint 
goal: left ⊣ left.rightAdjoint

full_name: CategoryTheory.Adjunction.ofIsRightAdjoint
code: /-- The adjunction associated to a functor known to be a right adjoint. -/
noncomputable def Adjunction.ofIsRightAdjoint (right : C ⥤ D) [right.IsRightAdjoint] :
    right.leftAdjoint ⊣ right 
goal: right.leftAdjoint ⊣ right

full_name: CategoryTheory.Adjunction.isLeftAdjoint
code: lemma isLeftAdjoint (adj : F ⊣ G) : F.IsLeftAdjoint 
goal: F.IsLeftAdjoint

full_name: CategoryTheory.Adjunction.isRightAdjoint
code: lemma isRightAdjoint (adj : F ⊣ G) : G.IsRightAdjoint 
goal: G.IsRightAdjoint

full_name: CategoryTheory.Adjunction.instIsLeftAdjointLeftAdjoint
code: instance (R : D ⥤ C) [R.IsRightAdjoint] : R.leftAdjoint.IsLeftAdjoint 
goal: R.leftAdjoint.IsLeftAdjoint

full_name: CategoryTheory.Adjunction.instIsRightAdjointRightAdjoint
code: instance (L : C ⥤ D) [L.IsLeftAdjoint] : L.rightAdjoint.IsRightAdjoint 
goal: L.rightAdjoint.IsRightAdjoint

full_name: CategoryTheory.Adjunction.homEquiv_id
code: theorem homEquiv_id (X : C) : adj.homEquiv X _ (𝟙 _) = adj.unit.app X 
goal: (adj.homEquiv X (F.obj X)) (CategoryTheory.CategoryStruct.id (F.obj X)) = adj.unit.app X

full_name: CategoryTheory.Adjunction.homEquiv_symm_id
code: theorem homEquiv_symm_id (X : D) : (adj.homEquiv _ X).symm (𝟙 _) = adj.counit.app X 
goal: (adj.homEquiv (G.obj X) X).symm (CategoryTheory.CategoryStruct.id (G.obj X)) = adj.counit.app X

full_name: CategoryTheory.Adjunction.homEquiv_naturality_left_symm
code: @[simp, nolint simpNF]
theorem homEquiv_naturality_left_symm (f : X' ⟶ X) (g : X ⟶ G.obj Y) :
    (adj.homEquiv X' Y).symm (f ≫ g) = F.map f ≫ (adj.homEquiv X Y).symm g 
goal: (adj.homEquiv X' Y).symm (CategoryTheory.CategoryStruct.comp f g) =
  CategoryTheory.CategoryStruct.comp (F.map f) ((adj.homEquiv X Y).symm g)

full_name: CategoryTheory.Adjunction.homEquiv_naturality_left
code: @[simp, nolint simpNF]
theorem homEquiv_naturality_left (f : X' ⟶ X) (g : F.obj X ⟶ Y) :
    (adj.homEquiv X' Y) (F.map f ≫ g) = f ≫ (adj.homEquiv X Y) g 
goal: (adj.homEquiv X' Y) (CategoryTheory.CategoryStruct.comp (F.map f) g) =
  CategoryTheory.CategoryStruct.comp f ((adj.homEquiv X Y) g)

full_name: CategoryTheory.Adjunction.homEquiv_naturality_right
code: @[simp, nolint simpNF]
theorem homEquiv_naturality_right (f : F.obj X ⟶ Y) (g : Y ⟶ Y') :
    (adj.homEquiv X Y') (f ≫ g) = (adj.homEquiv X Y) f ≫ G.map g 
goal: (adj.homEquiv X Y') (CategoryTheory.CategoryStruct.comp f g) =
  CategoryTheory.CategoryStruct.comp ((adj.homEquiv X Y) f) (G.map g)

full_name: CategoryTheory.Adjunction.homEquiv_naturality_right_symm
code: @[simp, nolint simpNF]
theorem homEquiv_naturality_right_symm (f : X ⟶ G.obj Y) (g : Y ⟶ Y') :
    (adj.homEquiv X Y').symm (f ≫ G.map g) = (adj.homEquiv X Y).symm f ≫ g 
goal: (adj.homEquiv X Y').symm (CategoryTheory.CategoryStruct.comp f (G.map g)) =
  CategoryTheory.CategoryStruct.comp ((adj.homEquiv X Y).symm f) g

full_name: CategoryTheory.Adjunction.homEquiv_naturality_left_square
code: @[reassoc]
theorem homEquiv_naturality_left_square (f : X' ⟶ X) (g : F.obj X ⟶ Y')
    (h : F.obj X' ⟶ Y) (k : Y ⟶ Y') (w : F.map f ≫ g = h ≫ k) :
    f ≫ (adj.homEquiv X Y') g = (adj.homEquiv X' Y) h ≫ G.map k 
goal: CategoryTheory.CategoryStruct.comp f ((adj.homEquiv X Y') g) =
  CategoryTheory.CategoryStruct.comp ((adj.homEquiv X' Y) h) (G.map k)

full_name: CategoryTheory.Adjunction.homEquiv_naturality_right_square
code: @[reassoc]
theorem homEquiv_naturality_right_square (f : X' ⟶ X) (g : X ⟶ G.obj Y')
    (h : X' ⟶ G.obj Y) (k : Y ⟶ Y') (w : f ≫ g = h ≫ G.map k) :
    F.map f ≫ (adj.homEquiv X Y').symm g = (adj.homEquiv X' Y).symm h ≫ k 
goal: CategoryTheory.CategoryStruct.comp (F.map f) ((adj.homEquiv X Y').symm g) =
  CategoryTheory.CategoryStruct.comp ((adj.homEquiv X' Y).symm h) k

full_name: CategoryTheory.Adjunction.homEquiv_naturality_left_square_iff
code: theorem homEquiv_naturality_left_square_iff (f : X' ⟶ X) (g : F.obj X ⟶ Y')
    (h : F.obj X' ⟶ Y) (k : Y ⟶ Y') :
    (f ≫ (adj.homEquiv X Y') g = (adj.homEquiv X' Y) h ≫ G.map k) ↔
      (F.map f ≫ g = h ≫ k) 
goal: CategoryTheory.CategoryStruct.comp f ((adj.homEquiv X Y') g) =
    CategoryTheory.CategoryStruct.comp ((adj.homEquiv X' Y) h) (G.map k) ↔
  CategoryTheory.CategoryStruct.comp (F.map f) g = CategoryTheory.CategoryStruct.comp h k

full_name: CategoryTheory.Adjunction.homEquiv_naturality_right_square_iff
code: theorem homEquiv_naturality_right_square_iff (f : X' ⟶ X) (g : X ⟶ G.obj Y')
    (h : X' ⟶ G.obj Y) (k : Y ⟶ Y') :
    (F.map f ≫ (adj.homEquiv X Y').symm g = (adj.homEquiv X' Y).symm h ≫ k) ↔
      (f ≫ g = h ≫ G.map k) 
goal: CategoryTheory.CategoryStruct.comp (F.map f) ((adj.homEquiv X Y').symm g) =
    CategoryTheory.CategoryStruct.comp ((adj.homEquiv X' Y).symm h) k ↔
  CategoryTheory.CategoryStruct.comp f g = CategoryTheory.CategoryStruct.comp h (G.map k)

full_name: CategoryTheory.Adjunction.left_triangle
code: @[simp]
theorem left_triangle : whiskerRight adj.unit F ≫ whiskerLeft F adj.counit = 𝟙 _ 
goal: CategoryTheory.CategoryStruct.comp (CategoryTheory.whiskerRight adj.unit F) (CategoryTheory.whiskerLeft F adj.counit) =
  CategoryTheory.CategoryStruct.id ((CategoryTheory.Functor.id C).comp F)

full_name: CategoryTheory.Adjunction.right_triangle
code: @[simp]
theorem right_triangle : whiskerLeft G adj.unit ≫ whiskerRight adj.counit G = 𝟙 _ 
goal: CategoryTheory.CategoryStruct.comp (CategoryTheory.whiskerLeft G adj.unit) (CategoryTheory.whiskerRight adj.counit G) =
  CategoryTheory.CategoryStruct.id (G.comp (CategoryTheory.Functor.id C))

full_name: CategoryTheory.Adjunction.left_triangle_components
code: @[reassoc (attr := simp)]
theorem left_triangle_components :
    F.map (adj.unit.app X) ≫ adj.counit.app (F.obj X) = 𝟙 (F.obj X) 
goal: CategoryTheory.CategoryStruct.comp (F.map (adj.unit.app X)) (adj.counit.app (F.obj X)) =
  CategoryTheory.CategoryStruct.id (F.obj X)

full_name: CategoryTheory.Adjunction.right_triangle_components
code: @[reassoc (attr := simp)]
theorem right_triangle_components :
    adj.unit.app (G.obj Y) ≫ G.map (adj.counit.app Y) = 𝟙 (G.obj Y) 
goal: CategoryTheory.CategoryStruct.comp (adj.unit.app (G.obj Y)) (G.map (adj.counit.app Y)) =
  CategoryTheory.CategoryStruct.id (G.obj Y)

full_name: CategoryTheory.Adjunction.counit_naturality
code: @[reassoc (attr := simp)]
theorem counit_naturality {X Y : D} (f : X ⟶ Y) :
    F.map (G.map f) ≫ adj.counit.app Y = adj.counit.app X ≫ f 
goal: CategoryTheory.CategoryStruct.comp (F.map (G.map f)) (adj.counit.app Y) =
  CategoryTheory.CategoryStruct.comp (adj.counit.app X) f

full_name: CategoryTheory.Adjunction.unit_naturality
code: @[reassoc (attr := simp)]
theorem unit_naturality {X Y : C} (f : X ⟶ Y) :
    adj.unit.app X ≫ G.map (F.map f) = f ≫ adj.unit.app Y 
goal: CategoryTheory.CategoryStruct.comp (adj.unit.app X) (G.map (F.map f)) =
  CategoryTheory.CategoryStruct.comp f (adj.unit.app Y)

full_name: CategoryTheory.Adjunction.homEquiv_apply_eq
code: theorem homEquiv_apply_eq {A : C} {B : D} (f : F.obj A ⟶ B) (g : A ⟶ G.obj B) :
    adj.homEquiv A B f = g ↔ f = (adj.homEquiv A B).symm g 
goal: (adj.homEquiv A B) f = g ↔ f = (adj.homEquiv A B).symm g

full_name: CategoryTheory.Adjunction.eq_homEquiv_apply
code: theorem eq_homEquiv_apply {A : C} {B : D} (f : F.obj A ⟶ B) (g : A ⟶ G.obj B) :
    g = adj.homEquiv A B f ↔ (adj.homEquiv A B).symm g = f 
goal: g = (adj.homEquiv A B) f ↔ (adj.homEquiv A B).symm g = f

full_name: CategoryTheory.Adjunction.CoreHomEquiv
code: /-- This is an auxiliary data structure useful for constructing adjunctions.
See `Adjunction.mkOfHomEquiv`.
This structure won't typically be used anywhere else.
-/
-- Porting note(#5171): `has_nonempty_instance` linter not ported yet
-- @[nolint has_nonempty_instance]
structure CoreHomEquiv (F : C ⥤ D) (G : D ⥤ C) where
  /-- The equivalence between `Hom (F X) Y` and `Hom X (G Y)` -/
  homEquiv : ∀ X Y, (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)
  /-- The property that describes how `homEquiv.symm` transforms compositions `X' ⟶ X ⟶ G Y` -/
  homEquiv_naturality_left_symm :
    ∀ {X' X Y} (f : X' ⟶ X) (g : X ⟶ G.obj Y),
      (homEquiv X' Y).symm (f ≫ g) = F.map f ≫ (homEquiv X Y).symm g := by
    aesop_cat
  /-- The property that describes how `homEquiv` transforms compositions `F X ⟶ Y ⟶ Y'` -/
  homEquiv_naturality_right :
    ∀ {X Y Y'} (f : F.obj X ⟶ Y) (g : Y ⟶ Y'),
      (homEquiv X Y') (f ≫ g) = (homEquiv X Y) f ≫ G.map g := by
    aesop_cat
goal: Type (max (max (max u₁ u₂) v₁) v₂)

full_name: CategoryTheory.Adjunction.CoreHomEquiv.homEquiv_naturality_right
code: /-- This is an auxiliary data structure useful for constructing adjunctions.
See `Adjunction.mkOfHomEquiv`.
This structure won't typically be used anywhere else.
-/
-- Porting note(#5171): `has_nonempty_instance` linter not ported yet
-- @[nolint has_nonempty_instance]
structure CoreHomEquiv (F : C ⥤ D) (G : D ⥤ C) where
  /-- The equivalence between `Hom (F X) Y` and `Hom X (G Y)` -/
  homEquiv : ∀ X Y, (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)
  /-- The property that describes how `homEquiv.symm` transforms compositions `X' ⟶ X ⟶ G Y` -/
  homEquiv_naturality_left_symm :
    ∀ {X' X Y} (f : X' ⟶ X) (g : X ⟶ G.obj Y),
      (homEquiv X' Y).symm (f ≫ g) = F.map f ≫ (homEquiv X Y).symm g := by
    aesop_cat
  /-- The property that describes how `homEquiv` transforms compositions `F X ⟶ Y ⟶ Y'` -/
  homEquiv_naturality_right :
    ∀ {X Y Y'} (f : F.obj X ⟶ Y) (g : Y ⟶ Y'),
      (homEquiv X Y') (f ≫ g) = (homEquiv X Y) f ≫ G.map g := by
    aesop_cat
goal: (self.homEquiv X Y') (CategoryTheory.CategoryStruct.comp f g) =
  CategoryTheory.CategoryStruct.comp ((self.homEquiv X Y) f) (G.map g)

full_name: CategoryTheory.Adjunction.CoreHomEquiv.homEquiv
code: /-- This is an auxiliary data structure useful for constructing adjunctions.
See `Adjunction.mkOfHomEquiv`.
This structure won't typically be used anywhere else.
-/
-- Porting note(#5171): `has_nonempty_instance` linter not ported yet
-- @[nolint has_nonempty_instance]
structure CoreHomEquiv (F : C ⥤ D) (G : D ⥤ C) where
  /-- The equivalence between `Hom (F X) Y` and `Hom X (G Y)` -/
  homEquiv : ∀ X Y, (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)
  /-- The property that describes how `homEquiv.symm` transforms compositions `X' ⟶ X ⟶ G Y` -/
  homEquiv_naturality_left_symm :
    ∀ {X' X Y} (f : X' ⟶ X) (g : X ⟶ G.obj Y),
      (homEquiv X' Y).symm (f ≫ g) = F.map f ≫ (homEquiv X Y).symm g := by
    aesop_cat
  /-- The property that describes how `homEquiv` transforms compositions `F X ⟶ Y ⟶ Y'` -/
  homEquiv_naturality_right :
    ∀ {X Y Y'} (f : F.obj X ⟶ Y) (g : Y ⟶ Y'),
      (homEquiv X Y') (f ≫ g) = (homEquiv X Y) f ≫ G.map g := by
    aesop_cat
goal: (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)

full_name: CategoryTheory.Adjunction.CoreHomEquiv.homEquiv_naturality_left_symm
code: /-- This is an auxiliary data structure useful for constructing adjunctions.
See `Adjunction.mkOfHomEquiv`.
This structure won't typically be used anywhere else.
-/
-- Porting note(#5171): `has_nonempty_instance` linter not ported yet
-- @[nolint has_nonempty_instance]
structure CoreHomEquiv (F : C ⥤ D) (G : D ⥤ C) where
  /-- The equivalence between `Hom (F X) Y` and `Hom X (G Y)` -/
  homEquiv : ∀ X Y, (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)
  /-- The property that describes how `homEquiv.symm` transforms compositions `X' ⟶ X ⟶ G Y` -/
  homEquiv_naturality_left_symm :
    ∀ {X' X Y} (f : X' ⟶ X) (g : X ⟶ G.obj Y),
      (homEquiv X' Y).symm (f ≫ g) = F.map f ≫ (homEquiv X Y).symm g := by
    aesop_cat
  /-- The property that describes how `homEquiv` transforms compositions `F X ⟶ Y ⟶ Y'` -/
  homEquiv_naturality_right :
    ∀ {X Y Y'} (f : F.obj X ⟶ Y) (g : Y ⟶ Y'),
      (homEquiv X Y') (f ≫ g) = (homEquiv X Y) f ≫ G.map g := by
    aesop_cat
goal: (self.homEquiv X' Y).symm (CategoryTheory.CategoryStruct.comp f g) =
  CategoryTheory.CategoryStruct.comp (F.map f) ((self.homEquiv X Y).symm g)

full_name: CategoryTheory.Adjunction.CoreHomEquiv.homEquiv_naturality_left_aux
code: @[simp]
theorem homEquiv_naturality_left_aux (f : X' ⟶ X) (g : F.obj X ⟶ Y) :
    (adj.homEquiv X' (F.obj X)) (F.map f) ≫ G.map g = f ≫ (adj.homEquiv X Y) g 
goal: CategoryTheory.CategoryStruct.comp ((adj.homEquiv X' (F.obj X)) (F.map f)) (G.map g) =
  CategoryTheory.CategoryStruct.comp f ((adj.homEquiv X Y) g)

full_name: CategoryTheory.Adjunction.CoreHomEquiv.homEquiv_naturality_left
code: theorem homEquiv_naturality_left (f : X' ⟶ X) (g : F.obj X ⟶ Y) :
    (adj.homEquiv X' Y) (F.map f ≫ g) = f ≫ (adj.homEquiv X Y) g 
goal: (adj.homEquiv X' Y) (CategoryTheory.CategoryStruct.comp (F.map f) g) =
  CategoryTheory.CategoryStruct.comp f ((adj.homEquiv X Y) g)

full_name: CategoryTheory.Adjunction.CoreHomEquiv.homEquiv_naturality_right_symm_aux
code: @[simp]
theorem homEquiv_naturality_right_symm_aux (f : X ⟶ G.obj Y) (g : Y ⟶ Y') :
    F.map f ≫ (adj.homEquiv (G.obj Y) Y').symm (G.map g) = (adj.homEquiv X Y).symm f ≫ g 
goal: CategoryTheory.CategoryStruct.comp (F.map f) ((adj.homEquiv (G.obj Y) Y').symm (G.map g)) =
  CategoryTheory.CategoryStruct.comp ((adj.homEquiv X Y).symm f) g

full_name: CategoryTheory.Adjunction.CoreHomEquiv.homEquiv_naturality_right_symm
code: theorem homEquiv_naturality_right_symm (f : X ⟶ G.obj Y) (g : Y ⟶ Y') :
    (adj.homEquiv X Y').symm (f ≫ G.map g) = (adj.homEquiv X Y).symm f ≫ g 
goal: (adj.homEquiv X Y').symm (CategoryTheory.CategoryStruct.comp f (G.map g)) =
  CategoryTheory.CategoryStruct.comp ((adj.homEquiv X Y).symm f) g

full_name: CategoryTheory.Adjunction.CoreUnitCounit.left_triangle
code: /-- This is an auxiliary data structure useful for constructing adjunctions.
See `Adjunction.mkOfUnitCounit`.
This structure won't typically be used anywhere else.
-/
-- Porting note(#5171): `has_nonempty_instance` linter not ported yet
-- @[nolint has_nonempty_instance]
structure CoreUnitCounit (F : C ⥤ D) (G : D ⥤ C) where
  /-- The unit of an adjunction between `F` and `G` -/
  unit : 𝟭 C ⟶ F.comp G
  /-- The counit of an adjunction between `F` and `G`s -/
  counit : G.comp F ⟶ 𝟭 D
  /-- Equality of the composition of the unit, associator, and counit with the identity
  `F ⟶ (F G) F ⟶ F (G F) ⟶ F = NatTrans.id F` -/
  left_triangle :
    whiskerRight unit F ≫ (Functor.associator F G F).hom ≫ whiskerLeft F counit =
      NatTrans.id (𝟭 C ⋙ F) := by
    aesop_cat
  /-- Equality of the composition of the unit, associator, and counit with the identity
  `G ⟶ G (F G) ⟶ (F G) F ⟶ G = NatTrans.id G` -/
  right_triangle :
    whiskerLeft G unit ≫ (Functor.associator G F G).inv ≫ whiskerRight counit G =
      NatTrans.id (G ⋙ 𝟭 C) := by
    aesop_cat
goal: CategoryTheory.CategoryStruct.comp (CategoryTheory.whiskerRight self.unit F)
    (CategoryTheory.CategoryStruct.comp (F.associator G F).hom (CategoryTheory.whiskerLeft F self.counit)) =
  CategoryTheory.NatTrans.id ((CategoryTheory.Functor.id C).comp F)

full_name: CategoryTheory.Adjunction.CoreUnitCounit.unit
code: /-- This is an auxiliary data structure useful for constructing adjunctions.
See `Adjunction.mkOfUnitCounit`.
This structure won't typically be used anywhere else.
-/
-- Porting note(#5171): `has_nonempty_instance` linter not ported yet
-- @[nolint has_nonempty_instance]
structure CoreUnitCounit (F : C ⥤ D) (G : D ⥤ C) where
  /-- The unit of an adjunction between `F` and `G` -/
  unit : 𝟭 C ⟶ F.comp G
  /-- The counit of an adjunction between `F` and `G`s -/
  counit : G.comp F ⟶ 𝟭 D
  /-- Equality of the composition of the unit, associator, and counit with the identity
  `F ⟶ (F G) F ⟶ F (G F) ⟶ F = NatTrans.id F` -/
  left_triangle :
    whiskerRight unit F ≫ (Functor.associator F G F).hom ≫ whiskerLeft F counit =
      NatTrans.id (𝟭 C ⋙ F) := by
    aesop_cat
  /-- Equality of the composition of the unit, associator, and counit with the identity
  `G ⟶ G (F G) ⟶ (F G) F ⟶ G = NatTrans.id G` -/
  right_triangle :
    whiskerLeft G unit ≫ (Functor.associator G F G).inv ≫ whiskerRight counit G =
      NatTrans.id (G ⋙ 𝟭 C) := by
    aesop_cat
goal: CategoryTheory.Functor.id C ⟶ F.comp G

full_name: CategoryTheory.Adjunction.CoreUnitCounit.right_triangle
code: /-- This is an auxiliary data structure useful for constructing adjunctions.
See `Adjunction.mkOfUnitCounit`.
This structure won't typically be used anywhere else.
-/
-- Porting note(#5171): `has_nonempty_instance` linter not ported yet
-- @[nolint has_nonempty_instance]
structure CoreUnitCounit (F : C ⥤ D) (G : D ⥤ C) where
  /-- The unit of an adjunction between `F` and `G` -/
  unit : 𝟭 C ⟶ F.comp G
  /-- The counit of an adjunction between `F` and `G`s -/
  counit : G.comp F ⟶ 𝟭 D
  /-- Equality of the composition of the unit, associator, and counit with the identity
  `F ⟶ (F G) F ⟶ F (G F) ⟶ F = NatTrans.id F` -/
  left_triangle :
    whiskerRight unit F ≫ (Functor.associator F G F).hom ≫ whiskerLeft F counit =
      NatTrans.id (𝟭 C ⋙ F) := by
    aesop_cat
  /-- Equality of the composition of the unit, associator, and counit with the identity
  `G ⟶ G (F G) ⟶ (F G) F ⟶ G = NatTrans.id G` -/
  right_triangle :
    whiskerLeft G unit ≫ (Functor.associator G F G).inv ≫ whiskerRight counit G =
      NatTrans.id (G ⋙ 𝟭 C) := by
    aesop_cat
goal: CategoryTheory.CategoryStruct.comp (CategoryTheory.whiskerLeft G self.unit)
    (CategoryTheory.CategoryStruct.comp (G.associator F G).inv (CategoryTheory.whiskerRight self.counit G)) =
  CategoryTheory.NatTrans.id (G.comp (CategoryTheory.Functor.id C))

full_name: CategoryTheory.Adjunction.CoreUnitCounit
code: /-- This is an auxiliary data structure useful for constructing adjunctions.
See `Adjunction.mkOfUnitCounit`.
This structure won't typically be used anywhere else.
-/
-- Porting note(#5171): `has_nonempty_instance` linter not ported yet
-- @[nolint has_nonempty_instance]
structure CoreUnitCounit (F : C ⥤ D) (G : D ⥤ C) where
  /-- The unit of an adjunction between `F` and `G` -/
  unit : 𝟭 C ⟶ F.comp G
  /-- The counit of an adjunction between `F` and `G`s -/
  counit : G.comp F ⟶ 𝟭 D
  /-- Equality of the composition of the unit, associator, and counit with the identity
  `F ⟶ (F G) F ⟶ F (G F) ⟶ F = NatTrans.id F` -/
  left_triangle :
    whiskerRight unit F ≫ (Functor.associator F G F).hom ≫ whiskerLeft F counit =
      NatTrans.id (𝟭 C ⋙ F) := by
    aesop_cat
  /-- Equality of the composition of the unit, associator, and counit with the identity
  `G ⟶ G (F G) ⟶ (F G) F ⟶ G = NatTrans.id G` -/
  right_triangle :
    whiskerLeft G unit ≫ (Functor.associator G F G).inv ≫ whiskerRight counit G =
      NatTrans.id (G ⋙ 𝟭 C) := by
    aesop_cat
goal: Type (max (max (max u₁ u₂) v₁) v₂)

full_name: CategoryTheory.Adjunction.CoreUnitCounit.counit
code: /-- This is an auxiliary data structure useful for constructing adjunctions.
See `Adjunction.mkOfUnitCounit`.
This structure won't typically be used anywhere else.
-/
-- Porting note(#5171): `has_nonempty_instance` linter not ported yet
-- @[nolint has_nonempty_instance]
structure CoreUnitCounit (F : C ⥤ D) (G : D ⥤ C) where
  /-- The unit of an adjunction between `F` and `G` -/
  unit : 𝟭 C ⟶ F.comp G
  /-- The counit of an adjunction between `F` and `G`s -/
  counit : G.comp F ⟶ 𝟭 D
  /-- Equality of the composition of the unit, associator, and counit with the identity
  `F ⟶ (F G) F ⟶ F (G F) ⟶ F = NatTrans.id F` -/
  left_triangle :
    whiskerRight unit F ≫ (Functor.associator F G F).hom ≫ whiskerLeft F counit =
      NatTrans.id (𝟭 C ⋙ F) := by
    aesop_cat
  /-- Equality of the composition of the unit, associator, and counit with the identity
  `G ⟶ G (F G) ⟶ (F G) F ⟶ G = NatTrans.id G` -/
  right_triangle :
    whiskerLeft G unit ≫ (Functor.associator G F G).inv ≫ whiskerRight counit G =
      NatTrans.id (G ⋙ 𝟭 C) := by
    aesop_cat
goal: G.comp F ⟶ CategoryTheory.Functor.id D

full_name: CategoryTheory.Adjunction.mkOfHomEquiv_counit_app
code: /-- Construct an adjunction between `F` and `G` out of a natural bijection between each
`F.obj X ⟶ Y` and `X ⟶ G.obj Y`. -/
@[simps]
def mkOfHomEquiv (adj : CoreHomEquiv F G) : F ⊣ G 
goal: (CategoryTheory.Adjunction.mkOfHomEquiv adj).counit.app Y =
  (adj.homEquiv (G.obj Y) ((CategoryTheory.Functor.id D).obj Y)).invFun (CategoryTheory.CategoryStruct.id (G.obj Y))

full_name: CategoryTheory.Adjunction.mkOfHomEquiv_unit_app
code: /-- Construct an adjunction between `F` and `G` out of a natural bijection between each
`F.obj X ⟶ Y` and `X ⟶ G.obj Y`. -/
@[simps]
def mkOfHomEquiv (adj : CoreHomEquiv F G) : F ⊣ G 
goal: (CategoryTheory.Adjunction.mkOfHomEquiv adj).unit.app X =
  (adj.homEquiv X (F.obj X)) (CategoryTheory.CategoryStruct.id (F.obj X))

full_name: CategoryTheory.Adjunction.mkOfHomEquiv
code: /-- Construct an adjunction between `F` and `G` out of a natural bijection between each
`F.obj X ⟶ Y` and `X ⟶ G.obj Y`. -/
@[simps]
def mkOfHomEquiv (adj : CoreHomEquiv F G) : F ⊣ G 
goal: F ⊣ G

full_name: CategoryTheory.Adjunction.mkOfHomEquiv_homEquiv
code: /-- Construct an adjunction between `F` and `G` out of a natural bijection between each
`F.obj X ⟶ Y` and `X ⟶ G.obj Y`. -/
@[simps]
def mkOfHomEquiv (adj : CoreHomEquiv F G) : F ⊣ G 
goal: (CategoryTheory.Adjunction.mkOfHomEquiv adj).homEquiv X Y = adj.homEquiv X Y

full_name: CategoryTheory.Adjunction.mkOfUnitCounit_unit
code: /-- Construct an adjunction between functors `F` and `G` given a unit and counit for the adjunction
satisfying the triangle identities. -/

@[simps!]
def mkOfUnitCounit (adj : CoreUnitCounit F G) : F ⊣ G 
goal: (CategoryTheory.Adjunction.mkOfUnitCounit adj).unit = adj.unit

full_name: CategoryTheory.Adjunction.mkOfUnitCounit_homEquiv_apply
code: /-- Construct an adjunction between functors `F` and `G` given a unit and counit for the adjunction
satisfying the triangle identities. -/

@[simps!]
def mkOfUnitCounit (adj : CoreUnitCounit F G) : F ⊣ G 
goal: ((CategoryTheory.Adjunction.mkOfUnitCounit adj).homEquiv X Y) f =
  CategoryTheory.CategoryStruct.comp (adj.unit.app X) (G.map f)

full_name: CategoryTheory.Adjunction.mkOfUnitCounit
code: /-- Construct an adjunction between functors `F` and `G` given a unit and counit for the adjunction
satisfying the triangle identities. -/

@[simps!]
def mkOfUnitCounit (adj : CoreUnitCounit F G) : F ⊣ G 
goal: F ⊣ G

full_name: CategoryTheory.Adjunction.mkOfUnitCounit_homEquiv_symm_apply
code: /-- Construct an adjunction between functors `F` and `G` given a unit and counit for the adjunction
satisfying the triangle identities. -/

@[simps!]
def mkOfUnitCounit (adj : CoreUnitCounit F G) : F ⊣ G 
goal: ((CategoryTheory.Adjunction.mkOfUnitCounit adj).homEquiv X Y).symm g =
  CategoryTheory.CategoryStruct.comp (F.map g) (adj.counit.app Y)

full_name: CategoryTheory.Adjunction.mkOfUnitCounit_counit
code: /-- Construct an adjunction between functors `F` and `G` given a unit and counit for the adjunction
satisfying the triangle identities. -/

@[simps!]
def mkOfUnitCounit (adj : CoreUnitCounit F G) : F ⊣ G 
goal: (CategoryTheory.Adjunction.mkOfUnitCounit adj).counit = adj.counit

full_name: CategoryTheory.Adjunction.id
code: /-- The adjunction between the identity functor on a category and itself. -/
def id : 𝟭 C ⊣ 𝟭 C 
goal: CategoryTheory.Functor.id C ⊣ CategoryTheory.Functor.id C

full_name: CategoryTheory.Adjunction.instInhabitedId
code: instance : Inhabited (Adjunction (𝟭 C) (𝟭 C)) 
goal: Inhabited (CategoryTheory.Functor.id C ⊣ CategoryTheory.Functor.id C)

full_name: CategoryTheory.Adjunction.equivHomsetLeftOfNatIso_apply
code: /-- If F and G are naturally isomorphic functors, establish an equivalence of hom-sets. -/
@[simps]
def equivHomsetLeftOfNatIso {F F' : C ⥤ D} (iso : F ≅ F') {X : C} {Y : D} :
    (F.obj X ⟶ Y) ≃ (F'.obj X ⟶ Y) 
goal: (CategoryTheory.Adjunction.equivHomsetLeftOfNatIso iso) f = CategoryTheory.CategoryStruct.comp (iso.inv.app X) f

full_name: CategoryTheory.Adjunction.equivHomsetLeftOfNatIso
code: /-- If F and G are naturally isomorphic functors, establish an equivalence of hom-sets. -/
@[simps]
def equivHomsetLeftOfNatIso {F F' : C ⥤ D} (iso : F ≅ F') {X : C} {Y : D} :
    (F.obj X ⟶ Y) ≃ (F'.obj X ⟶ Y) 
goal: (F.obj X ⟶ Y) ≃ (F'.obj X ⟶ Y)

full_name: CategoryTheory.Adjunction.equivHomsetLeftOfNatIso_symm_apply
code: /-- If F and G are naturally isomorphic functors, establish an equivalence of hom-sets. -/
@[simps]
def equivHomsetLeftOfNatIso {F F' : C ⥤ D} (iso : F ≅ F') {X : C} {Y : D} :
    (F.obj X ⟶ Y) ≃ (F'.obj X ⟶ Y) 
goal: (CategoryTheory.Adjunction.equivHomsetLeftOfNatIso iso).symm g = CategoryTheory.CategoryStruct.comp (iso.hom.app X) g

full_name: CategoryTheory.Adjunction.equivHomsetRightOfNatIso_apply
code: /-- If G and H are naturally isomorphic functors, establish an equivalence of hom-sets. -/
@[simps]
def equivHomsetRightOfNatIso {G G' : D ⥤ C} (iso : G ≅ G') {X : C} {Y : D} :
    (X ⟶ G.obj Y) ≃ (X ⟶ G'.obj Y) 
goal: (CategoryTheory.Adjunction.equivHomsetRightOfNatIso iso) f = CategoryTheory.CategoryStruct.comp f (iso.hom.app Y)

full_name: CategoryTheory.Adjunction.equivHomsetRightOfNatIso
code: /-- If G and H are naturally isomorphic functors, establish an equivalence of hom-sets. -/
@[simps]
def equivHomsetRightOfNatIso {G G' : D ⥤ C} (iso : G ≅ G') {X : C} {Y : D} :
    (X ⟶ G.obj Y) ≃ (X ⟶ G'.obj Y) 
goal: (X ⟶ G.obj Y) ≃ (X ⟶ G'.obj Y)

full_name: CategoryTheory.Adjunction.equivHomsetRightOfNatIso_symm_apply
code: /-- If G and H are naturally isomorphic functors, establish an equivalence of hom-sets. -/
@[simps]
def equivHomsetRightOfNatIso {G G' : D ⥤ C} (iso : G ≅ G') {X : C} {Y : D} :
    (X ⟶ G.obj Y) ≃ (X ⟶ G'.obj Y) 
goal: (CategoryTheory.Adjunction.equivHomsetRightOfNatIso iso).symm g = CategoryTheory.CategoryStruct.comp g (iso.inv.app Y)

full_name: CategoryTheory.Adjunction.ofNatIsoLeft
code: /-- Transport an adjunction along a natural isomorphism on the left. -/
def ofNatIsoLeft {F G : C ⥤ D} {H : D ⥤ C} (adj : F ⊣ H) (iso : F ≅ G) : G ⊣ H 
goal: G ⊣ H

full_name: CategoryTheory.Adjunction.ofNatIsoRight
code: /-- Transport an adjunction along a natural isomorphism on the right. -/
def ofNatIsoRight {F : C ⥤ D} {G H : D ⥤ C} (adj : F ⊣ G) (iso : G ≅ H) : F ⊣ H 
goal: F ⊣ H

full_name: CategoryTheory.Adjunction.comp
code: /-- Composition of adjunctions.

See <https://stacks.math.columbia.edu/tag/0DV0>.
-/
def comp : F ⋙ H ⊣ I ⋙ G 
goal: F.comp H ⊣ I.comp G

full_name: CategoryTheory.Adjunction.comp_unit_app
code: @[simp, reassoc]
lemma comp_unit_app (X : C) :
    (adj₁.comp adj₂).unit.app X = adj₁.unit.app X ≫ G.map (adj₂.unit.app (F.obj X)) 
goal: (adj₁.comp adj₂).unit.app X = CategoryTheory.CategoryStruct.comp (adj₁.unit.app X) (G.map (adj₂.unit.app (F.obj X)))

full_name: CategoryTheory.Adjunction.comp_counit_app
code: @[simp, reassoc]
lemma comp_counit_app (X : E) :
    (adj₁.comp adj₂).counit.app X = H.map (adj₁.counit.app (I.obj X)) ≫ adj₂.counit.app X 
goal: (adj₁.comp adj₂).counit.app X =
  CategoryTheory.CategoryStruct.comp (H.map (adj₁.counit.app (I.obj X))) (adj₂.counit.app X)

full_name: CategoryTheory.Adjunction.leftAdjointOfEquiv_map
code: /-- Construct a left adjoint functor to `G`, given the functor's value on objects `F_obj` and
a bijection `e` between `F_obj X ⟶ Y` and `X ⟶ G.obj Y` satisfying a naturality law
`he : ∀ X Y Y' g h, e X Y' (h ≫ g) = e X Y h ≫ G.map g`.
Dual to `rightAdjointOfEquiv`. -/
@[simps!]
def leftAdjointOfEquiv (he : ∀ X Y Y' g h, e X Y' (h ≫ g) = e X Y h ≫ G.map g) : C ⥤ D 
goal: (CategoryTheory.Adjunction.leftAdjointOfEquiv e he).map f =
  (e X (F_obj X')).symm
    (CategoryTheory.CategoryStruct.comp f ((e X' (F_obj X')) (CategoryTheory.CategoryStruct.id (F_obj X'))))

full_name: CategoryTheory.Adjunction.leftAdjointOfEquiv_obj
code: /-- Construct a left adjoint functor to `G`, given the functor's value on objects `F_obj` and
a bijection `e` between `F_obj X ⟶ Y` and `X ⟶ G.obj Y` satisfying a naturality law
`he : ∀ X Y Y' g h, e X Y' (h ≫ g) = e X Y h ≫ G.map g`.
Dual to `rightAdjointOfEquiv`. -/
@[simps!]
def leftAdjointOfEquiv (he : ∀ X Y Y' g h, e X Y' (h ≫ g) = e X Y h ≫ G.map g) : C ⥤ D 
goal: ∀ (a : C), (CategoryTheory.Adjunction.leftAdjointOfEquiv e he).obj a = F_obj a

full_name: CategoryTheory.Adjunction.leftAdjointOfEquiv
code: /-- Construct a left adjoint functor to `G`, given the functor's value on objects `F_obj` and
a bijection `e` between `F_obj X ⟶ Y` and `X ⟶ G.obj Y` satisfying a naturality law
`he : ∀ X Y Y' g h, e X Y' (h ≫ g) = e X Y h ≫ G.map g`.
Dual to `rightAdjointOfEquiv`. -/
@[simps!]
def leftAdjointOfEquiv (he : ∀ X Y Y' g h, e X Y' (h ≫ g) = e X Y h ≫ G.map g) : C ⥤ D 
goal: CategoryTheory.Functor C D

full_name: CategoryTheory.Adjunction.adjunctionOfEquivLeft_counit_app
code: /-- Show that the functor given by `leftAdjointOfEquiv` is indeed left adjoint to `G`. Dual
to `adjunctionOfRightEquiv`. -/
@[simps!]
def adjunctionOfEquivLeft : leftAdjointOfEquiv e he ⊣ G 
goal: (CategoryTheory.Adjunction.adjunctionOfEquivLeft e he).counit.app Y =
  (e (G.obj Y) Y).symm (CategoryTheory.CategoryStruct.id (G.obj Y))

full_name: CategoryTheory.Adjunction.adjunctionOfEquivLeft
code: /-- Show that the functor given by `leftAdjointOfEquiv` is indeed left adjoint to `G`. Dual
to `adjunctionOfRightEquiv`. -/
@[simps!]
def adjunctionOfEquivLeft : leftAdjointOfEquiv e he ⊣ G 
goal: CategoryTheory.Adjunction.leftAdjointOfEquiv e he ⊣ G

full_name: CategoryTheory.Adjunction.adjunctionOfEquivLeft_unit_app
code: /-- Show that the functor given by `leftAdjointOfEquiv` is indeed left adjoint to `G`. Dual
to `adjunctionOfRightEquiv`. -/
@[simps!]
def adjunctionOfEquivLeft : leftAdjointOfEquiv e he ⊣ G 
goal: (CategoryTheory.Adjunction.adjunctionOfEquivLeft e he).unit.app X =
  (e X (F_obj X)) (CategoryTheory.CategoryStruct.id (F_obj X))

full_name: CategoryTheory.Adjunction.adjunctionOfEquivLeft_homEquiv
code: /-- Show that the functor given by `leftAdjointOfEquiv` is indeed left adjoint to `G`. Dual
to `adjunctionOfRightEquiv`. -/
@[simps!]
def adjunctionOfEquivLeft : leftAdjointOfEquiv e he ⊣ G 
goal: (CategoryTheory.Adjunction.adjunctionOfEquivLeft e he).homEquiv X Y = e X Y

full_name: _private.Mathlib.CategoryTheory.Adjunction.Basic.0.CategoryTheory.Adjunction.he''
code: private theorem he'' (he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y g)
    {X' X Y} (f g) : F.map f ≫ (e X Y).symm g = (e X' Y).symm (f ≫ g) 
goal: CategoryTheory.CategoryStruct.comp (F.map f) ((e X Y).symm g) = (e X' Y).symm (CategoryTheory.CategoryStruct.comp f g)

full_name: CategoryTheory.Adjunction.rightAdjointOfEquiv_map
code: /-- Construct a right adjoint functor to `F`, given the functor's value on objects `G_obj` and
a bijection `e` between `F.obj X ⟶ Y` and `X ⟶ G_obj Y` satisfying a naturality law
`he : ∀ X Y Y' g h, e X' Y (F.map f ≫ g) = f ≫ e X Y g`.
Dual to `leftAdjointOfEquiv`. -/
@[simps!]
def rightAdjointOfEquiv (he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y g) : D ⥤ C 
goal: (CategoryTheory.Adjunction.rightAdjointOfEquiv e he).map g =
  (e (G_obj Y) Y')
    (CategoryTheory.CategoryStruct.comp ((e (G_obj Y) Y).symm (CategoryTheory.CategoryStruct.id (G_obj Y))) g)

full_name: CategoryTheory.Adjunction.rightAdjointOfEquiv
code: /-- Construct a right adjoint functor to `F`, given the functor's value on objects `G_obj` and
a bijection `e` between `F.obj X ⟶ Y` and `X ⟶ G_obj Y` satisfying a naturality law
`he : ∀ X Y Y' g h, e X' Y (F.map f ≫ g) = f ≫ e X Y g`.
Dual to `leftAdjointOfEquiv`. -/
@[simps!]
def rightAdjointOfEquiv (he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y g) : D ⥤ C 
goal: CategoryTheory.Functor D C

full_name: CategoryTheory.Adjunction.rightAdjointOfEquiv_obj
code: /-- Construct a right adjoint functor to `F`, given the functor's value on objects `G_obj` and
a bijection `e` between `F.obj X ⟶ Y` and `X ⟶ G_obj Y` satisfying a naturality law
`he : ∀ X Y Y' g h, e X' Y (F.map f ≫ g) = f ≫ e X Y g`.
Dual to `leftAdjointOfEquiv`. -/
@[simps!]
def rightAdjointOfEquiv (he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y g) : D ⥤ C 
goal: ∀ (a : D), (CategoryTheory.Adjunction.rightAdjointOfEquiv e he).obj a = G_obj a

full_name: CategoryTheory.Adjunction.adjunctionOfEquivRight
code: /-- Show that the functor given by `rightAdjointOfEquiv` is indeed right adjoint to `F`. Dual
to `adjunctionOfEquivRight`. -/
@[simps!]
def adjunctionOfEquivRight (he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y g) :
    F ⊣ (rightAdjointOfEquiv e he) 
goal: F ⊣ CategoryTheory.Adjunction.rightAdjointOfEquiv e he

full_name: CategoryTheory.Adjunction.adjunctionOfEquivRight_unit_app
code: /-- Show that the functor given by `rightAdjointOfEquiv` is indeed right adjoint to `F`. Dual
to `adjunctionOfEquivRight`. -/
@[simps!]
def adjunctionOfEquivRight (he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y g) :
    F ⊣ (rightAdjointOfEquiv e he) 
goal: (CategoryTheory.Adjunction.adjunctionOfEquivRight e he).unit.app X =
  (e X (F.obj X)) (CategoryTheory.CategoryStruct.id (F.obj X))

full_name: CategoryTheory.Adjunction.adjunctionOfEquivRight_counit_app
code: /-- Show that the functor given by `rightAdjointOfEquiv` is indeed right adjoint to `F`. Dual
to `adjunctionOfEquivRight`. -/
@[simps!]
def adjunctionOfEquivRight (he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y g) :
    F ⊣ (rightAdjointOfEquiv e he) 
goal: (CategoryTheory.Adjunction.adjunctionOfEquivRight e he).counit.app Y =
  (e (G_obj Y) Y).symm (CategoryTheory.CategoryStruct.id (G_obj Y))

full_name: CategoryTheory.Adjunction.adjunctionOfEquivRight_homEquiv
code: /-- Show that the functor given by `rightAdjointOfEquiv` is indeed right adjoint to `F`. Dual
to `adjunctionOfEquivRight`. -/
@[simps!]
def adjunctionOfEquivRight (he : ∀ X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y g) :
    F ⊣ (rightAdjointOfEquiv e he) 
goal: (CategoryTheory.Adjunction.adjunctionOfEquivRight e he).homEquiv X Y = e X Y

full_name: CategoryTheory.Adjunction.toEquivalence_functor
code: /--
If the unit and counit of a given adjunction are (pointwise) isomorphisms, then we can upgrade the
adjunction to an equivalence.
-/
@[simps!]
noncomputable def toEquivalence (adj : F ⊣ G) [∀ X, IsIso (adj.unit.app X)]
    [∀ Y, IsIso (adj.counit.app Y)] : C ≌ D 
goal: adj.toEquivalence.functor = F

full_name: CategoryTheory.Adjunction.toEquivalence_unitIso_inv_app
code: /--
If the unit and counit of a given adjunction are (pointwise) isomorphisms, then we can upgrade the
adjunction to an equivalence.
-/
@[simps!]
noncomputable def toEquivalence (adj : F ⊣ G) [∀ X, IsIso (adj.unit.app X)]
    [∀ Y, IsIso (adj.counit.app Y)] : C ≌ D 
goal: adj.toEquivalence.unitIso.inv.app X = CategoryTheory.inv (adj.unit.app X)

full_name: CategoryTheory.Adjunction.toEquivalence_counitIso_inv_app
code: /--
If the unit and counit of a given adjunction are (pointwise) isomorphisms, then we can upgrade the
adjunction to an equivalence.
-/
@[simps!]
noncomputable def toEquivalence (adj : F ⊣ G) [∀ X, IsIso (adj.unit.app X)]
    [∀ Y, IsIso (adj.counit.app Y)] : C ≌ D 
goal: adj.toEquivalence.counitIso.inv.app X = CategoryTheory.inv (adj.counit.app X)

full_name: CategoryTheory.Adjunction.toEquivalence
code: /--
If the unit and counit of a given adjunction are (pointwise) isomorphisms, then we can upgrade the
adjunction to an equivalence.
-/
@[simps!]
noncomputable def toEquivalence (adj : F ⊣ G) [∀ X, IsIso (adj.unit.app X)]
    [∀ Y, IsIso (adj.counit.app Y)] : C ≌ D 
goal: C ≌ D

full_name: CategoryTheory.Adjunction.toEquivalence_inverse
code: /--
If the unit and counit of a given adjunction are (pointwise) isomorphisms, then we can upgrade the
adjunction to an equivalence.
-/
@[simps!]
noncomputable def toEquivalence (adj : F ⊣ G) [∀ X, IsIso (adj.unit.app X)]
    [∀ Y, IsIso (adj.counit.app Y)] : C ≌ D 
goal: adj.toEquivalence.inverse = G

full_name: CategoryTheory.Adjunction.toEquivalence_unitIso_hom_app
code: /--
If the unit and counit of a given adjunction are (pointwise) isomorphisms, then we can upgrade the
adjunction to an equivalence.
-/
@[simps!]
noncomputable def toEquivalence (adj : F ⊣ G) [∀ X, IsIso (adj.unit.app X)]
    [∀ Y, IsIso (adj.counit.app Y)] : C ≌ D 
goal: adj.toEquivalence.unitIso.hom.app X = adj.unit.app X

full_name: CategoryTheory.Adjunction.toEquivalence_counitIso_hom_app
code: /--
If the unit and counit of a given adjunction are (pointwise) isomorphisms, then we can upgrade the
adjunction to an equivalence.
-/
@[simps!]
noncomputable def toEquivalence (adj : F ⊣ G) [∀ X, IsIso (adj.unit.app X)]
    [∀ Y, IsIso (adj.counit.app Y)] : C ≌ D 
goal: adj.toEquivalence.counitIso.hom.app X = adj.counit.app X

full_name: CategoryTheory.Functor.isEquivalence_of_isRightAdjoint
code: /--
If the unit and counit for the adjunction corresponding to a right adjoint functor are (pointwise)
isomorphisms, then the functor is an equivalence of categories.
-/
lemma Functor.isEquivalence_of_isRightAdjoint (G : C ⥤ D) [IsRightAdjoint G]
    [∀ X, IsIso ((Adjunction.ofIsRightAdjoint G).unit.app X)]
    [∀ Y, IsIso ((Adjunction.ofIsRightAdjoint G).counit.app Y)] : G.IsEquivalence 
goal: G.IsEquivalence

full_name: CategoryTheory.Equivalence.toAdjunction_counit
code: /-- The adjunction given by an equivalence of categories. (To obtain the opposite adjunction,
simply use `e.symm.toAdjunction`. -/
@[simps! unit counit]
def toAdjunction : e.functor ⊣ e.inverse 
goal: e.toAdjunction.counit = e.counit

full_name: CategoryTheory.Equivalence.toAdjunction_unit
code: /-- The adjunction given by an equivalence of categories. (To obtain the opposite adjunction,
simply use `e.symm.toAdjunction`. -/
@[simps! unit counit]
def toAdjunction : e.functor ⊣ e.inverse 
goal: e.toAdjunction.unit = e.unit

full_name: CategoryTheory.Equivalence.toAdjunction
code: /-- The adjunction given by an equivalence of categories. (To obtain the opposite adjunction,
simply use `e.symm.toAdjunction`. -/
@[simps! unit counit]
def toAdjunction : e.functor ⊣ e.inverse 
goal: e.functor ⊣ e.inverse

full_name: CategoryTheory.Equivalence.isLeftAdjoint_functor
code: lemma isLeftAdjoint_functor : e.functor.IsLeftAdjoint 
goal: e.functor.IsLeftAdjoint

full_name: CategoryTheory.Equivalence.isRightAdjoint_inverse
code: lemma isRightAdjoint_inverse : e.inverse.IsRightAdjoint 
goal: e.inverse.IsRightAdjoint

full_name: CategoryTheory.Equivalence.isLeftAdjoint_inverse
code: lemma isLeftAdjoint_inverse : e.inverse.IsLeftAdjoint 
goal: e.inverse.IsLeftAdjoint

full_name: CategoryTheory.Equivalence.isRightAdjoint_functor
code: lemma isRightAdjoint_functor : e.functor.IsRightAdjoint 
goal: e.functor.IsRightAdjoint

full_name: CategoryTheory.Functor.isLeftAdjoint_comp
code: /-- If `F` and `G` are left adjoints then `F ⋙ G` is a left adjoint too. -/
instance isLeftAdjoint_comp {E : Type u₃} [Category.{v₃} E] (F : C ⥤ D) (G : D ⥤ E)
    [F.IsLeftAdjoint] [G.IsLeftAdjoint] : (F ⋙ G).IsLeftAdjoint 
goal: (F.comp G).IsLeftAdjoint

full_name: CategoryTheory.Functor.isRightAdjoint_comp
code: /-- If `F` and `G` are right adjoints then `F ⋙ G` is a right adjoint too. -/
instance isRightAdjoint_comp {E : Type u₃} [Category.{v₃} E] {F : C ⥤ D} {G : D ⥤ E}
    [IsRightAdjoint F] [IsRightAdjoint G] : IsRightAdjoint (F ⋙ G) 
goal: (F.comp G).IsRightAdjoint

full_name: CategoryTheory.Functor.isRightAdjoint_of_iso
code: /-- Transport being a right adjoint along a natural isomorphism. -/
lemma isRightAdjoint_of_iso {F G : C ⥤ D} (h : F ≅ G) [F.IsRightAdjoint] :
    IsRightAdjoint G 
goal: G.IsRightAdjoint

full_name: CategoryTheory.Functor.isLeftAdjoint_of_iso
code: /-- Transport being a left adjoint along a natural isomorphism. -/
lemma isLeftAdjoint_of_iso {F G : C ⥤ D} (h : F ≅ G) [IsLeftAdjoint F] :
    IsLeftAdjoint G 
goal: G.IsLeftAdjoint

full_name: CategoryTheory.Functor.adjunction
code: /-- An equivalence `E` is left adjoint to its inverse. -/
noncomputable def adjunction (E : C ⥤ D) [IsEquivalence E] : E ⊣ E.inv 
goal: E ⊣ E.inv

full_name: CategoryTheory.Functor.isLeftAdjoint_of_isEquivalence
code: /-- If `F` is an equivalence, it's a left adjoint. -/
instance (priority := 10) isLeftAdjoint_of_isEquivalence {F : C ⥤ D} [F.IsEquivalence] :
    IsLeftAdjoint F 
goal: F.IsLeftAdjoint

full_name: CategoryTheory.Functor.isRightAdjoint_of_isEquivalence
code: /-- If `F` is an equivalence, it's a right adjoint. -/
instance (priority := 10) isRightAdjoint_of_isEquivalence {F : C ⥤ D} [F.IsEquivalence] :
    IsRightAdjoint F 
goal: F.IsRightAdjoint