l3lab/ntp-mathlib huggingface dataset:
theorem fromOpenSubsetsGlue_injective : Function.Injective (fromOpenSubsetsGlue U) := by
  intro x y e
  obtain ⟨i, ⟨x, hx⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  obtain ⟨j, ⟨y, hy⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective y
  -- porting note: now it is `erw`, it was `rw`
  -- see the porting note on `ι_fromOpenSubsetsGlue`
  erw [ι_fromOpenSubsetsGlue_apply, ι_fromOpenSubsetsGlue_apply] at e
  change x = y at e
  subst e
  rw [(ofOpenSubsets U).ι_eq_iff_rel]
  right
  

Proof state:
case intro.intro.mk.intro.intro.mk.h
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx : x ∈ U i
j : (ofOpenSubsets U).toGlueData.J
hy : x ∈ U j
⊢ ∃ x_1,
    (GlueData.f (ofOpenSubsets U).toGlueData { fst := i, snd := { val := x, property := hx } }.fst
            { fst := j, snd := { val := x, property := hy } }.fst)
          x_1 =
        { fst := i, snd := { val := x, property := hx } }.snd ∧
      (GlueData.f (ofOpenSubsets U).toGlueData { fst := j, snd := { val := x, property := hy } }.fst
            { fst := i, snd := { val := x, property := hx } }.fst)
          ((GlueData.t (ofOpenSubsets U).toGlueData { fst := i, snd := { val := x, property := hx } }.fst
              { fst := j, snd := { val := x, property := hy } }.fst)
            x_1) =
        { fst := j, snd := { val := x, property := hy } }.snd

Next tactic:
exact ⟨⟨⟨x, hx⟩, hy⟩, rfl, rfl⟩
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
⊢ IsOpenMap ⇑(fromOpenSubsetsGlue U)

Next tactic:
intro s hs
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : IsOpen s
⊢ IsOpen (⇑(fromOpenSubsetsGlue U) '' s)

Next tactic:
rw [(ofOpenSubsets U).isOpen_iff] at hs
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
⊢ IsOpen (⇑(fromOpenSubsetsGlue U) '' s)

Next tactic:
rw [isOpen_iff_forall_mem_open]
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
⊢ ∀ x ∈ ⇑(fromOpenSubsetsGlue U) '' s, ∃ t ⊆ ⇑(fromOpenSubsetsGlue U) '' s, IsOpen t ∧ x ∈ t

Next tactic:
rintro _ ⟨x, hx, rfl⟩
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  

Proof state:
case intro.intro
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
x : (forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData)
hx : x ∈ s
⊢ ∃ t ⊆ ⇑(fromOpenSubsetsGlue U) '' s, IsOpen t ∧ (fromOpenSubsetsGlue U) x ∈ t

Next tactic:
obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  

