l3lab/ntp-mathlib huggingface dataset:
theorem isMittagLeffler_of_exists_finite_range
    (h : ∀ j : J, ∃ (i : _) (f : i ⟶ j), (range <| F.map f).Finite) : F.IsMittagLeffler := by
  intro j
  obtain ⟨i, hi, hf⟩ := h j
  obtain ⟨m, ⟨i, f, hm⟩, hmin⟩ := Finset.wellFoundedLT.wf.has_min
    { s : Finset (F.obj j) | ∃ (i : _) (f : i ⟶ j), ↑s = range (F.map f) }
    ⟨_, i, hi, hf.coe_toFinset⟩
  refine' ⟨i, f, fun k g =>
    (directedOn_range.mp <| F.ranges_directed j).is_bot_of_is_min ⟨⟨i, f⟩, rfl⟩ _ _ ⟨⟨k, g⟩, rfl⟩⟩
  rintro _ ⟨⟨k', g'⟩, rfl⟩ hl
  

Proof state:
case intro.intro.intro.intro.intro.intro.intro.mk
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i✝¹ j✝ k✝ : J
s : Set (F.obj i✝¹)
inst✝ : IsCofilteredOrEmpty J
h : ∀ (j : J), ∃ i f, Set.Finite (range (F.map f))
j i✝ : J
hi : i✝ ⟶ j
hf : Set.Finite (range (F.map hi))
m : Finset (F.obj j)
hmin : ∀ x ∈ {s | ∃ i f, ↑s = range (F.map f)}, ¬x < m
i : J
f : i ⟶ j
hm : ↑m = range (F.map f)
k : J
g : k ⟶ j
k' : J
g' : k' ⟶ j
hl : (fun f => range (F.map f.snd)) { fst := k', snd := g' } ≤ (fun f => range (F.map f.snd)) { fst := i, snd := f }
⊢ (fun f => range (F.map f.snd)) { fst := i, snd := f } ≤ (fun f => range (F.map f.snd)) { fst := k', snd := g' }

Next tactic:
refine' (eq_of_le_of_not_lt hl _).ge
theorem isMittagLeffler_of_exists_finite_range
    (h : ∀ j : J, ∃ (i : _) (f : i ⟶ j), (range <| F.map f).Finite) : F.IsMittagLeffler := by
  intro j
  obtain ⟨i, hi, hf⟩ := h j
  obtain ⟨m, ⟨i, f, hm⟩, hmin⟩ := Finset.wellFoundedLT.wf.has_min
    { s : Finset (F.obj j) | ∃ (i : _) (f : i ⟶ j), ↑s = range (F.map f) }
    ⟨_, i, hi, hf.coe_toFinset⟩
  refine' ⟨i, f, fun k g =>
    (directedOn_range.mp <| F.ranges_directed j).is_bot_of_is_min ⟨⟨i, f⟩, rfl⟩ _ _ ⟨⟨k, g⟩, rfl⟩⟩
  rintro _ ⟨⟨k', g'⟩, rfl⟩ hl
  refine' (eq_of_le_of_not_lt hl _).ge
  

Proof state:
case intro.intro.intro.intro.intro.intro.intro.mk
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i✝¹ j✝ k✝ : J
s : Set (F.obj i✝¹)
inst✝ : IsCofilteredOrEmpty J
h : ∀ (j : J), ∃ i f, Set.Finite (range (F.map f))
j i✝ : J
hi : i✝ ⟶ j
hf : Set.Finite (range (F.map hi))
m : Finset (F.obj j)
hmin : ∀ x ∈ {s | ∃ i f, ↑s = range (F.map f)}, ¬x < m
i : J
f : i ⟶ j
hm : ↑m = range (F.map f)
k : J
g : k ⟶ j
k' : J
g' : k' ⟶ j
hl : (fun f => range (F.map f.snd)) { fst := k', snd := g' } ≤ (fun f => range (F.map f.snd)) { fst := i, snd := f }
⊢ ¬(fun f => range (F.map f.snd)) { fst := k', snd := g' } < (fun f => range (F.map f.snd)) { fst := i, snd := f }

