l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem imageSubobjectIso_imageToKernel' (w : f ≫ g = 0) :
    (imageSubobjectIso f).hom ≫ imageToKernel' f g w =
      imageToKernel f g w ≫ (kernelSubobjectIso g).hom := by
  ext
  

Proof state:
case h
ι : Type u_1
V : Type u
inst✝³ : Category.{v, u} V
inst✝² : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝¹ : HasKernels V
inst✝ : HasImages V
w : f ≫ g = 0
⊢ ((imageSubobjectIso f).hom ≫ imageToKernel' f g w) ≫ equalizer.ι g 0 =
    (imageToKernel f g w ≫ (kernelSubobjectIso g).hom) ≫ equalizer.ι g 0

Next tactic:
simp [imageToKernel']
@[simp]
theorem imageToKernel'_kernelSubobjectIso (w : f ≫ g = 0) :
    imageToKernel' f g w ≫ (kernelSubobjectIso g).inv =
      (imageSubobjectIso f).inv ≫ imageToKernel f g w := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝³ : Category.{v, u} V
inst✝² : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝¹ : HasKernels V
inst✝ : HasImages V
w : f ≫ g = 0
⊢ imageToKernel' f g w ≫ (kernelSubobjectIso g).inv = (imageSubobjectIso f).inv ≫ imageToKernel f g w

Next tactic:
ext
@[simp]
theorem imageToKernel'_kernelSubobjectIso (w : f ≫ g = 0) :
    imageToKernel' f g w ≫ (kernelSubobjectIso g).inv =
      (imageSubobjectIso f).inv ≫ imageToKernel f g w := by
  ext
  

Proof state:
case h
ι : Type u_1
V : Type u
inst✝³ : Category.{v, u} V
inst✝² : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝¹ : HasKernels V
inst✝ : HasImages V
w : f ≫ g = 0
⊢ (imageToKernel' f g w ≫ (kernelSubobjectIso g).inv) ≫ Subobject.arrow (kernelSubobject g) =
    ((imageSubobjectIso f).inv ≫ imageToKernel f g w) ≫ Subobject.arrow (kernelSubobject g)

Next tactic:
simp [imageToKernel']
/-- `homology' f g w` can be computed as the cokernel of `imageToKernel' f g w`.
-/
def homology'IsoCokernelImageToKernel' (w : f ≫ g = 0) :
    homology' f g w ≅ cokernel (imageToKernel' f g w) where
  hom := cokernel.map _ _ (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
      (by 

Proof state:
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝² : HasKernels V
inst✝¹ : HasImages V
inst✝ : HasCokernels V
w : f ≫ g = 0
⊢ imageToKernel f g w ≫ (kernelSubobjectIso g).hom = (imageSubobjectIso f).hom ≫ imageToKernel' f g w

Next tactic:
simp only [imageSubobjectIso_imageToKernel']
/-- `homology' f g w` can be computed as the cokernel of `imageToKernel' f g w`.
-/
def homology'IsoCokernelImageToKernel' (w : f ≫ g = 0) :
    homology' f g w ≅ cokernel (imageToKernel' f g w) where
  hom := cokernel.map _ _ (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
      (by simp only [imageSubobjectIso_imageToKernel'])
  inv := cokernel.map _ _ (imageSubobjectIso f).inv (kernelSubobjectIso g).inv
      (by 

Proof state:
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝² : HasKernels V
inst✝¹ : HasImages V
inst✝ : HasCokernels V
w : f ≫ g = 0
⊢ imageToKernel' f g w ≫ (kernelSubobjectIso g).inv = (imageSubobjectIso f).inv ≫ imageToKernel f g w

Next tactic:
simp only [imageToKernel'_kernelSubobjectIso]
/-- `homology' f g w` can be computed as the cokernel of `imageToKernel' f g w`.
-/
def homology'IsoCokernelImageToKernel' (w : f ≫ g = 0) :
    homology' f g w ≅ cokernel (imageToKernel' f g w) where
  hom := cokernel.map _ _ (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
      (by simp only [imageSubobjectIso_imageToKernel'])
  inv := cokernel.map _ _ (imageSubobjectIso f).inv (kernelSubobjectIso g).inv
      (by simp only [imageToKernel'_kernelSubobjectIso])
  hom_inv_id := by
    -- Just calling `ext` here uses the higher priority `homology'.ext`,
    -- which precomposes with `homology'.π`.
    -- As we are trying to work in terms of `cokernel`, it is better to use `coequalizer.hom_ext`.
    

Proof state:
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝² : HasKernels V
inst✝¹ : HasImages V
inst✝ : HasCokernels V
w : f ≫ g = 0
⊢ cokernel.map (imageToKernel f g w) (imageToKernel' f g w) (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
        (_ : imageToKernel f g w ≫ (kernelSubobjectIso g).hom = (imageSubobjectIso f).hom ≫ imageToKernel' f g w) ≫
      cokernel.map (imageToKernel' f g w) (imageToKernel f g w) (imageSubobjectIso f).inv (kernelSubobjectIso g).inv
        (_ : imageToKernel' f g w ≫ (kernelSubobjectIso g).inv = (imageSubobjectIso f).inv ≫ imageToKernel f g w) =
    𝟙 (homology' f g w)

Next tactic:
apply coequalizer.hom_ext
/-- `homology' f g w` can be computed as the cokernel of `imageToKernel' f g w`.
-/
def homology'IsoCokernelImageToKernel' (w : f ≫ g = 0) :
    homology' f g w ≅ cokernel (imageToKernel' f g w) where
  hom := cokernel.map _ _ (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
      (by simp only [imageSubobjectIso_imageToKernel'])
  inv := cokernel.map _ _ (imageSubobjectIso f).inv (kernelSubobjectIso g).inv
      (by simp only [imageToKernel'_kernelSubobjectIso])
  hom_inv_id := by
    -- Just calling `ext` here uses the higher priority `homology'.ext`,
    -- which precomposes with `homology'.π`.
    -- As we are trying to work in terms of `cokernel`, it is better to use `coequalizer.hom_ext`.
    apply coequalizer.hom_ext
    

Proof state:
case h
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝² : HasKernels V
inst✝¹ : HasImages V
inst✝ : HasCokernels V
w : f ≫ g = 0
⊢ coequalizer.π (imageToKernel f g w) 0 ≫
      cokernel.map (imageToKernel f g w) (imageToKernel' f g w) (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
          (_ : imageToKernel f g w ≫ (kernelSubobjectIso g).hom = (imageSubobjectIso f).hom ≫ imageToKernel' f g w) ≫
        cokernel.map (imageToKernel' f g w) (imageToKernel f g w) (imageSubobjectIso f).inv (kernelSubobjectIso g).inv
          (_ : imageToKernel' f g w ≫ (kernelSubobjectIso g).inv = (imageSubobjectIso f).inv ≫ imageToKernel f g w) =
    coequalizer.π (imageToKernel f g w) 0 ≫ 𝟙 (homology' f g w)

Next tactic:
simp only [Iso.hom_inv_id_assoc, cokernel.π_desc, cokernel.π_desc_assoc, Category.assoc,
      coequalizer_as_cokernel]
/-- `homology' f g w` can be computed as the cokernel of `imageToKernel' f g w`.
-/
def homology'IsoCokernelImageToKernel' (w : f ≫ g = 0) :
    homology' f g w ≅ cokernel (imageToKernel' f g w) where
  hom := cokernel.map _ _ (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
      (by simp only [imageSubobjectIso_imageToKernel'])
  inv := cokernel.map _ _ (imageSubobjectIso f).inv (kernelSubobjectIso g).inv
      (by simp only [imageToKernel'_kernelSubobjectIso])
  hom_inv_id := by
    -- Just calling `ext` here uses the higher priority `homology'.ext`,
    -- which precomposes with `homology'.π`.
    -- As we are trying to work in terms of `cokernel`, it is better to use `coequalizer.hom_ext`.
    apply coequalizer.hom_ext
    simp only [Iso.hom_inv_id_assoc, cokernel.π_desc, cokernel.π_desc_assoc, Category.assoc,
      coequalizer_as_cokernel]
    

Proof state:
case h
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝² : HasKernels V
inst✝¹ : HasImages V
inst✝ : HasCokernels V
w : f ≫ g = 0
⊢ cokernel.π (imageToKernel f g w) = cokernel.π (imageToKernel f g w) ≫ 𝟙 (homology' f g w)

Next tactic:
exact (Category.comp_id _).symm
/-- `homology' f g w` can be computed as the cokernel of `imageToKernel' f g w`.
-/
def homology'IsoCokernelImageToKernel' (w : f ≫ g = 0) :
    homology' f g w ≅ cokernel (imageToKernel' f g w) where
  hom := cokernel.map _ _ (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
      (by simp only [imageSubobjectIso_imageToKernel'])
  inv := cokernel.map _ _ (imageSubobjectIso f).inv (kernelSubobjectIso g).inv
      (by simp only [imageToKernel'_kernelSubobjectIso])
  hom_inv_id := by
    -- Just calling `ext` here uses the higher priority `homology'.ext`,
    -- which precomposes with `homology'.π`.
    -- As we are trying to work in terms of `cokernel`, it is better to use `coequalizer.hom_ext`.
    apply coequalizer.hom_ext
    simp only [Iso.hom_inv_id_assoc, cokernel.π_desc, cokernel.π_desc_assoc, Category.assoc,
      coequalizer_as_cokernel]
    exact (Category.comp_id _).symm
  inv_hom_id := by
    

Proof state:
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝² : HasKernels V
inst✝¹ : HasImages V
inst✝ : HasCokernels V
w : f ≫ g = 0
⊢ cokernel.map (imageToKernel' f g w) (imageToKernel f g w) (imageSubobjectIso f).inv (kernelSubobjectIso g).inv
        (_ : imageToKernel' f g w ≫ (kernelSubobjectIso g).inv = (imageSubobjectIso f).inv ≫ imageToKernel f g w) ≫
      cokernel.map (imageToKernel f g w) (imageToKernel' f g w) (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
        (_ : imageToKernel f g w ≫ (kernelSubobjectIso g).hom = (imageSubobjectIso f).hom ≫ imageToKernel' f g w) =
    𝟙 (cokernel (imageToKernel' f g w))

Next tactic:
ext
/-- `homology' f g w` can be computed as the cokernel of `imageToKernel' f g w`.
-/
def homology'IsoCokernelImageToKernel' (w : f ≫ g = 0) :
    homology' f g w ≅ cokernel (imageToKernel' f g w) where
  hom := cokernel.map _ _ (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
      (by simp only [imageSubobjectIso_imageToKernel'])
  inv := cokernel.map _ _ (imageSubobjectIso f).inv (kernelSubobjectIso g).inv
      (by simp only [imageToKernel'_kernelSubobjectIso])
  hom_inv_id := by
    -- Just calling `ext` here uses the higher priority `homology'.ext`,
    -- which precomposes with `homology'.π`.
    -- As we are trying to work in terms of `cokernel`, it is better to use `coequalizer.hom_ext`.
    apply coequalizer.hom_ext
    simp only [Iso.hom_inv_id_assoc, cokernel.π_desc, cokernel.π_desc_assoc, Category.assoc,
      coequalizer_as_cokernel]
    exact (Category.comp_id _).symm
  inv_hom_id := by
    ext
    

Proof state:
case h
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝² : HasKernels V
inst✝¹ : HasImages V
inst✝ : HasCokernels V
w : f ≫ g = 0
⊢ coequalizer.π (imageToKernel' f g w) 0 ≫
      cokernel.map (imageToKernel' f g w) (imageToKernel f g w) (imageSubobjectIso f).inv (kernelSubobjectIso g).inv
          (_ : imageToKernel' f g w ≫ (kernelSubobjectIso g).inv = (imageSubobjectIso f).inv ≫ imageToKernel f g w) ≫
        cokernel.map (imageToKernel f g w) (imageToKernel' f g w) (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
          (_ : imageToKernel f g w ≫ (kernelSubobjectIso g).hom = (imageSubobjectIso f).hom ≫ imageToKernel' f g w) =
    coequalizer.π (imageToKernel' f g w) 0 ≫ 𝟙 (cokernel (imageToKernel' f g w))

Next tactic:
simp only [Iso.inv_hom_id_assoc, cokernel.π_desc, Category.comp_id, cokernel.π_desc_assoc,
      Category.assoc]
/-- `homology f g w` can be computed as the cokernel of `kernel.lift g f w`.
-/
def homology'IsoCokernelLift (w : f ≫ g = 0) : homology' f g w ≅ cokernel (kernel.lift g f w) := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasImages V
inst✝¹ : HasCokernels V
inst✝ : HasEqualizers V
w : f ≫ g = 0
⊢ homology' f g w ≅ cokernel (kernel.lift g f w)

Next tactic:
refine' homology'IsoCokernelImageToKernel' f g w ≪≫ _
/-- `homology f g w` can be computed as the cokernel of `kernel.lift g f w`.
-/
def homology'IsoCokernelLift (w : f ≫ g = 0) : homology' f g w ≅ cokernel (kernel.lift g f w) := by
  refine' homology'IsoCokernelImageToKernel' f g w ≪≫ _
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasImages V
inst✝¹ : HasCokernels V
inst✝ : HasEqualizers V
w : f ≫ g = 0
⊢ cokernel (imageToKernel' f g w) ≅ cokernel (kernel.lift g f w)

Next tactic:
have p : factorThruImage f ≫ imageToKernel' f g w = kernel.lift g f w := by
    ext
    simp [imageToKernel']
/-- `homology f g w` can be computed as the cokernel of `kernel.lift g f w`.
-/
def homology'IsoCokernelLift (w : f ≫ g = 0) : homology' f g w ≅ cokernel (kernel.lift g f w) := by
  refine' homology'IsoCokernelImageToKernel' f g w ≪≫ _
  have p : factorThruImage f ≫ imageToKernel' f g w = kernel.lift g f w := by
    

Proof state:
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasImages V
inst✝¹ : HasCokernels V
inst✝ : HasEqualizers V
w : f ≫ g = 0
⊢ factorThruImage f ≫ imageToKernel' f g w = kernel.lift g f w

Next tactic:
ext
/-- `homology f g w` can be computed as the cokernel of `kernel.lift g f w`.
-/
def homology'IsoCokernelLift (w : f ≫ g = 0) : homology' f g w ≅ cokernel (kernel.lift g f w) := by
  refine' homology'IsoCokernelImageToKernel' f g w ≪≫ _
  have p : factorThruImage f ≫ imageToKernel' f g w = kernel.lift g f w := by
    ext
    

Proof state:
case h
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasImages V
inst✝¹ : HasCokernels V
inst✝ : HasEqualizers V
w : f ≫ g = 0
⊢ (factorThruImage f ≫ imageToKernel' f g w) ≫ equalizer.ι g 0 = kernel.lift g f w ≫ equalizer.ι g 0

Next tactic:
simp [imageToKernel']
/-- `homology f g w` can be computed as the cokernel of `kernel.lift g f w`.
-/
def homology'IsoCokernelLift (w : f ≫ g = 0) : homology' f g w ≅ cokernel (kernel.lift g f w) := by
  refine' homology'IsoCokernelImageToKernel' f g w ≪≫ _
  have p : factorThruImage f ≫ imageToKernel' f g w = kernel.lift g f w := by
    ext
    simp [imageToKernel']
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w✝ : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasImages V
inst✝¹ : HasCokernels V
inst✝ : HasEqualizers V
w : f ≫ g = 0
p : factorThruImage f ≫ imageToKernel' f g w = kernel.lift g f w
⊢ cokernel (imageToKernel' f g w) ≅ cokernel (kernel.lift g f w)

Next tactic:
exact (cokernelEpiComp _ _).symm ≪≫ cokernelIsoOfEq p
@[simp]
lemma Tor'_map_app' (n : ℕ) {X Y : C} (f : X ⟶ Y) (Z : C) :
    ((Tor' C n).map f).app Z = (Functor.leftDerived ((tensoringRight C).obj Z) n).map f := by
  

Proof state:
C : Type u_1
inst✝⁴ : Category.{u_2, u_1} C
inst✝³ : MonoidalCategory C
inst✝² : Abelian C
inst✝¹ : MonoidalPreadditive C
inst✝ : HasProjectiveResolutions C
n : ℕ
X Y : C
f : X ⟶ Y
Z : C
⊢ ((Tor' C n).map f).app Z = (Functor.leftDerived ((tensoringRight C).obj Z) n).map f

Next tactic:
rfl
/-- The higher `Tor` groups for `X` and `Y` are zero if `Y` is projective. -/
lemma isZero_Tor_succ_of_projective (X Y : C) [Projective Y] (n : ℕ) :
    IsZero (((Tor C (n + 1)).obj X).obj Y) := by
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
inst✝⁴ : MonoidalCategory C
inst✝³ : Abelian C
inst✝² : MonoidalPreadditive C
inst✝¹ : HasProjectiveResolutions C
X Y : C
inst✝ : Projective Y
n : ℕ
⊢ IsZero (((Tor C (n + 1)).obj X).obj Y)

Next tactic:
apply Functor.isZero_leftDerived_obj_projective_succ
/-- The higher `Tor'` groups for `X` and `Y` are zero if `X` is projective. -/
lemma isZero_Tor'_succ_of_projective (X Y : C) [Projective X] (n : ℕ) :
    IsZero (((Tor' C (n + 1)).obj X).obj Y) := by
  

Proof state:
C : Type u_1
inst✝⁵ : Category.{u_2, u_1} C
inst✝⁴ : MonoidalCategory C
inst✝³ : Abelian C
inst✝² : MonoidalPreadditive C
inst✝¹ : HasProjectiveResolutions C
X Y : C
inst✝ : Projective X
n : ℕ
⊢ IsZero (((Tor' C (n + 1)).obj X).obj Y)

Next tactic:
apply Functor.isZero_leftDerived_obj_projective_succ
/-- If `X` is a cofiltered limit of profinite sets, then any clopen subset of `X` arises from
a clopen set in one of the terms in the limit.
-/
theorem exists_isClopen_of_cofiltered {U : Set C.pt} (hC : IsLimit C) (hU : IsClopen U) :
    ∃ (j : J) (V : Set (F.obj j)), IsClopen V ∧ U = C.π.app j ⁻¹' V := by
  

Proof state:
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
U : Set ↑C.pt.toCompHaus.toTop
hC : IsLimit C
hU : IsClopen U
⊢ ∃ j V, IsClopen V ∧ U = ⇑(C.π.app j) ⁻¹' V

Next tactic:
have := preserves_smaller_limits_toTopCat.{u, v}
/-- If `X` is a cofiltered limit of profinite sets, then any clopen subset of `X` arises from
a clopen set in one of the terms in the limit.
-/
theorem exists_isClopen_of_cofiltered {U : Set C.pt} (hC : IsLimit C) (hU : IsClopen U) :
    ∃ (j : J) (V : Set (F.obj j)), IsClopen V ∧ U = C.π.app j ⁻¹' V := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  -- First, we have the topological basis of the cofiltered limit obtained by pulling back
  -- clopen sets from the factors in the limit. By continuity, all such sets are again clopen.
  

Proof state:
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
U : Set ↑C.pt.toCompHaus.toTop
hC : IsLimit C
hU : IsClopen U
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
⊢ ∃ j V, IsClopen V ∧ U = ⇑(C.π.app j) ⁻¹' V

Next tactic:
have hB := TopCat.isTopologicalBasis_cofiltered_limit.{u, v} (F ⋙ Profinite.toTopCat)
      (Profinite.toTopCat.mapCone C) (isLimitOfPreserves _ hC) (fun j => {W | IsClopen W}) ?_
      (fun i => isClopen_univ) (fun i U1 U2 hU1 hU2 => hU1.inter hU2) ?_
/-- If `X` is a cofiltered limit of profinite sets, then any clopen subset of `X` arises from
a clopen set in one of the terms in the limit.
-/
theorem exists_isClopen_of_cofiltered {U : Set C.pt} (hC : IsLimit C) (hU : IsClopen U) :
    ∃ (j : J) (V : Set (F.obj j)), IsClopen V ∧ U = C.π.app j ⁻¹' V := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  -- First, we have the topological basis of the cofiltered limit obtained by pulling back
  -- clopen sets from the factors in the limit. By continuity, all such sets are again clopen.
  have hB := TopCat.isTopologicalBasis_cofiltered_limit.{u, v} (F ⋙ Profinite.toTopCat)
      (Profinite.toTopCat.mapCone C) (isLimitOfPreserves _ hC) (fun j => {W | IsClopen W}) ?_
      (fun i => isClopen_univ) (fun i U1 U2 hU1 hU2 => hU1.inter hU2) ?_
  

Proof state:
case refine_3
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
U : Set ↑C.pt.toCompHaus.toTop
hC : IsLimit C
hU : IsClopen U
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
hB :
  TopologicalSpace.IsTopologicalBasis
    {U | ∃ j, ∃ V ∈ (fun j => {W | IsClopen W}) j, U = ⇑((toTopCat.mapCone C).π.app j) ⁻¹' V}
⊢ ∃ j V, IsClopen V ∧ U = ⇑(C.π.app j) ⁻¹' V
case refine_1
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
U : Set ↑C.pt.toCompHaus.toTop
hC : IsLimit C
hU : IsClopen U
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
⊢ ∀ (j : J), TopologicalSpace.IsTopologicalBasis ((fun j => {W | IsClopen W}) j)
case refine_2
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
U : Set ↑C.pt.toCompHaus.toTop
hC : IsLimit C
hU : IsClopen U
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
⊢ ∀ (i j : J) (f : i ⟶ j),
    ∀ V ∈ (fun j => {W | IsClopen W}) j, ⇑((F ⋙ toTopCat).map f) ⁻¹' V ∈ (fun j => {W | IsClopen W}) i

Next tactic:
rotate_left
/-- If `X` is a cofiltered limit of profinite sets, then any clopen subset of `X` arises from
a clopen set in one of the terms in the limit.
-/
theorem exists_isClopen_of_cofiltered {U : Set C.pt} (hC : IsLimit C) (hU : IsClopen U) :
    ∃ (j : J) (V : Set (F.obj j)), IsClopen V ∧ U = C.π.app j ⁻¹' V := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  -- First, we have the topological basis of the cofiltered limit obtained by pulling back
  -- clopen sets from the factors in the limit. By continuity, all such sets are again clopen.
  have hB := TopCat.isTopologicalBasis_cofiltered_limit.{u, v} (F ⋙ Profinite.toTopCat)
      (Profinite.toTopCat.mapCone C) (isLimitOfPreserves _ hC) (fun j => {W | IsClopen W}) ?_
      (fun i => isClopen_univ) (fun i U1 U2 hU1 hU2 => hU1.inter hU2) ?_
  rotate_left
  · 

Proof state:
case refine_1
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
U : Set ↑C.pt.toCompHaus.toTop
hC : IsLimit C
hU : IsClopen U
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
⊢ ∀ (j : J), TopologicalSpace.IsTopologicalBasis ((fun j => {W | IsClopen W}) j)

Next tactic:
intro i
/-- If `X` is a cofiltered limit of profinite sets, then any clopen subset of `X` arises from
a clopen set in one of the terms in the limit.
-/
theorem exists_isClopen_of_cofiltered {U : Set C.pt} (hC : IsLimit C) (hU : IsClopen U) :
    ∃ (j : J) (V : Set (F.obj j)), IsClopen V ∧ U = C.π.app j ⁻¹' V := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  -- First, we have the topological basis of the cofiltered limit obtained by pulling back
  -- clopen sets from the factors in the limit. By continuity, all such sets are again clopen.
  have hB := TopCat.isTopologicalBasis_cofiltered_limit.{u, v} (F ⋙ Profinite.toTopCat)
      (Profinite.toTopCat.mapCone C) (isLimitOfPreserves _ hC) (fun j => {W | IsClopen W}) ?_
      (fun i => isClopen_univ) (fun i U1 U2 hU1 hU2 => hU1.inter hU2) ?_
  rotate_left
  · intro i
    

Proof state:
case refine_1
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
U : Set ↑C.pt.toCompHaus.toTop
hC : IsLimit C
hU : IsClopen U
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
i : J
⊢ TopologicalSpace.IsTopologicalBasis ((fun j => {W | IsClopen W}) i)

Next tactic:
change TopologicalSpace.IsTopologicalBasis {W : Set (F.obj i) | IsClopen W}
/-- If `X` is a cofiltered limit of profinite sets, then any clopen subset of `X` arises from
a clopen set in one of the terms in the limit.
-/
theorem exists_isClopen_of_cofiltered {U : Set C.pt} (hC : IsLimit C) (hU : IsClopen U) :
    ∃ (j : J) (V : Set (F.obj j)), IsClopen V ∧ U = C.π.app j ⁻¹' V := by
  have := preserves_smaller_limits_toTopCat.{u, v}
  -- First, we have the topological basis of the cofiltered limit obtained by pulling back
  -- clopen sets from the factors in the limit. By continuity, all such sets are again clopen.
  have hB := TopCat.isTopologicalBasis_cofiltered_limit.{u, v} (F ⋙ Profinite.toTopCat)
      (Profinite.toTopCat.mapCone C) (isLimitOfPreserves _ hC) (fun j => {W | IsClopen W}) ?_
      (fun i => isClopen_univ) (fun i U1 U2 hU1 hU2 => hU1.inter hU2) ?_
  rotate_left
  · intro i
    change TopologicalSpace.IsTopologicalBasis {W : Set (F.obj i) | IsClopen W}
    

Proof state:
case refine_1
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsCofiltered J
F : J ⥤ ProfiniteMax
C : Cone F
U : Set ↑C.pt.toCompHaus.toTop
hC : IsLimit C
hU : IsClopen U
this : PreservesLimitsOfSize.{v, v, max u v, max u v, max (u + 1) (v + 1), max (u + 1) (v + 1)} toTopCat
i : J
⊢ TopologicalSpace.IsTopologicalBasis {W | IsClopen W}

Next tactic:
apply isTopologicalBasis_isClopen