l3lab/ntp-mathlib huggingface dataset:
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
⊢ ∀ ⦃Y : C⦄ ⦃f_1 : Y ⟶ V.unop⦄,
    (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows f_1 →
      F'.map f_1.op
          (((toPresheaf (sheafify J G)).map i ≫
              (fun U s =>
                  Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor F' (sieveOfSection G ↑s).arrows)
                    (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))
                    (_ :
                      Presieve.FamilyOfElements.Compatible
                        (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))))
                V)
            s) =
        F'.map f_1.op
          (((fun U s =>
                  Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor F' (sieveOfSection G ↑s).arrows)
                    (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))
                    (_ :
                      Presieve.FamilyOfElements.Compatible
                        (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))))
                U ≫
              F'.map i)
            s)

Next tactic:
intro W j hj
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    intro W j hj
    

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows j
⊢ F'.map j.op
      (((toPresheaf (sheafify J G)).map i ≫
          (fun U s =>
              Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor F' (sieveOfSection G ↑s).arrows)
                (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))
                (_ :
                  Presieve.FamilyOfElements.Compatible
                    (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))))
            V)
        s) =
    F'.map j.op
      (((fun U s =>
              Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor F' (sieveOfSection G ↑s).arrows)
                (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))
                (_ :
                  Presieve.FamilyOfElements.Compatible
                    (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))))
            U ≫
          F'.map i)
        s)

Next tactic:
refine' (Presieve.IsSheafFor.valid_glue (h _ ((G.sheafify J).toPresheaf.map i s).2)
      ((G.family_of_elements_compatible _).compPresheafMap _) _ hj).trans _
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    intro W j hj
    refine' (Presieve.IsSheafFor.valid_glue (h _ ((G.sheafify J).toPresheaf.map i s).2)
      ((G.family_of_elements_compatible _).compPresheafMap _) _ hj).trans _
    

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows j
⊢ Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑((toPresheaf (sheafify J G)).map i s)) j
      hj =
    F'.map j.op
      (((fun U s =>
              Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor F' (sieveOfSection G ↑s).arrows)
                (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))
                (_ :
                  Presieve.FamilyOfElements.Compatible
                    (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))))
            U ≫
          F'.map i)
        s)

Next tactic:
dsimp
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    intro W j hj
    refine' (Presieve.IsSheafFor.valid_glue (h _ ((G.sheafify J).toPresheaf.map i s).2)
      ((G.family_of_elements_compatible _).compPresheafMap _) _ hj).trans _
    dsimp
    

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows j
⊢ Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G (F.map i ↑s)) j hj =
    F'.map j.op
      (F'.map i
        (Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor F' (sieveOfSection G ↑s).arrows)
          (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))
          (_ :
            Presieve.FamilyOfElements.Compatible
              (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s)))))

Next tactic:
conv_rhs => rw [← FunctorToTypes.map_comp_apply]
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    intro W j hj
    refine' (Presieve.IsSheafFor.valid_glue (h _ ((G.sheafify J).toPresheaf.map i s).2)
      ((G.family_of_elements_compatible _).compPresheafMap _) _ hj).trans _
    dsimp
    conv_rhs => 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows j
| F'.map j.op
    (F'.map i
      (Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor F' (sieveOfSection G ↑s).arrows)
        (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))
        (_ :
          Presieve.FamilyOfElements.Compatible
            (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s)))))

Next tactic:
rw [← FunctorToTypes.map_comp_apply]
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    intro W j hj
    refine' (Presieve.IsSheafFor.valid_glue (h _ ((G.sheafify J).toPresheaf.map i s).2)
      ((G.family_of_elements_compatible _).compPresheafMap _) _ hj).trans _
    dsimp
    conv_rhs => rw [← FunctorToTypes.map_comp_apply]
    

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows j
⊢ Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G (F.map i ↑s)) j hj =
    F'.map (i ≫ j.op)
      (Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor F' (sieveOfSection G ↑s).arrows)
        (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))
        (_ :
          Presieve.FamilyOfElements.Compatible
            (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))))

