l3lab/ntp-mathlib huggingface dataset:
set_option maxHeartbeats 600000 in
/-- (Implementation) The natural map `Γ(𝒪_{U_i}, U) ⟶ Γ(𝒪_X, 𝖣.ι i '' U)`.
This forms the inverse of `(𝖣.ι i).c.app (op U)`. -/
def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) :
    (D.U i).presheaf.obj (op U) ⟶ limit (D.diagramOverOpen U) :=
  limit.lift (D.diagramOverOpen U)
    { pt := (D.U i).presheaf.obj (op U)
      π :=
        { app := fun j => D.ιInvAppπApp U (unop j)
          naturality := fun {X Y} f' => by
            induction X using Opposite.rec' with | h X => ?_
            induction Y using Opposite.rec' with | h Y => ?_
            let f : Y ⟶ X := f'.unop; have : f' = f.op := rfl; 

Proof state:
case h.h
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
X Y : WalkingMultispan (diagram D.toGlueData).fstFrom (diagram D.toGlueData).sndFrom
f' : op X ⟶ op Y
f : Y ⟶ X := f'.unop
this : f' = f.op
⊢ ((Functor.const (WalkingMultispan (diagram D.toGlueData).fstFrom (diagram D.toGlueData).sndFrom)ᵒᵖ).obj
            ((CategoryTheory.GlueData.U D.toGlueData i).presheaf.obj (op U))).map
        f' ≫
      (fun j => ιInvAppπApp D U j.unop) (op Y) =
    (fun j => ιInvAppπApp D U j.unop) (op X) ≫ (diagramOverOpen D U).map f'

Next tactic:
clear_value f
set_option maxHeartbeats 600000 in
/-- (Implementation) The natural map `Γ(𝒪_{U_i}, U) ⟶ Γ(𝒪_X, 𝖣.ι i '' U)`.
This forms the inverse of `(𝖣.ι i).c.app (op U)`. -/
def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) :
    (D.U i).presheaf.obj (op U) ⟶ limit (D.diagramOverOpen U) :=
  limit.lift (D.diagramOverOpen U)
    { pt := (D.U i).presheaf.obj (op U)
      π :=
        { app := fun j => D.ιInvAppπApp U (unop j)
          naturality := fun {X Y} f' => by
            induction X using Opposite.rec' with | h X => ?_
            induction Y using Opposite.rec' with | h Y => ?_
            let f : Y ⟶ X := f'.unop; have : f' = f.op := rfl; clear_value f; 

Proof state:
case h.h
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
X Y : WalkingMultispan (diagram D.toGlueData).fstFrom (diagram D.toGlueData).sndFrom
f' : op X ⟶ op Y
f : Y ⟶ X
this : f' = f.op
⊢ ((Functor.const (WalkingMultispan (diagram D.toGlueData).fstFrom (diagram D.toGlueData).sndFrom)ᵒᵖ).obj
            ((CategoryTheory.GlueData.U D.toGlueData i).presheaf.obj (op U))).map
        f' ≫
      (fun j => ιInvAppπApp D U j.unop) (op Y) =
    (fun j => ιInvAppπApp D U j.unop) (op X) ≫ (diagramOverOpen D U).map f'

Next tactic:
subst this
set_option maxHeartbeats 600000 in
/-- (Implementation) The natural map `Γ(𝒪_{U_i}, U) ⟶ Γ(𝒪_X, 𝖣.ι i '' U)`.
This forms the inverse of `(𝖣.ι i).c.app (op U)`. -/
def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) :
    (D.U i).presheaf.obj (op U) ⟶ limit (D.diagramOverOpen U) :=
  limit.lift (D.diagramOverOpen U)
    { pt := (D.U i).presheaf.obj (op U)
      π :=
        { app := fun j => D.ιInvAppπApp U (unop j)
          naturality := fun {X Y} f' => by
            induction X using Opposite.rec' with | h X => ?_
            induction Y using Opposite.rec' with | h Y => ?_
            let f : Y ⟶ X := f'.unop; have : f' = f.op := rfl; clear_value f; subst this
            

Proof state:
case h.h
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
X Y : WalkingMultispan (diagram D.toGlueData).fstFrom (diagram D.toGlueData).sndFrom
f : Y ⟶ X
⊢ ((Functor.const (WalkingMultispan (diagram D.toGlueData).fstFrom (diagram D.toGlueData).sndFrom)ᵒᵖ).obj
            ((CategoryTheory.GlueData.U D.toGlueData i).presheaf.obj (op U))).map
        f.op ≫
      (fun j => ιInvAppπApp D U j.unop) (op Y) =
    (fun j => ιInvAppπApp D U j.unop) (op X) ≫ (diagramOverOpen D U).map f.op

Next tactic:
rcases f with (_ | ⟨j, k⟩ | ⟨j, k⟩)
set_option maxHeartbeats 600000 in
/-- (Implementation) The natural map `Γ(𝒪_{U_i}, U) ⟶ Γ(𝒪_X, 𝖣.ι i '' U)`.
This forms the inverse of `(𝖣.ι i).c.app (op U)`. -/
def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) :
    (D.U i).presheaf.obj (op U) ⟶ limit (D.diagramOverOpen U) :=
  limit.lift (D.diagramOverOpen U)
    { pt := (D.U i).presheaf.obj (op U)
      π :=
        { app := fun j => D.ιInvAppπApp U (unop j)
          naturality := fun {X Y} f' => by
            induction X using Opposite.rec' with | h X => ?_
            induction Y using Opposite.rec' with | h Y => ?_
            let f : Y ⟶ X := f'.unop; have : f' = f.op := rfl; clear_value f; subst this
            rcases f with (_ | ⟨j, k⟩ | ⟨j, k⟩)
            · 

Proof state:
case h.h.id
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
X : WalkingMultispan (diagram D.toGlueData).fstFrom (diagram D.toGlueData).sndFrom
⊢ ((Functor.const (WalkingMultispan (diagram D.toGlueData).fstFrom (diagram D.toGlueData).sndFrom)ᵒᵖ).obj
            ((CategoryTheory.GlueData.U D.toGlueData i).presheaf.obj (op U))).map
        (WalkingMultispan.Hom.id X).op ≫
      (fun j => ιInvAppπApp D U j.unop) (op X) =
    (fun j => ιInvAppπApp D U j.unop) (op X) ≫ (diagramOverOpen D U).map (WalkingMultispan.Hom.id X).op

Next tactic:
erw [Category.id_comp, CategoryTheory.Functor.map_id]
set_option maxHeartbeats 600000 in
/-- (Implementation) The natural map `Γ(𝒪_{U_i}, U) ⟶ Γ(𝒪_X, 𝖣.ι i '' U)`.
This forms the inverse of `(𝖣.ι i).c.app (op U)`. -/
def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) :
    (D.U i).presheaf.obj (op U) ⟶ limit (D.diagramOverOpen U) :=
  limit.lift (D.diagramOverOpen U)
    { pt := (D.U i).presheaf.obj (op U)
      π :=
        { app := fun j => D.ιInvAppπApp U (unop j)
          naturality := fun {X Y} f' => by
            induction X using Opposite.rec' with | h X => ?_
            induction Y using Opposite.rec' with | h Y => ?_
            let f : Y ⟶ X := f'.unop; have : f' = f.op := rfl; clear_value f; subst this
            rcases f with (_ | ⟨j, k⟩ | ⟨j, k⟩)
            · erw [Category.id_comp, CategoryTheory.Functor.map_id]
              

Proof state:
case h.h.id
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
X : WalkingMultispan (diagram D.toGlueData).fstFrom (diagram D.toGlueData).sndFrom
⊢ (fun j => ιInvAppπApp D U j.unop) (op X) =
    (fun j => ιInvAppπApp D U j.unop) (op X) ≫ 𝟙 ((diagramOverOpen D U).obj (op X))

Next tactic:
rw [Category.comp_id]
set_option maxHeartbeats 600000 in
/-- (Implementation) The natural map `Γ(𝒪_{U_i}, U) ⟶ Γ(𝒪_X, 𝖣.ι i '' U)`.
This forms the inverse of `(𝖣.ι i).c.app (op U)`. -/
def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) :
    (D.U i).presheaf.obj (op U) ⟶ limit (D.diagramOverOpen U) :=
  limit.lift (D.diagramOverOpen U)
    { pt := (D.U i).presheaf.obj (op U)
      π :=
        { app := fun j => D.ιInvAppπApp U (unop j)
          naturality := fun {X Y} f' => by
            induction X using Opposite.rec' with | h X => ?_
            induction Y using Opposite.rec' with | h Y => ?_
            let f : Y ⟶ X := f'.unop; have : f' = f.op := rfl; clear_value f; subst this
            rcases f with (_ | ⟨j, k⟩ | ⟨j, k⟩)
            · erw [Category.id_comp, CategoryTheory.Functor.map_id]
              rw [Category.comp_id]
            · 

Proof state:
case h.h.fst.mk
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
j k : D.J
⊢ ((Functor.const (WalkingMultispan (diagram D.toGlueData).fstFrom (diagram D.toGlueData).sndFrom)ᵒᵖ).obj
            ((CategoryTheory.GlueData.U D.toGlueData i).presheaf.obj (op U))).map
        (WalkingMultispan.Hom.fst (j, k)).op ≫
      (fun j => ιInvAppπApp D U j.unop) (op (WalkingMultispan.left (j, k))) =
    (fun j => ιInvAppπApp D U j.unop)
        (op (WalkingMultispan.right (MultispanIndex.fstFrom (diagram D.toGlueData) (j, k)))) ≫
      (diagramOverOpen D U).map (WalkingMultispan.Hom.fst (j, k)).op

Next tactic:
erw [Category.id_comp]
set_option maxHeartbeats 600000 in
/-- (Implementation) The natural map `Γ(𝒪_{U_i}, U) ⟶ Γ(𝒪_X, 𝖣.ι i '' U)`.
This forms the inverse of `(𝖣.ι i).c.app (op U)`. -/
def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) :
    (D.U i).presheaf.obj (op U) ⟶ limit (D.diagramOverOpen U) :=
  limit.lift (D.diagramOverOpen U)
    { pt := (D.U i).presheaf.obj (op U)
      π :=
        { app := fun j => D.ιInvAppπApp U (unop j)
          naturality := fun {X Y} f' => by
            induction X using Opposite.rec' with | h X => ?_
            induction Y using Opposite.rec' with | h Y => ?_
            let f : Y ⟶ X := f'.unop; have : f' = f.op := rfl; clear_value f; subst this
            rcases f with (_ | ⟨j, k⟩ | ⟨j, k⟩)
            · erw [Category.id_comp, CategoryTheory.Functor.map_id]
              rw [Category.comp_id]
            · erw [Category.id_comp]; 

Proof state:
case h.h.fst.mk
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
j k : D.J
⊢ (fun j => ιInvAppπApp D U j.unop) (op (WalkingMultispan.left (j, k))) =
    (fun j => ιInvAppπApp D U j.unop)
        (op (WalkingMultispan.right (MultispanIndex.fstFrom (diagram D.toGlueData) (j, k)))) ≫
      (diagramOverOpen D U).map (WalkingMultispan.Hom.fst (j, k)).op

Next tactic:
congr 1
set_option maxHeartbeats 600000 in
/-- (Implementation) The natural map `Γ(𝒪_{U_i}, U) ⟶ Γ(𝒪_X, 𝖣.ι i '' U)`.
This forms the inverse of `(𝖣.ι i).c.app (op U)`. -/
def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) :
    (D.U i).presheaf.obj (op U) ⟶ limit (D.diagramOverOpen U) :=
  limit.lift (D.diagramOverOpen U)
    { pt := (D.U i).presheaf.obj (op U)
      π :=
        { app := fun j => D.ιInvAppπApp U (unop j)
          naturality := fun {X Y} f' => by
            induction X using Opposite.rec' with | h X => ?_
            induction Y using Opposite.rec' with | h Y => ?_
            let f : Y ⟶ X := f'.unop; have : f' = f.op := rfl; clear_value f; subst this
            rcases f with (_ | ⟨j, k⟩ | ⟨j, k⟩)
            · erw [Category.id_comp, CategoryTheory.Functor.map_id]
              rw [Category.comp_id]
            · erw [Category.id_comp]; congr 1
            

Proof state:
case h.h.snd.mk
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
j k : D.J
⊢ ((Functor.const (WalkingMultispan (diagram D.toGlueData).fstFrom (diagram D.toGlueData).sndFrom)ᵒᵖ).obj
            ((CategoryTheory.GlueData.U D.toGlueData i).presheaf.obj (op U))).map
        (WalkingMultispan.Hom.snd (j, k)).op ≫
      (fun j => ιInvAppπApp D U j.unop) (op (WalkingMultispan.left (j, k))) =
    (fun j => ιInvAppπApp D U j.unop)
        (op (WalkingMultispan.right (MultispanIndex.sndFrom (diagram D.toGlueData) (j, k)))) ≫
      (diagramOverOpen D U).map (WalkingMultispan.Hom.snd (j, k)).op

Next tactic:
erw [Category.id_comp]
set_option maxHeartbeats 600000 in
/-- (Implementation) The natural map `Γ(𝒪_{U_i}, U) ⟶ Γ(𝒪_X, 𝖣.ι i '' U)`.
This forms the inverse of `(𝖣.ι i).c.app (op U)`. -/
def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) :
    (D.U i).presheaf.obj (op U) ⟶ limit (D.diagramOverOpen U) :=
  limit.lift (D.diagramOverOpen U)
    { pt := (D.U i).presheaf.obj (op U)
      π :=
        { app := fun j => D.ιInvAppπApp U (unop j)
          naturality := fun {X Y} f' => by
            induction X using Opposite.rec' with | h X => ?_
            induction Y using Opposite.rec' with | h Y => ?_
            let f : Y ⟶ X := f'.unop; have : f' = f.op := rfl; clear_value f; subst this
            rcases f with (_ | ⟨j, k⟩ | ⟨j, k⟩)
            · erw [Category.id_comp, CategoryTheory.Functor.map_id]
              rw [Category.comp_id]
            · erw [Category.id_comp]; congr 1
            erw [Category.id_comp]
            -- It remains to show that the blue is equal to red + green in the original diagram.
            -- The proof strategy is illustrated in ![this diagram](https://i.imgur.com/mBzV1Rx.png)
            -- where we prove red = pink = light-blue = green = blue.
            

Proof state:
case h.h.snd.mk
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
j k : D.J
⊢ (fun j => ιInvAppπApp D U j.unop) (op (WalkingMultispan.left (j, k))) =
    (fun j => ιInvAppπApp D U j.unop)
        (op (WalkingMultispan.right (MultispanIndex.sndFrom (diagram D.toGlueData) (j, k)))) ≫
      (diagramOverOpen D U).map (WalkingMultispan.Hom.snd (j, k)).op

Next tactic:
change
              D.opensImagePreimageMap i j U ≫
                  (D.f j k).c.app _ ≫ (D.V (j, k)).presheaf.map (eqToHom _) =
                D.opensImagePreimageMap _ _ _ ≫
                  ((D.f k j).c.app _ ≫ (D.t j k).c.app _) ≫ (D.V (j, k)).presheaf.map (eqToHom _)
set_option maxHeartbeats 600000 in
/-- (Implementation) The natural map `Γ(𝒪_{U_i}, U) ⟶ Γ(𝒪_X, 𝖣.ι i '' U)`.
This forms the inverse of `(𝖣.ι i).c.app (op U)`. -/
def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) :
    (D.U i).presheaf.obj (op U) ⟶ limit (D.diagramOverOpen U) :=
  limit.lift (D.diagramOverOpen U)
    { pt := (D.U i).presheaf.obj (op U)
      π :=
        { app := fun j => D.ιInvAppπApp U (unop j)
          naturality := fun {X Y} f' => by
            induction X using Opposite.rec' with | h X => ?_
            induction Y using Opposite.rec' with | h Y => ?_
            let f : Y ⟶ X := f'.unop; have : f' = f.op := rfl; clear_value f; subst this
            rcases f with (_ | ⟨j, k⟩ | ⟨j, k⟩)
            · erw [Category.id_comp, CategoryTheory.Functor.map_id]
              rw [Category.comp_id]
            · erw [Category.id_comp]; congr 1
            erw [Category.id_comp]
            -- It remains to show that the blue is equal to red + green in the original diagram.
            -- The proof strategy is illustrated in ![this diagram](https://i.imgur.com/mBzV1Rx.png)
            -- where we prove red = pink = light-blue = green = blue.
            change
              D.opensImagePreimageMap i j U ≫
                  (D.f j k).c.app _ ≫ (D.V (j, k)).presheaf.map (eqToHom _) =
                D.opensImagePreimageMap _ _ _ ≫
                  ((D.f k j).c.app _ ≫ (D.t j k).c.app _) ≫ (D.V (j, k)).presheaf.map (eqToHom _)
            erw [opensImagePreimageMap_app_assoc]
            simp_rw [Category.assoc]
            erw [opensImagePreimageMap_app_assoc, (D.t j k).c.naturality_assoc]
            rw [snd_invApp_t_app_assoc]
            erw [← PresheafedSpace.comp_c_app_assoc]
            -- light-blue = green is relatively easy since the part that differs does not involve
            -- partial inverses.
            have :
              D.t' j k i ≫ (π₁ k, i, j) ≫ D.t k i ≫ 𝖣.f i k =
                (pullbackSymmetry _ _).hom ≫ (π₁ j, i, k) ≫ D.t j i ≫ D.f i j := by
              

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
j k : D.J
⊢ t' D.toGlueData j k i ≫ pullback.fst ≫ t D.toGlueData k i ≫ f D.toGlueData i k =
    (pullbackSymmetry (f D.toGlueData j k) (f D.toGlueData j i)).hom ≫
      pullback.fst ≫ t D.toGlueData j i ≫ f D.toGlueData i j

Next tactic:
rw [← 𝖣.t_fac_assoc, 𝖣.t'_comp_eq_pullbackSymmetry_assoc,
                pullbackSymmetry_hom_comp_snd_assoc, pullback.condition, 𝖣.t_fac_assoc]
/-- `ιInvApp` is the left inverse of `D.ι i` on `U`. -/
theorem ιInvApp_π {i : D.J} (U : Opens (D.U i).carrier) :
    ∃ eq, D.ιInvApp U ≫ D.diagramOverOpenπ U i = (D.U i).presheaf.map (eqToHom eq) := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
⊢ ∃ (eq :
    op U =
      op
        ((Opens.map
              (colimit.ι (MultispanIndex.multispan (diagram D.toGlueData))
                  (op (WalkingMultispan.right i)).unop).base).obj
          ((IsOpenMap.functor (_ : IsOpenMap ⇑(ι D.toGlueData i).base)).obj U))),
    ιInvApp D U ≫ diagramOverOpenπ D U i = (CategoryTheory.GlueData.U D.toGlueData i).presheaf.map (eqToHom eq)

Next tactic:
fconstructor
/-- `ιInvApp` is the left inverse of `D.ι i` on `U`. -/
theorem ιInvApp_π {i : D.J} (U : Opens (D.U i).carrier) :
    ∃ eq, D.ιInvApp U ≫ D.diagramOverOpenπ U i = (D.U i).presheaf.map (eqToHom eq) := by
  fconstructor
  -- Porting note: I don't know what the magic was in Lean3 proof, it just skipped the proof of `eq`
  · 

Proof state:
case w
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
⊢ op U =
    op
      ((Opens.map
            (colimit.ι (MultispanIndex.multispan (diagram D.toGlueData)) (op (WalkingMultispan.right i)).unop).base).obj
        ((IsOpenMap.functor (_ : IsOpenMap ⇑(ι D.toGlueData i).base)).obj U))

Next tactic:
congr
/-- `ιInvApp` is the left inverse of `D.ι i` on `U`. -/
theorem ιInvApp_π {i : D.J} (U : Opens (D.U i).carrier) :
    ∃ eq, D.ιInvApp U ≫ D.diagramOverOpenπ U i = (D.U i).presheaf.map (eqToHom eq) := by
  fconstructor
  -- Porting note: I don't know what the magic was in Lean3 proof, it just skipped the proof of `eq`
  · congr; 

Proof state:
case w.e_x
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
⊢ U =
    (Opens.map
          (colimit.ι (MultispanIndex.multispan (diagram D.toGlueData)) (op (WalkingMultispan.right i)).unop).base).obj
      ((IsOpenMap.functor (_ : IsOpenMap ⇑(ι D.toGlueData i).base)).obj U)

Next tactic:
ext1
/-- `ιInvApp` is the left inverse of `D.ι i` on `U`. -/
theorem ιInvApp_π {i : D.J} (U : Opens (D.U i).carrier) :
    ∃ eq, D.ιInvApp U ≫ D.diagramOverOpenπ U i = (D.U i).presheaf.map (eqToHom eq) := by
  fconstructor
  -- Porting note: I don't know what the magic was in Lean3 proof, it just skipped the proof of `eq`
  · congr; ext1; 

Proof state:
case w.e_x.h
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
⊢ ↑U =
    ↑((Opens.map
            (colimit.ι (MultispanIndex.multispan (diagram D.toGlueData)) (op (WalkingMultispan.right i)).unop).base).obj
        ((IsOpenMap.functor (_ : IsOpenMap ⇑(ι D.toGlueData i).base)).obj U))

Next tactic:
change _ = _ ⁻¹' (_ '' _)
/-- `ιInvApp` is the left inverse of `D.ι i` on `U`. -/
theorem ιInvApp_π {i : D.J} (U : Opens (D.U i).carrier) :
    ∃ eq, D.ιInvApp U ≫ D.diagramOverOpenπ U i = (D.U i).presheaf.map (eqToHom eq) := by
  fconstructor
  -- Porting note: I don't know what the magic was in Lean3 proof, it just skipped the proof of `eq`
  · congr; ext1; change _ = _ ⁻¹' (_ '' _); 

Proof state:
case w.e_x.h
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
⊢ ↑U =
    (fun x =>
        (colimit.ι (MultispanIndex.multispan (diagram D.toGlueData)) (op (WalkingMultispan.right i)).unop).base x) ⁻¹'
      ((fun a => (ι D.toGlueData i).base a) '' ↑U)

Next tactic:
ext1 x
/-- `ιInvApp` is the left inverse of `D.ι i` on `U`. -/
theorem ιInvApp_π {i : D.J} (U : Opens (D.U i).carrier) :
    ∃ eq, D.ιInvApp U ≫ D.diagramOverOpenπ U i = (D.U i).presheaf.map (eqToHom eq) := by
  fconstructor
  -- Porting note: I don't know what the magic was in Lean3 proof, it just skipped the proof of `eq`
  · congr; ext1; change _ = _ ⁻¹' (_ '' _); ext1 x
    

Proof state:
case w.e_x.h.h
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
x : ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
⊢ x ∈ ↑U ↔
    x ∈
      (fun x =>
          (colimit.ι (MultispanIndex.multispan (diagram D.toGlueData)) (op (WalkingMultispan.right i)).unop).base x) ⁻¹'
        ((fun a => (ι D.toGlueData i).base a) '' ↑U)

Next tactic:
simp only [SetLike.mem_coe, diagram_l, diagram_r, unop_op, Set.mem_preimage, Set.mem_image]
/-- `ιInvApp` is the left inverse of `D.ι i` on `U`. -/
theorem ιInvApp_π {i : D.J} (U : Opens (D.U i).carrier) :
    ∃ eq, D.ιInvApp U ≫ D.diagramOverOpenπ U i = (D.U i).presheaf.map (eqToHom eq) := by
  fconstructor
  -- Porting note: I don't know what the magic was in Lean3 proof, it just skipped the proof of `eq`
  · congr; ext1; change _ = _ ⁻¹' (_ '' _); ext1 x
    simp only [SetLike.mem_coe, diagram_l, diagram_r, unop_op, Set.mem_preimage, Set.mem_image]
    

Proof state:
case w.e_x.h.h
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
x : ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
⊢ x ∈ U ↔
    ∃ x_1 ∈ U,
      (ι D.toGlueData i).base x_1 =
        (colimit.ι (MultispanIndex.multispan (diagram D.toGlueData)) (WalkingMultispan.right i)).base x

Next tactic:
refine ⟨fun h => ⟨_, h, rfl⟩, ?_⟩
/-- `ιInvApp` is the left inverse of `D.ι i` on `U`. -/
theorem ιInvApp_π {i : D.J} (U : Opens (D.U i).carrier) :
    ∃ eq, D.ιInvApp U ≫ D.diagramOverOpenπ U i = (D.U i).presheaf.map (eqToHom eq) := by
  fconstructor
  -- Porting note: I don't know what the magic was in Lean3 proof, it just skipped the proof of `eq`
  · congr; ext1; change _ = _ ⁻¹' (_ '' _); ext1 x
    simp only [SetLike.mem_coe, diagram_l, diagram_r, unop_op, Set.mem_preimage, Set.mem_image]
    refine ⟨fun h => ⟨_, h, rfl⟩, ?_⟩
    

Proof state:
case w.e_x.h.h
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
x : ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
⊢ (∃ x_1 ∈ U,
      (ι D.toGlueData i).base x_1 =
        (colimit.ι (MultispanIndex.multispan (diagram D.toGlueData)) (WalkingMultispan.right i)).base x) →
    x ∈ U

Next tactic:
rintro ⟨y, h1, h2⟩
/-- `ιInvApp` is the left inverse of `D.ι i` on `U`. -/
theorem ιInvApp_π {i : D.J} (U : Opens (D.U i).carrier) :
    ∃ eq, D.ιInvApp U ≫ D.diagramOverOpenπ U i = (D.U i).presheaf.map (eqToHom eq) := by
  fconstructor
  -- Porting note: I don't know what the magic was in Lean3 proof, it just skipped the proof of `eq`
  · congr; ext1; change _ = _ ⁻¹' (_ '' _); ext1 x
    simp only [SetLike.mem_coe, diagram_l, diagram_r, unop_op, Set.mem_preimage, Set.mem_image]
    refine ⟨fun h => ⟨_, h, rfl⟩, ?_⟩
    rintro ⟨y, h1, h2⟩
    

Proof state:
case w.e_x.h.h.intro.intro
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
x : ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
y : (CategoryTheory.forget TopCat).obj ↑(CategoryTheory.GlueData.U D.toGlueData i)
h1 : y ∈ U
h2 :
  (ι D.toGlueData i).base y =
    (colimit.ι (MultispanIndex.multispan (diagram D.toGlueData)) (WalkingMultispan.right i)).base x
⊢ x ∈ U

Next tactic:
convert h1 using 1
/-- `ιInvApp` is the left inverse of `D.ι i` on `U`. -/
theorem ιInvApp_π {i : D.J} (U : Opens (D.U i).carrier) :
    ∃ eq, D.ιInvApp U ≫ D.diagramOverOpenπ U i = (D.U i).presheaf.map (eqToHom eq) := by
  fconstructor
  -- Porting note: I don't know what the magic was in Lean3 proof, it just skipped the proof of `eq`
  · congr; ext1; change _ = _ ⁻¹' (_ '' _); ext1 x
    simp only [SetLike.mem_coe, diagram_l, diagram_r, unop_op, Set.mem_preimage, Set.mem_image]
    refine ⟨fun h => ⟨_, h, rfl⟩, ?_⟩
    rintro ⟨y, h1, h2⟩
    convert h1 using 1
    

Proof state:
case h.e'_4.h
C : Type u
inst✝¹ : Category.{v, u} C
D : GlueData C
inst✝ : HasLimits C
i : D.J
U : Opens ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
x : ↑↑(CategoryTheory.GlueData.U D.toGlueData i)
y : (CategoryTheory.forget TopCat).obj ↑(CategoryTheory.GlueData.U D.toGlueData i)
h1 : y ∈ U
h2 :
  (ι D.toGlueData i).base y =
    (colimit.ι (MultispanIndex.multispan (diagram D.toGlueData)) (WalkingMultispan.right i)).base x
e_1✝ :
  ↑↑(CategoryTheory.GlueData.U D.toGlueData i) =
    (CategoryTheory.forget TopCat).obj ↑(CategoryTheory.GlueData.U D.toGlueData i)
⊢ x = y

Next tactic:
delta ι Multicoequalizer.π at h2