Theorem: CategoryTheory.RanIsSheafOfIsCocontinuous.helper
File: Mathlib/CategoryTheory/Sites/CoverLifting.lean

tactic: dsimp only [gluedLimitCone_π_app]
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
⊢ y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W =
    (gluedLimitCone ℱ hS hx).π.app ((StructuredArrow.map f.op).obj W)
state_after: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
⊢ y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W = getSection ℱ hS hx ((StructuredArrow.map f.op).obj W)

tactic: apply getSection_is_unique ℱ hS hx ((StructuredArrow.map f.op).obj W)
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
⊢ y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W = getSection ℱ hS hx ((StructuredArrow.map f.op).obj W)
state_after: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
⊢ (pulledbackFamily ℱ S x ((StructuredArrow.map f.op).obj W)).IsAmalgamation
    (y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W)

tactic: intro V' fV' hV'
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
⊢ (pulledbackFamily ℱ S x ((StructuredArrow.map f.op).obj W)).IsAmalgamation
    (y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W)
state_after: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
⊢ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val ⋙ coyoneda.obj { unop := X }).map fV'.op
      (y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W) =
    pulledbackFamily ℱ S x ((StructuredArrow.map f.op).obj W) fV' hV'

tactic: dsimp only [Ran.adjunction, Ran.equiv, pulledbackFamily_apply]
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
⊢ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val ⋙ coyoneda.obj { unop := X }).map fV'.op
      (y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W) =
    pulledbackFamily ℱ S x ((StructuredArrow.map f.op).obj W) fV' hV'