Next tactic:
change _ = F'.map (j ≫ i.unop).op _
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    intro W j hj
    refine' (Presieve.IsSheafFor.valid_glue (h _ ((G.sheafify J).toPresheaf.map i s).2)
      ((G.family_of_elements_compatible _).compPresheafMap _) _ hj).trans _
    dsimp
    conv_rhs => rw [← FunctorToTypes.map_comp_apply]
    change _ = F'.map (j ≫ i.unop).op _
    

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows j
⊢ Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G (F.map i ↑s)) j hj =
    F'.map (j ≫ i.unop).op
      (Presieve.IsSheafFor.amalgamate (_ : Presieve.IsSheafFor F' (sieveOfSection G ↑s).arrows)
        (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))
        (_ :
          Presieve.FamilyOfElements.Compatible
            (Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s))))

Next tactic:
refine' Eq.trans _ (Presieve.IsSheafFor.valid_glue (h _ s.2)
      ((G.family_of_elements_compatible s.1).compPresheafMap f) (j ≫ i.unop) _).symm
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    intro W j hj
    refine' (Presieve.IsSheafFor.valid_glue (h _ ((G.sheafify J).toPresheaf.map i s).2)
      ((G.family_of_elements_compatible _).compPresheafMap _) _ hj).trans _
    dsimp
    conv_rhs => rw [← FunctorToTypes.map_comp_apply]
    change _ = F'.map (j ≫ i.unop).op _
    refine' Eq.trans _ (Presieve.IsSheafFor.valid_glue (h _ s.2)
      ((G.family_of_elements_compatible s.1).compPresheafMap f) (j ≫ i.unop) _).symm
    

Proof state:
case h.refine'_1
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows j
⊢ Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G (F.map i ↑s)) j hj =
    Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s) (j ≫ i.unop) ?h.refine'_2
case h.refine'_2
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows j
⊢ (sieveOfSection G ↑s).arrows (j ≫ i.unop)

Next tactic:
swap
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    intro W j hj
    refine' (Presieve.IsSheafFor.valid_glue (h _ ((G.sheafify J).toPresheaf.map i s).2)
      ((G.family_of_elements_compatible _).compPresheafMap _) _ hj).trans _
    dsimp
    conv_rhs => rw [← FunctorToTypes.map_comp_apply]
    change _ = F'.map (j ≫ i.unop).op _
    refine' Eq.trans _ (Presieve.IsSheafFor.valid_glue (h _ s.2)
      ((G.family_of_elements_compatible s.1).compPresheafMap f) (j ≫ i.unop) _).symm
    swap -- porting note: need to swap two goals otherwise the first goal needs to be proven
    -- inside the second goal any way
    · 

Proof state:
case h.refine'_2
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows j
⊢ (sieveOfSection G ↑s).arrows (j ≫ i.unop)

Next tactic:
dsimp [Presieve.FamilyOfElements.compPresheafMap] at hj ⊢
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    intro W j hj
    refine' (Presieve.IsSheafFor.valid_glue (h _ ((G.sheafify J).toPresheaf.map i s).2)
      ((G.family_of_elements_compatible _).compPresheafMap _) _ hj).trans _
    dsimp
    conv_rhs => rw [← FunctorToTypes.map_comp_apply]
    change _ = F'.map (j ≫ i.unop).op _
    refine' Eq.trans _ (Presieve.IsSheafFor.valid_glue (h _ s.2)
      ((G.family_of_elements_compatible s.1).compPresheafMap f) (j ≫ i.unop) _).symm
    swap -- porting note: need to swap two goals otherwise the first goal needs to be proven
    -- inside the second goal any way
    · dsimp [Presieve.FamilyOfElements.compPresheafMap] at hj ⊢
      

Proof state:
case h.refine'_2
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : F.map j.op (F.map i ↑s) ∈ obj G (op W)
⊢ F.map (i ≫ j.op) ↑s ∈ obj G (op W)

