l3lab/ntp-mathlib huggingface dataset:
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    

Proof state:
case mp
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : IsLocallySurjective T
⊢ ∀ (x : ↑X), Function.Surjective ⇑((stalkFunctor C x).map T)

Next tactic:
intro x g
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    intro x g
    -- Represent it on an open set U ⊆ X as ⟨t, U⟩.
    

Proof state:
case mp
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : IsLocallySurjective T
x : ↑X
g : (forget C).obj ((stalkFunctor C x).obj 𝒢)
⊢ ∃ a, ((stalkFunctor C x).map T) a = g

Next tactic:
obtain ⟨U, hxU, t, rfl⟩ := 𝒢.germ_exist x g
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    intro x g
    -- Represent it on an open set U ⊆ X as ⟨t, U⟩.
    obtain ⟨U, hxU, t, rfl⟩ := 𝒢.germ_exist x g
    -- By local surjectivity, pass to a smaller open set V
    -- on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
    

Proof state:
case mp.intro.intro.intro
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : IsLocallySurjective T
x : ↑X
U : Opens ↑X
hxU : x ∈ U
t : (forget C).obj (𝒢.obj (op U))
⊢ ∃ a, ((stalkFunctor C x).map T) a = (germ 𝒢 { val := x, property := hxU }) t

Next tactic:
rcases hT U t x hxU with ⟨V, ι, ⟨s, h_eq⟩, hxV⟩
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    intro x g
    -- Represent it on an open set U ⊆ X as ⟨t, U⟩.
    obtain ⟨U, hxU, t, rfl⟩ := 𝒢.germ_exist x g
    -- By local surjectivity, pass to a smaller open set V
    -- on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
    rcases hT U t x hxU with ⟨V, ι, ⟨s, h_eq⟩, hxV⟩
    -- Then the germ of s maps to g.
    

Proof state:
case mp.intro.intro.intro.intro.intro.intro.intro
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : IsLocallySurjective T
x : ↑X
U : Opens ↑X
hxU : x ∈ U
t : (forget C).obj (𝒢.obj (op U))
V : Opens ↑X
ι : V ⟶ U
hxV : x ∈ V
s : (forget C).obj (ℱ.obj (op V))
h_eq : (T.app (op V)) s = (𝒢.map ι.op) t
⊢ ∃ a, ((stalkFunctor C x).map T) a = (germ 𝒢 { val := x, property := hxU }) t

Next tactic:
use ℱ.germ ⟨x, hxV⟩ s
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    intro x g
    -- Represent it on an open set U ⊆ X as ⟨t, U⟩.
    obtain ⟨U, hxU, t, rfl⟩ := 𝒢.germ_exist x g
    -- By local surjectivity, pass to a smaller open set V
    -- on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
    rcases hT U t x hxU with ⟨V, ι, ⟨s, h_eq⟩, hxV⟩
    -- Then the germ of s maps to g.
    use ℱ.germ ⟨x, hxV⟩ s
    -- Porting note: `convert` went too deep and swapped LHS and RHS of the remaining goal relative
    -- to lean 3.
    

Proof state:
case h
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : IsLocallySurjective T
x : ↑X
U : Opens ↑X
hxU : x ∈ U
t : (forget C).obj (𝒢.obj (op U))
V : Opens ↑X
ι : V ⟶ U
hxV : x ∈ V
s : (forget C).obj (ℱ.obj (op V))
h_eq : (T.app (op V)) s = (𝒢.map ι.op) t
⊢ ((stalkFunctor C x).map T) ((germ ℱ { val := x, property := hxV }) s) = (germ 𝒢 { val := x, property := hxU }) t

