l3lab/ntp-mathlib huggingface dataset:
/-- Any locally constant function from a cofiltered limit of profinite sets factors through
one of the components. -/
theorem exists_locallyConstant {α : Type*} (hC : IsLimit C) (f : LocallyConstant C.pt α) :
    ∃ (j : J) (g : LocallyConstant (F.obj j) α), f = g.comap (C.π.app _) := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  let S := f.discreteQuotient
  let ff : S → α := f.lift
  cases isEmpty_or_nonempty S
  · suffices ∃ j, IsEmpty (F.obj j) by
      refine' this.imp fun j hj => _
      refine' ⟨⟨hj.elim, fun A => _⟩, _⟩
      · suffices : (fun a ↦ IsEmpty.elim hj a) ⁻¹' A = ∅
        · rw [this]
          exact isOpen_empty
        exact @Set.eq_empty_of_isEmpty _ hj _
      · ext x
        exact hj.elim' (C.π.app j x)
    simp only [← not_nonempty_iff, ← not_forall]
    intro h
    haveI : ∀ j : J, Nonempty ((F ⋙ Profinite.toTopCat).obj j) := h
    haveI : ∀ j : J, T2Space ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : T2Space (F.obj j))
    haveI : ∀ j : J, CompactSpace ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : CompactSpace (F.obj j))
    have cond := TopCat.nonempty_limitCone_of_compact_t2_cofiltered_system.{u}
      (F ⋙ Profinite.toTopCat)
    suffices : Nonempty C.pt; exact IsEmpty.false (S.proj this.some)
    let D := Profinite.toTopCat.mapCone C
    have hD : IsLimit D := isLimitOfPreserves Profinite.toTopCat hC
    have CD := (hD.conePointUniqueUpToIso (TopCat.limitConeIsLimit.{v, max u v} _)).inv
    exact cond.map CD
  · let f' : LocallyConstant C.pt S := ⟨S.proj, S.proj_isLocallyConstant⟩
    

Proof state:
case inr
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
α : Type u_1
hC : IsLimit C
f : LocallyConstant (↑C.pt.toCompHaus.toTop) α
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
S : DiscreteQuotient ↑C.pt.toCompHaus.toTop := LocallyConstant.discreteQuotient f
ff : Quotient S.toSetoid → α := ⇑(LocallyConstant.lift f)
h✝ : Nonempty (Quotient S.toSetoid)
f' : LocallyConstant (↑C.pt.toCompHaus.toTop) (Quotient S.toSetoid) :=
  { toFun := DiscreteQuotient.proj S, isLocallyConstant := (_ : IsLocallyConstant (DiscreteQuotient.proj S)) }
⊢ ∃ j g, f = LocallyConstant.comap (⇑(C.π.app j)) g

Next tactic:
obtain ⟨j, g', hj⟩ := exists_locallyConstant_finite_nonempty _ hC f'
/-- Any locally constant function from a cofiltered limit of profinite sets factors through
one of the components. -/
theorem exists_locallyConstant {α : Type*} (hC : IsLimit C) (f : LocallyConstant C.pt α) :
    ∃ (j : J) (g : LocallyConstant (F.obj j) α), f = g.comap (C.π.app _) := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  let S := f.discreteQuotient
  let ff : S → α := f.lift
  cases isEmpty_or_nonempty S
  · suffices ∃ j, IsEmpty (F.obj j) by
      refine' this.imp fun j hj => _
      refine' ⟨⟨hj.elim, fun A => _⟩, _⟩
      · suffices : (fun a ↦ IsEmpty.elim hj a) ⁻¹' A = ∅
        · rw [this]
          exact isOpen_empty
        exact @Set.eq_empty_of_isEmpty _ hj _
      · ext x
        exact hj.elim' (C.π.app j x)
    simp only [← not_nonempty_iff, ← not_forall]
    intro h
    haveI : ∀ j : J, Nonempty ((F ⋙ Profinite.toTopCat).obj j) := h
    haveI : ∀ j : J, T2Space ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : T2Space (F.obj j))
    haveI : ∀ j : J, CompactSpace ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : CompactSpace (F.obj j))
    have cond := TopCat.nonempty_limitCone_of_compact_t2_cofiltered_system.{u}
      (F ⋙ Profinite.toTopCat)
    suffices : Nonempty C.pt; exact IsEmpty.false (S.proj this.some)
    let D := Profinite.toTopCat.mapCone C
    have hD : IsLimit D := isLimitOfPreserves Profinite.toTopCat hC
    have CD := (hD.conePointUniqueUpToIso (TopCat.limitConeIsLimit.{v, max u v} _)).inv
    exact cond.map CD
  · let f' : LocallyConstant C.pt S := ⟨S.proj, S.proj_isLocallyConstant⟩
    obtain ⟨j, g', hj⟩ := exists_locallyConstant_finite_nonempty _ hC f'
    