Next tactic:
rwa [FunctorToTypes.map_comp_apply]
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    intro W j hj
    refine' (Presieve.IsSheafFor.valid_glue (h _ ((G.sheafify J).toPresheaf.map i s).2)
      ((G.family_of_elements_compatible _).compPresheafMap _) _ hj).trans _
    dsimp
    conv_rhs => rw [← FunctorToTypes.map_comp_apply]
    change _ = F'.map (j ≫ i.unop).op _
    refine' Eq.trans _ (Presieve.IsSheafFor.valid_glue (h _ s.2)
      ((G.family_of_elements_compatible s.1).compPresheafMap f) (j ≫ i.unop) _).symm
    swap -- porting note: need to swap two goals otherwise the first goal needs to be proven
    -- inside the second goal any way
    · dsimp [Presieve.FamilyOfElements.compPresheafMap] at hj ⊢
      rwa [FunctorToTypes.map_comp_apply]
    · 

Proof state:
case h.refine'_1
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows j
⊢ Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G (F.map i ↑s)) j hj =
    Presieve.FamilyOfElements.compPresheafMap f (familyOfElementsOfSection G ↑s) (j ≫ i.unop)
      (_ : (sieveOfSection G ↑s).arrows (j ≫ i.unop))

Next tactic:
dsimp [Presieve.FamilyOfElements.compPresheafMap]
/-- The lift of a presheaf morphism onto the sheafification subpresheaf.  -/
noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    (G.sheafify J).toPresheaf ⟶ F' where
  app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate
    (_) ((G.family_of_elements_compatible s.1).compPresheafMap f)
  naturality := by
    intro U V i
    ext s
    apply (h _ ((Subpresheaf.sheafify J G).toPresheaf.map i s).prop).isSeparatedFor.ext
    intro W j hj
    refine' (Presieve.IsSheafFor.valid_glue (h _ ((G.sheafify J).toPresheaf.map i s).2)
      ((G.family_of_elements_compatible _).compPresheafMap _) _ hj).trans _
    dsimp
    conv_rhs => rw [← FunctorToTypes.map_comp_apply]
    change _ = F'.map (j ≫ i.unop).op _
    refine' Eq.trans _ (Presieve.IsSheafFor.valid_glue (h _ s.2)
      ((G.family_of_elements_compatible s.1).compPresheafMap f) (j ≫ i.unop) _).symm
    swap -- porting note: need to swap two goals otherwise the first goal needs to be proven
    -- inside the second goal any way
    · dsimp [Presieve.FamilyOfElements.compPresheafMap] at hj ⊢
      rwa [FunctorToTypes.map_comp_apply]
    · dsimp [Presieve.FamilyOfElements.compPresheafMap]
      

Proof state:
case h.refine'_1
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U V : Cᵒᵖ
i : U ⟶ V
s : (toPresheaf (sheafify J G)).obj U
W : C
j : W ⟶ V.unop
hj : (sieveOfSection G ↑((toPresheaf (sheafify J G)).map i s)).arrows j
⊢ f.app (op W) (familyOfElementsOfSection G (F.map i ↑s) j hj) =
    f.app (op W) (familyOfElementsOfSection G (↑s) (j ≫ i.unop) (_ : F.map (i ≫ j.op) ↑s ∈ obj G (op W)))

Next tactic:
exact congr_arg _ (Subtype.ext (FunctorToTypes.map_comp_apply _ _ _ _).symm)
theorem Subpresheaf.to_sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    Subpresheaf.homOfLe (G.le_sheafify J) ≫ G.sheafifyLift f h = f := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
⊢ homOfLe (_ : G ≤ sheafify J G) ≫ sheafifyLift G f h = f

Next tactic:
ext U s
theorem Subpresheaf.to_sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    Subpresheaf.homOfLe (G.le_sheafify J) ≫ G.sheafifyLift f h = f := by
  ext U s
  

Proof state:
case w.h.h
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U : Cᵒᵖ
s : (toPresheaf G).obj U
⊢ (homOfLe (_ : G ≤ sheafify J G) ≫ sheafifyLift G f h).app U s = f.app U s

