l3lab/ntp-mathlib huggingface dataset:
/-- An auxiliary definition to be used in defining `CategoryTheory.Sheaf.adjunction` below. -/
@[simps]
def composeEquiv (adj : G ⊣ F) (X : Sheaf J E) (Y : Sheaf J D) :
    ((composeAndSheafify J G).obj X ⟶ Y) ≃ (X ⟶ (sheafCompose J F).obj Y) :=
  let A := adj.whiskerRight Cᵒᵖ
  { toFun := fun η => ⟨A.homEquiv _ _ (J.toSheafify _ ≫ η.val)⟩
    invFun := fun γ => ⟨J.sheafifyLift ((A.homEquiv _ _).symm ((sheafToPresheaf _ _).map γ)) Y.2⟩
    left_inv := by
      intro η
      ext1
      

Proof state:
case h
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X : Sheaf J E
Y : Sheaf J D
A : (whiskeringRight Cᵒᵖ E D).obj G ⊣ (whiskeringRight Cᵒᵖ D E).obj F := Adjunction.whiskerRight Cᵒᵖ adj
η : (composeAndSheafify J G).obj X ⟶ Y
⊢ ((fun γ =>
          {
            val :=
              sheafifyLift J
                ((Adjunction.homEquiv A ((sheafToPresheaf J E).obj X) Y.val).symm ((sheafToPresheaf J E).map γ))
                (_ : Presheaf.IsSheaf J Y.val) })
        ((fun η =>
            {
              val :=
                (Adjunction.homEquiv A X.val Y.val)
                  (toSheafify J (((whiskeringRight Cᵒᵖ E D).obj G).obj X.val) ≫ η.val) })
          η)).val =
    η.val

Next tactic:
dsimp
/-- An auxiliary definition to be used in defining `CategoryTheory.Sheaf.adjunction` below. -/
@[simps]
def composeEquiv (adj : G ⊣ F) (X : Sheaf J E) (Y : Sheaf J D) :
    ((composeAndSheafify J G).obj X ⟶ Y) ≃ (X ⟶ (sheafCompose J F).obj Y) :=
  let A := adj.whiskerRight Cᵒᵖ
  { toFun := fun η => ⟨A.homEquiv _ _ (J.toSheafify _ ≫ η.val)⟩
    invFun := fun γ => ⟨J.sheafifyLift ((A.homEquiv _ _).symm ((sheafToPresheaf _ _).map γ)) Y.2⟩
    left_inv := by
      intro η
      ext1
      dsimp
      

Proof state:
case h
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X : Sheaf J E
Y : Sheaf J D
A : (whiskeringRight Cᵒᵖ E D).obj G ⊣ (whiskeringRight Cᵒᵖ D E).obj F := Adjunction.whiskerRight Cᵒᵖ adj
η : (composeAndSheafify J G).obj X ⟶ Y
⊢ sheafifyLift J
      ((Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X.val Y.val).symm
        ((Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X.val Y.val) (toSheafify J (X.val ⋙ G) ≫ η.val)))
      (_ : Presheaf.IsSheaf J Y.val) =
    η.val

Next tactic:
symm
/-- An auxiliary definition to be used in defining `CategoryTheory.Sheaf.adjunction` below. -/
@[simps]
def composeEquiv (adj : G ⊣ F) (X : Sheaf J E) (Y : Sheaf J D) :
    ((composeAndSheafify J G).obj X ⟶ Y) ≃ (X ⟶ (sheafCompose J F).obj Y) :=
  let A := adj.whiskerRight Cᵒᵖ
  { toFun := fun η => ⟨A.homEquiv _ _ (J.toSheafify _ ≫ η.val)⟩
    invFun := fun γ => ⟨J.sheafifyLift ((A.homEquiv _ _).symm ((sheafToPresheaf _ _).map γ)) Y.2⟩
    left_inv := by
      intro η
      ext1
      dsimp
      symm
      

Proof state:
case h
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X : Sheaf J E
Y : Sheaf J D
A : (whiskeringRight Cᵒᵖ E D).obj G ⊣ (whiskeringRight Cᵒᵖ D E).obj F := Adjunction.whiskerRight Cᵒᵖ adj
η : (composeAndSheafify J G).obj X ⟶ Y
⊢ η.val =
    sheafifyLift J
      ((Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X.val Y.val).symm
        ((Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X.val Y.val) (toSheafify J (X.val ⋙ G) ≫ η.val)))
      (_ : Presheaf.IsSheaf J Y.val)

Next tactic:
apply J.sheafifyLift_unique
/-- An auxiliary definition to be used in defining `CategoryTheory.Sheaf.adjunction` below. -/
@[simps]
def composeEquiv (adj : G ⊣ F) (X : Sheaf J E) (Y : Sheaf J D) :
    ((composeAndSheafify J G).obj X ⟶ Y) ≃ (X ⟶ (sheafCompose J F).obj Y) :=
  let A := adj.whiskerRight Cᵒᵖ
  { toFun := fun η => ⟨A.homEquiv _ _ (J.toSheafify _ ≫ η.val)⟩
    invFun := fun γ => ⟨J.sheafifyLift ((A.homEquiv _ _).symm ((sheafToPresheaf _ _).map γ)) Y.2⟩
    left_inv := by
      intro η
      ext1
      dsimp
      symm
      apply J.sheafifyLift_unique
      

Proof state:
case h.a
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X : Sheaf J E
Y : Sheaf J D
A : (whiskeringRight Cᵒᵖ E D).obj G ⊣ (whiskeringRight Cᵒᵖ D E).obj F := Adjunction.whiskerRight Cᵒᵖ adj
η : (composeAndSheafify J G).obj X ⟶ Y
⊢ toSheafify J (X.val ⋙ G) ≫ η.val =
    (Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X.val Y.val).symm
      ((Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X.val Y.val) (toSheafify J (X.val ⋙ G) ≫ η.val))

Next tactic:
rw [Equiv.symm_apply_apply]
/-- An auxiliary definition to be used in defining `CategoryTheory.Sheaf.adjunction` below. -/
@[simps]
def composeEquiv (adj : G ⊣ F) (X : Sheaf J E) (Y : Sheaf J D) :
    ((composeAndSheafify J G).obj X ⟶ Y) ≃ (X ⟶ (sheafCompose J F).obj Y) :=
  let A := adj.whiskerRight Cᵒᵖ
  { toFun := fun η => ⟨A.homEquiv _ _ (J.toSheafify _ ≫ η.val)⟩
    invFun := fun γ => ⟨J.sheafifyLift ((A.homEquiv _ _).symm ((sheafToPresheaf _ _).map γ)) Y.2⟩
    left_inv := by
      intro η
      ext1
      dsimp
      symm
      apply J.sheafifyLift_unique
      rw [Equiv.symm_apply_apply]
    right_inv := by
      

Proof state:
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X : Sheaf J E
Y : Sheaf J D
A : (whiskeringRight Cᵒᵖ E D).obj G ⊣ (whiskeringRight Cᵒᵖ D E).obj F := Adjunction.whiskerRight Cᵒᵖ adj
⊢ Function.RightInverse
    (fun γ =>
      {
        val :=
          sheafifyLift J
            ((Adjunction.homEquiv A ((sheafToPresheaf J E).obj X) Y.val).symm ((sheafToPresheaf J E).map γ))
            (_ : Presheaf.IsSheaf J Y.val) })
    fun η =>
    { val := (Adjunction.homEquiv A X.val Y.val) (toSheafify J (((whiskeringRight Cᵒᵖ E D).obj G).obj X.val) ≫ η.val) }

Next tactic:
intro γ
/-- An auxiliary definition to be used in defining `CategoryTheory.Sheaf.adjunction` below. -/
@[simps]
def composeEquiv (adj : G ⊣ F) (X : Sheaf J E) (Y : Sheaf J D) :
    ((composeAndSheafify J G).obj X ⟶ Y) ≃ (X ⟶ (sheafCompose J F).obj Y) :=
  let A := adj.whiskerRight Cᵒᵖ
  { toFun := fun η => ⟨A.homEquiv _ _ (J.toSheafify _ ≫ η.val)⟩
    invFun := fun γ => ⟨J.sheafifyLift ((A.homEquiv _ _).symm ((sheafToPresheaf _ _).map γ)) Y.2⟩
    left_inv := by
      intro η
      ext1
      dsimp
      symm
      apply J.sheafifyLift_unique
      rw [Equiv.symm_apply_apply]
    right_inv := by
      intro γ
      

Proof state:
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X : Sheaf J E
Y : Sheaf J D
A : (whiskeringRight Cᵒᵖ E D).obj G ⊣ (whiskeringRight Cᵒᵖ D E).obj F := Adjunction.whiskerRight Cᵒᵖ adj
γ : X ⟶ (sheafCompose J F).obj Y
⊢ (fun η =>
        {
          val :=
            (Adjunction.homEquiv A X.val Y.val) (toSheafify J (((whiskeringRight Cᵒᵖ E D).obj G).obj X.val) ≫ η.val) })
      ((fun γ =>
          {
            val :=
              sheafifyLift J
                ((Adjunction.homEquiv A ((sheafToPresheaf J E).obj X) Y.val).symm ((sheafToPresheaf J E).map γ))
                (_ : Presheaf.IsSheaf J Y.val) })
        γ) =
    γ

Next tactic:
ext1
/-- An auxiliary definition to be used in defining `CategoryTheory.Sheaf.adjunction` below. -/
@[simps]
def composeEquiv (adj : G ⊣ F) (X : Sheaf J E) (Y : Sheaf J D) :
    ((composeAndSheafify J G).obj X ⟶ Y) ≃ (X ⟶ (sheafCompose J F).obj Y) :=
  let A := adj.whiskerRight Cᵒᵖ
  { toFun := fun η => ⟨A.homEquiv _ _ (J.toSheafify _ ≫ η.val)⟩
    invFun := fun γ => ⟨J.sheafifyLift ((A.homEquiv _ _).symm ((sheafToPresheaf _ _).map γ)) Y.2⟩
    left_inv := by
      intro η
      ext1
      dsimp
      symm
      apply J.sheafifyLift_unique
      rw [Equiv.symm_apply_apply]
    right_inv := by
      intro γ
      ext1
      

Proof state:
case h
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X : Sheaf J E
Y : Sheaf J D
A : (whiskeringRight Cᵒᵖ E D).obj G ⊣ (whiskeringRight Cᵒᵖ D E).obj F := Adjunction.whiskerRight Cᵒᵖ adj
γ : X ⟶ (sheafCompose J F).obj Y
⊢ ((fun η =>
          {
            val :=
              (Adjunction.homEquiv A X.val Y.val)
                (toSheafify J (((whiskeringRight Cᵒᵖ E D).obj G).obj X.val) ≫ η.val) })
        ((fun γ =>
            {
              val :=
                sheafifyLift J
                  ((Adjunction.homEquiv A ((sheafToPresheaf J E).obj X) Y.val).symm ((sheafToPresheaf J E).map γ))
                  (_ : Presheaf.IsSheaf J Y.val) })
          γ)).val =
    γ.val

Next tactic:
dsimp
/-- An auxiliary definition to be used in defining `CategoryTheory.Sheaf.adjunction` below. -/
@[simps]
def composeEquiv (adj : G ⊣ F) (X : Sheaf J E) (Y : Sheaf J D) :
    ((composeAndSheafify J G).obj X ⟶ Y) ≃ (X ⟶ (sheafCompose J F).obj Y) :=
  let A := adj.whiskerRight Cᵒᵖ
  { toFun := fun η => ⟨A.homEquiv _ _ (J.toSheafify _ ≫ η.val)⟩
    invFun := fun γ => ⟨J.sheafifyLift ((A.homEquiv _ _).symm ((sheafToPresheaf _ _).map γ)) Y.2⟩
    left_inv := by
      intro η
      ext1
      dsimp
      symm
      apply J.sheafifyLift_unique
      rw [Equiv.symm_apply_apply]
    right_inv := by
      intro γ
      ext1
      dsimp
      -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
      

Proof state:
case h
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X : Sheaf J E
Y : Sheaf J D
A : (whiskeringRight Cᵒᵖ E D).obj G ⊣ (whiskeringRight Cᵒᵖ D E).obj F := Adjunction.whiskerRight Cᵒᵖ adj
γ : X ⟶ (sheafCompose J F).obj Y
⊢ (Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X.val Y.val)
      (toSheafify J (X.val ⋙ G) ≫
        sheafifyLift J ((Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X.val Y.val).symm γ.val)
          (_ : Presheaf.IsSheaf J Y.val)) =
    γ.val

Next tactic:
erw [J.toSheafify_sheafifyLift, Equiv.apply_symm_apply]
/-- An adjunction `adj : G ⊣ F` with `F : D ⥤ E` and `G : E ⥤ D` induces an adjunction
between `Sheaf J D` and `Sheaf J E`, in contexts where one can sheafify `D`-valued presheaves,
and `F` preserves the correct limits. -/
@[simps! unit_app_val counit_app_val]
def adjunction (adj : G ⊣ F) : composeAndSheafify J G ⊣ sheafCompose J F :=
  Adjunction.mkOfHomEquiv
    { homEquiv := composeEquiv J adj
      homEquiv_naturality_left_symm := fun f g => by
        

Proof state:
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X'✝ X✝ : Sheaf J E
Y✝ : Sheaf J D
f : X'✝ ⟶ X✝
g : X✝ ⟶ (sheafCompose J F).obj Y✝
⊢ (composeEquiv J adj X'✝ Y✝).symm (f ≫ g) = (composeAndSheafify J G).map f ≫ (composeEquiv J adj X✝ Y✝).symm g

Next tactic:
ext1
/-- An adjunction `adj : G ⊣ F` with `F : D ⥤ E` and `G : E ⥤ D` induces an adjunction
between `Sheaf J D` and `Sheaf J E`, in contexts where one can sheafify `D`-valued presheaves,
and `F` preserves the correct limits. -/
@[simps! unit_app_val counit_app_val]
def adjunction (adj : G ⊣ F) : composeAndSheafify J G ⊣ sheafCompose J F :=
  Adjunction.mkOfHomEquiv
    { homEquiv := composeEquiv J adj
      homEquiv_naturality_left_symm := fun f g => by
        ext1
        

Proof state:
case h
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X'✝ X✝ : Sheaf J E
Y✝ : Sheaf J D
f : X'✝ ⟶ X✝
g : X✝ ⟶ (sheafCompose J F).obj Y✝
⊢ ((composeEquiv J adj X'✝ Y✝).symm (f ≫ g)).val =
    ((composeAndSheafify J G).map f ≫ (composeEquiv J adj X✝ Y✝).symm g).val

Next tactic:
dsimp [composeEquiv]
/-- An adjunction `adj : G ⊣ F` with `F : D ⥤ E` and `G : E ⥤ D` induces an adjunction
between `Sheaf J D` and `Sheaf J E`, in contexts where one can sheafify `D`-valued presheaves,
and `F` preserves the correct limits. -/
@[simps! unit_app_val counit_app_val]
def adjunction (adj : G ⊣ F) : composeAndSheafify J G ⊣ sheafCompose J F :=
  Adjunction.mkOfHomEquiv
    { homEquiv := composeEquiv J adj
      homEquiv_naturality_left_symm := fun f g => by
        ext1
        dsimp [composeEquiv]
        

Proof state:
case h
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X'✝ X✝ : Sheaf J E
Y✝ : Sheaf J D
f : X'✝ ⟶ X✝
g : X✝ ⟶ (sheafCompose J F).obj Y✝
⊢ sheafifyLift J ((Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X'✝.val Y✝.val).symm (f.val ≫ g.val))
      (_ : Presheaf.IsSheaf J Y✝.val) =
    sheafifyMap J (whiskerRight f.val G) ≫
      sheafifyLift J ((Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X✝.val Y✝.val).symm g.val)
        (_ : Presheaf.IsSheaf J Y✝.val)

Next tactic:
rw [sheafifyMap_sheafifyLift]
/-- An adjunction `adj : G ⊣ F` with `F : D ⥤ E` and `G : E ⥤ D` induces an adjunction
between `Sheaf J D` and `Sheaf J E`, in contexts where one can sheafify `D`-valued presheaves,
and `F` preserves the correct limits. -/
@[simps! unit_app_val counit_app_val]
def adjunction (adj : G ⊣ F) : composeAndSheafify J G ⊣ sheafCompose J F :=
  Adjunction.mkOfHomEquiv
    { homEquiv := composeEquiv J adj
      homEquiv_naturality_left_symm := fun f g => by
        ext1
        dsimp [composeEquiv]
        rw [sheafifyMap_sheafifyLift]
        

Proof state:
case h
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X'✝ X✝ : Sheaf J E
Y✝ : Sheaf J D
f : X'✝ ⟶ X✝
g : X✝ ⟶ (sheafCompose J F).obj Y✝
⊢ sheafifyLift J ((Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X'✝.val Y✝.val).symm (f.val ≫ g.val))
      (_ : Presheaf.IsSheaf J Y✝.val) =
    sheafifyLift J
      (whiskerRight f.val G ≫ (Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X✝.val Y✝.val).symm g.val)
      (_ : Presheaf.IsSheaf J Y✝.val)

Next tactic:
erw [Adjunction.homEquiv_naturality_left_symm]
/-- An adjunction `adj : G ⊣ F` with `F : D ⥤ E` and `G : E ⥤ D` induces an adjunction
between `Sheaf J D` and `Sheaf J E`, in contexts where one can sheafify `D`-valued presheaves,
and `F` preserves the correct limits. -/
@[simps! unit_app_val counit_app_val]
def adjunction (adj : G ⊣ F) : composeAndSheafify J G ⊣ sheafCompose J F :=
  Adjunction.mkOfHomEquiv
    { homEquiv := composeEquiv J adj
      homEquiv_naturality_left_symm := fun f g => by
        ext1
        dsimp [composeEquiv]
        rw [sheafifyMap_sheafifyLift]
        erw [Adjunction.homEquiv_naturality_left_symm]
        

Proof state:
case h
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X'✝ X✝ : Sheaf J E
Y✝ : Sheaf J D
f : X'✝ ⟶ X✝
g : X✝ ⟶ (sheafCompose J F).obj Y✝
⊢ sheafifyLift J
      (((whiskeringRight Cᵒᵖ E D).obj G).map f.val ≫
        (Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X✝.val Y✝.val).symm g.val)
      (_ : Presheaf.IsSheaf J Y✝.val) =
    sheafifyLift J
      (whiskerRight f.val G ≫ (Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X✝.val Y✝.val).symm g.val)
      (_ : Presheaf.IsSheaf J Y✝.val)

Next tactic:
rw [whiskeringRight_obj_map]
/-- An adjunction `adj : G ⊣ F` with `F : D ⥤ E` and `G : E ⥤ D` induces an adjunction
between `Sheaf J D` and `Sheaf J E`, in contexts where one can sheafify `D`-valued presheaves,
and `F` preserves the correct limits. -/
@[simps! unit_app_val counit_app_val]
def adjunction (adj : G ⊣ F) : composeAndSheafify J G ⊣ sheafCompose J F :=
  Adjunction.mkOfHomEquiv
    { homEquiv := composeEquiv J adj
      homEquiv_naturality_left_symm := fun f g => by
        ext1
        dsimp [composeEquiv]
        rw [sheafifyMap_sheafifyLift]
        erw [Adjunction.homEquiv_naturality_left_symm]
        rw [whiskeringRight_obj_map]
        

Proof state:
case h
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
D : Type w₁
inst✝⁸ : Category.{max v u, w₁} D
E : Type w₂
inst✝⁷ : Category.{max v u, w₂} E
F : D ⥤ E
G : E ⥤ D
inst✝⁶ : (X : C) → (S : Cover J X) → (P : Cᵒᵖ ⥤ D) → PreservesLimit (MulticospanIndex.multicospan (Cover.index S P)) F
inst✝⁵ : ConcreteCategory D
inst✝⁴ : PreservesLimits (forget D)
inst✝³ : ∀ (P : Cᵒᵖ ⥤ D) (X : C) (S : Cover J X), HasMultiequalizer (Cover.index S P)
inst✝² : ∀ (X : C), HasColimitsOfShape (Cover J X)ᵒᵖ D
inst✝¹ : (X : C) → PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget D)
inst✝ : ReflectsIsomorphisms (forget D)
adj : G ⊣ F
X'✝ X✝ : Sheaf J E
Y✝ : Sheaf J D
f : X'✝ ⟶ X✝
g : X✝ ⟶ (sheafCompose J F).obj Y✝
⊢ sheafifyLift J
      (whiskerRight f.val G ≫ (Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X✝.val Y✝.val).symm g.val)
      (_ : Presheaf.IsSheaf J Y✝.val) =
    sheafifyLift J
      (whiskerRight f.val G ≫ (Adjunction.homEquiv (Adjunction.whiskerRight Cᵒᵖ adj) X✝.val Y✝.val).symm g.val)
      (_ : Presheaf.IsSheaf J Y✝.val)

Next tactic:
rfl