Proof state:
case inr.intro.intro
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
α : Type u_1
hC : IsLimit C
f : LocallyConstant (↑C.pt.toCompHaus.toTop) α
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
S : DiscreteQuotient ↑C.pt.toCompHaus.toTop := LocallyConstant.discreteQuotient f
ff : Quotient S.toSetoid → α := ⇑(LocallyConstant.lift f)
h✝ : Nonempty (Quotient S.toSetoid)
f' : LocallyConstant (↑C.pt.toCompHaus.toTop) (Quotient S.toSetoid) :=
  { toFun := DiscreteQuotient.proj S, isLocallyConstant := (_ : IsLocallyConstant (DiscreteQuotient.proj S)) }
j : J
g' : LocallyConstant (↑(F.obj j).toCompHaus.toTop) (Quotient S.toSetoid)
hj : f' = LocallyConstant.comap (⇑(C.π.app j)) g'
⊢ ∃ j g, f = LocallyConstant.comap (⇑(C.π.app j)) g

Next tactic:
refine' ⟨j, ⟨ff ∘ g', g'.isLocallyConstant.comp _⟩, _⟩
/-- Any locally constant function from a cofiltered limit of profinite sets factors through
one of the components. -/
theorem exists_locallyConstant {α : Type*} (hC : IsLimit C) (f : LocallyConstant C.pt α) :
    ∃ (j : J) (g : LocallyConstant (F.obj j) α), f = g.comap (C.π.app _) := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  let S := f.discreteQuotient
  let ff : S → α := f.lift
  cases isEmpty_or_nonempty S
  · suffices ∃ j, IsEmpty (F.obj j) by
      refine' this.imp fun j hj => _
      refine' ⟨⟨hj.elim, fun A => _⟩, _⟩
      · suffices : (fun a ↦ IsEmpty.elim hj a) ⁻¹' A = ∅
        · rw [this]
          exact isOpen_empty
        exact @Set.eq_empty_of_isEmpty _ hj _
      · ext x
        exact hj.elim' (C.π.app j x)
    simp only [← not_nonempty_iff, ← not_forall]
    intro h
    haveI : ∀ j : J, Nonempty ((F ⋙ Profinite.toTopCat).obj j) := h
    haveI : ∀ j : J, T2Space ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : T2Space (F.obj j))
    haveI : ∀ j : J, CompactSpace ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : CompactSpace (F.obj j))
    have cond := TopCat.nonempty_limitCone_of_compact_t2_cofiltered_system.{u}
      (F ⋙ Profinite.toTopCat)
    suffices : Nonempty C.pt; exact IsEmpty.false (S.proj this.some)
    let D := Profinite.toTopCat.mapCone C
    have hD : IsLimit D := isLimitOfPreserves Profinite.toTopCat hC
    have CD := (hD.conePointUniqueUpToIso (TopCat.limitConeIsLimit.{v, max u v} _)).inv
    exact cond.map CD
  · let f' : LocallyConstant C.pt S := ⟨S.proj, S.proj_isLocallyConstant⟩
    obtain ⟨j, g', hj⟩ := exists_locallyConstant_finite_nonempty _ hC f'
    refine' ⟨j, ⟨ff ∘ g', g'.isLocallyConstant.comp _⟩, _⟩
    

Proof state:
case inr.intro.intro
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
α : Type u_1
hC : IsLimit C
f : LocallyConstant (↑C.pt.toCompHaus.toTop) α
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
S : DiscreteQuotient ↑C.pt.toCompHaus.toTop := LocallyConstant.discreteQuotient f
ff : Quotient S.toSetoid → α := ⇑(LocallyConstant.lift f)
h✝ : Nonempty (Quotient S.toSetoid)
f' : LocallyConstant (↑C.pt.toCompHaus.toTop) (Quotient S.toSetoid) :=
  { toFun := DiscreteQuotient.proj S, isLocallyConstant := (_ : IsLocallyConstant (DiscreteQuotient.proj S)) }
