Theorem: CategoryTheory.Functor.IsCoverDense.compatiblePreserving
File: Mathlib/CategoryTheory/Sites/DenseSubsite.lean

Proof steps:
state_before: C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
⊢ CompatiblePreserving K G
state_after: case compatible
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
⊢ ∀ (ℱ : SheafOfTypes K) {Z : C} {T : Presieve Z} {x : FamilyOfElements (G.op ⋙ ℱ.val) T},
    x.Compatible →
      ∀ {Y₁ Y₂ : C} {X : D} (f₁ : X ⟶ G.obj Y₁) (f₂ : X ⟶ G.obj Y₂) {g₁ : Y₁ ⟶ Z} {g₂ : Y₂ ⟶ Z} (hg₁ : T g₁)
        (hg₂ : T g₂), f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂ → ℱ.val.map f₁.op (x g₁ hg₁) = ℱ.val.map f₂.op (x g₂ hg₂)
tactic: constructor
state_before: case compatible
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
⊢ ∀ (ℱ : SheafOfTypes K) {Z : C} {T : Presieve Z} {x : FamilyOfElements (G.op ⋙ ℱ.val) T},
    x.Compatible →
      ∀ {Y₁ Y₂ : C} {X : D} (f₁ : X ⟶ G.obj Y₁) (f₂ : X ⟶ G.obj Y₂) {g₁ : Y₁ ⟶ Z} {g₂ : Y₂ ⟶ Z} (hg₁ : T g₁)
        (hg₂ : T g₂), f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂ → ℱ.val.map f₁.op (x g₁ hg₁) = ℱ.val.map f₂.op (x g₂ hg₂)
state_after: case compatible
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
⊢ ℱ.val.map f₁.op (x g₁ hg₁) = ℱ.val.map f₂.op (x g₂ hg₂)
tactic: intro ℱ Z T x hx Y₁ Y₂ X f₁ f₂ g₁ g₂ hg₁ hg₂ eq
state_before: case compatible
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
⊢ ℱ.val.map f₁.op (x g₁ hg₁) = ℱ.val.map f₂.op (x g₂ hg₂)
state_after: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
⊢ ∀ ⦃Y : C⦄ (f : G.obj Y ⟶ X), ℱ.val.map f.op (ℱ.val.map f₁.op (x g₁ hg₁)) = ℱ.val.map f.op (ℱ.val.map f₂.op (x g₂ hg₂))
tactic: apply Functor.IsCoverDense.ext G
state_before: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
⊢ ∀ ⦃Y : C⦄ (f : G.obj Y ⟶ X), ℱ.val.map f.op (ℱ.val.map f₁.op (x g₁ hg₁)) = ℱ.val.map f.op (ℱ.val.map f₂.op (x g₂ hg₂))
state_after: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
⊢ ℱ.val.map i.op (ℱ.val.map f₁.op (x g₁ hg₁)) = ℱ.val.map i.op (ℱ.val.map f₂.op (x g₂ hg₂))
tactic: intro W i
state_before: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
⊢ ℱ.val.map i.op (ℱ.val.map f₁.op (x g₁ hg₁)) = ℱ.val.map i.op (ℱ.val.map f₂.op (x g₂ hg₂))
state_after: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
⊢ ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₁.op (x g₁ hg₁))) =
    ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₂.op (x g₂ hg₂)))
tactic: refine IsLocallyFull.ext G _ (i ≫ f₁) fun V₁ iVW iV₁Y₁ e₁ ↦ ?_
state_before: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
⊢ ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₁.op (x g₁ hg₁))) =
    ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₂.op (x g₂ hg₂)))
state_after: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
V₂ : C
iV₂V₁ : V₂ ⟶ V₁
iV₂Y₂ : V₂ ⟶ Y₂
e₂ : G.map iV₂Y₂ = G.map iV₂V₁ ≫ G.map iVW ≫ i ≫ f₂
⊢ ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₁.op (x g₁ hg₁)))) =
    ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₂.op (x g₂ hg₂))))