state_after: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
⊢ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val ⋙ coyoneda.obj { unop := X }).map fV'.op
      (y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W) =
    x (G.map fV' ≫ ((StructuredArrow.map f.op).obj W).hom.unop) hV' ≫
      ((Adjunction.adjunctionOfEquivRight
                  (fun F G_1 =>
                    {
                        toFun := fun f =>
                          {
                            app := fun x =>
                              f.app (G.op.obj x) ≫
                                limit.π (Ran.diagram G.op G_1 (G.op.obj x)) (StructuredArrow.mk (𝟙 (G.op.obj x))),
                            naturality := ⋯ },
                        invFun := fun f =>
                          { app := fun x => limit.lift (Ran.diagram G.op G_1 x) (Ran.cone x f), naturality := ⋯ },
                        left_inv := ⋯, right_inv := ⋯ }.symm)
                  ⋯).counit.app
            ℱ.val).app
        { unop := V' }

tactic: erw [Adjunction.adjunctionOfEquivRight_counit_app]
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
⊢ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val ⋙ coyoneda.obj { unop := X }).map fV'.op
      (y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W) =
    x (G.map fV' ≫ ((StructuredArrow.map f.op).obj W).hom.unop) hV' ≫
      ((Adjunction.adjunctionOfEquivRight
                  (fun F G_1 =>
                    {
                        toFun := fun f =>
                          {
                            app := fun x =>
                              f.app (G.op.obj x) ≫
                                limit.π (Ran.diagram G.op G_1 (G.op.obj x)) (StructuredArrow.mk (𝟙 (G.op.obj x))),
                            naturality := ⋯ },
                        invFun := fun f =>
                          { app := fun x => limit.lift (Ran.diagram G.op G_1 x) (Ran.cone x f), naturality := ⋯ },
                        left_inv := ⋯, right_inv := ⋯ }.symm)
                  ⋯).counit.app
            ℱ.val).app
        { unop := V' }
state_after: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
⊢ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val ⋙ coyoneda.obj { unop := X }).map fV'.op
      (y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W) =
    x (G.map fV' ≫ ((StructuredArrow.map f.op).obj W).hom.unop) hV' ≫
      ({
                  toFun := fun f =>
                    {
                      app := fun x =>
                        f.app (G.op.obj x) ≫
                          limit.π (Ran.diagram G.op ℱ.val (G.op.obj x)) (StructuredArrow.mk (𝟙 (G.op.obj x))),
                      naturality := ⋯ },
                  invFun := fun f =>
                    { app := fun x => limit.lift (Ran.diagram G.op ℱ.val x) (Ran.cone x f), naturality := ⋯ },
                  left_inv := ⋯, right_inv := ⋯ }.symm.symm
            (𝟙 (Ran.loc G.op ℱ.val))).app
        { unop := V' }

tactic: have :
  y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op =
    x (G.map fV' ≫ W.hom.unop ≫ f) (by simpa only using hV') := by
  convert H (show S ((G.map fV' ≫ W.hom.unop) ≫ f) by simpa only [Category.assoc] using hV')
    using 2
  simp only [Category.assoc]
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
⊢ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val ⋙ coyoneda.obj { unop := X }).map fV'.op
      (y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W) =
    x (G.map fV' ≫ ((StructuredArrow.map f.op).obj W).hom.unop) hV' ≫
      ({
                  toFun := fun f =>
                    {
                      app := fun x =>
                        f.app (G.op.obj x) ≫
                          limit.π (Ran.diagram G.op ℱ.val (G.op.obj x)) (StructuredArrow.mk (𝟙 (G.op.obj x))),
                      naturality := ⋯ },
                  invFun := fun f =>
                    { app := fun x => limit.lift (Ran.diagram G.op ℱ.val x) (Ran.cone x f), naturality := ⋯ },
                  left_inv := ⋯, right_inv := ⋯ }.symm.symm
            (𝟙 (Ran.loc G.op ℱ.val))).app
        { unop := V' }
state_after: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
⊢ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val ⋙ coyoneda.obj { unop := X }).map fV'.op
      (y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W) =
    x (G.map fV' ≫ ((StructuredArrow.map f.op).obj W).hom.unop) hV' ≫
      ({
                  toFun := fun f =>
                    {
                      app := fun x =>
                        f.app (G.op.obj x) ≫
                          limit.π (Ran.diagram G.op ℱ.val (G.op.obj x)) (StructuredArrow.mk (𝟙 (G.op.obj x))),
                      naturality := ⋯ },
                  invFun := fun f =>
                    { app := fun x => limit.lift (Ran.diagram G.op ℱ.val x) (Ran.cone x f), naturality := ⋯ },
                  left_inv := ⋯, right_inv := ⋯ }.symm.symm
            (𝟙 (Ran.loc G.op ℱ.val))).app
        { unop := V' }

tactic: simp only [Quiver.Hom.unop_op, Equiv.symm_symm, StructuredArrow.map_obj_hom, unop_comp,
  Equiv.coe_fn_mk, Functor.comp_map, coyoneda_obj_map, Category.assoc, ← this, op_comp,
  ran_obj_map, NatTrans.id_app]
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
⊢ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val ⋙ coyoneda.obj { unop := X }).map fV'.op
      (y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W) =
    x (G.map fV' ≫ ((StructuredArrow.map f.op).obj W).hom.unop) hV' ≫
      ({
                  toFun := fun f =>
                    {
                      app := fun x =>
                        f.app (G.op.obj x) ≫
                          limit.π (Ran.diagram G.op ℱ.val (G.op.obj x)) (StructuredArrow.mk (𝟙 (G.op.obj x))),
                      naturality := ⋯ },
                  invFun := fun f =>
                    { app := fun x => limit.lift (Ran.diagram G.op ℱ.val x) (Ran.cone x f), naturality := ⋯ },
                  left_inv := ⋯, right_inv := ⋯ }.symm.symm
            (𝟙 (Ran.loc G.op ℱ.val))).app
        { unop := V' }
state_after: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
⊢ y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W ≫ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).map fV'.op =
    y ≫
      limit.pre (Ran.diagram G.op ℱ.val { unop := V }) (StructuredArrow.map (W.hom.unop.op ≫ (G.map fV').op)) ≫
        𝟙 ((Ran.loc G.op ℱ.val).obj (G.op.obj { unop := V' })) ≫
          limit.π (Ran.diagram G.op ℱ.val (G.op.obj { unop := V' })) (StructuredArrow.mk (𝟙 (G.op.obj { unop := V' })))

tactic: erw [Category.id_comp, limit.pre_π]
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
⊢ y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W ≫ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).map fV'.op =
    y ≫
      limit.pre (Ran.diagram G.op ℱ.val { unop := V }) (StructuredArrow.map (W.hom.unop.op ≫ (G.map fV').op)) ≫
        𝟙 ((Ran.loc G.op ℱ.val).obj (G.op.obj { unop := V' })) ≫
          limit.π (Ran.diagram G.op ℱ.val (G.op.obj { unop := V' })) (StructuredArrow.mk (𝟙 (G.op.obj { unop := V' })))
state_after: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
⊢ y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W ≫ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).map fV'.op =
    y ≫
      limit.π (Ran.diagram G.op ℱ.val { unop := V })
        ((StructuredArrow.map (W.hom.unop.op ≫ (G.map fV').op)).obj (StructuredArrow.mk (𝟙 (G.op.obj { unop := V' }))))

tactic: congr
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
⊢ y ≫ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W ≫ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).map fV'.op =
    y ≫
      limit.π (Ran.diagram G.op ℱ.val { unop := V })
        ((StructuredArrow.map (W.hom.unop.op ≫ (G.map fV').op)).obj (StructuredArrow.mk (𝟙 (G.op.obj { unop := V' }))))
state_after: case e_a
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
⊢ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W ≫ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).map fV'.op =
    limit.π (Ran.diagram G.op ℱ.val { unop := V })
      ((StructuredArrow.map (W.hom.unop.op ≫ (G.map fV').op)).obj (StructuredArrow.mk (𝟙 (G.op.obj { unop := V' }))))

tactic: convert limit.w (Ran.diagram G.op ℱ.val (op V)) (StructuredArrow.homMk' W fV'.op)
state_before: case e_a
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
⊢ limit.π (Ran.diagram G.op ℱ.val { unop := V }) W ≫ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).map fV'.op =
    limit.π (Ran.diagram G.op ℱ.val { unop := V })
      ((StructuredArrow.map (W.hom.unop.op ≫ (G.map fV').op)).obj (StructuredArrow.mk (𝟙 (G.op.obj { unop := V' }))))
state_after: case h.e'_3.h.h.e'_7
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
e_1✝ :
  (((ran G.op).obj ℱ.val).obj { unop := V } ⟶ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).obj { unop := V' }) =
    (limit (Ran.diagram G.op ℱ.val { unop := V }) ⟶
      (Ran.diagram G.op ℱ.val { unop := V }).obj (StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)))
⊢ (StructuredArrow.map (W.hom.unop.op ≫ (G.map fV').op)).obj (StructuredArrow.mk (𝟙 (G.op.obj { unop := V' }))) =
    StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)

tactic: rw [StructuredArrow.map_mk]
state_before: case h.e'_3.h.h.e'_7
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
e_1✝ :
  (((ran G.op).obj ℱ.val).obj { unop := V } ⟶ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).obj { unop := V' }) =
    (limit (Ran.diagram G.op ℱ.val { unop := V }) ⟶
      (Ran.diagram G.op ℱ.val { unop := V }).obj (StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)))
⊢ (StructuredArrow.map (W.hom.unop.op ≫ (G.map fV').op)).obj (StructuredArrow.mk (𝟙 (G.op.obj { unop := V' }))) =
    StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)
state_after: case h.e'_3.h.h.e'_7
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
e_1✝ :
  (((ran G.op).obj ℱ.val).obj { unop := V } ⟶ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).obj { unop := V' }) =
    (limit (Ran.diagram G.op ℱ.val { unop := V }) ⟶
      (Ran.diagram G.op ℱ.val { unop := V }).obj (StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)))
⊢ StructuredArrow.mk ((W.hom.unop.op ≫ (G.map fV').op) ≫ 𝟙 (G.op.obj { unop := V' })) =
    StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)

tactic: erw [Category.comp_id]
state_before: case h.e'_3.h.h.e'_7
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
e_1✝ :
  (((ran G.op).obj ℱ.val).obj { unop := V } ⟶ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).obj { unop := V' }) =
    (limit (Ran.diagram G.op ℱ.val { unop := V }) ⟶
      (Ran.diagram G.op ℱ.val { unop := V }).obj (StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)))
⊢ StructuredArrow.mk ((W.hom.unop.op ≫ (G.map fV').op) ≫ 𝟙 (G.op.obj { unop := V' })) =
    StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)
state_after: case h.e'_3.h.h.e'_7
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
e_1✝ :
  (((ran G.op).obj ℱ.val).obj { unop := V } ⟶ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).obj { unop := V' }) =
    (limit (Ran.diagram G.op ℱ.val { unop := V }) ⟶
      (Ran.diagram G.op ℱ.val { unop := V }).obj (StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)))
⊢ StructuredArrow.mk (W.hom.unop.op ≫ (G.map fV').op) = StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)

tactic: simp only [Quiver.Hom.unop_op, Functor.op_map, Quiver.Hom.op_unop]
state_before: case h.e'_3.h.h.e'_7
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
this : y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
e_1✝ :
  (((ran G.op).obj ℱ.val).obj { unop := V } ⟶ ((𝟭 (Cᵒᵖ ⥤ A)).obj ℱ.val).obj { unop := V' }) =
    (limit (Ran.diagram G.op ℱ.val { unop := V }) ⟶
      (Ran.diagram G.op ℱ.val { unop := V }).obj (StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)))
⊢ StructuredArrow.mk (W.hom.unop.op ≫ (G.map fV').op) = StructuredArrow.mk (W.hom ≫ G.op.map fV'.op)
state_after: no goals

tactic: simpa only using hV'
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
⊢ S.arrows (G.map fV' ≫ W.hom.unop ≫ f)
state_after: no goals

tactic: convert H (show S ((G.map fV' ≫ W.hom.unop) ≫ f) by simpa only [Category.assoc] using hV')
  using 2
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
⊢ y ≫ ((ran G.op).obj ℱ.val).map (G.map fV' ≫ W.hom.unop).op = x (G.map fV' ≫ W.hom.unop ≫ f) hV'
state_after: case h.e'_3.h.e'_2
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
⊢ G.map fV' ≫ W.hom.unop ≫ f = (G.map fV' ≫ W.hom.unop) ≫ f

tactic: simp only [Category.assoc]
state_before: case h.e'_3.h.e'_2
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
⊢ G.map fV' ≫ W.hom.unop ≫ f = (G.map fV' ≫ W.hom.unop) ≫ f
state_after: no goals

tactic: simpa only [Category.assoc] using hV'
state_before: C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_4, u_1} C
inst✝³ : Category.{u_3, u_2} D
G : C ⥤ D
A : Type w
inst✝² : Category.{w', w} A
inst✝¹ : ∀ (X : Dᵒᵖ), HasLimitsOfShape (StructuredArrow X G.op) A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝ : G.IsCocontinuous J K
ℱ : Sheaf J A
X : A
U : D
S : Sieve U
hS : S ∈ K.sieves U
x : FamilyOfElements ((ran G.op).obj ℱ.val ⋙ coyoneda.obj { unop := X }) S.arrows
hx : x.Compatible
V : D
f : V ⟶ U
y : X ⟶ ((ran G.op).obj ℱ.val).obj { unop := V }
W : StructuredArrow { unop := V } G.op
H : ∀ {V' : C} {fV : G.obj V' ⟶ V} (hV : S.arrows (fV ≫ f)), y ≫ ((ran G.op).obj ℱ.val).map fV.op = x (fV ≫ f) hV
V' : C
fV' : V' ⟶ ((StructuredArrow.map f.op).obj W).right.unop
hV' : Presieve.functorPullback G (Sieve.pullback ((StructuredArrow.map f.op).obj W).hom.unop S).arrows fV'
⊢ S.arrows ((G.map fV' ≫ W.hom.unop) ≫ f)
state_after: no goals