j : J
g' : LocallyConstant (↑(F.obj j).toCompHaus.toTop) (Quotient S.toSetoid)
hj : f' = LocallyConstant.comap (⇑(C.π.app j)) g'
⊢ f =
    LocallyConstant.comap ⇑(C.π.app j)
      { toFun := ff ∘ ⇑g', isLocallyConstant := (_ : IsLocallyConstant (ff ∘ g'.toFun)) }

Next tactic:
ext1 t
/-- Any locally constant function from a cofiltered limit of profinite sets factors through
one of the components. -/
theorem exists_locallyConstant {α : Type*} (hC : IsLimit C) (f : LocallyConstant C.pt α) :
    ∃ (j : J) (g : LocallyConstant (F.obj j) α), f = g.comap (C.π.app _) := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  let S := f.discreteQuotient
  let ff : S → α := f.lift
  cases isEmpty_or_nonempty S
  · suffices ∃ j, IsEmpty (F.obj j) by
      refine' this.imp fun j hj => _
      refine' ⟨⟨hj.elim, fun A => _⟩, _⟩
      · suffices : (fun a ↦ IsEmpty.elim hj a) ⁻¹' A = ∅
        · rw [this]
          exact isOpen_empty
        exact @Set.eq_empty_of_isEmpty _ hj _
      · ext x
        exact hj.elim' (C.π.app j x)
    simp only [← not_nonempty_iff, ← not_forall]
    intro h
    haveI : ∀ j : J, Nonempty ((F ⋙ Profinite.toTopCat).obj j) := h
    haveI : ∀ j : J, T2Space ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : T2Space (F.obj j))
    haveI : ∀ j : J, CompactSpace ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : CompactSpace (F.obj j))
    have cond := TopCat.nonempty_limitCone_of_compact_t2_cofiltered_system.{u}
      (F ⋙ Profinite.toTopCat)
    suffices : Nonempty C.pt; exact IsEmpty.false (S.proj this.some)
    let D := Profinite.toTopCat.mapCone C
    have hD : IsLimit D := isLimitOfPreserves Profinite.toTopCat hC
    have CD := (hD.conePointUniqueUpToIso (TopCat.limitConeIsLimit.{v, max u v} _)).inv
    exact cond.map CD
  · let f' : LocallyConstant C.pt S := ⟨S.proj, S.proj_isLocallyConstant⟩
    obtain ⟨j, g', hj⟩ := exists_locallyConstant_finite_nonempty _ hC f'
    refine' ⟨j, ⟨ff ∘ g', g'.isLocallyConstant.comp _⟩, _⟩
    ext1 t
    

Proof state:
case inr.intro.intro.h
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
α : Type u_1
hC : IsLimit C
f : LocallyConstant (↑C.pt.toCompHaus.toTop) α
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
S : DiscreteQuotient ↑C.pt.toCompHaus.toTop := LocallyConstant.discreteQuotient f
ff : Quotient S.toSetoid → α := ⇑(LocallyConstant.lift f)
h✝ : Nonempty (Quotient S.toSetoid)
f' : LocallyConstant (↑C.pt.toCompHaus.toTop) (Quotient S.toSetoid) :=
  { toFun := DiscreteQuotient.proj S, isLocallyConstant := (_ : IsLocallyConstant (DiscreteQuotient.proj S)) }
j : J
g' : LocallyConstant (↑(F.obj j).toCompHaus.toTop) (Quotient S.toSetoid)
hj : f' = LocallyConstant.comap (⇑(C.π.app j)) g'
t : ↑C.pt.toCompHaus.toTop
⊢ f t =
    (LocallyConstant.comap ⇑(C.π.app j)
        { toFun := ff ∘ ⇑g', isLocallyConstant := (_ : IsLocallyConstant (ff ∘ g'.toFun)) })
      t