tactic: refine IsLocallyFull.ext G _ (G.map iVW ≫ i ≫ f₂) fun V₂ iV₂V₁ iV₂Y₂ e₂ ↦ ?_
state_before: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
V₂ : C
iV₂V₁ : V₂ ⟶ V₁
iV₂Y₂ : V₂ ⟶ Y₂
e₂ : G.map iV₂Y₂ = G.map iV₂V₁ ≫ G.map iVW ≫ i ≫ f₂
⊢ ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₁.op (x g₁ hg₁)))) =
    ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₂.op (x g₂ hg₂))))
state_after: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
V₂ : C
iV₂V₁ : V₂ ⟶ V₁
iV₂Y₂ : V₂ ⟶ Y₂
e₂ : G.map iV₂Y₂ = G.map iV₂V₁ ≫ G.map iVW ≫ i ≫ f₂
⊢ ∀ ⦃Z_1 : C⦄ (j : Z_1 ⟶ V₂),
    j ≫ iV₂V₁ ≫ iV₁Y₁ ≫ g₁ = j ≫ iV₂Y₂ ≫ g₂ →
      ℱ.val.map (G.map j).op
          (ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₁.op (x g₁ hg₁))))) =
        ℱ.val.map (G.map j).op
          (ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₂.op (x g₂ hg₂)))))
tactic: refine IsLocallyFaithful.ext G _ (iV₂V₁ ≫ iV₁Y₁ ≫ g₁) (iV₂Y₂ ≫ g₂) (by simp [e₁, e₂, eq]) ?_
state_before: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
V₂ : C
iV₂V₁ : V₂ ⟶ V₁
iV₂Y₂ : V₂ ⟶ Y₂
e₂ : G.map iV₂Y₂ = G.map iV₂V₁ ≫ G.map iVW ≫ i ≫ f₂
⊢ ∀ ⦃Z_1 : C⦄ (j : Z_1 ⟶ V₂),
    j ≫ iV₂V₁ ≫ iV₁Y₁ ≫ g₁ = j ≫ iV₂Y₂ ≫ g₂ →
      ℱ.val.map (G.map j).op
          (ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₁.op (x g₁ hg₁))))) =
        ℱ.val.map (G.map j).op
          (ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₂.op (x g₂ hg₂)))))
state_after: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
V₂ : C
iV₂V₁ : V₂ ⟶ V₁
iV₂Y₂ : V₂ ⟶ Y₂
e₂ : G.map iV₂Y₂ = G.map iV₂V₁ ≫ G.map iVW ≫ i ≫ f₂
V₃ : C
iV₃ : V₃ ⟶ V₂
e₄ : iV₃ ≫ iV₂V₁ ≫ iV₁Y₁ ≫ g₁ = iV₃ ≫ iV₂Y₂ ≫ g₂
⊢ ℱ.val.map (G.map iV₃).op
      (ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₁.op (x g₁ hg₁))))) =
    ℱ.val.map (G.map iV₃).op
      (ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₂.op (x g₂ hg₂)))))
tactic: intro V₃ iV₃ e₄
state_before: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
V₂ : C
iV₂V₁ : V₂ ⟶ V₁
iV₂Y₂ : V₂ ⟶ Y₂
e₂ : G.map iV₂Y₂ = G.map iV₂V₁ ≫ G.map iVW ≫ i ≫ f₂
V₃ : C
iV₃ : V₃ ⟶ V₂
e₄ : iV₃ ≫ iV₂V₁ ≫ iV₁Y₁ ≫ g₁ = iV₃ ≫ iV₂Y₂ ≫ g₂
⊢ ℱ.val.map (G.map iV₃).op
      (ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₁.op (x g₁ hg₁))))) =
    ℱ.val.map (G.map iV₃).op
      (ℱ.val.map (G.map iV₂V₁).op (ℱ.val.map (G.map iVW).op (ℱ.val.map i.op (ℱ.val.map f₂.op (x g₂ hg₂)))))
