l3lab/ntp-mathlib huggingface dataset:
/-- This is a constructor of `TopCat.GlueData` whose arguments are in terms of elements and
intersections rather than subobjects and pullbacks. Please refer to `TopCat.GlueData.MkCore` for
details. -/
def mk' (h : MkCore.{u}) : TopCat.GlueData where
  J := h.J
  U := h.U
  V i := (Opens.toTopCat _).obj (h.V i.1 i.2)
  f i j := (h.V i j).inclusion
  f_id i := by
    -- Porting note: added `dsimp only`
    dsimp only
    exact (h.V_id i).symm ▸ IsIso.of_iso (Opens.inclusionTopIso (h.U i))
  f_open := fun i j : h.J => (h.V i j).openEmbedding
  t := h.t
  t_id i := by ext; rw [h.t_id]; 

Proof state:
case w
D : GlueData
h : MkCore
i : h.J
x✝ : (forget TopCat).obj ((Opens.toTopCat (MkCore.U h i)).obj (MkCore.V h i i))
⊢ id x✝ = (𝟙 ((fun i => (Opens.toTopCat (MkCore.U h i.1)).obj (MkCore.V h i.1 i.2)) (i, i))) x✝

Next tactic:
rfl
/-- This is a constructor of `TopCat.GlueData` whose arguments are in terms of elements and
intersections rather than subobjects and pullbacks. Please refer to `TopCat.GlueData.MkCore` for
details. -/
def mk' (h : MkCore.{u}) : TopCat.GlueData where
  J := h.J
  U := h.U
  V i := (Opens.toTopCat _).obj (h.V i.1 i.2)
  f i j := (h.V i j).inclusion
  f_id i := by
    -- Porting note: added `dsimp only`
    dsimp only
    exact (h.V_id i).symm ▸ IsIso.of_iso (Opens.inclusionTopIso (h.U i))
  f_open := fun i j : h.J => (h.V i j).openEmbedding
  t := h.t
  t_id i := by ext; rw [h.t_id]; rfl
  t' := h.t'
  t_fac i j k := by
    

Proof state:
D : GlueData
h : MkCore
i j k : h.J
⊢ MkCore.t' h i j k ≫ pullback.snd = pullback.fst ≫ MkCore.t h i j

Next tactic:
delta MkCore.t'
/-- This is a constructor of `TopCat.GlueData` whose arguments are in terms of elements and
intersections rather than subobjects and pullbacks. Please refer to `TopCat.GlueData.MkCore` for
details. -/
def mk' (h : MkCore.{u}) : TopCat.GlueData where
  J := h.J
  U := h.U
  V i := (Opens.toTopCat _).obj (h.V i.1 i.2)
  f i j := (h.V i j).inclusion
  f_id i := by
    -- Porting note: added `dsimp only`
    dsimp only
    exact (h.V_id i).symm ▸ IsIso.of_iso (Opens.inclusionTopIso (h.U i))
  f_open := fun i j : h.J => (h.V i j).openEmbedding
  t := h.t
  t_id i := by ext; rw [h.t_id]; rfl
  t' := h.t'
  t_fac i j k := by
    delta MkCore.t'
    

Proof state:
D : GlueData
h : MkCore
i j k : h.J
⊢ ((pullbackIsoProdSubtype (Opens.inclusion (MkCore.V h i j)) (Opens.inclusion (MkCore.V h i k))).hom ≫
        (ContinuousMap.mk fun x =>
            {
              val :=
                ({ val := ↑((MkCore.t h i j) (↑x).1), property := (_ : ↑((MkCore.t h i j) (↑x).1) ∈ MkCore.V h j k) },
                  (MkCore.t h i j) (↑x).1),
              property :=
                (_ :
                  (Opens.inclusion (MkCore.V h j k))
                      ({ val := ↑((MkCore.t h i j) (↑x).1),
                            property := (_ : ↑((MkCore.t h i j) (↑x).1) ∈ MkCore.V h j k) },
                          (MkCore.t h i j) (↑x).1).1 =
                    (Opens.inclusion (MkCore.V h j k))
                      ({ val := ↑((MkCore.t h i j) (↑x).1),
                            property := (_ : ↑((MkCore.t h i j) (↑x).1) ∈ MkCore.V h j k) },
                          (MkCore.t h i j) (↑x).1).1) }) ≫
          (pullbackIsoProdSubtype (Opens.inclusion (MkCore.V h j k)) (Opens.inclusion (MkCore.V h j i))).inv) ≫
      pullback.snd =
    pullback.fst ≫ MkCore.t h i j