Next tactic:
apply_fun fun e => e t at hj
/-- Any locally constant function from a cofiltered limit of profinite sets factors through
one of the components. -/
theorem exists_locallyConstant {α : Type*} (hC : IsLimit C) (f : LocallyConstant C.pt α) :
    ∃ (j : J) (g : LocallyConstant (F.obj j) α), f = g.comap (C.π.app _) := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  let S := f.discreteQuotient
  let ff : S → α := f.lift
  cases isEmpty_or_nonempty S
  · suffices ∃ j, IsEmpty (F.obj j) by
      refine' this.imp fun j hj => _
      refine' ⟨⟨hj.elim, fun A => _⟩, _⟩
      · suffices : (fun a ↦ IsEmpty.elim hj a) ⁻¹' A = ∅
        · rw [this]
          exact isOpen_empty
        exact @Set.eq_empty_of_isEmpty _ hj _
      · ext x
        exact hj.elim' (C.π.app j x)
    simp only [← not_nonempty_iff, ← not_forall]
    intro h
    haveI : ∀ j : J, Nonempty ((F ⋙ Profinite.toTopCat).obj j) := h
    haveI : ∀ j : J, T2Space ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : T2Space (F.obj j))
    haveI : ∀ j : J, CompactSpace ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : CompactSpace (F.obj j))
    have cond := TopCat.nonempty_limitCone_of_compact_t2_cofiltered_system.{u}
      (F ⋙ Profinite.toTopCat)
    suffices : Nonempty C.pt; exact IsEmpty.false (S.proj this.some)
    let D := Profinite.toTopCat.mapCone C
    have hD : IsLimit D := isLimitOfPreserves Profinite.toTopCat hC
    have CD := (hD.conePointUniqueUpToIso (TopCat.limitConeIsLimit.{v, max u v} _)).inv
    exact cond.map CD
  · let f' : LocallyConstant C.pt S := ⟨S.proj, S.proj_isLocallyConstant⟩
    obtain ⟨j, g', hj⟩ := exists_locallyConstant_finite_nonempty _ hC f'
    refine' ⟨j, ⟨ff ∘ g', g'.isLocallyConstant.comp _⟩, _⟩
    ext1 t
    apply_fun fun e => e t at hj
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    

Proof state:
case inr.intro.intro.h
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
α : Type u_1
hC : IsLimit C
f : LocallyConstant (↑C.pt.toCompHaus.toTop) α
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
S : DiscreteQuotient ↑C.pt.toCompHaus.toTop := LocallyConstant.discreteQuotient f
ff : Quotient S.toSetoid → α := ⇑(LocallyConstant.lift f)
h✝ : Nonempty (Quotient S.toSetoid)
f' : LocallyConstant (↑C.pt.toCompHaus.toTop) (Quotient S.toSetoid) :=
  { toFun := DiscreteQuotient.proj S, isLocallyConstant := (_ : IsLocallyConstant (DiscreteQuotient.proj S)) }
j : J
g' : LocallyConstant (↑(F.obj j).toCompHaus.toTop) (Quotient S.toSetoid)
t : ↑C.pt.toCompHaus.toTop
hj : f' t = (LocallyConstant.comap (⇑(C.π.app j)) g') t
⊢ f t =
    (LocallyConstant.comap ⇑(C.π.app j)
        { toFun := ff ∘ ⇑g', isLocallyConstant := (_ : IsLocallyConstant (ff ∘ g'.toFun)) })
      t

Next tactic:
erw [LocallyConstant.coe_comap _ _ (C.π.app j).continuous] at hj ⊢
/-- Any locally constant function from a cofiltered limit of profinite sets factors through
one of the components. -/
theorem exists_locallyConstant {α : Type*} (hC : IsLimit C) (f : LocallyConstant C.pt α) :
    ∃ (j : J) (g : LocallyConstant (F.obj j) α), f = g.comap (C.π.app _) := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  let S := f.discreteQuotient
  let ff : S → α := f.lift
  cases isEmpty_or_nonempty S
  · suffices ∃ j, IsEmpty (F.obj j) by
      refine' this.imp fun j hj => _
      refine' ⟨⟨hj.elim, fun A => _⟩, _⟩
      · suffices : (fun a ↦ IsEmpty.elim hj a) ⁻¹' A = ∅
        · rw [this]
          exact isOpen_empty
        exact @Set.eq_empty_of_isEmpty _ hj _
      · ext x
        exact hj.elim' (C.π.app j x)
    simp only [← not_nonempty_iff, ← not_forall]
    intro h
    haveI : ∀ j : J, Nonempty ((F ⋙ Profinite.toTopCat).obj j) := h
    haveI : ∀ j : J, T2Space ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : T2Space (F.obj j))
    haveI : ∀ j : J, CompactSpace ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : CompactSpace (F.obj j))
    have cond := TopCat.nonempty_limitCone_of_compact_t2_cofiltered_system.{u}
      (F ⋙ Profinite.toTopCat)
    suffices : Nonempty C.pt; exact IsEmpty.false (S.proj this.some)
    let D := Profinite.toTopCat.mapCone C
    have hD : IsLimit D := isLimitOfPreserves Profinite.toTopCat hC
    have CD := (hD.conePointUniqueUpToIso (TopCat.limitConeIsLimit.{v, max u v} _)).inv
    exact cond.map CD
  · let f' : LocallyConstant C.pt S := ⟨S.proj, S.proj_isLocallyConstant⟩
    obtain ⟨j, g', hj⟩ := exists_locallyConstant_finite_nonempty _ hC f'
    refine' ⟨j, ⟨ff ∘ g', g'.isLocallyConstant.comp _⟩, _⟩
    ext1 t
    apply_fun fun e => e t at hj
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    erw [LocallyConstant.coe_comap _ _ (C.π.app j).continuous] at hj ⊢
    

