l3lab/ntp-mathlib huggingface dataset:
@[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 := by
  rw [Equiv.symm_apply_eq]
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
f : X ⟶ G.obj Y
g : Y ⟶ Y'
⊢ f ≫ G.map g = (homEquiv adj X Y') ((homEquiv adj X Y).symm f ≫ g)

Next tactic:
simp only [homEquiv_naturality_right,eq_self_iff_true,Equiv.apply_symm_apply]
@[simp]
theorem left_triangle : whiskerRight adj.unit F ≫ whiskerLeft F adj.counit = 𝟙 _ := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
⊢ whiskerRight adj.unit F ≫ whiskerLeft F adj.counit = 𝟙 (𝟭 C ⋙ F)

Next tactic:
ext
@[simp]
theorem left_triangle : whiskerRight adj.unit F ≫ whiskerLeft F adj.counit = 𝟙 _ := by
  ext; 

Proof state:
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
x✝ : C
⊢ (whiskerRight adj.unit F ≫ whiskerLeft F adj.counit).app x✝ = (𝟙 (𝟭 C ⋙ F)).app x✝

Next tactic:
dsimp
@[simp]
theorem left_triangle : whiskerRight adj.unit F ≫ whiskerLeft F adj.counit = 𝟙 _ := by
  ext; dsimp
  

Proof state:
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
x✝ : C
⊢ F.map (adj.unit.app x✝) ≫ adj.counit.app (F.obj x✝) = 𝟙 (F.obj x✝)

Next tactic:
erw [← adj.homEquiv_counit, Equiv.symm_apply_eq, adj.homEquiv_unit]
@[simp]
theorem left_triangle : whiskerRight adj.unit F ≫ whiskerLeft F adj.counit = 𝟙 _ := by
  ext; dsimp
  erw [← adj.homEquiv_counit, Equiv.symm_apply_eq, adj.homEquiv_unit]
  

Proof state:
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
x✝ : C
⊢ adj.unit.app x✝ = adj.unit.app x✝ ≫ G.map (𝟙 (F.obj x✝))

Next tactic:
simp
@[simp]
theorem right_triangle : whiskerLeft G adj.unit ≫ whiskerRight adj.counit G = 𝟙 _ := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
⊢ whiskerLeft G adj.unit ≫ whiskerRight adj.counit G = 𝟙 (G ⋙ 𝟭 C)

Next tactic:
ext
@[simp]
theorem right_triangle : whiskerLeft G adj.unit ≫ whiskerRight adj.counit G = 𝟙 _ := by
  ext; 

Proof state:
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' x✝ : D
⊢ (whiskerLeft G adj.unit ≫ whiskerRight adj.counit G).app x✝ = (𝟙 (G ⋙ 𝟭 C)).app x✝

Next tactic:
dsimp
@[simp]
theorem right_triangle : whiskerLeft G adj.unit ≫ whiskerRight adj.counit G = 𝟙 _ := by
  ext; dsimp
  

Proof state:
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' x✝ : D
⊢ adj.unit.app (G.obj x✝) ≫ G.map (adj.counit.app x✝) = 𝟙 (G.obj x✝)

Next tactic:
erw [← adj.homEquiv_unit, ← Equiv.eq_symm_apply, adj.homEquiv_counit]
@[simp]
theorem right_triangle : whiskerLeft G adj.unit ≫ whiskerRight adj.counit G = 𝟙 _ := by
  ext; dsimp
  erw [← adj.homEquiv_unit, ← Equiv.eq_symm_apply, adj.homEquiv_counit]
  

Proof state:
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' x✝ : D
⊢ adj.counit.app x✝ = F.map (𝟙 (G.obj x✝)) ≫ adj.counit.app x✝

Next tactic:
simp
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 :=
  ⟨fun h => by
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
A : C
B : D
f : F.obj A ⟶ B
g : A ⟶ G.obj B
h : (homEquiv adj A B) f = g
⊢ f = (homEquiv adj A B).symm g

Next tactic:
cases h
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 :=
  ⟨fun h => by
    cases h
    

Proof state:
case refl
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
A : C
B : D
f : F.obj A ⟶ B
⊢ f = (homEquiv adj A B).symm ((homEquiv adj A B) f)

Next tactic:
simp
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 :=
  ⟨fun h => by
    cases h
    simp, fun h => by
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
A : C
B : D
f : F.obj A ⟶ B
g : A ⟶ G.obj B
h : f = (homEquiv adj A B).symm g
⊢ (homEquiv adj A B) f = g

Next tactic:
cases h
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 :=
  ⟨fun h => by
    cases h
    simp, fun h => by
    cases h
    

Proof state:
case refl
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
A : C
B : D
g : A ⟶ G.obj B
⊢ (homEquiv adj A B) ((homEquiv adj A B).symm g) = g

Next tactic:
simp
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 :=
  ⟨fun h => by
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
A : C
B : D
f : F.obj A ⟶ B
g : A ⟶ G.obj B
h : g = (homEquiv adj A B) f
⊢ (homEquiv adj A B).symm g = f

Next tactic:
cases h
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 :=
  ⟨fun h => by
    cases h
    

Proof state:
case refl
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
A : C
B : D
f : F.obj A ⟶ B
⊢ (homEquiv adj A B).symm ((homEquiv adj A B) f) = f

Next tactic:
simp
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 :=
  ⟨fun h => by
    cases h
    simp, fun h => by
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
A : C
B : D
f : F.obj A ⟶ B
g : A ⟶ G.obj B
h : (homEquiv adj A B).symm g = f
⊢ g = (homEquiv adj A B) f

Next tactic:
cases h
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 :=
  ⟨fun h => by
    cases h
    simp, fun h => by
    cases h
    

Proof state:
case refl
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : F ⊣ G
X' X : C
Y Y' : D
A : C
B : D
g : A ⟶ G.obj B
⊢ g = (homEquiv adj A B) ((homEquiv adj A B).symm g)

Next tactic:
simp
@[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 := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X' X : C
Y Y' : D
f : X' ⟶ X
g : F.obj X ⟶ Y
⊢ (homEquiv adj X' (F.obj X)) (F.map f) ≫ G.map g = f ≫ (homEquiv adj X Y) g

Next tactic:
rw [← homEquiv_naturality_right, ← Equiv.eq_symm_apply]
@[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 := by
  rw [← homEquiv_naturality_right, ← Equiv.eq_symm_apply]; 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X' X : C
Y Y' : D
f : X' ⟶ X
g : F.obj X ⟶ Y
⊢ F.map f ≫ g = (homEquiv adj X' Y).symm (f ≫ (homEquiv adj X Y) g)

Next tactic:
simp
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 := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X' X : C
Y Y' : D
f : X' ⟶ X
g : F.obj X ⟶ Y
⊢ (homEquiv adj X' Y) (F.map f ≫ g) = f ≫ (homEquiv adj X Y) g

Next tactic:
rw [← Equiv.eq_symm_apply]
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 := by
  rw [← Equiv.eq_symm_apply]; 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X' X : C
Y Y' : D
f : X' ⟶ X
g : F.obj X ⟶ Y
⊢ F.map f ≫ g = (homEquiv adj X' Y).symm (f ≫ (homEquiv adj X Y) g)

Next tactic:
simp
@[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 := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X' X : C
Y Y' : D
f : X ⟶ G.obj Y
g : Y ⟶ Y'
⊢ F.map f ≫ (homEquiv adj (G.obj Y) Y').symm (G.map g) = (homEquiv adj X Y).symm f ≫ g

Next tactic:
rw [← homEquiv_naturality_left_symm, Equiv.symm_apply_eq]
@[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 := by
  rw [← homEquiv_naturality_left_symm, Equiv.symm_apply_eq]; 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X' X : C
Y Y' : D
f : X ⟶ G.obj Y
g : Y ⟶ Y'
⊢ f ≫ G.map g = (homEquiv adj X Y') ((homEquiv adj X Y).symm f ≫ g)

Next tactic:
simp
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 := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X' X : C
Y Y' : D
f : X ⟶ G.obj Y
g : Y ⟶ Y'
⊢ (homEquiv adj X Y').symm (f ≫ G.map g) = (homEquiv adj X Y).symm f ≫ g

Next tactic:
rw [Equiv.symm_apply_eq]
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 := by
  rw [Equiv.symm_apply_eq]; 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X' X : C
Y Y' : D
f : X ⟶ G.obj Y
g : Y ⟶ Y'
⊢ f ≫ G.map g = (homEquiv adj X Y') ((homEquiv adj X Y).symm f ≫ g)

Next tactic:
simp
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
⊢ ∀ ⦃X Y : C⦄ (f : X ⟶ Y),
    (𝟭 C).map f ≫ (fun X => (CoreHomEquiv.homEquiv adj X (F.obj X)) (𝟙 (F.obj X))) Y =
      (fun X => (CoreHomEquiv.homEquiv adj X (F.obj X)) (𝟙 (F.obj X))) X ≫ (F ⋙ G).map f

Next tactic:
intros
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          intros
          

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X✝ Y✝ : C
f✝ : X✝ ⟶ Y✝
⊢ (𝟭 C).map f✝ ≫ (fun X => (CoreHomEquiv.homEquiv adj X (F.obj X)) (𝟙 (F.obj X))) Y✝ =
    (fun X => (CoreHomEquiv.homEquiv adj X (F.obj X)) (𝟙 (F.obj X))) X✝ ≫ (F ⋙ G).map f✝

Next tactic:
erw [← adj.homEquiv_naturality_left, ← adj.homEquiv_naturality_right]
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left, ← adj.homEquiv_naturality_right]
          

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X✝ Y✝ : C
f✝ : X✝ ⟶ Y✝
⊢ (CoreHomEquiv.homEquiv adj ((𝟭 C).obj X✝) (F.obj Y✝)) (F.map ((𝟭 C).map f✝) ≫ 𝟙 (F.obj Y✝)) =
    (CoreHomEquiv.homEquiv adj ((𝟭 C).obj X✝) (F.obj Y✝)) (𝟙 (F.obj X✝) ≫ F.map f✝)

Next tactic:
dsimp
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left, ← adj.homEquiv_naturality_right]
          dsimp; 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X✝ Y✝ : C
f✝ : X✝ ⟶ Y✝
⊢ (CoreHomEquiv.homEquiv adj X✝ (F.obj Y✝)) (F.map f✝ ≫ 𝟙 (F.obj Y✝)) =
    (CoreHomEquiv.homEquiv adj X✝ (F.obj Y✝)) (𝟙 (F.obj X✝) ≫ F.map f✝)

Next tactic:
simp
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left, ← adj.homEquiv_naturality_right]
          dsimp; simp }
    counit :=
      { app := fun Y => (adj.homEquiv _ _).invFun (𝟙 (G.obj Y))
        naturality := by
          

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
⊢ ∀ ⦃X Y : D⦄ (f : X ⟶ Y),
    (G ⋙ F).map f ≫ (fun Y => Equiv.invFun (CoreHomEquiv.homEquiv adj (G.obj Y) ((𝟭 D).obj Y)) (𝟙 (G.obj Y))) Y =
      (fun Y => Equiv.invFun (CoreHomEquiv.homEquiv adj (G.obj Y) ((𝟭 D).obj Y)) (𝟙 (G.obj Y))) X ≫ (𝟭 D).map f

Next tactic:
intros
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left, ← adj.homEquiv_naturality_right]
          dsimp; simp }
    counit :=
      { app := fun Y => (adj.homEquiv _ _).invFun (𝟙 (G.obj Y))
        naturality := by
          intros
          

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X✝ Y✝ : D
f✝ : X✝ ⟶ Y✝
⊢ (G ⋙ F).map f✝ ≫ (fun Y => Equiv.invFun (CoreHomEquiv.homEquiv adj (G.obj Y) ((𝟭 D).obj Y)) (𝟙 (G.obj Y))) Y✝ =
    (fun Y => Equiv.invFun (CoreHomEquiv.homEquiv adj (G.obj Y) ((𝟭 D).obj Y)) (𝟙 (G.obj Y))) X✝ ≫ (𝟭 D).map f✝

Next tactic:
erw [← adj.homEquiv_naturality_left_symm, ← adj.homEquiv_naturality_right_symm]
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left, ← adj.homEquiv_naturality_right]
          dsimp; simp }
    counit :=
      { app := fun Y => (adj.homEquiv _ _).invFun (𝟙 (G.obj Y))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left_symm, ← adj.homEquiv_naturality_right_symm]
          

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X✝ Y✝ : D
f✝ : X✝ ⟶ Y✝
⊢ (CoreHomEquiv.homEquiv adj (G.obj X✝) ((𝟭 D).obj Y✝)).symm (G.map f✝ ≫ 𝟙 (G.obj Y✝)) =
    (CoreHomEquiv.homEquiv adj (G.obj X✝) ((𝟭 D).obj Y✝)).symm (𝟙 (G.obj X✝) ≫ G.map ((𝟭 D).map f✝))

Next tactic:
dsimp
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left, ← adj.homEquiv_naturality_right]
          dsimp; simp }
    counit :=
      { app := fun Y => (adj.homEquiv _ _).invFun (𝟙 (G.obj Y))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left_symm, ← adj.homEquiv_naturality_right_symm]
          dsimp; 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X✝ Y✝ : D
f✝ : X✝ ⟶ Y✝
⊢ (CoreHomEquiv.homEquiv adj (G.obj X✝) Y✝).symm (G.map f✝ ≫ 𝟙 (G.obj Y✝)) =
    (CoreHomEquiv.homEquiv adj (G.obj X✝) Y✝).symm (𝟙 (G.obj X✝) ≫ G.map f✝)

Next tactic:
simp
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left, ← adj.homEquiv_naturality_right]
          dsimp; simp }
    counit :=
      { app := fun Y => (adj.homEquiv _ _).invFun (𝟙 (G.obj Y))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left_symm, ← adj.homEquiv_naturality_right_symm]
          dsimp; simp }
    homEquiv_unit := @fun X Y f => by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X : C
Y : D
f : F.obj X ⟶ Y
⊢ (CoreHomEquiv.homEquiv adj X Y) f =
    (NatTrans.mk fun X => (CoreHomEquiv.homEquiv adj X (F.obj X)) (𝟙 (F.obj X))).app X ≫ G.map f

Next tactic:
erw [← adj.homEquiv_naturality_right]
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left, ← adj.homEquiv_naturality_right]
          dsimp; simp }
    counit :=
      { app := fun Y => (adj.homEquiv _ _).invFun (𝟙 (G.obj Y))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left_symm, ← adj.homEquiv_naturality_right_symm]
          dsimp; simp }
    homEquiv_unit := @fun X Y f => by erw [← adj.homEquiv_naturality_right]; 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X : C