Next tactic:
convert stalkFunctor_map_germ_apply V ⟨x, hxV⟩ T s using 1
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    intro x g
    -- Represent it on an open set U ⊆ X as ⟨t, U⟩.
    obtain ⟨U, hxU, t, rfl⟩ := 𝒢.germ_exist x g
    -- By local surjectivity, pass to a smaller open set V
    -- on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
    rcases hT U t x hxU with ⟨V, ι, ⟨s, h_eq⟩, hxV⟩
    -- Then the germ of s maps to g.
    use ℱ.germ ⟨x, hxV⟩ s
    -- Porting note: `convert` went too deep and swapped LHS and RHS of the remaining goal relative
    -- to lean 3.
    convert stalkFunctor_map_germ_apply V ⟨x, hxV⟩ T s using 1
    

Proof state:
case h.e'_3.h
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : IsLocallySurjective T
x : ↑X
U : Opens ↑X
hxU : x ∈ U
t : (forget C).obj (𝒢.obj (op U))
V : Opens ↑X
ι : V ⟶ U
hxV : x ∈ V
s : (forget C).obj (ℱ.obj (op V))
h_eq : (T.app (op V)) s = (𝒢.map ι.op) t
e_1✝ :
  (forget C).obj ((stalkFunctor C x).obj 𝒢) =
    (forget C).obj (Limits.colim.obj ((OpenNhds.inclusion ↑{ val := x, property := hxV }).op ⋙ 𝒢))
⊢ (germ 𝒢 { val := x, property := hxU }) t =
    (Limits.colimit.ι ((OpenNhds.inclusion ↑{ val := x, property := hxV }).op ⋙ 𝒢)
        (op { obj := V, property := (_ : ↑{ val := x, property := hxV } ∈ V) }))
      ((T.app (op V)) s)

Next tactic:
simpa [h_eq] using (germ_res_apply 𝒢 ι ⟨x, hxV⟩ t).symm
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    intro x g
    -- Represent it on an open set U ⊆ X as ⟨t, U⟩.
    obtain ⟨U, hxU, t, rfl⟩ := 𝒢.germ_exist x g
    -- By local surjectivity, pass to a smaller open set V
    -- on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
    rcases hT U t x hxU with ⟨V, ι, ⟨s, h_eq⟩, hxV⟩
    -- Then the germ of s maps to g.
    use ℱ.germ ⟨x, hxV⟩ s
    -- Porting note: `convert` went too deep and swapped LHS and RHS of the remaining goal relative
    -- to lean 3.
    convert stalkFunctor_map_germ_apply V ⟨x, hxV⟩ T s using 1
    simpa [h_eq] using (germ_res_apply 𝒢 ι ⟨x, hxV⟩ t).symm
  · /- human proof:
        Let U be an open set, t ∈ Γ ℱ U a section, x ∈ U a point.
        By surjectivity on stalks, the germ of t is the image of
        some germ f ∈ Γₛₜ ℱ x. Represent f on some open set V ⊆ X as ⟨s, V⟩.
        Then there is some possibly smaller open set x ∈ W ⊆ V ∩ U on which
        we have T(s) |_ W = t |_ W. -/
    

Proof state:
case mpr
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : ∀ (x : ↑X), Function.Surjective ⇑((stalkFunctor C x).map T)
⊢ IsLocallySurjective T

Next tactic:
intro U t x hxU
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    intro x g
    -- Represent it on an open set U ⊆ X as ⟨t, U⟩.
    obtain ⟨U, hxU, t, rfl⟩ := 𝒢.germ_exist x g
    -- By local surjectivity, pass to a smaller open set V
    -- on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
    rcases hT U t x hxU with ⟨V, ι, ⟨s, h_eq⟩, hxV⟩
    -- Then the germ of s maps to g.
    use ℱ.germ ⟨x, hxV⟩ s
    -- Porting note: `convert` went too deep and swapped LHS and RHS of the remaining goal relative
    -- to lean 3.
    convert stalkFunctor_map_germ_apply V ⟨x, hxV⟩ T s using 1
    simpa [h_eq] using (germ_res_apply 𝒢 ι ⟨x, hxV⟩ t).symm
  · /- human proof:
        Let U be an open set, t ∈ Γ ℱ U a section, x ∈ U a point.
        By surjectivity on stalks, the germ of t is the image of
        some germ f ∈ Γₛₜ ℱ x. Represent f on some open set V ⊆ X as ⟨s, V⟩.
        Then there is some possibly smaller open set x ∈ W ⊆ V ∩ U on which
        we have T(s) |_ W = t |_ W. -/
    intro U t x hxU
    