Proof state:
case inr.intro.intro.h
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
α : Type u_1
hC : IsLimit C
f : LocallyConstant (↑C.pt.toCompHaus.toTop) α
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
S : DiscreteQuotient ↑C.pt.toCompHaus.toTop := LocallyConstant.discreteQuotient f
ff : Quotient S.toSetoid → α := ⇑(LocallyConstant.lift f)
h✝ : Nonempty (Quotient S.toSetoid)
f' : LocallyConstant (↑C.pt.toCompHaus.toTop) (Quotient S.toSetoid) :=
  { toFun := DiscreteQuotient.proj S, isLocallyConstant := (_ : IsLocallyConstant (DiscreteQuotient.proj S)) }
j : J
g' : LocallyConstant (↑(F.obj j).toCompHaus.toTop) (Quotient S.toSetoid)
t : ↑C.pt.toCompHaus.toTop
hj : f' t = (⇑g' ∘ ⇑(C.π.app j)) t
⊢ f t = (⇑{ toFun := ff ∘ ⇑g', isLocallyConstant := (_ : IsLocallyConstant (ff ∘ g'.toFun)) } ∘ ⇑(C.π.app j)) t

Next tactic:
dsimp at hj ⊢
/-- Any locally constant function from a cofiltered limit of profinite sets factors through
one of the components. -/
theorem exists_locallyConstant {α : Type*} (hC : IsLimit C) (f : LocallyConstant C.pt α) :
    ∃ (j : J) (g : LocallyConstant (F.obj j) α), f = g.comap (C.π.app _) := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  let S := f.discreteQuotient
  let ff : S → α := f.lift
  cases isEmpty_or_nonempty S
  · suffices ∃ j, IsEmpty (F.obj j) by
      refine' this.imp fun j hj => _
      refine' ⟨⟨hj.elim, fun A => _⟩, _⟩
      · suffices : (fun a ↦ IsEmpty.elim hj a) ⁻¹' A = ∅
        · rw [this]
          exact isOpen_empty
        exact @Set.eq_empty_of_isEmpty _ hj _
      · ext x
        exact hj.elim' (C.π.app j x)
    simp only [← not_nonempty_iff, ← not_forall]
    intro h
    haveI : ∀ j : J, Nonempty ((F ⋙ Profinite.toTopCat).obj j) := h
    haveI : ∀ j : J, T2Space ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : T2Space (F.obj j))
    haveI : ∀ j : J, CompactSpace ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : CompactSpace (F.obj j))
    have cond := TopCat.nonempty_limitCone_of_compact_t2_cofiltered_system.{u}
      (F ⋙ Profinite.toTopCat)
    suffices : Nonempty C.pt; exact IsEmpty.false (S.proj this.some)
    let D := Profinite.toTopCat.mapCone C
    have hD : IsLimit D := isLimitOfPreserves Profinite.toTopCat hC
    have CD := (hD.conePointUniqueUpToIso (TopCat.limitConeIsLimit.{v, max u v} _)).inv
    exact cond.map CD
  · let f' : LocallyConstant C.pt S := ⟨S.proj, S.proj_isLocallyConstant⟩
    obtain ⟨j, g', hj⟩ := exists_locallyConstant_finite_nonempty _ hC f'
    refine' ⟨j, ⟨ff ∘ g', g'.isLocallyConstant.comp _⟩, _⟩
    ext1 t
    apply_fun fun e => e t at hj
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    erw [LocallyConstant.coe_comap _ _ (C.π.app j).continuous] at hj ⊢
    dsimp at hj ⊢
    