Y : D
f : F.obj X ⟶ Y
⊢ (CoreHomEquiv.homEquiv adj X Y) f = (CoreHomEquiv.homEquiv adj ((𝟭 C).obj X) Y) (𝟙 (F.obj X) ≫ f)

Next tactic:
simp
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left, ← adj.homEquiv_naturality_right]
          dsimp; simp }
    counit :=
      { app := fun Y => (adj.homEquiv _ _).invFun (𝟙 (G.obj Y))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left_symm, ← adj.homEquiv_naturality_right_symm]
          dsimp; simp }
    homEquiv_unit := @fun X Y f => by erw [← adj.homEquiv_naturality_right]; simp
    homEquiv_counit := @fun X Y f => by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X : C
Y : D
f : X ⟶ G.obj Y
⊢ (CoreHomEquiv.homEquiv adj X Y).symm f =
    F.map f ≫
      (NatTrans.mk fun Y => Equiv.invFun (CoreHomEquiv.homEquiv adj (G.obj Y) ((𝟭 D).obj Y)) (𝟙 (G.obj Y))).app Y

Next tactic:
erw [← adj.homEquiv_naturality_left_symm]
/-- 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 :=
  -- See note [dsimp, simp].
  { adj with
    unit :=
      { app := fun X => (adj.homEquiv X (F.obj X)) (𝟙 (F.obj X))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left, ← adj.homEquiv_naturality_right]
          dsimp; simp }
    counit :=
      { app := fun Y => (adj.homEquiv _ _).invFun (𝟙 (G.obj Y))
        naturality := by
          intros
          erw [← adj.homEquiv_naturality_left_symm, ← adj.homEquiv_naturality_right_symm]
          dsimp; simp }
    homEquiv_unit := @fun X Y f => by erw [← adj.homEquiv_naturality_right]; simp
    homEquiv_counit := @fun X Y f => by erw [← adj.homEquiv_naturality_left_symm]; 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreHomEquiv F G