Next tactic:
have := hmin _ ⟨k', g', (m.finite_toSet.subset <| hm.substr hl).coe_toFinset⟩
theorem isMittagLeffler_of_exists_finite_range
    (h : ∀ j : J, ∃ (i : _) (f : i ⟶ j), (range <| F.map f).Finite) : F.IsMittagLeffler := by
  intro j
  obtain ⟨i, hi, hf⟩ := h j
  obtain ⟨m, ⟨i, f, hm⟩, hmin⟩ := Finset.wellFoundedLT.wf.has_min
    { s : Finset (F.obj j) | ∃ (i : _) (f : i ⟶ j), ↑s = range (F.map f) }
    ⟨_, i, hi, hf.coe_toFinset⟩
  refine' ⟨i, f, fun k g =>
    (directedOn_range.mp <| F.ranges_directed j).is_bot_of_is_min ⟨⟨i, f⟩, rfl⟩ _ _ ⟨⟨k, g⟩, rfl⟩⟩
  rintro _ ⟨⟨k', g'⟩, rfl⟩ hl
  refine' (eq_of_le_of_not_lt hl _).ge
  have := hmin _ ⟨k', g', (m.finite_toSet.subset <| hm.substr hl).coe_toFinset⟩
  

Proof state:
case intro.intro.intro.intro.intro.intro.intro.mk
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i✝¹ j✝ k✝ : J
s : Set (F.obj i✝¹)
inst✝ : IsCofilteredOrEmpty J
h : ∀ (j : J), ∃ i f, Set.Finite (range (F.map f))
j i✝ : J
hi : i✝ ⟶ j
hf : Set.Finite (range (F.map hi))
m : Finset (F.obj j)
hmin : ∀ x ∈ {s | ∃ i f, ↑s = range (F.map f)}, ¬x < m
i : J
f : i ⟶ j
hm : ↑m = range (F.map f)
k : J
g : k ⟶ j
k' : J
g' : k' ⟶ j
hl : (fun f => range (F.map f.snd)) { fst := k', snd := g' } ≤ (fun f => range (F.map f.snd)) { fst := i, snd := f }
this : ¬Finite.toFinset (_ : Set.Finite (range (F.map g'))) < m
⊢ ¬(fun f => range (F.map f.snd)) { fst := k', snd := g' } < (fun f => range (F.map f.snd)) { fst := i, snd := f }

Next tactic:
rwa [Finset.lt_iff_ssubset, ← Finset.coe_ssubset, Set.Finite.coe_toFinset, hm] at this
/-- The subfunctor of `F` obtained by restricting to the eventual range at each index. -/
@[simps]
def toEventualRanges : J ⥤ Type v where
  obj j := F.eventualRange j
  map f := (F.eventualRange_mapsTo f).restrict _ _ _
  map_id i := by
    

Proof state:
J : Type u
inst✝¹ : Category.{?u.25599, u} J
F : J ⥤ Type v
i✝ j k : J
s : Set (F.obj i✝)
inst✝ : IsCofilteredOrEmpty J
i : J
⊢ { obj := fun j => ↑(eventualRange F j),
          map := fun {X Y} f =>
            MapsTo.restrict (F.map f) (eventualRange F X) (eventualRange F Y)
              (_ : MapsTo (F.map f) (eventualRange F X) (eventualRange F Y)) }.map
      (𝟙 i) =
    𝟙
      ({ obj := fun j => ↑(eventualRange F j),
            map := fun {X Y} f =>
              MapsTo.restrict (F.map f) (eventualRange F X) (eventualRange F Y)
                (_ : MapsTo (F.map f) (eventualRange F X) (eventualRange F Y)) }.obj
        i)

Next tactic:
simp (config := { unfoldPartialApp := true }) only [MapsTo.restrict, Subtype.map, F.map_id]
/-- The subfunctor of `F` obtained by restricting to the eventual range at each index. -/
@[simps]
def toEventualRanges : J ⥤ Type v where
  obj j := F.eventualRange j
  map f := (F.eventualRange_mapsTo f).restrict _ _ _
  map_id i := by
    simp (config := { unfoldPartialApp := true }) only [MapsTo.restrict, Subtype.map, F.map_id]
    

Proof state:
J : Type u
inst✝¹ : Category.{?u.25599, u} J
F : J ⥤ Type v
i✝ j k : J
s : Set (F.obj i✝)
inst✝ : IsCofilteredOrEmpty J
i : J
⊢ (fun x => { val := 𝟙 (F.obj i) ↑x, property := (_ : (fun x => x ∈ eventualRange F i) (𝟙 (F.obj i) ↑x)) }) =
    𝟙 ↑(eventualRange F i)

Next tactic:
ext
/-- The subfunctor of `F` obtained by restricting to the eventual range at each index. -/
@[simps]
def toEventualRanges : J ⥤ Type v where
  obj j := F.eventualRange j
  map f := (F.eventualRange_mapsTo f).restrict _ _ _
  map_id i := by
    simp (config := { unfoldPartialApp := true }) only [MapsTo.restrict, Subtype.map, F.map_id]
    ext
    

Proof state:
case h.a
J : Type u
inst✝¹ : Category.{?u.25599, u} J
F : J ⥤ Type v
i✝ j k : J
s : Set (F.obj i✝)
inst✝ : IsCofilteredOrEmpty J
i : J
a✝ : { x // x ∈ eventualRange F i }
⊢ ↑{ val := 𝟙 (F.obj i) ↑a✝, property := (_ : (fun x => x ∈ eventualRange F i) (𝟙 (F.obj i) ↑a✝)) } =
    ↑(𝟙 (↑(eventualRange F i)) a✝)

Next tactic:
rfl
/-- The subfunctor of `F` obtained by restricting to the eventual range at each index. -/
@[simps]
def toEventualRanges : J ⥤ Type v where
  obj j := F.eventualRange j
  map f := (F.eventualRange_mapsTo f).restrict _ _ _
  map_id i := by
    simp (config := { unfoldPartialApp := true }) only [MapsTo.restrict, Subtype.map, F.map_id]
    ext
    rfl
  map_comp _ _ := by
    

Proof state:
J : Type u
inst✝¹ : Category.{?u.25599, u} J
F : J ⥤ Type v
i j k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
X✝ Y✝ Z✝ : J
x✝¹ : X✝ ⟶ Y✝
x✝ : Y✝ ⟶ Z✝
⊢ { obj := fun j => ↑(eventualRange F j),
          map := fun {X Y} f =>
            MapsTo.restrict (F.map f) (eventualRange F X) (eventualRange F Y)
              (_ : MapsTo (F.map f) (eventualRange F X) (eventualRange F Y)) }.map
      (x✝¹ ≫ x✝) =
    { obj := fun j => ↑(eventualRange F j),
            map := fun {X Y} f =>
              MapsTo.restrict (F.map f) (eventualRange F X) (eventualRange F Y)
                (_ : MapsTo (F.map f) (eventualRange F X) (eventualRange F Y)) }.map
        x✝¹ ≫
      { obj := fun j => ↑(eventualRange F j),
            map := fun {X Y} f =>
              MapsTo.restrict (F.map f) (eventualRange F X) (eventualRange F Y)
                (_ : MapsTo (F.map f) (eventualRange F X) (eventualRange F Y)) }.map
        x✝

Next tactic:
simp (config := { unfoldPartialApp := true }) only [MapsTo.restrict, Subtype.map, F.map_comp]
/-- The subfunctor of `F` obtained by restricting to the eventual range at each index. -/
@[simps]
def toEventualRanges : J ⥤ Type v where
  obj j := F.eventualRange j
  map f := (F.eventualRange_mapsTo f).restrict _ _ _
  map_id i := by
    simp (config := { unfoldPartialApp := true }) only [MapsTo.restrict, Subtype.map, F.map_id]
    ext
    rfl
  map_comp _ _ := by
    simp (config := { unfoldPartialApp := true }) only [MapsTo.restrict, Subtype.map, F.map_comp]
    

Proof state:
J : Type u
inst✝¹ : Category.{?u.25599, u} J
F : J ⥤ Type v
i j k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
X✝ Y✝ Z✝ : J
x✝¹ : X✝ ⟶ Y✝
x✝ : Y✝ ⟶ Z✝
⊢ (fun x =>
      { val := (F.map x✝¹ ≫ F.map x✝) ↑x,
        property := (_ : (fun x => x ∈ eventualRange F Z✝) ((F.map x✝¹ ≫ F.map x✝) ↑x)) }) =
    (fun x => { val := F.map x✝¹ ↑x, property := (_ : F.map x✝¹ ↑x ∈ eventualRange F Y✝) }) ≫ fun x =>
      { val := F.map x✝ ↑x, property := (_ : F.map x✝ ↑x ∈ eventualRange F Z✝) }

Next tactic:
rfl
/-- The sections of the functor `F : J ⥤ Type v` are in bijection with the sections of
`F.toEventualRanges`. -/
def toEventualRangesSectionsEquiv : F.toEventualRanges.sections ≃ F.sections where
  toFun s := ⟨_, fun f => Subtype.coe_inj.2 <| s.prop f⟩
  invFun s :=
    ⟨fun j => ⟨_, mem_iInter₂.2 fun i f => ⟨_, s.prop f⟩⟩, fun f => Subtype.ext <| s.prop f⟩
  left_inv _ := by
    

Proof state:
J : Type u
inst✝¹ : Category.{?u.27819, u} J
F : J ⥤ Type v
i j k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
x✝ : ↑(sections (toEventualRanges F))
⊢ (fun s =>
        { val := fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) },
          property :=
            (_ :
              ∀ {j j' : J} (f : j ⟶ j'),
                (toEventualRanges F).map f
                    ((fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) }) j) =
                  (fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) }) j') })
      ((fun s =>
          { val := fun {j} => ↑(↑s j),
            property := (_ : ∀ {j j' : J} (f : j ⟶ j'), ↑((toEventualRanges F).map f (↑s j)) = ↑(↑s j')) })
        x✝) =
    x✝

Next tactic:
ext
/-- The sections of the functor `F : J ⥤ Type v` are in bijection with the sections of
`F.toEventualRanges`. -/
def toEventualRangesSectionsEquiv : F.toEventualRanges.sections ≃ F.sections where
  toFun s := ⟨_, fun f => Subtype.coe_inj.2 <| s.prop f⟩
  invFun s :=
    ⟨fun j => ⟨_, mem_iInter₂.2 fun i f => ⟨_, s.prop f⟩⟩, fun f => Subtype.ext <| s.prop f⟩
  left_inv _ := by
    ext
    

Proof state:
case a.h
J : Type u
inst✝¹ : Category.{?u.27819, u} J
F : J ⥤ Type v
i j k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
x✝¹ : ↑(sections (toEventualRanges F))
x✝ : J
⊢ ↑((fun s =>
            { val := fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) },
              property :=
                (_ :
                  ∀ {j j' : J} (f : j ⟶ j'),
                    (toEventualRanges F).map f
                        ((fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) }) j) =
                      (fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) }) j') })
          ((fun s =>
              { val := fun {j} => ↑(↑s j),
                property := (_ : ∀ {j j' : J} (f : j ⟶ j'), ↑((toEventualRanges F).map f (↑s j)) = ↑(↑s j')) })
            x✝¹))
      x✝ =
    ↑x✝¹ x✝

Next tactic:
rfl
/-- The sections of the functor `F : J ⥤ Type v` are in bijection with the sections of
`F.toEventualRanges`. -/
def toEventualRangesSectionsEquiv : F.toEventualRanges.sections ≃ F.sections where
  toFun s := ⟨_, fun f => Subtype.coe_inj.2 <| s.prop f⟩
  invFun s :=
    ⟨fun j => ⟨_, mem_iInter₂.2 fun i f => ⟨_, s.prop f⟩⟩, fun f => Subtype.ext <| s.prop f⟩
  left_inv _ := by
    ext
    rfl
  right_inv _ := by
    

Proof state:
J : Type u
inst✝¹ : Category.{?u.27819, u} J
F : J ⥤ Type v
i j k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
x✝ : ↑(sections F)
⊢ (fun s =>
        { val := fun {j} => ↑(↑s j),
          property := (_ : ∀ {j j' : J} (f : j ⟶ j'), ↑((toEventualRanges F).map f (↑s j)) = ↑(↑s j')) })
      ((fun s =>
          { val := fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) },
            property :=
              (_ :
                ∀ {j j' : J} (f : j ⟶ j'),
                  (toEventualRanges F).map f
                      ((fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) }) j) =
                    (fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) }) j') })
        x✝) =
    x✝

Next tactic:
ext
/-- The sections of the functor `F : J ⥤ Type v` are in bijection with the sections of
`F.toEventualRanges`. -/
def toEventualRangesSectionsEquiv : F.toEventualRanges.sections ≃ F.sections where
  toFun s := ⟨_, fun f => Subtype.coe_inj.2 <| s.prop f⟩
  invFun s :=
    ⟨fun j => ⟨_, mem_iInter₂.2 fun i f => ⟨_, s.prop f⟩⟩, fun f => Subtype.ext <| s.prop f⟩
  left_inv _ := by
    ext
    rfl
  right_inv _ := by
    ext
    

Proof state:
case a.h
J : Type u
inst✝¹ : Category.{?u.27819, u} J
F : J ⥤ Type v
i j k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
x✝¹ : ↑(sections F)
x✝ : J
⊢ ↑((fun s =>
            { val := fun {j} => ↑(↑s j),
              property := (_ : ∀ {j j' : J} (f : j ⟶ j'), ↑((toEventualRanges F).map f (↑s j)) = ↑(↑s j')) })
          ((fun s =>
              { val := fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) },
                property :=
                  (_ :
                    ∀ {j j' : J} (f : j ⟶ j'),
                      (toEventualRanges F).map f
                          ((fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) }) j) =
                        (fun j => { val := ↑s j, property := (_ : ↑s j ∈ ⋂ i, ⋂ j_1, range (F.map j_1)) }) j') })
            x✝¹))
      x✝ =
    ↑x✝¹ x✝

Next tactic:
rfl
/-- If `F` satisfies the Mittag-Leffler condition, its restriction to eventual ranges is a
surjective functor. -/
theorem surjective_toEventualRanges (h : F.IsMittagLeffler) ⦃i j⦄ (f : i ⟶ j) :
    (F.toEventualRanges.map f).Surjective := fun ⟨x, hx⟩ => by
  

Proof state:
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i✝ j✝ k : J
s : Set (F.obj i✝)
inst✝ : IsCofilteredOrEmpty J
h : IsMittagLeffler F
i j : J
f : i ⟶ j
x✝ : (toEventualRanges F).obj j
x : F.obj j
hx : x ∈ eventualRange F j
⊢ ∃ a, (toEventualRanges F).map f a = { val := x, property := hx }

Next tactic:
obtain ⟨y, hy, rfl⟩ := h.subset_image_eventualRange F f hx
/-- If `F` satisfies the Mittag-Leffler condition, its restriction to eventual ranges is a
surjective functor. -/
theorem surjective_toEventualRanges (h : F.IsMittagLeffler) ⦃i j⦄ (f : i ⟶ j) :
    (F.toEventualRanges.map f).Surjective := fun ⟨x, hx⟩ => by
  obtain ⟨y, hy, rfl⟩ := h.subset_image_eventualRange F f hx
  

Proof state:
case intro.intro
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i✝ j✝ k : J
s : Set (F.obj i✝)
inst✝ : IsCofilteredOrEmpty J
h : IsMittagLeffler F
i j : J
f : i ⟶ j
x✝ : (toEventualRanges F).obj j
y : F.obj i
hy : y ∈ eventualRange F i
hx : F.map f y ∈ eventualRange F j
⊢ ∃ a, (toEventualRanges F).map f a = { val := F.map f y, property := hx }

Next tactic:
exact ⟨⟨y, hy⟩, rfl⟩
/-- If `F` is nonempty at each index and Mittag-Leffler, then so is `F.toEventualRanges`. -/
theorem toEventualRanges_nonempty (h : F.IsMittagLeffler) [∀ j : J, Nonempty (F.obj j)] (j : J) :
    Nonempty (F.toEventualRanges.obj j) := by
  

Proof state:
J : Type u
inst✝² : Category.{u_1, u} J
F : J ⥤ Type v
i j✝ k : J
s : Set (F.obj i)
inst✝¹ : IsCofilteredOrEmpty J
h : IsMittagLeffler F
inst✝ : ∀ (j : J), Nonempty (F.obj j)
j : J
⊢ Nonempty ((toEventualRanges F).obj j)

Next tactic:
let ⟨i, f, h⟩ := F.isMittagLeffler_iff_eventualRange.1 h j
/-- If `F` is nonempty at each index and Mittag-Leffler, then so is `F.toEventualRanges`. -/
theorem toEventualRanges_nonempty (h : F.IsMittagLeffler) [∀ j : J, Nonempty (F.obj j)] (j : J) :
    Nonempty (F.toEventualRanges.obj j) := by
  let ⟨i, f, h⟩ := F.isMittagLeffler_iff_eventualRange.1 h j
  

Proof state:
J : Type u
inst✝² : Category.{u_1, u} J
F : J ⥤ Type v
i✝ j✝ k : J
s : Set (F.obj i✝)
inst✝¹ : IsCofilteredOrEmpty J
h✝ : IsMittagLeffler F
inst✝ : ∀ (j : J), Nonempty (F.obj j)
j i : J
f : i ⟶ j
h : eventualRange F j = range (F.map f)
⊢ Nonempty ((toEventualRanges F).obj j)

Next tactic:
rw [toEventualRanges_obj, h]
/-- If `F` is nonempty at each index and Mittag-Leffler, then so is `F.toEventualRanges`. -/
theorem toEventualRanges_nonempty (h : F.IsMittagLeffler) [∀ j : J, Nonempty (F.obj j)] (j : J) :
    Nonempty (F.toEventualRanges.obj j) := by
  let ⟨i, f, h⟩ := F.isMittagLeffler_iff_eventualRange.1 h j
  rw [toEventualRanges_obj, h]
  

Proof state:
J : Type u
inst✝² : Category.{u_1, u} J
F : J ⥤ Type v
i✝ j✝ k : J
s : Set (F.obj i✝)
inst✝¹ : IsCofilteredOrEmpty J
h✝ : IsMittagLeffler F
inst✝ : ∀ (j : J), Nonempty (F.obj j)
j i : J
f : i ⟶ j
h : eventualRange F j = range (F.map f)
⊢ Nonempty ↑(range (F.map f))

Next tactic:
infer_instance
/-- If `F` has all arrows surjective, then it "factors through a poset". -/
theorem thin_diagram_of_surjective (Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), (F.map f).Surjective) {i j}
    (f g : i ⟶ j) : F.map f = F.map g :=
  let ⟨k, φ, hφ⟩ := IsCofilteredOrEmpty.cone_maps f g
  (Fsur φ).injective_comp_right <| by 

Proof state:
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i✝ j✝ k✝ : J
s : Set (F.obj i✝)
inst✝ : IsCofilteredOrEmpty J
Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), Function.Surjective (F.map f)
i j : J
f g : i ⟶ j
k : J
φ : k ⟶ i
hφ : φ ≫ f = φ ≫ g
⊢ (fun g => g ∘ F.map φ) (F.map f) = (fun g => g ∘ F.map φ) (F.map g)

Next tactic:
simp_rw [← types_comp, ← F.map_comp, hφ]
theorem toPreimages_nonempty_of_surjective [hFn : ∀ j : J, Nonempty (F.obj j)]
    (Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), (F.map f).Surjective) (hs : s.Nonempty) (j) :
    Nonempty ((F.toPreimages s).obj j) := by
  

Proof state:
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i j✝ k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
hFn : ∀ (j : J), Nonempty (F.obj j)
Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), Function.Surjective (F.map f)
hs : Set.Nonempty s
j : J
⊢ Nonempty ((toPreimages F s).obj j)

Next tactic:
simp only [toPreimages_obj, nonempty_coe_sort, nonempty_iInter, mem_preimage]
theorem toPreimages_nonempty_of_surjective [hFn : ∀ j : J, Nonempty (F.obj j)]
    (Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), (F.map f).Surjective) (hs : s.Nonempty) (j) :
    Nonempty ((F.toPreimages s).obj j) := by
  simp only [toPreimages_obj, nonempty_coe_sort, nonempty_iInter, mem_preimage]
  

Proof state:
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i j✝ k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
hFn : ∀ (j : J), Nonempty (F.obj j)
Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), Function.Surjective (F.map f)
hs : Set.Nonempty s
j : J
⊢ ∃ x, ∀ (i_1 : j ⟶ i), F.map i_1 x ∈ s

Next tactic:
obtain h | ⟨⟨ji⟩⟩ := isEmpty_or_nonempty (j ⟶ i)
theorem toPreimages_nonempty_of_surjective [hFn : ∀ j : J, Nonempty (F.obj j)]
    (Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), (F.map f).Surjective) (hs : s.Nonempty) (j) :
    Nonempty ((F.toPreimages s).obj j) := by
  simp only [toPreimages_obj, nonempty_coe_sort, nonempty_iInter, mem_preimage]
  obtain h | ⟨⟨ji⟩⟩ := isEmpty_or_nonempty (j ⟶ i)
  · 

Proof state:
case inl
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i j✝ k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
hFn : ∀ (j : J), Nonempty (F.obj j)
Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), Function.Surjective (F.map f)
hs : Set.Nonempty s
j : J
h : IsEmpty (j ⟶ i)
⊢ ∃ x, ∀ (i_1 : j ⟶ i), F.map i_1 x ∈ s

Next tactic:
exact ⟨(hFn j).some, fun ji => h.elim ji⟩
theorem toPreimages_nonempty_of_surjective [hFn : ∀ j : J, Nonempty (F.obj j)]
    (Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), (F.map f).Surjective) (hs : s.Nonempty) (j) :
    Nonempty ((F.toPreimages s).obj j) := by
  simp only [toPreimages_obj, nonempty_coe_sort, nonempty_iInter, mem_preimage]
  obtain h | ⟨⟨ji⟩⟩ := isEmpty_or_nonempty (j ⟶ i)
  · exact ⟨(hFn j).some, fun ji => h.elim ji⟩
  · 

Proof state:
case inr.intro
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i j✝ k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
hFn : ∀ (j : J), Nonempty (F.obj j)
Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), Function.Surjective (F.map f)
hs : Set.Nonempty s
j : J
ji : j ⟶ i
⊢ ∃ x, ∀ (i_1 : j ⟶ i), F.map i_1 x ∈ s