Proof state:
case mpr
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : ∀ (x : ↑X), Function.Surjective ⇑((stalkFunctor C x).map T)
U : Opens ↑X
t : (forget C).obj (𝒢.obj (op U))
x : ↑X
hxU : x ∈ U
⊢ ∃ U_1 f, (imageSieve T t).arrows f ∧ x ∈ U_1

Next tactic:
set t_x := 𝒢.germ ⟨x, hxU⟩ t with ht_x
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    intro x g
    -- Represent it on an open set U ⊆ X as ⟨t, U⟩.
    obtain ⟨U, hxU, t, rfl⟩ := 𝒢.germ_exist x g
    -- By local surjectivity, pass to a smaller open set V
    -- on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
    rcases hT U t x hxU with ⟨V, ι, ⟨s, h_eq⟩, hxV⟩
    -- Then the germ of s maps to g.
    use ℱ.germ ⟨x, hxV⟩ s
    -- Porting note: `convert` went too deep and swapped LHS and RHS of the remaining goal relative
    -- to lean 3.
    convert stalkFunctor_map_germ_apply V ⟨x, hxV⟩ T s using 1
    simpa [h_eq] using (germ_res_apply 𝒢 ι ⟨x, hxV⟩ t).symm
  · /- human proof:
        Let U be an open set, t ∈ Γ ℱ U a section, x ∈ U a point.
        By surjectivity on stalks, the germ of t is the image of
        some germ f ∈ Γₛₜ ℱ x. Represent f on some open set V ⊆ X as ⟨s, V⟩.
        Then there is some possibly smaller open set x ∈ W ⊆ V ∩ U on which
        we have T(s) |_ W = t |_ W. -/
    intro U t x hxU
    set t_x := 𝒢.germ ⟨x, hxU⟩ t with ht_x
    

Proof state:
case mpr
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : ∀ (x : ↑X), Function.Surjective ⇑((stalkFunctor C x).map T)
U : Opens ↑X
t : (forget C).obj (𝒢.obj (op U))
x : ↑X
hxU : x ∈ U
t_x : (forget C).obj (stalk 𝒢 ↑{ val := x, property := hxU }) := (germ 𝒢 { val := x, property := hxU }) t
ht_x : t_x = (germ 𝒢 { val := x, property := hxU }) t
⊢ ∃ U_1 f, (imageSieve T t).arrows f ∧ x ∈ U_1

Next tactic:
obtain ⟨s_x, hs_x : ((stalkFunctor C x).map T) s_x = t_x⟩ := hT x t_x
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    intro x g
    -- Represent it on an open set U ⊆ X as ⟨t, U⟩.
    obtain ⟨U, hxU, t, rfl⟩ := 𝒢.germ_exist x g
    -- By local surjectivity, pass to a smaller open set V
    -- on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
    rcases hT U t x hxU with ⟨V, ι, ⟨s, h_eq⟩, hxV⟩
    -- Then the germ of s maps to g.
    use ℱ.germ ⟨x, hxV⟩ s
    -- Porting note: `convert` went too deep and swapped LHS and RHS of the remaining goal relative
    -- to lean 3.
    convert stalkFunctor_map_germ_apply V ⟨x, hxV⟩ T s using 1
    simpa [h_eq] using (germ_res_apply 𝒢 ι ⟨x, hxV⟩ t).symm
  · /- human proof:
        Let U be an open set, t ∈ Γ ℱ U a section, x ∈ U a point.
        By surjectivity on stalks, the germ of t is the image of
        some germ f ∈ Γₛₜ ℱ x. Represent f on some open set V ⊆ X as ⟨s, V⟩.
        Then there is some possibly smaller open set x ∈ W ⊆ V ∩ U on which
        we have T(s) |_ W = t |_ W. -/
    intro U t x hxU
    set t_x := 𝒢.germ ⟨x, hxU⟩ t with ht_x
    obtain ⟨s_x, hs_x : ((stalkFunctor C x).map T) s_x = t_x⟩ := hT x t_x
    