Proof state:
case inr.intro.intro.h
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
α : Type u_1
hC : IsLimit C
f : LocallyConstant (↑C.pt.toCompHaus.toTop) α
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
S : DiscreteQuotient ↑C.pt.toCompHaus.toTop := LocallyConstant.discreteQuotient f
ff : Quotient S.toSetoid → α := ⇑(LocallyConstant.lift f)
h✝ : Nonempty (Quotient S.toSetoid)
f' : LocallyConstant (↑C.pt.toCompHaus.toTop) (Quotient S.toSetoid) :=
  { toFun := DiscreteQuotient.proj S, isLocallyConstant := (_ : IsLocallyConstant (DiscreteQuotient.proj S)) }
j : J
g' : LocallyConstant (↑(F.obj j).toCompHaus.toTop) (Quotient S.toSetoid)
t : ↑C.pt.toCompHaus.toTop
hj : DiscreteQuotient.proj (LocallyConstant.discreteQuotient f) t = g' ((C.π.app j) t)
⊢ f t = (LocallyConstant.lift f) (g' ((C.π.app j) t))

Next tactic:
rw [← hj]
/-- Any locally constant function from a cofiltered limit of profinite sets factors through
one of the components. -/
theorem exists_locallyConstant {α : Type*} (hC : IsLimit C) (f : LocallyConstant C.pt α) :
    ∃ (j : J) (g : LocallyConstant (F.obj j) α), f = g.comap (C.π.app _) := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  let S := f.discreteQuotient
  let ff : S → α := f.lift
  cases isEmpty_or_nonempty S
  · suffices ∃ j, IsEmpty (F.obj j) by
      refine' this.imp fun j hj => _
      refine' ⟨⟨hj.elim, fun A => _⟩, _⟩
      · suffices : (fun a ↦ IsEmpty.elim hj a) ⁻¹' A = ∅
        · rw [this]
          exact isOpen_empty
        exact @Set.eq_empty_of_isEmpty _ hj _
      · ext x
        exact hj.elim' (C.π.app j x)
    simp only [← not_nonempty_iff, ← not_forall]
    intro h
    haveI : ∀ j : J, Nonempty ((F ⋙ Profinite.toTopCat).obj j) := h
    haveI : ∀ j : J, T2Space ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : T2Space (F.obj j))
    haveI : ∀ j : J, CompactSpace ((F ⋙ Profinite.toTopCat).obj j) := fun j =>
      (inferInstance : CompactSpace (F.obj j))
    have cond := TopCat.nonempty_limitCone_of_compact_t2_cofiltered_system.{u}
      (F ⋙ Profinite.toTopCat)
    suffices : Nonempty C.pt; exact IsEmpty.false (S.proj this.some)
    let D := Profinite.toTopCat.mapCone C
    have hD : IsLimit D := isLimitOfPreserves Profinite.toTopCat hC
    have CD := (hD.conePointUniqueUpToIso (TopCat.limitConeIsLimit.{v, max u v} _)).inv
    exact cond.map CD
  · let f' : LocallyConstant C.pt S := ⟨S.proj, S.proj_isLocallyConstant⟩
    obtain ⟨j, g', hj⟩ := exists_locallyConstant_finite_nonempty _ hC f'
    refine' ⟨j, ⟨ff ∘ g', g'.isLocallyConstant.comp _⟩, _⟩
    ext1 t
    apply_fun fun e => e t at hj
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    erw [LocallyConstant.coe_comap _ _ (C.π.app j).continuous] at hj ⊢
    dsimp at hj ⊢
    rw [← hj]
    

Proof state:
case inr.intro.intro.h
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
α : Type u_1
hC : IsLimit C
f : LocallyConstant (↑C.pt.toCompHaus.toTop) α
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
S : DiscreteQuotient ↑C.pt.toCompHaus.toTop := LocallyConstant.discreteQuotient f
ff : Quotient S.toSetoid → α := ⇑(LocallyConstant.lift f)
h✝ : Nonempty (Quotient S.toSetoid)
f' : LocallyConstant (↑C.pt.toCompHaus.toTop) (Quotient S.toSetoid) :=
  { toFun := DiscreteQuotient.proj S, isLocallyConstant := (_ : IsLocallyConstant (DiscreteQuotient.proj S)) }