Next tactic:
obtain ⟨y, ys⟩ := hs
theorem toPreimages_nonempty_of_surjective [hFn : ∀ j : J, Nonempty (F.obj j)]
    (Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), (F.map f).Surjective) (hs : s.Nonempty) (j) :
    Nonempty ((F.toPreimages s).obj j) := by
  simp only [toPreimages_obj, nonempty_coe_sort, nonempty_iInter, mem_preimage]
  obtain h | ⟨⟨ji⟩⟩ := isEmpty_or_nonempty (j ⟶ i)
  · exact ⟨(hFn j).some, fun ji => h.elim ji⟩
  · obtain ⟨y, ys⟩ := hs
    

Proof state:
case inr.intro.intro
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i j✝ k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
hFn : ∀ (j : J), Nonempty (F.obj j)
Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), Function.Surjective (F.map f)
j : J
ji : j ⟶ i
y : F.obj i
ys : y ∈ s
⊢ ∃ x, ∀ (i_1 : j ⟶ i), F.map i_1 x ∈ s

Next tactic:
obtain ⟨x, rfl⟩ := Fsur ji y
theorem toPreimages_nonempty_of_surjective [hFn : ∀ j : J, Nonempty (F.obj j)]
    (Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), (F.map f).Surjective) (hs : s.Nonempty) (j) :
    Nonempty ((F.toPreimages s).obj j) := by
  simp only [toPreimages_obj, nonempty_coe_sort, nonempty_iInter, mem_preimage]
  obtain h | ⟨⟨ji⟩⟩ := isEmpty_or_nonempty (j ⟶ i)
  · exact ⟨(hFn j).some, fun ji => h.elim ji⟩
  · obtain ⟨y, ys⟩ := hs
    obtain ⟨x, rfl⟩ := Fsur ji y
    