X : C
Y : D
f : X ⟶ G.obj Y
⊢ (CoreHomEquiv.homEquiv adj X Y).symm f = (CoreHomEquiv.homEquiv adj X ((𝟭 D).obj Y)).symm (f ≫ 𝟙 (G.obj Y))

Next tactic:
simp
/-- 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 :=
  { adj with
    homEquiv := fun X Y =>
      { toFun := fun f => adj.unit.app X ≫ G.map f
        invFun := fun g => F.map g ≫ adj.counit.app Y
        left_inv := fun f => by
          

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreUnitCounit F G
X : C
Y : D
f : F.obj X ⟶ Y
⊢ (fun g => F.map g ≫ adj.counit.app Y) ((fun f => adj.unit.app X ≫ G.map f) f) = f

Next tactic:
change F.map (_ ≫ _) ≫ _ = _
/-- 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 :=
  { adj with
    homEquiv := fun X Y =>
      { toFun := fun f => adj.unit.app X ≫ G.map f
        invFun := fun g => F.map g ≫ adj.counit.app Y
        left_inv := fun f => by
          change F.map (_ ≫ _) ≫ _ = _
          

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : C ⥤ D
G : D ⥤ C
adj : CoreUnitCounit F G
X : C
Y : D
f : F.obj X ⟶ Y
⊢ F.map (adj.unit.app X ≫ G.map f) ≫ adj.counit.app Y = f

Next tactic:
rw [F.map_comp, assoc, ← Functor.comp_map, adj.counit.naturality, ← assoc]