Proof state:
case mpr.intro
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : ∀ (x : ↑X), Function.Surjective ⇑((stalkFunctor C x).map T)
U : Opens ↑X
t : (forget C).obj (𝒢.obj (op U))
x : ↑X
hxU : x ∈ U
t_x : (forget C).obj (stalk 𝒢 ↑{ val := x, property := hxU }) := (germ 𝒢 { val := x, property := hxU }) t
ht_x : t_x = (germ 𝒢 { val := x, property := hxU }) t
s_x : (forget C).obj ((stalkFunctor C x).obj ℱ)
hs_x : ((stalkFunctor C x).map T) s_x = t_x
⊢ ∃ U_1 f, (imageSieve T t).arrows f ∧ x ∈ U_1

Next tactic:
obtain ⟨V, hxV, s, rfl⟩ := ℱ.germ_exist x s_x
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    intro x g
    -- Represent it on an open set U ⊆ X as ⟨t, U⟩.
    obtain ⟨U, hxU, t, rfl⟩ := 𝒢.germ_exist x g
    -- By local surjectivity, pass to a smaller open set V
    -- on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
    rcases hT U t x hxU with ⟨V, ι, ⟨s, h_eq⟩, hxV⟩
    -- Then the germ of s maps to g.
    use ℱ.germ ⟨x, hxV⟩ s
    -- Porting note: `convert` went too deep and swapped LHS and RHS of the remaining goal relative
    -- to lean 3.
    convert stalkFunctor_map_germ_apply V ⟨x, hxV⟩ T s using 1
    simpa [h_eq] using (germ_res_apply 𝒢 ι ⟨x, hxV⟩ t).symm
  · /- human proof:
        Let U be an open set, t ∈ Γ ℱ U a section, x ∈ U a point.
        By surjectivity on stalks, the germ of t is the image of
        some germ f ∈ Γₛₜ ℱ x. Represent f on some open set V ⊆ X as ⟨s, V⟩.
        Then there is some possibly smaller open set x ∈ W ⊆ V ∩ U on which
        we have T(s) |_ W = t |_ W. -/
    intro U t x hxU
    set t_x := 𝒢.germ ⟨x, hxU⟩ t with ht_x
    obtain ⟨s_x, hs_x : ((stalkFunctor C x).map T) s_x = t_x⟩ := hT x t_x
    obtain ⟨V, hxV, s, rfl⟩ := ℱ.germ_exist x s_x
    -- rfl : ℱ.germ x s = s_x
    

Proof state:
case mpr.intro.intro.intro.intro
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : ∀ (x : ↑X), Function.Surjective ⇑((stalkFunctor C x).map T)
U : Opens ↑X
t : (forget C).obj (𝒢.obj (op U))
x : ↑X
hxU : x ∈ U
t_x : (forget C).obj (stalk 𝒢 ↑{ val := x, property := hxU }) := (germ 𝒢 { val := x, property := hxU }) t
ht_x : t_x = (germ 𝒢 { val := x, property := hxU }) t
V : Opens ↑X
hxV : x ∈ V
s : (forget C).obj (ℱ.obj (op V))
hs_x : ((stalkFunctor C x).map T) ((germ ℱ { val := x, property := hxV }) s) = t_x
⊢ ∃ U_1 f, (imageSieve T t).arrows f ∧ x ∈ U_1