Proof state:
case inr.intro.intro.intro
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i j✝ k : J
s : Set (F.obj i)
inst✝ : IsCofilteredOrEmpty J
hFn : ∀ (j : J), Nonempty (F.obj j)
Fsur : ∀ ⦃i j : J⦄ (f : i ⟶ j), Function.Surjective (F.map f)
j : J
ji : j ⟶ i
x : F.obj j
ys : F.map ji x ∈ s
⊢ ∃ x, ∀ (i_1 : j ⟶ i), F.map i_1 x ∈ s

Next tactic:
exact ⟨x, fun ji' => (F.thin_diagram_of_surjective Fsur ji' ji).symm ▸ ys⟩
theorem eval_section_injective_of_eventually_injective {j}
    (Finj : ∀ (i) (f : i ⟶ j), (F.map f).Injective) (i) (f : i ⟶ j) :
    (fun s : F.sections => s.val j).Injective := by
  

Proof state:
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i✝ j✝ k : J
s : Set (F.obj i✝)
inst✝ : IsCofilteredOrEmpty J
j : J
Finj : ∀ (i : J) (f : i ⟶ j), Function.Injective (F.map f)
i : J
f : i ⟶ j
⊢ Function.Injective fun s => ↑s j

Next tactic:
refine' fun s₀ s₁ h => Subtype.ext <| funext fun k => _
theorem eval_section_injective_of_eventually_injective {j}
    (Finj : ∀ (i) (f : i ⟶ j), (F.map f).Injective) (i) (f : i ⟶ j) :
    (fun s : F.sections => s.val j).Injective := by
  refine' fun s₀ s₁ h => Subtype.ext <| funext fun k => _
  