Proof state:
case intro.intro.intro.intro.mk
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
⊢ ∃ t ⊆ ⇑(fromOpenSubsetsGlue U) '' s,
    IsOpen t ∧ (fromOpenSubsetsGlue U) ((GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' }) ∈ t

Next tactic:
use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
  

Proof state:
case h
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
⊢ ⇑(fromOpenSubsetsGlue U) '' s ∩ Set.range ⇑(Opens.inclusion (U i)) ⊆ ⇑(fromOpenSubsetsGlue U) '' s ∧
    IsOpen (⇑(fromOpenSubsetsGlue U) '' s ∩ Set.range ⇑(Opens.inclusion (U i))) ∧
      (fromOpenSubsetsGlue U) ((GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' }) ∈
        ⇑(fromOpenSubsetsGlue U) '' s ∩ Set.range ⇑(Opens.inclusion (U i))

Next tactic:
use Set.inter_subset_left _ _
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
  use Set.inter_subset_left _ _
  

Proof state:
case right
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
⊢ IsOpen (⇑(fromOpenSubsetsGlue U) '' s ∩ Set.range ⇑(Opens.inclusion (U i))) ∧
    (fromOpenSubsetsGlue U) ((GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' }) ∈
      ⇑(fromOpenSubsetsGlue U) '' s ∩ Set.range ⇑(Opens.inclusion (U i))

Next tactic:
constructor
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
  use Set.inter_subset_left _ _
  constructor
  · 

Proof state:
case right.left
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
⊢ IsOpen (⇑(fromOpenSubsetsGlue U) '' s ∩ Set.range ⇑(Opens.inclusion (U i)))

Next tactic:
erw [← Set.image_preimage_eq_inter_range]
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
  use Set.inter_subset_left _ _
  constructor
  · erw [← Set.image_preimage_eq_inter_range]
    

Proof state:
case right.left
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
⊢ IsOpen (⇑(Opens.inclusion (U i)) '' (⇑(Opens.inclusion (U i)) ⁻¹' (⇑(fromOpenSubsetsGlue U) '' s)))

Next tactic:
apply (Opens.openEmbedding (X := TopCat.of α) (U i)).isOpenMap
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
  use Set.inter_subset_left _ _
  constructor
  · erw [← Set.image_preimage_eq_inter_range]
    apply (Opens.openEmbedding (X := TopCat.of α) (U i)).isOpenMap
    

Proof state:
case right.left.a
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
⊢ IsOpen (⇑(Opens.inclusion (U i)) ⁻¹' (⇑(fromOpenSubsetsGlue U) '' s))

Next tactic:
convert hs i using 1
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
  use Set.inter_subset_left _ _
  constructor
  · erw [← Set.image_preimage_eq_inter_range]
    apply (Opens.openEmbedding (X := TopCat.of α) (U i)).isOpenMap
    convert hs i using 1
    

Proof state:
case h.e'_3.h
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
e_1✝ :
  (forget TopCat).obj ((Opens.toTopCat (of α)).obj (U i)) =
    (forget TopCat).obj (GlueData.U (ofOpenSubsets U).toGlueData i)
⊢ ⇑(Opens.inclusion (U i)) ⁻¹' (⇑(fromOpenSubsetsGlue U) '' s) = ⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s

Next tactic:
erw [← ι_fromOpenSubsetsGlue, coe_comp, Set.preimage_comp]
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
  use Set.inter_subset_left _ _
  constructor
  · erw [← Set.image_preimage_eq_inter_range]
    apply (Opens.openEmbedding (X := TopCat.of α) (U i)).isOpenMap
    convert hs i using 1
    erw [← ι_fromOpenSubsetsGlue, coe_comp, Set.preimage_comp]
    --  porting note: `congr 1` did nothing, so I replaced it with `apply congr_arg`
    

Proof state:
case h.e'_3.h
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
e_1✝ :
  (forget TopCat).obj ((Opens.toTopCat (of α)).obj (U i)) =
    (forget TopCat).obj (GlueData.U (ofOpenSubsets U).toGlueData i)
⊢ ⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' (⇑(fromOpenSubsetsGlue U) ⁻¹' (⇑(fromOpenSubsetsGlue U) '' s)) =
    ⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s

Next tactic:
apply congr_arg
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
  use Set.inter_subset_left _ _
  constructor
  · erw [← Set.image_preimage_eq_inter_range]
    apply (Opens.openEmbedding (X := TopCat.of α) (U i)).isOpenMap
    convert hs i using 1
    erw [← ι_fromOpenSubsetsGlue, coe_comp, Set.preimage_comp]
    --  porting note: `congr 1` did nothing, so I replaced it with `apply congr_arg`
    apply congr_arg
    

Proof state:
case h.e'_3.h.h
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
e_1✝ :
  (forget TopCat).obj ((Opens.toTopCat (of α)).obj (U i)) =
    (forget TopCat).obj (GlueData.U (ofOpenSubsets U).toGlueData i)
⊢ ⇑(fromOpenSubsetsGlue U) ⁻¹' (⇑(fromOpenSubsetsGlue U) '' s) = s

Next tactic:
refine' Set.preimage_image_eq _ (fromOpenSubsetsGlue_injective U)
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
  use Set.inter_subset_left _ _
  constructor
  · erw [← Set.image_preimage_eq_inter_range]
    apply (Opens.openEmbedding (X := TopCat.of α) (U i)).isOpenMap
    convert hs i using 1
    erw [← ι_fromOpenSubsetsGlue, coe_comp, Set.preimage_comp]
    --  porting note: `congr 1` did nothing, so I replaced it with `apply congr_arg`
    apply congr_arg
    refine' Set.preimage_image_eq _ (fromOpenSubsetsGlue_injective U)
  · 

Proof state:
case right.right
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
⊢ (fromOpenSubsetsGlue U) ((GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' }) ∈
    ⇑(fromOpenSubsetsGlue U) '' s ∩ Set.range ⇑(Opens.inclusion (U i))

Next tactic:
refine' ⟨Set.mem_image_of_mem _ hx, _⟩
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
  use Set.inter_subset_left _ _
  constructor
  · erw [← Set.image_preimage_eq_inter_range]
    apply (Opens.openEmbedding (X := TopCat.of α) (U i)).isOpenMap
    convert hs i using 1
    erw [← ι_fromOpenSubsetsGlue, coe_comp, Set.preimage_comp]
    --  porting note: `congr 1` did nothing, so I replaced it with `apply congr_arg`
    apply congr_arg
    refine' Set.preimage_image_eq _ (fromOpenSubsetsGlue_injective U)
  · refine' ⟨Set.mem_image_of_mem _ hx, _⟩
    -- porting note: another `rw ↦ erw`
    -- See above.
    

Proof state:
case right.right
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
⊢ (fromOpenSubsetsGlue U) ((GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' }) ∈
    Set.range ⇑(Opens.inclusion (U i))

Next tactic:
erw [ι_fromOpenSubsetsGlue_apply]
theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by
  intro s hs
  rw [(ofOpenSubsets U).isOpen_iff] at hs
  rw [isOpen_iff_forall_mem_open]
  rintro _ ⟨x, hx, rfl⟩
  obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  use fromOpenSubsetsGlue U '' s ∩ Set.range (@Opens.inclusion (TopCat.of α) (U i))
  use Set.inter_subset_left _ _
  constructor
  · erw [← Set.image_preimage_eq_inter_range]
    apply (Opens.openEmbedding (X := TopCat.of α) (U i)).isOpenMap
    convert hs i using 1
    erw [← ι_fromOpenSubsetsGlue, coe_comp, Set.preimage_comp]
    --  porting note: `congr 1` did nothing, so I replaced it with `apply congr_arg`
    apply congr_arg
    refine' Set.preimage_image_eq _ (fromOpenSubsetsGlue_injective U)
  · refine' ⟨Set.mem_image_of_mem _ hx, _⟩
    -- porting note: another `rw ↦ erw`
    -- See above.
    erw [ι_fromOpenSubsetsGlue_apply]
    

Proof state:
case right.right
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
s : Set ((forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData))
hs : ∀ (i : (ofOpenSubsets U).toGlueData.J), IsOpen (⇑(GlueData.ι (ofOpenSubsets U).toGlueData i) ⁻¹' s)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
hx : (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' } ∈ s
⊢ (Opens.inclusion (U i)) { val := x, property := hx' } ∈ Set.range ⇑(Opens.inclusion (U i))

Next tactic:
exact Set.mem_range_self _
theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, (U i : Set α) := by
  

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
⊢ Set.range ⇑(fromOpenSubsetsGlue U) = ⋃ i, ↑(U i)

Next tactic:
ext
theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, (U i : Set α) := by
  ext
  

Proof state:
case h
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
x✝ : (forget TopCat).obj (of α)
⊢ x✝ ∈ Set.range ⇑(fromOpenSubsetsGlue U) ↔ x✝ ∈ ⋃ i, ↑(U i)

Next tactic:
constructor
theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, (U i : Set α) := by
  ext
  constructor
  · 

Proof state:
case h.mp
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
x✝ : (forget TopCat).obj (of α)
⊢ x✝ ∈ Set.range ⇑(fromOpenSubsetsGlue U) → x✝ ∈ ⋃ i, ↑(U i)

Next tactic:
rintro ⟨x, rfl⟩
theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, (U i : Set α) := by
  ext
  constructor
  · rintro ⟨x, rfl⟩
    

Proof state:
case h.mp.intro
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
x : (forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData)
⊢ (fromOpenSubsetsGlue U) x ∈ ⋃ i, ↑(U i)

Next tactic:
obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, (U i : Set α) := by
  ext
  constructor
  · rintro ⟨x, rfl⟩
    obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
    -- porting note: another `rw ↦ erw`
    -- See above
    

Proof state:
case h.mp.intro.intro.intro.mk
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
⊢ (fromOpenSubsetsGlue U) ((GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx' }) ∈ ⋃ i, ↑(U i)

Next tactic:
erw [ι_fromOpenSubsetsGlue_apply]
theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, (U i : Set α) := by
  ext
  constructor
  · rintro ⟨x, rfl⟩
    obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
    -- porting note: another `rw ↦ erw`
    -- See above
    erw [ι_fromOpenSubsetsGlue_apply]
    

Proof state:
case h.mp.intro.intro.intro.mk
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx' : x ∈ U i
⊢ (Opens.inclusion (U i)) { val := x, property := hx' } ∈ ⋃ i, ↑(U i)

Next tactic:
exact Set.subset_iUnion _ i hx'
theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, (U i : Set α) := by
  ext
  constructor
  · rintro ⟨x, rfl⟩
    obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
    -- porting note: another `rw ↦ erw`
    -- See above
    erw [ι_fromOpenSubsetsGlue_apply]
    exact Set.subset_iUnion _ i hx'
  · 

Proof state:
case h.mpr
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
x✝ : (forget TopCat).obj (of α)
⊢ x✝ ∈ ⋃ i, ↑(U i) → x✝ ∈ Set.range ⇑(fromOpenSubsetsGlue U)

Next tactic:
rintro ⟨_, ⟨i, rfl⟩, hx⟩
theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, (U i : Set α) := by
  ext
  constructor
  · rintro ⟨x, rfl⟩
    obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
    -- porting note: another `rw ↦ erw`
    -- See above
    erw [ι_fromOpenSubsetsGlue_apply]
    exact Set.subset_iUnion _ i hx'
  · rintro ⟨_, ⟨i, rfl⟩, hx⟩
    

Proof state:
case h.mpr.intro.intro.intro
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
x✝ : (forget TopCat).obj (of α)
i : J
hx : x✝ ∈ (fun i => ↑(U i)) i
⊢ x✝ ∈ Set.range ⇑(fromOpenSubsetsGlue U)

Next tactic:
rename_i x
theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, (U i : Set α) := by
  ext
  constructor
  · rintro ⟨x, rfl⟩
    obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
    -- porting note: another `rw ↦ erw`
    -- See above
    erw [ι_fromOpenSubsetsGlue_apply]
    exact Set.subset_iUnion _ i hx'
  · rintro ⟨_, ⟨i, rfl⟩, hx⟩
    rename_i x
    

Proof state:
case h.mpr.intro.intro.intro
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
x : (forget TopCat).obj (of α)
i : J
hx : x ∈ (fun i => ↑(U i)) i
⊢ x ∈ Set.range ⇑(fromOpenSubsetsGlue U)

Next tactic:
refine' ⟨(ofOpenSubsets U).toGlueData.ι i ⟨x, hx⟩, ι_fromOpenSubsetsGlue_apply _ _ _⟩
instance [Countable α] [Countable β] : Countable (Sum α β) := by
  

Proof state:
α : Type u
β : Type v
π : α → Type w
inst✝¹ : Countable α
inst✝ : Countable β
⊢ Countable (α ⊕ β)

Next tactic:
rcases exists_injective_nat α with ⟨f, hf⟩
instance [Countable α] [Countable β] : Countable (Sum α β) := by
  rcases exists_injective_nat α with ⟨f, hf⟩
  

Proof state:
case intro
α : Type u
β : Type v
π : α → Type w
inst✝¹ : Countable α
inst✝ : Countable β
f : α → ℕ
hf : Injective f
⊢ Countable (α ⊕ β)

Next tactic:
rcases exists_injective_nat β with ⟨g, hg⟩
instance [Countable α] [Countable β] : Countable (Sum α β) := by
  rcases exists_injective_nat α with ⟨f, hf⟩
  rcases exists_injective_nat β with ⟨g, hg⟩
  

Proof state:
case intro.intro
α : Type u
β : Type v
π : α → Type w
inst✝¹ : Countable α
inst✝ : Countable β
f : α → ℕ
hf : Injective f
g : β → ℕ
hg : Injective g
⊢ Countable (α ⊕ β)

Next tactic:
exact (Equiv.natSumNatEquivNat.injective.comp <| hf.sum_map hg).countable