Next tactic:
rw [Category.assoc, Category.assoc, pullbackIsoProdSubtype_inv_snd, ← Iso.eq_inv_comp,
      pullbackIsoProdSubtype_inv_fst_assoc]
/-- This is a constructor of `TopCat.GlueData` whose arguments are in terms of elements and
intersections rather than subobjects and pullbacks. Please refer to `TopCat.GlueData.MkCore` for
details. -/
def mk' (h : MkCore.{u}) : TopCat.GlueData where
  J := h.J
  U := h.U
  V i := (Opens.toTopCat _).obj (h.V i.1 i.2)
  f i j := (h.V i j).inclusion
  f_id i := by
    -- Porting note: added `dsimp only`
    dsimp only
    exact (h.V_id i).symm ▸ IsIso.of_iso (Opens.inclusionTopIso (h.U i))
  f_open := fun i j : h.J => (h.V i j).openEmbedding
  t := h.t
  t_id i := by ext; rw [h.t_id]; rfl
  t' := h.t'
  t_fac i j k := by
    delta MkCore.t'
    rw [Category.assoc, Category.assoc, pullbackIsoProdSubtype_inv_snd, ← Iso.eq_inv_comp,
      pullbackIsoProdSubtype_inv_fst_assoc]
    

Proof state:
D : GlueData
h : MkCore
i j k : h.J
⊢ (ContinuousMap.mk fun x =>
        {
          val :=
            ({ val := ↑((MkCore.t h i j) (↑x).1), property := (_ : ↑((MkCore.t h i j) (↑x).1) ∈ MkCore.V h j k) },
              (MkCore.t h i j) (↑x).1),
          property :=
            (_ :
              (Opens.inclusion (MkCore.V h j k))
                  ({ val := ↑((MkCore.t h i j) (↑x).1), property := (_ : ↑((MkCore.t h i j) (↑x).1) ∈ MkCore.V h j k) },
                      (MkCore.t h i j) (↑x).1).1 =
                (Opens.inclusion (MkCore.V h j k))
                  ({ val := ↑((MkCore.t h i j) (↑x).1), property := (_ : ↑((MkCore.t h i j) (↑x).1) ∈ MkCore.V h j k) },
                      (MkCore.t h i j) (↑x).1).1) }) ≫
      pullbackSnd (Opens.inclusion (MkCore.V h j k)) (Opens.inclusion (MkCore.V h j i)) =
    pullbackFst (Opens.inclusion (MkCore.V h i j)) (Opens.inclusion (MkCore.V h i k)) ≫ MkCore.t h i j

Next tactic:
ext ⟨⟨⟨x, hx⟩, ⟨x', hx'⟩⟩, rfl : x = x'⟩
/-- This is a constructor of `TopCat.GlueData` whose arguments are in terms of elements and
intersections rather than subobjects and pullbacks. Please refer to `TopCat.GlueData.MkCore` for
details. -/
def mk' (h : MkCore.{u}) : TopCat.GlueData where
  J := h.J
  U := h.U
  V i := (Opens.toTopCat _).obj (h.V i.1 i.2)
  f i j := (h.V i j).inclusion
  f_id i := by
    -- Porting note: added `dsimp only`
    dsimp only
    exact (h.V_id i).symm ▸ IsIso.of_iso (Opens.inclusionTopIso (h.U i))
  f_open := fun i j : h.J => (h.V i j).openEmbedding
  t := h.t
  t_id i := by ext; rw [h.t_id]; rfl
  t' := h.t'
  t_fac i j k := by
    delta MkCore.t'
    rw [Category.assoc, Category.assoc, pullbackIsoProdSubtype_inv_snd, ← Iso.eq_inv_comp,
      pullbackIsoProdSubtype_inv_fst_assoc]
    ext ⟨⟨⟨x, hx⟩, ⟨x', hx'⟩⟩, rfl : x = x'⟩
    