Proof state:
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i✝ j✝ k✝ : J
s : Set (F.obj i✝)
inst✝ : IsCofilteredOrEmpty J
j : J
Finj : ∀ (i : J) (f : i ⟶ j), Function.Injective (F.map f)
i : J
f : i ⟶ j
s₀ s₁ : ↑(sections F)
h : (fun s => ↑s j) s₀ = (fun s => ↑s j) s₁
k : J
⊢ ↑s₀ k = ↑s₁ k

Next tactic:
obtain ⟨m, mi, mk, _⟩ := IsCofilteredOrEmpty.cone_objs i k
theorem eval_section_injective_of_eventually_injective {j}
    (Finj : ∀ (i) (f : i ⟶ j), (F.map f).Injective) (i) (f : i ⟶ j) :
    (fun s : F.sections => s.val j).Injective := by
  refine' fun s₀ s₁ h => Subtype.ext <| funext fun k => _
  obtain ⟨m, mi, mk, _⟩ := IsCofilteredOrEmpty.cone_objs i k
  

Proof state:
case intro.intro.intro
J : Type u
inst✝¹ : Category.{u_1, u} J
F : J ⥤ Type v
i✝ j✝ k✝ : J
s : Set (F.obj i✝)
inst✝ : IsCofilteredOrEmpty J
j : J
Finj : ∀ (i : J) (f : i ⟶ j), Function.Injective (F.map f)
i : J
f : i ⟶ j
s₀ s₁ : ↑(sections F)
h : (fun s => ↑s j) s₀ = (fun s => ↑s j) s₁
k m : J
mi : m ⟶ i
mk : m ⟶ k
h✝ : True
⊢ ↑s₀ k = ↑s₁ k

Next tactic:
dsimp at h