j : J
g' : LocallyConstant (↑(F.obj j).toCompHaus.toTop) (Quotient S.toSetoid)
t : ↑C.pt.toCompHaus.toTop
hj : DiscreteQuotient.proj (LocallyConstant.discreteQuotient f) t = g' ((C.π.app j) t)
⊢ f t = (LocallyConstant.lift f) (DiscreteQuotient.proj (LocallyConstant.discreteQuotient f) t)

Next tactic:
rfl
theorem sum_blocksFun : ∑ i, c.blocksFun i = n := by
  

Proof state:
n : ℕ
c : Composition n
⊢ ∑ i : Fin (length c), blocksFun c i = n

Next tactic:
conv_rhs => rw [← c.blocks_sum, ← ofFn_blocksFun, sum_ofFn]
theorem sum_blocksFun : ∑ i, c.blocksFun i = n := by
  conv_rhs => 

Proof state:
n : ℕ
c : Composition n
| n

Next tactic:
rw [← c.blocks_sum, ← ofFn_blocksFun, sum_ofFn]
theorem length_le : c.length ≤ n := by
  

Proof state:
n : ℕ
c : Composition n
⊢ length c ≤ n

Next tactic:
conv_rhs => rw [← c.blocks_sum]
theorem length_le : c.length ≤ n := by
  conv_rhs => 

Proof state:
n : ℕ
c : Composition n
| n

Next tactic:
rw [← c.blocks_sum]
theorem length_le : c.length ≤ n := by
  conv_rhs => rw [← c.blocks_sum]
  

Proof state:
n : ℕ
c : Composition n
⊢ length c ≤ sum c.blocks

Next tactic:
exact length_le_sum_of_one_le _ fun i hi => c.one_le_blocks hi
theorem length_pos_of_pos (h : 0 < n) : 0 < c.length := by
  

Proof state:
n : ℕ
c : Composition n
h : 0 < n
⊢ 0 < length c

Next tactic:
apply length_pos_of_sum_pos
theorem length_pos_of_pos (h : 0 < n) : 0 < c.length := by
  apply length_pos_of_sum_pos
  

Proof state:
case h
n : ℕ
c : Composition n
h : 0 < n
⊢ 0 < sum c.blocks

Next tactic:
convert h
theorem length_pos_of_pos (h : 0 < n) : 0 < c.length := by
  apply length_pos_of_sum_pos
  convert h
  

Proof state:
case h.e'_4
n : ℕ
c : Composition n
h : 0 < n
⊢ sum c.blocks = n

Next tactic:
exact c.blocks_sum
@[simp]
theorem sizeUpTo_zero : c.sizeUpTo 0 = 0 := by 

Proof state:
n : ℕ
c : Composition n
⊢ sizeUpTo c 0 = 0

Next tactic:
simp [sizeUpTo]
theorem sizeUpTo_ofLength_le (i : ℕ) (h : c.length ≤ i) : c.sizeUpTo i = n := by
  

Proof state:
n : ℕ
c : Composition n
i : ℕ
h : length c ≤ i
⊢ sizeUpTo c i = n

Next tactic:
dsimp [sizeUpTo]
theorem sizeUpTo_ofLength_le (i : ℕ) (h : c.length ≤ i) : c.sizeUpTo i = n := by
  dsimp [sizeUpTo]
  

Proof state:
n : ℕ
c : Composition n
i : ℕ
h : length c ≤ i
⊢ sum (take i c.blocks) = n

Next tactic:
convert c.blocks_sum
theorem sizeUpTo_ofLength_le (i : ℕ) (h : c.length ≤ i) : c.sizeUpTo i = n := by
  dsimp [sizeUpTo]
  convert c.blocks_sum
  

Proof state:
case h.e'_2.h.e'_4
n : ℕ
c : Composition n
i : ℕ
h : length c ≤ i
⊢ take i c.blocks = c.blocks

Next tactic:
exact take_all_of_le h
theorem sizeUpTo_le (i : ℕ) : c.sizeUpTo i ≤ n := by
  

Proof state:
n : ℕ
c : Composition n
i : ℕ
⊢ sizeUpTo c i ≤ n

Next tactic:
conv_rhs => rw [← c.blocks_sum, ← sum_take_add_sum_drop _ i]