state_after: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
V₂ : C
iV₂V₁ : V₂ ⟶ V₁
iV₂Y₂ : V₂ ⟶ Y₂
e₂ : G.map iV₂Y₂ = G.map iV₂V₁ ≫ G.map iVW ≫ i ≫ f₂
V₃ : C
iV₃ : V₃ ⟶ V₂
e₄ : iV₃ ≫ iV₂V₁ ≫ iV₁Y₁ ≫ g₁ = iV₃ ≫ iV₂Y₂ ≫ g₂
⊢ ℱ.val.map (G.map (iV₃ ≫ iV₂V₁ ≫ iV₁Y₁)).op (x g₁ hg₁) = ℱ.val.map (G.map (iV₃ ≫ iV₂Y₂)).op (x g₂ hg₂)
tactic: simp only [← op_comp, ← FunctorToTypes.map_comp_apply, ← e₁, ← e₂, ← Functor.map_comp]
state_before: case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
V₂ : C
iV₂V₁ : V₂ ⟶ V₁
iV₂Y₂ : V₂ ⟶ Y₂
e₂ : G.map iV₂Y₂ = G.map iV₂V₁ ≫ G.map iVW ≫ i ≫ f₂
V₃ : C
iV₃ : V₃ ⟶ V₂
e₄ : iV₃ ≫ iV₂V₁ ≫ iV₁Y₁ ≫ g₁ = iV₃ ≫ iV₂Y₂ ≫ g₂
⊢ ℱ.val.map (G.map (iV₃ ≫ iV₂V₁ ≫ iV₁Y₁)).op (x g₁ hg₁) = ℱ.val.map (G.map (iV₃ ≫ iV₂Y₂)).op (x g₂ hg₂)
state_after: case compatible.h.a
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
V₂ : C
iV₂V₁ : V₂ ⟶ V₁
iV₂Y₂ : V₂ ⟶ Y₂
e₂ : G.map iV₂Y₂ = G.map iV₂V₁ ≫ G.map iVW ≫ i ≫ f₂
V₃ : C
iV₃ : V₃ ⟶ V₂
e₄ : iV₃ ≫ iV₂V₁ ≫ iV₁Y₁ ≫ g₁ = iV₃ ≫ iV₂Y₂ ≫ g₂
⊢ (iV₃ ≫ iV₂V₁ ≫ iV₁Y₁) ≫ g₁ = (iV₃ ≫ iV₂Y₂) ≫ g₂
tactic: apply hx
state_before: case compatible.h.a
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.131985, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.132037, u_4} A
G : C ⥤ D
inst✝² : G.IsCoverDense K
inst✝¹ : G.IsLocallyFull K
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : G.IsLocallyFaithful K
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : x.Compatible
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
V₁ : C
iVW : V₁ ⟶ W
iV₁Y₁ : V₁ ⟶ Y₁
e₁ : G.map iV₁Y₁ = G.map iVW ≫ i ≫ f₁
V₂ : C
iV₂V₁ : V₂ ⟶ V₁
iV₂Y₂ : V₂ ⟶ Y₂
e₂ : G.map iV₂Y₂ = G.map iV₂V₁ ≫ G.map iVW ≫ i ≫ f₂
V₃ : C
iV₃ : V₃ ⟶ V₂
e₄ : iV₃ ≫ iV₂V₁ ≫ iV₁Y₁ ≫ g₁ = iV₃ ≫ iV₂Y₂ ≫ g₂
⊢ (iV₃ ≫ iV₂V₁ ≫ iV₁Y₁) ≫ g₁ = (iV₃ ≫ iV₂Y₂) ≫ g₂
state_after: no goals
tactic: simpa using e₄