Next tactic:
apply (h _ ((Subpresheaf.homOfLe (G.le_sheafify J)).app U s).prop).isSeparatedFor.ext
theorem Subpresheaf.to_sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    Subpresheaf.homOfLe (G.le_sheafify J) ≫ G.sheafifyLift f h = f := by
  ext U s
  apply (h _ ((Subpresheaf.homOfLe (G.le_sheafify J)).app U s).prop).isSeparatedFor.ext
  

Proof state:
case w.h.h
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U : Cᵒᵖ
s : (toPresheaf G).obj U
⊢ ∀ ⦃Y : C⦄ ⦃f_1 : Y ⟶ U.unop⦄,
    (sieveOfSection G ↑((homOfLe (_ : G ≤ sheafify J G)).app U s)).arrows f_1 →
      F'.map f_1.op ((homOfLe (_ : G ≤ sheafify J G) ≫ sheafifyLift G f h).app U s) = F'.map f_1.op (f.app U s)

Next tactic:
intro V i hi
theorem Subpresheaf.to_sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    Subpresheaf.homOfLe (G.le_sheafify J) ≫ G.sheafifyLift f h = f := by
  ext U s
  apply (h _ ((Subpresheaf.homOfLe (G.le_sheafify J)).app U s).prop).isSeparatedFor.ext
  intro V i hi
  

Proof state:
case w.h.h
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U : Cᵒᵖ
s : (toPresheaf G).obj U
V : C
i : V ⟶ U.unop
hi : (sieveOfSection G ↑((homOfLe (_ : G ≤ sheafify J G)).app U s)).arrows i
⊢ F'.map i.op ((homOfLe (_ : G ≤ sheafify J G) ≫ sheafifyLift G f h).app U s) = F'.map i.op (f.app U s)

Next tactic:
have := elementwise_of% f.naturality
theorem Subpresheaf.to_sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') :
    Subpresheaf.homOfLe (G.le_sheafify J) ≫ G.sheafifyLift f h = f := by
  ext U s
  apply (h _ ((Subpresheaf.homOfLe (G.le_sheafify J)).app U s).prop).isSeparatedFor.ext
  intro V i hi
  have := elementwise_of% f.naturality
  -- porting note: filled in some underscores where Lean3 could automatically fill.
  

Proof state:
case w.h.h
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
f : toPresheaf G ⟶ F'
h : Presieve.IsSheaf J F'
U : Cᵒᵖ
s : (toPresheaf G).obj U
V : C
i : V ⟶ U.unop
hi : (sieveOfSection G ↑((homOfLe (_ : G ≤ sheafify J G)).app U s)).arrows i
this :
  ∀ ⦃X Y : Cᵒᵖ⦄ (f_1 : X ⟶ Y) (x : (toPresheaf G).obj X), f.app Y ((toPresheaf G).map f_1 x) = F'.map f_1 (f.app X x)
⊢ F'.map i.op ((homOfLe (_ : G ≤ sheafify J G) ≫ sheafifyLift G f h).app U s) = F'.map i.op (f.app U s)

Next tactic:
exact (Presieve.IsSheafFor.valid_glue (h _ ((homOfLe (_ : G ≤ sheafify J G)).app U s).2)
    ((G.family_of_elements_compatible _).compPresheafMap _) _ hi).trans (this _ _)
theorem Subpresheaf.to_sheafify_lift_unique (h : Presieve.IsSheaf J F')
    (l₁ l₂ : (G.sheafify J).toPresheaf ⟶ F')
    (e : Subpresheaf.homOfLe (G.le_sheafify J) ≫ l₁ = Subpresheaf.homOfLe (G.le_sheafify J) ≫ l₂) :
    l₁ = l₂ := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J : GrothendieckTopology C
F F' F'' : Cᵒᵖ ⥤ Type w
G G' : Subpresheaf F
h : Presieve.IsSheaf J F'
l₁ l₂ : toPresheaf (sheafify J G) ⟶ F'
e : homOfLe (_ : G ≤ sheafify J G) ≫ l₁ = homOfLe (_ : G ≤ sheafify J G) ≫ l₂
⊢ l₁ = l₂

Next tactic:
ext U ⟨s, hs⟩