Theorem: CategoryTheory.Presheaf.conesEquivSieveCompatibleFamily_symm_apply_app
File: Mathlib/CategoryTheory/Sites/Sheaf.lean

Proof steps:
state_before: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X✝ : C
S : Sieve X✝
R : Presieve X✝
E : Aᵒᵖ
π : (S.arrows.diagram.op ⋙ P).cones.obj E
X Y : C
f : X ⟶ X✝
g : Y ⟶ X
hf : S.arrows f
⊢ (fun Y f h => π.app (op { obj := Over.mk f, property := h })) Y (g ≫ f) ⋯ =
    (P ⋙ coyoneda.obj E).map g.op ((fun Y f h => π.app (op { obj := Over.mk f, property := h })) X f hf)
state_after: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X✝ : C
S : Sieve X✝
R : Presieve X✝
E : Aᵒᵖ
π : (S.arrows.diagram.op ⋙ P).cones.obj E
X Y : C
f : X ⟶ X✝
g : Y ⟶ X
hf : S.arrows f
⊢ 𝟙 ((unop ((Functor.const S.arrows.categoryᵒᵖ).op.obj E)).obj (op { obj := Over.mk (g ≫ f), property := ⋯ })) ≫
      (fun Y f h => π.app (op { obj := Over.mk f, property := h })) Y (g ≫ f) ⋯ =
    (P ⋙ coyoneda.obj E).map g.op ((fun Y f h => π.app (op { obj := Over.mk f, property := h })) X f hf)
tactic: apply (id_comp _).symm.trans
state_before: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X✝ : C
S : Sieve X✝
R : Presieve X✝
E : Aᵒᵖ
π : (S.arrows.diagram.op ⋙ P).cones.obj E
X Y : C
f : X ⟶ X✝
g : Y ⟶ X
hf : S.arrows f
⊢ 𝟙 ((unop ((Functor.const S.arrows.categoryᵒᵖ).op.obj E)).obj (op { obj := Over.mk (g ≫ f), property := ⋯ })) ≫
      (fun Y f h => π.app (op { obj := Over.mk f, property := h })) Y (g ≫ f) ⋯ =
    (P ⋙ coyoneda.obj E).map g.op ((fun Y f h => π.app (op { obj := Over.mk f, property := h })) X f hf)
state_after: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X✝ : C
S : Sieve X✝
R : Presieve X✝
E : Aᵒᵖ
π : (S.arrows.diagram.op ⋙ P).cones.obj E
X Y : C
f : X ⟶ X✝
g : Y ⟶ X
hf : S.arrows f
⊢ 𝟙 (unop E) ≫ π.app (op { obj := Over.mk (g ≫ f), property := ⋯ }) =
    π.app (op { obj := Over.mk f, property := hf }) ≫ P.map g.op
tactic: dsimp
state_before: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X✝ : C
S : Sieve X✝
R : Presieve X✝
E : Aᵒᵖ
π : (S.arrows.diagram.op ⋙ P).cones.obj E
X Y : C
f : X ⟶ X✝
g : Y ⟶ X
hf : S.arrows f
⊢ 𝟙 (unop E) ≫ π.app (op { obj := Over.mk (g ≫ f), property := ⋯ }) =
    π.app (op { obj := Over.mk f, property := hf }) ≫ P.map g.op
state_after: no goals
tactic: exact π.naturality (Quiver.Hom.op (Over.homMk _ (by rfl)))
state_before: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X : C
S : Sieve X
R : Presieve X
E : Aᵒᵖ
x : { x // x.SieveCompatible }
f f' : S.arrows.categoryᵒᵖ
g : f ⟶ f'
⊢ (unop ((Functor.const S.arrows.categoryᵒᵖ).op.obj E)).map g ≫ (fun f => ↑x (unop f).obj.hom ⋯) f' =
    (fun f => ↑x (unop f).obj.hom ⋯) f ≫ (S.arrows.diagram.op ⋙ P).map g
state_after: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X : C
S : Sieve X
R : Presieve X
E : Aᵒᵖ
x : { x // x.SieveCompatible }
f f' : S.arrows.categoryᵒᵖ
g : f ⟶ f'
⊢ (unop ((Functor.const S.arrows.categoryᵒᵖ).op.obj E)).map g ≫ (fun f => ↑x (unop f).obj.hom ⋯) f' =
    ↑x (g.unop.left ≫ (unop f).obj.hom) ⋯
tactic: refine Eq.trans ?_ (x.2 f.unop.1.hom g.unop.left f.unop.2)
state_before: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X : C
S : Sieve X
R : Presieve X
E : Aᵒᵖ
x : { x // x.SieveCompatible }
f f' : S.arrows.categoryᵒᵖ
g : f ⟶ f'
⊢ (unop ((Functor.const S.arrows.categoryᵒᵖ).op.obj E)).map g ≫ (fun f => ↑x (unop f).obj.hom ⋯) f' =
    ↑x (g.unop.left ≫ (unop f).obj.hom) ⋯
state_after: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X : C
S : Sieve X
R : Presieve X
E : Aᵒᵖ
x : { x // x.SieveCompatible }
f f' : S.arrows.categoryᵒᵖ
g : f ⟶ f'
⊢ 𝟙 (unop E) ≫ ↑x (unop f').obj.hom ⋯ = ↑x (g.unop.left ≫ (unop f).obj.hom) ⋯
tactic: dsimp
state_before: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X : C
S : Sieve X
R : Presieve X
E : Aᵒᵖ
x : { x // x.SieveCompatible }
f f' : S.arrows.categoryᵒᵖ
g : f ⟶ f'
⊢ 𝟙 (unop E) ≫ ↑x (unop f').obj.hom ⋯ = ↑x (g.unop.left ≫ (unop f).obj.hom) ⋯
state_after: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X : C
S : Sieve X
R : Presieve X
E : Aᵒᵖ
x : { x // x.SieveCompatible }
f f' : S.arrows.categoryᵒᵖ
g : f ⟶ f'
⊢ ↑x (unop f').obj.hom ⋯ = ↑x (g.unop.left ≫ (unop f).obj.hom) ⋯
tactic: rw [id_comp]
state_before: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X : C
S : Sieve X
R : Presieve X
E : Aᵒᵖ
x : { x // x.SieveCompatible }
f f' : S.arrows.categoryᵒᵖ
g : f ⟶ f'
⊢ ↑x (unop f').obj.hom ⋯ = ↑x (g.unop.left ≫ (unop f).obj.hom) ⋯
state_after: case h.e'_3.h.e'_4
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X : C
S : Sieve X
R : Presieve X
E : Aᵒᵖ
x : { x // x.SieveCompatible }
f f' : S.arrows.categoryᵒᵖ
g : f ⟶ f'
⊢ g.unop.left ≫ (unop f).obj.hom = (unop f').obj.hom
tactic: convert rfl
state_before: case h.e'_3.h.e'_4
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
A : Type u₂
inst✝ : Category.{v₂, u₂} A
J : GrothendieckTopology C
P : Cᵒᵖ ⥤ A
X : C
S : Sieve X
R : Presieve X
E : Aᵒᵖ
x : { x // x.SieveCompatible }
f f' : S.arrows.categoryᵒᵖ
g : f ⟶ f'
⊢ g.unop.left ≫ (unop f).obj.hom = (unop f').obj.hom
state_after: no goals
tactic: rw [Over.w]