Theorem: CategoryTheory.Presheaf.FamilyOfElementsOnObjects.IsCompatible.exists_unique_section
File: Mathlib/CategoryTheory/Sites/CoversTop.lean

tactic: have H := (isSheaf_iff_isSheaf_of_type _ _).1 hF
state_before: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
⊢ ∃! s, ∀ (i : I), ↑s { unop := Y i } = x i
state_after: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
⊢ ∃! s, ∀ (i : I), ↑s { unop := Y i } = x i

tactic: apply exists_unique_of_exists_of_unique
state_before: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
⊢ ∃! s, ∀ (i : I), ↑s { unop := Y i } = x i
state_after: case hex
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
⊢ ∃ x_1, ∀ (i : I), ↑x_1 { unop := Y i } = x i

case hunique
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
⊢ ∀ (y₁ y₂ : ↑F.sections), (∀ (i : I), ↑y₁ { unop := Y i } = x i) → (∀ (i : I), ↑y₂ { unop := Y i } = x i) → y₁ = y₂

tactic: let s := fun (X : C) => (H _ (hY X)).amalgamate _
  (hx.familyOfElements_isCompatible X)
state_before: case hex
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
⊢ ∃ x_1, ∀ (i : I), ↑x_1 { unop := Y i } = x i
state_after: case hex
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
⊢ ∃ x_1, ∀ (i : I), ↑x_1 { unop := Y i } = x i

tactic: have hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i) := fun {X} i f => by
  have h := Presieve.IsSheafFor.valid_glue (H _ (hY X))
      (hx.familyOfElements_isCompatible _) (𝟙 _) ⟨i, ⟨f⟩⟩
  simp only [op_id, F.map_id, types_id_apply] at h
  exact h.trans (hx.familyOfElements_apply _ _ _)
state_before: case hex
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
⊢ ∃ x_1, ∀ (i : I), ↑x_1 { unop := Y i } = x i
state_after: case hex
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
⊢ ∃ x_1, ∀ (i : I), ↑x_1 { unop := Y i } = x i

tactic: have hs' : ∀ {W X : C} (a : W ⟶ X) (i : I) (_ : W ⟶ Y i), F.map a.op (s X) = s W := by
  intro W X a i b
  rw [hs i b]
  exact (Presieve.IsSheafFor.valid_glue (H _ (hY X))
    (hx.familyOfElements_isCompatible _) a ⟨i, ⟨b⟩⟩).trans (familyOfElements_apply hx _ _ _)
state_before: case hex
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
⊢ ∃ x_1, ∀ (i : I), ↑x_1 { unop := Y i } = x i
state_after: case hex
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
⊢ ∃ x_1, ∀ (i : I), ↑x_1 { unop := Y i } = x i

tactic: refine ⟨⟨fun X => s X.unop, ?_⟩, fun i => (hs i (𝟙 (Y i))).trans (by simp)⟩
state_before: case hex
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
⊢ ∃ x_1, ∀ (i : I), ↑x_1 { unop := Y i } = x i
state_after: case hex
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
⊢ (fun X => s X.unop) ∈ F.sections

tactic: rintro ⟨Y₁⟩ ⟨Y₂⟩ ⟨f : Y₂ ⟶ Y₁⟩
state_before: case hex
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
⊢ (fun X => s X.unop) ∈ F.sections
state_after: case hex.op.op.op
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
Y₁ Y₂ : C
f : Y₂ ⟶ Y₁
⊢ F.map { unop := f } ((fun X => s X.unop) { unop := Y₁ }) = (fun X => s X.unop) { unop := Y₂ }

tactic: change F.map f.op (s Y₁) = s Y₂
state_before: case hex.op.op.op
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
Y₁ Y₂ : C
f : Y₂ ⟶ Y₁
⊢ F.map { unop := f } ((fun X => s X.unop) { unop := Y₁ }) = (fun X => s X.unop) { unop := Y₂ }
state_after: case hex.op.op.op
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
Y₁ Y₂ : C
f : Y₂ ⟶ Y₁
⊢ F.map f.op (s Y₁) = s Y₂

tactic: apply (Presieve.isSeparated_of_isSheaf J F H _ (hY Y₂)).ext
state_before: case hex.op.op.op
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
Y₁ Y₂ : C
f : Y₂ ⟶ Y₁
⊢ F.map f.op (s Y₁) = s Y₂
state_after: case hex.op.op.op
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
Y₁ Y₂ : C
f : Y₂ ⟶ Y₁
⊢ ∀ ⦃Y_1 : C⦄ ⦃f_1 : Y_1 ⟶ Y₂⦄,
    (Sieve.ofObjects Y Y₂).arrows f_1 → F.map f_1.op (F.map f.op (s Y₁)) = F.map f_1.op (s Y₂)

tactic: rintro Z φ ⟨i, ⟨g⟩⟩
state_before: case hex.op.op.op
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
Y₁ Y₂ : C
f : Y₂ ⟶ Y₁
⊢ ∀ ⦃Y_1 : C⦄ ⦃f_1 : Y_1 ⟶ Y₂⦄,
    (Sieve.ofObjects Y Y₂).arrows f_1 → F.map f_1.op (F.map f.op (s Y₁)) = F.map f_1.op (s Y₂)
state_after: case hex.op.op.op.intro.intro
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
Y₁ Y₂ : C
f : Y₂ ⟶ Y₁
Z : C
φ : Z ⟶ Y₂
i : I
g : Z ⟶ Y i
⊢ F.map φ.op (F.map f.op (s Y₁)) = F.map φ.op (s Y₂)