Next tactic:
have key_W := 𝒢.germ_eq x hxV hxU (T.app _ s) t <| by
      convert hs_x using 1
      symm
      convert stalkFunctor_map_germ_apply _ _ _ s
/-- An equivalent condition for a map of presheaves to be locally surjective
is for all the induced maps on stalks to be surjective. -/
theorem locally_surjective_iff_surjective_on_stalks (T : ℱ ⟶ 𝒢) :
    IsLocallySurjective T ↔ ∀ x : X, Function.Surjective ((stalkFunctor C x).map T) := by
  constructor <;> intro hT
  · /- human proof:
        Let g ∈ Γₛₜ 𝒢 x be a germ. Represent it on an open set U ⊆ X
        as ⟨t, U⟩. By local surjectivity, pass to a smaller open set V
        on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
        Then the germ of s maps to g -/
    -- Let g ∈ Γₛₜ 𝒢 x be a germ.
    intro x g
    -- Represent it on an open set U ⊆ X as ⟨t, U⟩.
    obtain ⟨U, hxU, t, rfl⟩ := 𝒢.germ_exist x g
    -- By local surjectivity, pass to a smaller open set V
    -- on which there exists s ∈ Γ_ ℱ V mapping to t |_ V.
    rcases hT U t x hxU with ⟨V, ι, ⟨s, h_eq⟩, hxV⟩
    -- Then the germ of s maps to g.
    use ℱ.germ ⟨x, hxV⟩ s
    -- Porting note: `convert` went too deep and swapped LHS and RHS of the remaining goal relative
    -- to lean 3.
    convert stalkFunctor_map_germ_apply V ⟨x, hxV⟩ T s using 1
    simpa [h_eq] using (germ_res_apply 𝒢 ι ⟨x, hxV⟩ t).symm
  · /- human proof:
        Let U be an open set, t ∈ Γ ℱ U a section, x ∈ U a point.
        By surjectivity on stalks, the germ of t is the image of
        some germ f ∈ Γₛₜ ℱ x. Represent f on some open set V ⊆ X as ⟨s, V⟩.
        Then there is some possibly smaller open set x ∈ W ⊆ V ∩ U on which
        we have T(s) |_ W = t |_ W. -/
    intro U t x hxU
    set t_x := 𝒢.germ ⟨x, hxU⟩ t with ht_x
    obtain ⟨s_x, hs_x : ((stalkFunctor C x).map T) s_x = t_x⟩ := hT x t_x
    obtain ⟨V, hxV, s, rfl⟩ := ℱ.germ_exist x s_x
    -- rfl : ℱ.germ x s = s_x
    have key_W := 𝒢.germ_eq x hxV hxU (T.app _ s) t <| by
      

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
X : TopCat
ℱ 𝒢 : Presheaf C X
inst✝¹ : Limits.HasColimits C
inst✝ : Limits.PreservesFilteredColimits (forget C)
T : ℱ ⟶ 𝒢
hT : ∀ (x : ↑X), Function.Surjective ⇑((stalkFunctor C x).map T)
U : Opens ↑X
t : (forget C).obj (𝒢.obj (op U))
x : ↑X
hxU : x ∈ U
t_x : (forget C).obj (stalk 𝒢 ↑{ val := x, property := hxU }) := (germ 𝒢 { val := x, property := hxU }) t
ht_x : t_x = (germ 𝒢 { val := x, property := hxU }) t
V : Opens ↑X
hxV : x ∈ V
s : (forget C).obj (ℱ.obj (op V))
hs_x : ((stalkFunctor C x).map T) ((germ ℱ { val := x, property := hxV }) s) = t_x
⊢ (germ 𝒢 { val := x, property := hxV }) ((T.app (op V)) s) = (germ 𝒢 { val := x, property := hxU }) t

Next tactic:
convert hs_x using 1