l3lab/ntp-mathlib huggingface dataset:
lemma ofHom_injective {f₁ f₂ : F ⟶ G} (h : ofHom f₁ = ofHom f₂) : f₁ = f₂ :=
  (Cocycle.equivHom F G).injective (by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
R : Type u_1
inst✝¹ : Ring R
inst✝ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
f₁ f₂ : F ⟶ G
h : ofHom f₁ = ofHom f₂
⊢ (Cocycle.equivHom F G) f₁ = (Cocycle.equivHom F G) f₂

Next tactic:
ext1
lemma ofHom_injective {f₁ f₂ : F ⟶ G} (h : ofHom f₁ = ofHom f₂) : f₁ = f₂ :=
  (Cocycle.equivHom F G).injective (by ext1; 

Proof state:
case h
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
R : Type u_1
inst✝¹ : Ring R
inst✝ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
f₁ f₂ : F ⟶ G
h : ofHom f₁ = ofHom f₂
⊢ ↑((Cocycle.equivHom F G) f₁) = ↑((Cocycle.equivHom F G) f₂)

Next tactic:
exact h
@[simp]
lemma map_add : (z + z').map Φ = z.map Φ + z'.map Φ := by 

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : Preadditive C
R : Type u_1
inst✝⁴ : Ring R
inst✝³ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝² : Category.{u_3, u_2} D
inst✝¹ : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
⊢ map (z + z') Φ = map z Φ + map z' Φ

Next tactic:
aesop_cat
@[simp]
lemma map_neg : (-z).map Φ = -z.map Φ := by 

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : Preadditive C
R : Type u_1
inst✝⁴ : Ring R
inst✝³ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝² : Category.{u_3, u_2} D
inst✝¹ : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
⊢ map (-z) Φ = -map z Φ

Next tactic:
aesop_cat
@[simp]
lemma map_sub : (z - z').map Φ = z.map Φ - z'.map Φ := by 

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : Preadditive C
R : Type u_1
inst✝⁴ : Ring R
inst✝³ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝² : Category.{u_3, u_2} D
inst✝¹ : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
⊢ map (z - z') Φ = map z Φ - map z' Φ

Next tactic:
aesop_cat
@[simp]
lemma map_zero : (0 : Cochain K L n).map Φ = 0 := by 

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : Preadditive C
R : Type u_1
inst✝⁴ : Ring R
inst✝³ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝² : Category.{u_3, u_2} D
inst✝¹ : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
⊢ map 0 Φ = 0

Next tactic:
aesop_cat
@[simp]
lemma map_comp {n₁ n₂ n₁₂ : ℤ} (z₁ : Cochain F G n₁) (z₂ : Cochain G K n₂) (h : n₁ + n₂ = n₁₂)
    (Φ : C ⥤ D) [Φ.Additive] :
    (Cochain.comp z₁ z₂ h).map Φ = Cochain.comp (z₁.map Φ) (z₂.map Φ) h := by
  

Proof state:
C : Type u
inst✝⁷ : Category.{v, u} C
inst✝⁶ : Preadditive C
R : Type u_1
inst✝⁵ : Ring R
inst✝⁴ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
inst✝² : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ✝ : C ⥤ D
inst✝¹ : Functor.Additive Φ✝
n₁ n₂ n₁₂ : ℤ
z₁ : Cochain F G n₁
z₂ : Cochain G K n₂
h : n₁ + n₂ = n₁₂
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
⊢ map (z₁.comp z₂ h) Φ = (map z₁ Φ).comp (map z₂ Φ) h

Next tactic:
ext p q hpq
@[simp]
lemma map_comp {n₁ n₂ n₁₂ : ℤ} (z₁ : Cochain F G n₁) (z₂ : Cochain G K n₂) (h : n₁ + n₂ = n₁₂)
    (Φ : C ⥤ D) [Φ.Additive] :
    (Cochain.comp z₁ z₂ h).map Φ = Cochain.comp (z₁.map Φ) (z₂.map Φ) h := by
  ext p q hpq
  

Proof state:
case h
C : Type u
inst✝⁷ : Category.{v, u} C
inst✝⁶ : Preadditive C
R : Type u_1
inst✝⁵ : Ring R
inst✝⁴ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
inst✝² : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ✝ : C ⥤ D
inst✝¹ : Functor.Additive Φ✝
n₁ n₂ n₁₂ : ℤ
z₁ : Cochain F G n₁
z₂ : Cochain G K n₂
h : n₁ + n₂ = n₁₂
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
p q : ℤ
hpq : p + n₁₂ = q
⊢ (map (z₁.comp z₂ h) Φ).v p q hpq = ((map z₁ Φ).comp (map z₂ Φ) h).v p q hpq

Next tactic:
dsimp
@[simp]
lemma map_comp {n₁ n₂ n₁₂ : ℤ} (z₁ : Cochain F G n₁) (z₂ : Cochain G K n₂) (h : n₁ + n₂ = n₁₂)
    (Φ : C ⥤ D) [Φ.Additive] :
    (Cochain.comp z₁ z₂ h).map Φ = Cochain.comp (z₁.map Φ) (z₂.map Φ) h := by
  ext p q hpq
  dsimp
  

Proof state:
case h
C : Type u
inst✝⁷ : Category.{v, u} C
inst✝⁶ : Preadditive C
R : Type u_1
inst✝⁵ : Ring R
inst✝⁴ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
inst✝² : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ✝ : C ⥤ D
inst✝¹ : Functor.Additive Φ✝
n₁ n₂ n₁₂ : ℤ
z₁ : Cochain F G n₁
z₂ : Cochain G K n₂
h : n₁ + n₂ = n₁₂
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
p q : ℤ
hpq : p + n₁₂ = q
⊢ Φ.map ((z₁.comp z₂ h).v p q hpq) = ((map z₁ Φ).comp (map z₂ Φ) h).v p q hpq

Next tactic:
simp only [map_v, comp_v _ _ h p _ q rfl (by linarith), Φ.map_comp]
@[simp]
lemma map_comp {n₁ n₂ n₁₂ : ℤ} (z₁ : Cochain F G n₁) (z₂ : Cochain G K n₂) (h : n₁ + n₂ = n₁₂)
    (Φ : C ⥤ D) [Φ.Additive] :
    (Cochain.comp z₁ z₂ h).map Φ = Cochain.comp (z₁.map Φ) (z₂.map Φ) h := by
  ext p q hpq
  dsimp
  simp only [map_v, comp_v _ _ h p _ q rfl (by 

Proof state:
C : Type u
inst✝⁷ : Category.{v, u} C
inst✝⁶ : Preadditive C
R : Type u_1
inst✝⁵ : Ring R
inst✝⁴ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝³ : Category.{u_3, u_2} D
inst✝² : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ✝ : C ⥤ D
inst✝¹ : Functor.Additive Φ✝
n₁ n₂ n₁₂ : ℤ
z₁ : Cochain F G n₁
z₂ : Cochain G K n₂
h : n₁ + n₂ = n₁₂
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
p q : ℤ
hpq : p + n₁₂ = q
⊢ p + n₁ + n₂ = q

Next tactic:
linarith
@[simp]
lemma map_ofHom :
    (Cochain.ofHom f).map Φ = Cochain.ofHom ((Φ.mapHomologicalComplex _).map f) := by 

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : Preadditive C
R : Type u_1
inst✝⁴ : Ring R
inst✝³ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝² : Category.{u_3, u_2} D
inst✝¹ : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
⊢ map (ofHom f) Φ = ofHom ((Functor.mapHomologicalComplex Φ (ComplexShape.up ℤ)).map f)

Next tactic:
aesop_cat
@[simp]
lemma δ_map : δ n m (z.map Φ) = (δ n m z).map Φ := by
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : Preadditive C
R : Type u_1
inst✝⁴ : Ring R
inst✝³ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝² : Category.{u_3, u_2} D
inst✝¹ : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
⊢ δ n m (Cochain.map z Φ) = Cochain.map (δ n m z) Φ

Next tactic:
by_cases hnm : n + 1 = m
@[simp]
lemma δ_map : δ n m (z.map Φ) = (δ n m z).map Φ := by
  by_cases hnm : n + 1 = m
  · 

Proof state:
case pos
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : Preadditive C
R : Type u_1
inst✝⁴ : Ring R
inst✝³ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝² : Category.{u_3, u_2} D
inst✝¹ : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
hnm : n + 1 = m
⊢ δ n m (Cochain.map z Φ) = Cochain.map (δ n m z) Φ

Next tactic:
ext p q hpq
@[simp]
lemma δ_map : δ n m (z.map Φ) = (δ n m z).map Φ := by
  by_cases hnm : n + 1 = m
  · ext p q hpq
    

Proof state:
case pos.h
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : Preadditive C
R : Type u_1
inst✝⁴ : Ring R
inst✝³ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝² : Category.{u_3, u_2} D
inst✝¹ : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
hnm : n + 1 = m
p q : ℤ
hpq : p + m = q
⊢ (δ n m (Cochain.map z Φ)).v p q hpq = (Cochain.map (δ n m z) Φ).v p q hpq

Next tactic:
dsimp
@[simp]
lemma δ_map : δ n m (z.map Φ) = (δ n m z).map Φ := by
  by_cases hnm : n + 1 = m
  · ext p q hpq
    dsimp
    

Proof state:
case pos.h
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : Preadditive C
R : Type u_1
inst✝⁴ : Ring R
inst✝³ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝² : Category.{u_3, u_2} D
inst✝¹ : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
hnm : n + 1 = m
p q : ℤ
hpq : p + m = q
⊢ (δ n m (Cochain.map z Φ)).v p q hpq = Φ.map ((δ n m z).v p q hpq)

Next tactic:
simp only [δ_v n m hnm _ p q hpq (q-1) (p+1) rfl rfl,
      Functor.map_add, Functor.map_comp, Functor.map_units_smul,
      Cochain.map_v, Functor.mapHomologicalComplex_obj_d]
@[simp]
lemma δ_map : δ n m (z.map Φ) = (δ n m z).map Φ := by
  by_cases hnm : n + 1 = m
  · ext p q hpq
    dsimp
    simp only [δ_v n m hnm _ p q hpq (q-1) (p+1) rfl rfl,
      Functor.map_add, Functor.map_comp, Functor.map_units_smul,
      Cochain.map_v, Functor.mapHomologicalComplex_obj_d]
  · 

Proof state:
case neg
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : Preadditive C
R : Type u_1
inst✝⁴ : Ring R
inst✝³ : Linear R C
F G K L : CochainComplex C ℤ
n m : ℤ
D : Type u_2
inst✝² : Category.{u_3, u_2} D
inst✝¹ : Preadditive D
z z' : Cochain K L n
f : K ⟶ L
Φ : C ⥤ D
inst✝ : Functor.Additive Φ
hnm : ¬n + 1 = m
⊢ δ n m (Cochain.map z Φ) = Cochain.map (δ n m z) Φ

Next tactic:
simp only [δ_shape _ _ hnm, Cochain.map_zero]
/-- An open set is a Gδ set. -/
theorem IsOpen.isGδ {s : Set X} (h : IsOpen s) : IsGδ s :=
  ⟨{s}, by 

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
s : Set X
h : IsOpen s
⊢ ∀ t ∈ {s}, IsOpen t

Next tactic:
simp [h]
theorem isGδ_biInter_of_isOpen {I : Set ι} (hI : I.Countable) {f : ι → Set X}
    (hf : ∀ i ∈ I, IsOpen (f i)) : IsGδ (⋂ i ∈ I, f i) :=
  ⟨f '' I, by 

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
I : Set ι
hI : Set.Countable I
f : ι → Set X
hf : ∀ i ∈ I, IsOpen (f i)
⊢ ∀ t ∈ f '' I, IsOpen t

Next tactic:
rwa [ball_image_iff]
theorem isGδ_biInter_of_isOpen {I : Set ι} (hI : I.Countable) {f : ι → Set X}
    (hf : ∀ i ∈ I, IsOpen (f i)) : IsGδ (⋂ i ∈ I, f i) :=
  ⟨f '' I, by rwa [ball_image_iff], hI.image _, by 

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
I : Set ι
hI : Set.Countable I
f : ι → Set X
hf : ∀ i ∈ I, IsOpen (f i)
⊢ ⋂ i ∈ I, f i = ⋂₀ (f '' I)

Next tactic:
rw [sInter_image]
theorem isGδ_iInter_of_isOpen [Encodable ι] {f : ι → Set X} (hf : ∀ i, IsOpen (f i)) :
    IsGδ (⋂ i, f i) :=
  ⟨range f, by 

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : Encodable ι
f : ι → Set X
hf : ∀ (i : ι), IsOpen (f i)
⊢ ∀ t ∈ range f, IsOpen t

Next tactic:
rwa [forall_range_iff]
theorem isGδ_iInter_of_isOpen [Encodable ι] {f : ι → Set X} (hf : ∀ i, IsOpen (f i)) :
    IsGδ (⋂ i, f i) :=
  ⟨range f, by rwa [forall_range_iff], countable_range _, by 

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : Encodable ι
f : ι → Set X
hf : ∀ (i : ι), IsOpen (f i)
⊢ ⋂ i, f i = ⋂₀ range f

Next tactic:
rw [sInter_range]
/-- The intersection of an encodable family of Gδ sets is a Gδ set. -/
theorem isGδ_iInter [Encodable ι] {s : ι → Set X} (hs : ∀ i, IsGδ (s i)) : IsGδ (⋂ i, s i) := by
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : Encodable ι
s : ι → Set X
hs : ∀ (i : ι), IsGδ (s i)
⊢ IsGδ (⋂ i, s i)

Next tactic:
choose T hTo hTc hTs using hs
/-- The intersection of an encodable family of Gδ sets is a Gδ set. -/
theorem isGδ_iInter [Encodable ι] {s : ι → Set X} (hs : ∀ i, IsGδ (s i)) : IsGδ (⋂ i, s i) := by
  choose T hTo hTc hTs using hs
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : Encodable ι
s : ι → Set X
T : ι → Set (Set X)
hTo : ∀ (i : ι), ∀ t ∈ T i, IsOpen t
hTc : ∀ (i : ι), Set.Countable (T i)
hTs : ∀ (i : ι), s i = ⋂₀ T i
⊢ IsGδ (⋂ i, s i)

Next tactic:
obtain rfl : s = fun i => ⋂₀ T i := funext hTs
/-- The intersection of an encodable family of Gδ sets is a Gδ set. -/
theorem isGδ_iInter [Encodable ι] {s : ι → Set X} (hs : ∀ i, IsGδ (s i)) : IsGδ (⋂ i, s i) := by
  choose T hTo hTc hTs using hs
  obtain rfl : s = fun i => ⋂₀ T i := funext hTs
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : Encodable ι
T : ι → Set (Set X)
hTo : ∀ (i : ι), ∀ t ∈ T i, IsOpen t
hTc : ∀ (i : ι), Set.Countable (T i)
hTs : ∀ (i : ι), (fun i => ⋂₀ T i) i = ⋂₀ T i
⊢ IsGδ (⋂ i, (fun i => ⋂₀ T i) i)

Next tactic:
refine' ⟨⋃ i, T i, _, countable_iUnion hTc, (sInter_iUnion _).symm⟩
/-- The intersection of an encodable family of Gδ sets is a Gδ set. -/
theorem isGδ_iInter [Encodable ι] {s : ι → Set X} (hs : ∀ i, IsGδ (s i)) : IsGδ (⋂ i, s i) := by
  choose T hTo hTc hTs using hs
  obtain rfl : s = fun i => ⋂₀ T i := funext hTs
  refine' ⟨⋃ i, T i, _, countable_iUnion hTc, (sInter_iUnion _).symm⟩
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : Encodable ι
T : ι → Set (Set X)
hTo : ∀ (i : ι), ∀ t ∈ T i, IsOpen t
hTc : ∀ (i : ι), Set.Countable (T i)
hTs : ∀ (i : ι), (fun i => ⋂₀ T i) i = ⋂₀ T i
⊢ ∀ t ∈ ⋃ i, T i, IsOpen t

Next tactic:
simpa [@forall_swap ι] using hTo
theorem isGδ_biInter {s : Set ι} (hs : s.Countable) {t : ∀ i ∈ s, Set X}
    (ht : ∀ (i) (hi : i ∈ s), IsGδ (t i hi)) : IsGδ (⋂ i ∈ s, t i ‹_›) := by
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
s : Set ι
hs : Set.Countable s
t : (i : ι) → i ∈ s → Set X
ht : ∀ (i : ι) (hi : i ∈ s), IsGδ (t i hi)
⊢ IsGδ (⋂ i, ⋂ (h : i ∈ s), t i h)

Next tactic:
rw [biInter_eq_iInter]
theorem isGδ_biInter {s : Set ι} (hs : s.Countable) {t : ∀ i ∈ s, Set X}
    (ht : ∀ (i) (hi : i ∈ s), IsGδ (t i hi)) : IsGδ (⋂ i ∈ s, t i ‹_›) := by
  rw [biInter_eq_iInter]
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
s : Set ι
hs : Set.Countable s
t : (i : ι) → i ∈ s → Set X
ht : ∀ (i : ι) (hi : i ∈ s), IsGδ (t i hi)
⊢ IsGδ (⋂ x, t ↑x (_ : ↑x ∈ s))

Next tactic:
haveI := hs.toEncodable
theorem isGδ_biInter {s : Set ι} (hs : s.Countable) {t : ∀ i ∈ s, Set X}
    (ht : ∀ (i) (hi : i ∈ s), IsGδ (t i hi)) : IsGδ (⋂ i ∈ s, t i ‹_›) := by
  rw [biInter_eq_iInter]
  haveI := hs.toEncodable
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
s : Set ι
hs : Set.Countable s
t : (i : ι) → i ∈ s → Set X
ht : ∀ (i : ι) (hi : i ∈ s), IsGδ (t i hi)
this : Encodable ↑s
⊢ IsGδ (⋂ x, t ↑x (_ : ↑x ∈ s))

Next tactic:
exact isGδ_iInter fun x => ht x x.2
/-- A countable intersection of Gδ sets is a Gδ set. -/
theorem isGδ_sInter {S : Set (Set X)} (h : ∀ s ∈ S, IsGδ s) (hS : S.Countable) : IsGδ (⋂₀ S) := by
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
S : Set (Set X)
h : ∀ s ∈ S, IsGδ s
hS : Set.Countable S
⊢ IsGδ (⋂₀ S)

Next tactic:
simpa only [sInter_eq_biInter] using isGδ_biInter hS h
theorem IsGδ.inter {s t : Set X} (hs : IsGδ s) (ht : IsGδ t) : IsGδ (s ∩ t) := by
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
s t : Set X
hs : IsGδ s
ht : IsGδ t
⊢ IsGδ (s ∩ t)

Next tactic:
rw [inter_eq_iInter]
theorem IsGδ.inter {s t : Set X} (hs : IsGδ s) (ht : IsGδ t) : IsGδ (s ∩ t) := by
  rw [inter_eq_iInter]
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
s t : Set X
hs : IsGδ s
ht : IsGδ t
⊢ IsGδ (⋂ b, bif b then s else t)

Next tactic:
exact isGδ_iInter (Bool.forall_bool.2 ⟨ht, hs⟩)
/-- The union of two Gδ sets is a Gδ set. -/
theorem IsGδ.union {s t : Set X} (hs : IsGδ s) (ht : IsGδ t) : IsGδ (s ∪ t) := by
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
s t : Set X
hs : IsGδ s
ht : IsGδ t
⊢ IsGδ (s ∪ t)

Next tactic:
rcases hs with ⟨S, Sopen, Scount, rfl⟩
/-- The union of two Gδ sets is a Gδ set. -/
theorem IsGδ.union {s t : Set X} (hs : IsGδ s) (ht : IsGδ t) : IsGδ (s ∪ t) := by
  rcases hs with ⟨S, Sopen, Scount, rfl⟩
  

Proof state:
case intro.intro.intro
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
t : Set X
ht : IsGδ t
S : Set (Set X)
Sopen : ∀ t ∈ S, IsOpen t
Scount : Set.Countable S
⊢ IsGδ (⋂₀ S ∪ t)

Next tactic:
rcases ht with ⟨T, Topen, Tcount, rfl⟩
/-- The union of two Gδ sets is a Gδ set. -/
theorem IsGδ.union {s t : Set X} (hs : IsGδ s) (ht : IsGδ t) : IsGδ (s ∪ t) := by
  rcases hs with ⟨S, Sopen, Scount, rfl⟩
  rcases ht with ⟨T, Topen, Tcount, rfl⟩
  

Proof state:
case intro.intro.intro.intro.intro.intro
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
S : Set (Set X)
Sopen : ∀ t ∈ S, IsOpen t
Scount : Set.Countable S
T : Set (Set X)
Topen : ∀ t ∈ T, IsOpen t
Tcount : Set.Countable T
⊢ IsGδ (⋂₀ S ∪ ⋂₀ T)

Next tactic:
rw [sInter_union_sInter]
/-- The union of two Gδ sets is a Gδ set. -/
theorem IsGδ.union {s t : Set X} (hs : IsGδ s) (ht : IsGδ t) : IsGδ (s ∪ t) := by
  rcases hs with ⟨S, Sopen, Scount, rfl⟩
  rcases ht with ⟨T, Topen, Tcount, rfl⟩
  rw [sInter_union_sInter]
  

Proof state:
case intro.intro.intro.intro.intro.intro
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
S : Set (Set X)
Sopen : ∀ t ∈ S, IsOpen t
Scount : Set.Countable S
T : Set (Set X)
Topen : ∀ t ∈ T, IsOpen t
Tcount : Set.Countable T
⊢ IsGδ (⋂ p ∈ S ×ˢ T, p.1 ∪ p.2)

Next tactic:
apply isGδ_biInter_of_isOpen (Scount.prod Tcount)
/-- The union of two Gδ sets is a Gδ set. -/
theorem IsGδ.union {s t : Set X} (hs : IsGδ s) (ht : IsGδ t) : IsGδ (s ∪ t) := by
  rcases hs with ⟨S, Sopen, Scount, rfl⟩
  rcases ht with ⟨T, Topen, Tcount, rfl⟩
  rw [sInter_union_sInter]
  apply isGδ_biInter_of_isOpen (Scount.prod Tcount)
  

Proof state:
case intro.intro.intro.intro.intro.intro
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
S : Set (Set X)
Sopen : ∀ t ∈ S, IsOpen t
Scount : Set.Countable S
T : Set (Set X)
Topen : ∀ t ∈ T, IsOpen t
Tcount : Set.Countable T
⊢ ∀ i ∈ S ×ˢ T, IsOpen (i.1 ∪ i.2)

Next tactic:
rintro ⟨a, b⟩ ⟨ha, hb⟩
/-- The union of two Gδ sets is a Gδ set. -/
theorem IsGδ.union {s t : Set X} (hs : IsGδ s) (ht : IsGδ t) : IsGδ (s ∪ t) := by
  rcases hs with ⟨S, Sopen, Scount, rfl⟩
  rcases ht with ⟨T, Topen, Tcount, rfl⟩
  rw [sInter_union_sInter]
  apply isGδ_biInter_of_isOpen (Scount.prod Tcount)
  rintro ⟨a, b⟩ ⟨ha, hb⟩
  

Proof state:
case intro.intro.intro.intro.intro.intro.mk.intro
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
S : Set (Set X)
Sopen : ∀ t ∈ S, IsOpen t
Scount : Set.Countable S
T : Set (Set X)
Topen : ∀ t ∈ T, IsOpen t
Tcount : Set.Countable T
a b : Set X
ha : (a, b).1 ∈ S
hb : (a, b).2 ∈ T
⊢ IsOpen ((a, b).1 ∪ (a, b).2)

Next tactic:
exact (Sopen a ha).union (Topen b hb)
/-- The union of finitely many Gδ sets is a Gδ set. -/
theorem isGδ_biUnion {s : Set ι} (hs : s.Finite) {f : ι → Set X} (h : ∀ i ∈ s, IsGδ (f i)) :
    IsGδ (⋃ i ∈ s, f i) := by
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
s : Set ι
hs : Set.Finite s
f : ι → Set X
h : ∀ i ∈ s, IsGδ (f i)
⊢ IsGδ (⋃ i ∈ s, f i)

Next tactic:
refine' Finite.induction_on hs (by simp) _ h
/-- The union of finitely many Gδ sets is a Gδ set. -/
theorem isGδ_biUnion {s : Set ι} (hs : s.Finite) {f : ι → Set X} (h : ∀ i ∈ s, IsGδ (f i)) :
    IsGδ (⋃ i ∈ s, f i) := by
  refine' Finite.induction_on hs (by 

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
s : Set ι
hs : Set.Finite s
f : ι → Set X
h : ∀ i ∈ s, IsGδ (f i)
⊢ (∀ i ∈ ∅, IsGδ (f i)) → IsGδ (⋃ i ∈ ∅, f i)

Next tactic:
simp
/-- The union of finitely many Gδ sets is a Gδ set. -/
theorem isGδ_biUnion {s : Set ι} (hs : s.Finite) {f : ι → Set X} (h : ∀ i ∈ s, IsGδ (f i)) :
    IsGδ (⋃ i ∈ s, f i) := by
  refine' Finite.induction_on hs (by simp) _ h
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
s : Set ι
hs : Set.Finite s
f : ι → Set X
h : ∀ i ∈ s, IsGδ (f i)
⊢ ∀ {a : ι} {s : Set ι},
    a ∉ s →
      Set.Finite s →
        ((∀ i ∈ s, IsGδ (f i)) → IsGδ (⋃ i ∈ s, f i)) → (∀ i ∈ insert a s, IsGδ (f i)) → IsGδ (⋃ i ∈ insert a s, f i)

Next tactic:
simp only [ball_insert_iff, biUnion_insert]
/-- The union of finitely many Gδ sets is a Gδ set. -/
theorem isGδ_biUnion {s : Set ι} (hs : s.Finite) {f : ι → Set X} (h : ∀ i ∈ s, IsGδ (f i)) :
    IsGδ (⋃ i ∈ s, f i) := by
  refine' Finite.induction_on hs (by simp) _ h
  simp only [ball_insert_iff, biUnion_insert]
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝ : TopologicalSpace X
s : Set ι
hs : Set.Finite s
f : ι → Set X
h : ∀ i ∈ s, IsGδ (f i)
⊢ ∀ {a : ι} {s : Set ι},
    a ∉ s →
      Set.Finite s →
        ((∀ i ∈ s, IsGδ (f i)) → IsGδ (⋃ i ∈ s, f i)) → (IsGδ (f a) ∧ ∀ i ∈ s, IsGδ (f i)) → IsGδ (f a ∪ ⋃ i ∈ s, f i)

Next tactic:
exact fun _ _ ihs H => H.1.union (ihs H.2)
theorem IsClosed.isGδ {X} [UniformSpace X] [IsCountablyGenerated (uniformity X)] {s : Set X}
    (hs : IsClosed s) : IsGδ s := by
  

Proof state:
X✝ : Type u_1
Y : Type u_2
ι : Type u_3
inst✝² : TopologicalSpace X✝
X : Type u_4
inst✝¹ : UniformSpace X
inst✝ : IsCountablyGenerated (uniformity X)
s : Set X
hs : IsClosed s
⊢ IsGδ s

Next tactic:
rcases (@uniformity_hasBasis_open X _).exists_antitone_subbasis with ⟨U, hUo, hU, -⟩
theorem IsClosed.isGδ {X} [UniformSpace X] [IsCountablyGenerated (uniformity X)] {s : Set X}
    (hs : IsClosed s) : IsGδ s := by
  rcases (@uniformity_hasBasis_open X _).exists_antitone_subbasis with ⟨U, hUo, hU, -⟩
  

Proof state:
case intro.intro.mk
X✝ : Type u_1
Y : Type u_2
ι : Type u_3
inst✝² : TopologicalSpace X✝
X : Type u_4
inst✝¹ : UniformSpace X
inst✝ : IsCountablyGenerated (uniformity X)
s : Set X
hs : IsClosed s
U : ℕ → Set (X × X)
hUo : ∀ (i : ℕ), U i ∈ uniformity X ∧ IsOpen (U i)
hU : HasBasis (uniformity X) (fun x => True) fun i => id (U i)
⊢ IsGδ s

Next tactic:
rw [← hs.closure_eq, ← hU.biInter_biUnion_ball]
theorem IsClosed.isGδ {X} [UniformSpace X] [IsCountablyGenerated (uniformity X)] {s : Set X}
    (hs : IsClosed s) : IsGδ s := by
  rcases (@uniformity_hasBasis_open X _).exists_antitone_subbasis with ⟨U, hUo, hU, -⟩
  rw [← hs.closure_eq, ← hU.biInter_biUnion_ball]
  

Proof state:
case intro.intro.mk
X✝ : Type u_1
Y : Type u_2
ι : Type u_3
inst✝² : TopologicalSpace X✝
X : Type u_4
inst✝¹ : UniformSpace X
inst✝ : IsCountablyGenerated (uniformity X)
s : Set X
hs : IsClosed s
U : ℕ → Set (X × X)
hUo : ∀ (i : ℕ), U i ∈ uniformity X ∧ IsOpen (U i)
hU : HasBasis (uniformity X) (fun x => True) fun i => id (U i)
⊢ IsGδ (⋂ i, ⋂ (_ : True), ⋃ x ∈ s, UniformSpace.ball x (id (U i)))

Next tactic:
refine' isGδ_biInter (to_countable _) fun n _ => IsOpen.isGδ _
theorem IsClosed.isGδ {X} [UniformSpace X] [IsCountablyGenerated (uniformity X)] {s : Set X}
    (hs : IsClosed s) : IsGδ s := by
  rcases (@uniformity_hasBasis_open X _).exists_antitone_subbasis with ⟨U, hUo, hU, -⟩
  rw [← hs.closure_eq, ← hU.biInter_biUnion_ball]
  refine' isGδ_biInter (to_countable _) fun n _ => IsOpen.isGδ _
  

Proof state:
case intro.intro.mk
X✝ : Type u_1
Y : Type u_2
ι : Type u_3
inst✝² : TopologicalSpace X✝
X : Type u_4
inst✝¹ : UniformSpace X
inst✝ : IsCountablyGenerated (uniformity X)
s : Set X
hs : IsClosed s
U : ℕ → Set (X × X)
hUo : ∀ (i : ℕ), U i ∈ uniformity X ∧ IsOpen (U i)
hU : HasBasis (uniformity X) (fun x => True) fun i => id (U i)
n : ℕ
x✝ : n ∈ fun i => True
⊢ IsOpen (⋃ x ∈ s, UniformSpace.ball x (id (U n)))

Next tactic:
exact isOpen_biUnion fun x _ => UniformSpace.isOpen_ball _ (hUo _).2
theorem Set.Countable.isGδ_compl {s : Set X} (hs : s.Countable) : IsGδ sᶜ := by
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : T1Space X
s : Set X
hs : Set.Countable s
⊢ IsGδ sᶜ

Next tactic:
rw [← biUnion_of_singleton s, compl_iUnion₂]
theorem Set.Countable.isGδ_compl {s : Set X} (hs : s.Countable) : IsGδ sᶜ := by
  rw [← biUnion_of_singleton s, compl_iUnion₂]
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : T1Space X
s : Set X
hs : Set.Countable s
⊢ IsGδ (⋂ i ∈ s, {i}ᶜ)

Next tactic:
exact isGδ_biInter hs fun x _ => isGδ_compl_singleton x
theorem isGδ_singleton (x : X) : IsGδ ({x} : Set X) := by
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝² : TopologicalSpace X
inst✝¹ : T1Space X
inst✝ : FirstCountableTopology X
x : X
⊢ IsGδ {x}

Next tactic:
rcases (nhds_basis_opens x).exists_antitone_subbasis with ⟨U, hU, h_basis⟩
theorem isGδ_singleton (x : X) : IsGδ ({x} : Set X) := by
  rcases (nhds_basis_opens x).exists_antitone_subbasis with ⟨U, hU, h_basis⟩
  

Proof state:
case intro.intro
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝² : TopologicalSpace X
inst✝¹ : T1Space X
inst✝ : FirstCountableTopology X
x : X
U : ℕ → Set X
hU : ∀ (i : ℕ), x ∈ U i ∧ IsOpen (U i)
h_basis : HasAntitoneBasis (𝓝 x) fun i => U i
⊢ IsGδ {x}

Next tactic:
rw [← biInter_basis_nhds h_basis.toHasBasis]