Proof state:
case w.mk.mk.mk.mk
D : GlueData
h : MkCore
i j k : h.J
x : ↑(MkCore.U h i)
hx : x ∈ MkCore.V h i j
hx' : x ∈ MkCore.V h i k
⊢ ((ContinuousMap.mk fun x =>
          {
            val :=
              ({ val := ↑((MkCore.t h i j) (↑x).1), property := (_ : ↑((MkCore.t h i j) (↑x).1) ∈ MkCore.V h j k) },
                (MkCore.t h i j) (↑x).1),
            property :=
              (_ :
                (Opens.inclusion (MkCore.V h j k))
                    ({ val := ↑((MkCore.t h i j) (↑x).1),
                          property := (_ : ↑((MkCore.t h i j) (↑x).1) ∈ MkCore.V h j k) },
                        (MkCore.t h i j) (↑x).1).1 =
                  (Opens.inclusion (MkCore.V h j k))
                    ({ val := ↑((MkCore.t h i j) (↑x).1),
                          property := (_ : ↑((MkCore.t h i j) (↑x).1) ∈ MkCore.V h j k) },
                        (MkCore.t h i j) (↑x).1).1) }) ≫
        pullbackSnd (Opens.inclusion (MkCore.V h j k)) (Opens.inclusion (MkCore.V h j i)))
      { val := ({ val := x, property := hx }, { val := x, property := hx' }), property := (_ : x = x) } =
    (pullbackFst (Opens.inclusion (MkCore.V h i j)) (Opens.inclusion (MkCore.V h i k)) ≫ MkCore.t h i j)
      { val := ({ val := x, property := hx }, { val := x, property := hx' }), property := (_ : x = x) }

Next tactic:
rfl
/-- This is a constructor of `TopCat.GlueData` whose arguments are in terms of elements and
intersections rather than subobjects and pullbacks. Please refer to `TopCat.GlueData.MkCore` for
details. -/
def mk' (h : MkCore.{u}) : TopCat.GlueData where
  J := h.J
  U := h.U
  V i := (Opens.toTopCat _).obj (h.V i.1 i.2)
  f i j := (h.V i j).inclusion
  f_id i := by
    -- Porting note: added `dsimp only`
    dsimp only
    exact (h.V_id i).symm ▸ IsIso.of_iso (Opens.inclusionTopIso (h.U i))
  f_open := fun i j : h.J => (h.V i j).openEmbedding
  t := h.t
  t_id i := by ext; rw [h.t_id]; rfl
  t' := h.t'
  t_fac i j k := by
    delta MkCore.t'
    rw [Category.assoc, Category.assoc, pullbackIsoProdSubtype_inv_snd, ← Iso.eq_inv_comp,
      pullbackIsoProdSubtype_inv_fst_assoc]
    ext ⟨⟨⟨x, hx⟩, ⟨x', hx'⟩⟩, rfl : x = x'⟩
    rfl
  cocycle i j k := by
    

Proof state:
D : GlueData
h : MkCore
i j k : h.J
⊢ MkCore.t' h i j k ≫ MkCore.t' h j k i ≫ MkCore.t' h k i j =
    𝟙 (pullback ((fun i j => Opens.inclusion (MkCore.V h i j)) i j) ((fun i j => Opens.inclusion (MkCore.V h i j)) i k))

Next tactic:
delta MkCore.t'
/-- We may construct a glue data from a family of open sets. -/
@[simps! toGlueData_J toGlueData_U toGlueData_V toGlueData_t toGlueData_f]
def ofOpenSubsets : TopCat.GlueData.{u} :=
  mk'.{u}
    { J
      U := fun i => (Opens.toTopCat <| TopCat.of α).obj (U i)
      V := fun i j => (Opens.map <| Opens.inclusion _).obj (U j)
      t := fun i j => ⟨fun x => ⟨⟨x.1.1, x.2⟩, x.1.2⟩, by
        -- Porting note: was `continuity`, see https://github.com/leanprover-community/mathlib4/issues/5030
        

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i j : J
⊢ Continuous fun x =>
    { val := { val := ↑↑x, property := (_ : ↑x ∈ (fun i j => (Opens.map (Opens.inclusion (U i))).obj (U j)) i j) },
      property := (_ : ↑↑x ∈ U i) }

Next tactic:
refine Continuous.subtype_mk ?_ ?_
/-- We may construct a glue data from a family of open sets. -/
@[simps! toGlueData_J toGlueData_U toGlueData_V toGlueData_t toGlueData_f]
def ofOpenSubsets : TopCat.GlueData.{u} :=
  mk'.{u}
    { J
      U := fun i => (Opens.toTopCat <| TopCat.of α).obj (U i)
      V := fun i j => (Opens.map <| Opens.inclusion _).obj (U j)
      t := fun i j => ⟨fun x => ⟨⟨x.1.1, x.2⟩, x.1.2⟩, by
        -- Porting note: was `continuity`, see https://github.com/leanprover-community/mathlib4/issues/5030
        refine Continuous.subtype_mk ?_ ?_
        

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i j : J
⊢ Continuous fun x =>
    { val := ↑↑x, property := (_ : ↑x ∈ (fun i j => (Opens.map (Opens.inclusion (U i))).obj (U j)) i j) }

Next tactic:
refine Continuous.subtype_mk ?_ ?_
/-- We may construct a glue data from a family of open sets. -/
@[simps! toGlueData_J toGlueData_U toGlueData_V toGlueData_t toGlueData_f]
def ofOpenSubsets : TopCat.GlueData.{u} :=
  mk'.{u}
    { J
      U := fun i => (Opens.toTopCat <| TopCat.of α).obj (U i)
      V := fun i j => (Opens.map <| Opens.inclusion _).obj (U j)
      t := fun i j => ⟨fun x => ⟨⟨x.1.1, x.2⟩, x.1.2⟩, by
        -- Porting note: was `continuity`, see https://github.com/leanprover-community/mathlib4/issues/5030
        refine Continuous.subtype_mk ?_ ?_
        refine Continuous.subtype_mk ?_ ?_
        

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i j : J
⊢ Continuous fun x => ↑↑x

Next tactic:
continuity
/-- We may construct a glue data from a family of open sets. -/
@[simps! toGlueData_J toGlueData_U toGlueData_V toGlueData_t toGlueData_f]
def ofOpenSubsets : TopCat.GlueData.{u} :=
  mk'.{u}
    { J
      U := fun i => (Opens.toTopCat <| TopCat.of α).obj (U i)
      V := fun i j => (Opens.map <| Opens.inclusion _).obj (U j)
      t := fun i j => ⟨fun x => ⟨⟨x.1.1, x.2⟩, x.1.2⟩, by
        -- Porting note: was `continuity`, see https://github.com/leanprover-community/mathlib4/issues/5030
        refine Continuous.subtype_mk ?_ ?_
        refine Continuous.subtype_mk ?_ ?_
        continuity⟩
      V_id := fun i => by
        

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i : J
⊢ (fun i j => (Opens.map (Opens.inclusion (U i))).obj (U j)) i i = ⊤

Next tactic:
ext
/-- We may construct a glue data from a family of open sets. -/
@[simps! toGlueData_J toGlueData_U toGlueData_V toGlueData_t toGlueData_f]
def ofOpenSubsets : TopCat.GlueData.{u} :=
  mk'.{u}
    { J
      U := fun i => (Opens.toTopCat <| TopCat.of α).obj (U i)
      V := fun i j => (Opens.map <| Opens.inclusion _).obj (U j)
      t := fun i j => ⟨fun x => ⟨⟨x.1.1, x.2⟩, x.1.2⟩, by
        -- Porting note: was `continuity`, see https://github.com/leanprover-community/mathlib4/issues/5030
        refine Continuous.subtype_mk ?_ ?_
        refine Continuous.subtype_mk ?_ ?_
        continuity⟩
      V_id := fun i => by
        ext
        -- porting note: no longer needed `cases U i`!
        

Proof state:
case h.h
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i : J
x✝ : ↑((Opens.toTopCat (of α)).obj (U i))
⊢ x✝ ∈ ↑((fun i j => (Opens.map (Opens.inclusion (U i))).obj (U j)) i i) ↔ x✝ ∈ ↑⊤

Next tactic:
simp
/-- We may construct a glue data from a family of open sets. -/
@[simps! toGlueData_J toGlueData_U toGlueData_V toGlueData_t toGlueData_f]
def ofOpenSubsets : TopCat.GlueData.{u} :=
  mk'.{u}
    { J
      U := fun i => (Opens.toTopCat <| TopCat.of α).obj (U i)
      V := fun i j => (Opens.map <| Opens.inclusion _).obj (U j)
      t := fun i j => ⟨fun x => ⟨⟨x.1.1, x.2⟩, x.1.2⟩, by
        -- Porting note: was `continuity`, see https://github.com/leanprover-community/mathlib4/issues/5030
        refine Continuous.subtype_mk ?_ ?_
        refine Continuous.subtype_mk ?_ ?_
        continuity⟩
      V_id := fun i => by
        ext
        -- porting note: no longer needed `cases U i`!
        simp
      t_id := fun i => by 

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i : J
⊢ ⇑((fun i j =>
          ContinuousMap.mk fun x =>
            {
              val :=
                { val := ↑↑x, property := (_ : ↑x ∈ (fun i j => (Opens.map (Opens.inclusion (U i))).obj (U j)) i j) },
              property := (_ : ↑↑x ∈ U i) })
        i i) =
    id

Next tactic:
ext
/-- We may construct a glue data from a family of open sets. -/
@[simps! toGlueData_J toGlueData_U toGlueData_V toGlueData_t toGlueData_f]
def ofOpenSubsets : TopCat.GlueData.{u} :=
  mk'.{u}
    { J
      U := fun i => (Opens.toTopCat <| TopCat.of α).obj (U i)
      V := fun i j => (Opens.map <| Opens.inclusion _).obj (U j)
      t := fun i j => ⟨fun x => ⟨⟨x.1.1, x.2⟩, x.1.2⟩, by
        -- Porting note: was `continuity`, see https://github.com/leanprover-community/mathlib4/issues/5030
        refine Continuous.subtype_mk ?_ ?_
        refine Continuous.subtype_mk ?_ ?_
        continuity⟩
      V_id := fun i => by
        ext
        -- porting note: no longer needed `cases U i`!
        simp
      t_id := fun i => by ext; 

Proof state:
case h
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i : J
x✝ :
  (forget TopCat).obj
    ((Opens.toTopCat ((fun i => (Opens.toTopCat (of α)).obj (U i)) i)).obj
      ((fun i j => (Opens.map (Opens.inclusion (U i))).obj (U j)) i i))
⊢ ((fun i j =>
          ContinuousMap.mk fun x =>
            {
              val :=
                { val := ↑↑x, property := (_ : ↑x ∈ (fun i j => (Opens.map (Opens.inclusion (U i))).obj (U j)) i j) },
              property := (_ : ↑↑x ∈ U i) })
        i i)
      x✝ =
    id x✝

Next tactic:
rfl
/-- The canonical map from the glue of a family of open subsets `α` into `α`.
This map is an open embedding (`fromOpenSubsetsGlue_openEmbedding`),
and its range is `⋃ i, (U i : Set α)` (`range_fromOpenSubsetsGlue`).
-/
def fromOpenSubsetsGlue : (ofOpenSubsets U).toGlueData.glued ⟶ TopCat.of α :=
  Multicoequalizer.desc _ _ (fun x => Opens.inclusion _) (by 

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
⊢ ∀ (a : (GlueData.diagram (ofOpenSubsets U).toGlueData).L),
    MultispanIndex.fst (GlueData.diagram (ofOpenSubsets U).toGlueData) a ≫
        (fun x => Opens.inclusion (U x)) (MultispanIndex.fstFrom (GlueData.diagram (ofOpenSubsets U).toGlueData) a) =
      MultispanIndex.snd (GlueData.diagram (ofOpenSubsets U).toGlueData) a ≫
        (fun x => Opens.inclusion (U x)) (MultispanIndex.sndFrom (GlueData.diagram (ofOpenSubsets U).toGlueData) a)

Next tactic:
rintro ⟨i, j⟩
/-- The canonical map from the glue of a family of open subsets `α` into `α`.
This map is an open embedding (`fromOpenSubsetsGlue_openEmbedding`),
and its range is `⋃ i, (U i : Set α)` (`range_fromOpenSubsetsGlue`).
-/
def fromOpenSubsetsGlue : (ofOpenSubsets U).toGlueData.glued ⟶ TopCat.of α :=
  Multicoequalizer.desc _ _ (fun x => Opens.inclusion _) (by rintro ⟨i, j⟩; 

Proof state:
case mk
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i j : (ofOpenSubsets U).toGlueData.J
⊢ MultispanIndex.fst (GlueData.diagram (ofOpenSubsets U).toGlueData) (i, j) ≫
      (fun x => Opens.inclusion (U x)) (MultispanIndex.fstFrom (GlueData.diagram (ofOpenSubsets U).toGlueData) (i, j)) =
    MultispanIndex.snd (GlueData.diagram (ofOpenSubsets U).toGlueData) (i, j) ≫
      (fun x => Opens.inclusion (U x)) (MultispanIndex.sndFrom (GlueData.diagram (ofOpenSubsets U).toGlueData) (i, j))

Next tactic:
ext x
/-- The canonical map from the glue of a family of open subsets `α` into `α`.
This map is an open embedding (`fromOpenSubsetsGlue_openEmbedding`),
and its range is `⋃ i, (U i : Set α)` (`range_fromOpenSubsetsGlue`).
-/
def fromOpenSubsetsGlue : (ofOpenSubsets U).toGlueData.glued ⟶ TopCat.of α :=
  Multicoequalizer.desc _ _ (fun x => Opens.inclusion _) (by rintro ⟨i, j⟩; ext x; 

Proof state:
case mk.w
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
i j : (ofOpenSubsets U).toGlueData.J
x : (forget TopCat).obj (MultispanIndex.left (GlueData.diagram (ofOpenSubsets U).toGlueData) (i, j))
⊢ (MultispanIndex.fst (GlueData.diagram (ofOpenSubsets U).toGlueData) (i, j) ≫
        (fun x => Opens.inclusion (U x))
          (MultispanIndex.fstFrom (GlueData.diagram (ofOpenSubsets U).toGlueData) (i, j)))
      x =
    (MultispanIndex.snd (GlueData.diagram (ofOpenSubsets U).toGlueData) (i, j) ≫
        (fun x => Opens.inclusion (U x))
          (MultispanIndex.sndFrom (GlueData.diagram (ofOpenSubsets U).toGlueData) (i, j)))
      x

Next tactic:
rfl
theorem fromOpenSubsetsGlue_injective : Function.Injective (fromOpenSubsetsGlue U) := by
  

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

Next tactic:
intro x y e
theorem fromOpenSubsetsGlue_injective : Function.Injective (fromOpenSubsetsGlue U) := by
  intro x y e
  

Proof state:
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
x y : (forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData)
e : (fromOpenSubsetsGlue U) x = (fromOpenSubsetsGlue U) y
⊢ x = y

Next tactic:
obtain ⟨i, ⟨x, hx⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
theorem fromOpenSubsetsGlue_injective : Function.Injective (fromOpenSubsetsGlue U) := by
  intro x y e
  obtain ⟨i, ⟨x, hx⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x
  

Proof state:
case intro.intro.mk
D : GlueData
α : Type u
inst✝ : TopologicalSpace α
J : Type u
U : J → Opens α
y : (forget TopCat).obj (GlueData.glued (ofOpenSubsets U).toGlueData)
i : (ofOpenSubsets U).toGlueData.J
x : ↑(of α)
hx : x ∈ U i
e :
  (fromOpenSubsetsGlue U) ((GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx }) =
    (fromOpenSubsetsGlue U) y
⊢ (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx } = y

Next tactic:
obtain ⟨j, ⟨y, hy⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective y
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`
  

Proof state:
case intro.intro.mk.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
j : (ofOpenSubsets U).toGlueData.J
y : ↑(of α)
hy : y ∈ U j
e :
  (fromOpenSubsetsGlue U) ((GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx }) =
    (fromOpenSubsetsGlue U) ((GlueData.ι (ofOpenSubsets U).toGlueData j) { val := y, property := hy })
⊢ (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx } =
    (GlueData.ι (ofOpenSubsets U).toGlueData j) { val := y, property := hy }

Next tactic:
erw [ι_fromOpenSubsetsGlue_apply, ι_fromOpenSubsetsGlue_apply] at e
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
  

Proof state:
case intro.intro.mk.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
j : (ofOpenSubsets U).toGlueData.J
y : ↑(of α)
hy : y ∈ U j
e : (Opens.inclusion (U i)) { val := x, property := hx } = (Opens.inclusion (U j)) { val := y, property := hy }
⊢ (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx } =
    (GlueData.ι (ofOpenSubsets U).toGlueData j) { val := y, property := hy }

Next tactic:
change x = y at e
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
  

Proof state:
case intro.intro.mk.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
j : (ofOpenSubsets U).toGlueData.J
y : ↑(of α)
hy : y ∈ U j
e : x = y
⊢ (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx } =
    (GlueData.ι (ofOpenSubsets U).toGlueData j) { val := y, property := hy }

Next tactic:
subst e
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
  

Proof state:
case intro.intro.mk.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
j : (ofOpenSubsets U).toGlueData.J
hy : x ∈ U j
⊢ (GlueData.ι (ofOpenSubsets U).toGlueData i) { val := x, property := hx } =
    (GlueData.ι (ofOpenSubsets U).toGlueData j) { val := x, property := hy }

Next tactic:
rw [(ofOpenSubsets U).ι_eq_iff_rel]
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]
  

Proof state:
case intro.intro.mk.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
j : (ofOpenSubsets U).toGlueData.J
hy : x ∈ U j
⊢ Rel (ofOpenSubsets U) { fst := i, snd := { val := x, property := hx } }
    { fst := j, snd := { val := x, property := hy } }

Next tactic:
right