tactic: rw [hs' φ i g, ← hs' (φ ≫ f) i g, op_comp, F.map_comp]
state_before: case hex.op.op.op.intro.intro
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
Y₁ Y₂ : C
f : Y₂ ⟶ Y₁
Z : C
φ : Z ⟶ Y₂
i : I
g : Z ⟶ Y i
⊢ F.map φ.op (F.map f.op (s Y₁)) = F.map φ.op (s Y₂)
state_after: case hex.op.op.op.intro.intro
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
Y₁ Y₂ : C
f : Y₂ ⟶ Y₁
Z : C
φ : Z ⟶ Y₂
i : I
g : Z ⟶ Y i
⊢ F.map φ.op (F.map f.op (s Y₁)) = (F.map f.op ≫ F.map φ.op) (s Y₁)

tactic: rfl
state_before: case hex.op.op.op.intro.intro
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
Y₁ Y₂ : C
f : Y₂ ⟶ Y₁
Z : C
φ : Z ⟶ Y₂
i : I
g : Z ⟶ Y i
⊢ F.map φ.op (F.map f.op (s Y₁)) = (F.map f.op ≫ F.map φ.op) (s Y₁)
state_after: no goals

tactic: have h := Presieve.IsSheafFor.valid_glue (H _ (hY X))
    (hx.familyOfElements_isCompatible _) (𝟙 _) ⟨i, ⟨f⟩⟩
state_before: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
X : C
i : I
f : X ⟶ Y i
⊢ s X = F.map f.op (x i)
state_after: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
X : C
i : I
f : X ⟶ Y i
h : F.map (𝟙 X).op (⋯.amalgamate (x.familyOfElements X) ⋯) = x.familyOfElements X (𝟙 X) ⋯
⊢ s X = F.map f.op (x i)

tactic: simp only [op_id, F.map_id, types_id_apply] at h
state_before: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
X : C
i : I
f : X ⟶ Y i
h : F.map (𝟙 X).op (⋯.amalgamate (x.familyOfElements X) ⋯) = x.familyOfElements X (𝟙 X) ⋯
⊢ s X = F.map f.op (x i)
state_after: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
X : C
i : I
f : X ⟶ Y i
h : ⋯.amalgamate (x.familyOfElements X) ⋯ = x.familyOfElements X (𝟙 X) ⋯
⊢ s X = F.map f.op (x i)

tactic: exact h.trans (hx.familyOfElements_apply _ _ _)
state_before: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
X : C
i : I
f : X ⟶ Y i
h : ⋯.amalgamate (x.familyOfElements X) ⋯ = x.familyOfElements X (𝟙 X) ⋯
⊢ s X = F.map f.op (x i)
state_after: no goals

tactic: intro W X a i b
state_before: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
⊢ ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
state_after: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
W X : C
a : W ⟶ X
i : I
b : W ⟶ Y i
⊢ F.map a.op (s X) = s W

tactic: rw [hs i b]
state_before: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
W X : C
a : W ⟶ X
i : I
b : W ⟶ Y i
⊢ F.map a.op (s X) = s W
state_after: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
W X : C
a : W ⟶ X
i : I
b : W ⟶ Y i
⊢ F.map a.op (s X) = F.map b.op (x i)

tactic: exact (Presieve.IsSheafFor.valid_glue (H _ (hY X))
  (hx.familyOfElements_isCompatible _) a ⟨i, ⟨b⟩⟩).trans (familyOfElements_apply hx _ _ _)
state_before: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
W X : C
a : W ⟶ X
i : I
b : W ⟶ Y i
⊢ F.map a.op (s X) = F.map b.op (x i)
state_after: no goals

tactic: simp
state_before: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
s : (X : C) → F.obj { unop := X } := fun X => ⋯.amalgamate (x.familyOfElements X) ⋯
hs : ∀ {X : C} (i : I) (f : X ⟶ Y i), s X = F.map f.op (x i)
hs' : ∀ {W X : C} (a : W ⟶ X) (i : I), (W ⟶ Y i) → F.map a.op (s X) = s W
i : I
⊢ F.map (𝟙 (Y i)).op (x i) = x i
state_after: no goals

tactic: intro y₁ y₂ hy₁ hy₂
state_before: case hunique
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
⊢ ∀ (y₁ y₂ : ↑F.sections), (∀ (i : I), ↑y₁ { unop := Y i } = x i) → (∀ (i : I), ↑y₂ { unop := Y i } = x i) → y₁ = y₂
state_after: case hunique
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
y₁ y₂ : ↑F.sections
hy₁ : ∀ (i : I), ↑y₁ { unop := Y i } = x i
hy₂ : ∀ (i : I), ↑y₂ { unop := Y i } = x i
⊢ y₁ = y₂

tactic: exact hY.sections_ext ⟨F, hF⟩ (fun i => by rw [hy₁, hy₂])
state_before: case hunique
C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
y₁ y₂ : ↑F.sections
hy₁ : ∀ (i : I), ↑y₁ { unop := Y i } = x i
hy₂ : ∀ (i : I), ↑y₂ { unop := Y i } = x i
⊢ y₁ = y₂
state_after: no goals

tactic: rw [hy₁, hy₂]
state_before: C : Type u
inst✝¹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝ : Category.{v', u'} A
F : Cᵒᵖ ⥤ Type w
I : Type u_1
Y : I → C
x : FamilyOfElementsOnObjects F Y
hx : x.IsCompatible
hY : J.CoversTop Y
hF : IsSheaf J F
H : Presieve.IsSheaf J F
y₁ y₂ : ↑F.sections
hy₁ : ∀ (i : I), ↑y₁ { unop := Y i } = x i
hy₂ : ∀ (i : I), ↑y₂ { unop := Y i } = x i
i : I
⊢ ↑y₁ { unop := Y i } = ↑y₂ { unop := Y i }
state_after: no goals