/-- We can prove the `eq` along with the lemma. Thus this is bundled together here, and the
lemma itself is separated below.
-/
theorem snd_invApp_t_app' (i j k : D.J) (U : Opens (pullback (D.f i j) (D.f i k)).carrier) :
    ∃ eq,
      (π₂⁻¹ i, j, k) U ≫ (D.t k i).c.app _ ≫ (D.V (k, i)).presheaf.map (eqToHom eq) =
        (D.t' k i j).c.app _ ≫ (π₁⁻¹ k, j, i) (unop _) := by
  fconstructor
  -- Porting note: I don't know what the magic was in Lean3 proof, it just skipped the proof of `eq`
  · delta IsOpenImmersion.openFunctor
    dsimp only [Functor.op, Opens.map, IsOpenMap.functor, unop_op, Opens.coe_mk]
    congr
    have := (𝖣.t_fac k i j).symm
    rw [← IsIso.inv_comp_eq] at this
    replace this := (congr_arg ((PresheafedSpace.Hom.base ·)) this).symm
    replace this := congr_arg (ContinuousMap.toFun ·) this
    dsimp at this
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    erw [coe_comp, coe_comp] at this
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    erw [this, Set.image_comp, Set.image_comp, Set.preimage_image_eq]
    swap
    · refine Function.HasLeftInverse.injective ⟨(D.t i k).base, fun x => ?_⟩
      rw [← comp_apply, ← comp_base, D.t_inv, id_base, id_apply]
    refine congr_arg (_ '' ·) ?_
    refine congr_fun ?_ _
    refine Set.image_eq_preimage_of_inverse ?_ ?_
    · intro x
      rw [← comp_apply, ← comp_base, IsIso.inv_hom_id, id_base, id_apply]
    · intro x
      rw [← comp_apply, ← comp_base, IsIso.hom_inv_id, id_base, id_apply]
  · rw [← IsIso.eq_inv_comp, IsOpenImmersion.inv_invApp, Category.assoc,
      (D.t' k i j).c.naturality_assoc]
    simp_rw [← Category.assoc]
    erw [← comp_c_app]
    rw [congr_app (D.t_fac k i j), comp_c_app]
    simp_rw [Category.assoc]
    erw [IsOpenImmersion.inv_naturality, IsOpenImmersion.inv_naturality_assoc,
      IsOpenImmersion.app_inv_app'_assoc]
    

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
D : GlueData C
i j k : D.J
U : Opens ↑↑(pullback (f D.toGlueData i j) (f D.toGlueData i k))
⊢ (t D.toGlueData k i).c.app (op ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.snd)).obj U)) ≫
      (V D.toGlueData (k, i)).presheaf.map
        (eqToHom
          (_ :
            (Opens.map (t D.toGlueData k i).base).op.obj
                (op ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.snd)).obj U)) =
              op
                ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.fst)).obj
                  {
                      unop :=
                        { carrier := ⇑(t' D.toGlueData k i j).base ⁻¹' ↑(op U).unop,
                          is_open' := (_ : IsOpen (⇑(t' D.toGlueData k i j).base ⁻¹' ↑(op U).unop)) } }.unop))) =
    (t D.toGlueData k i).c.app (op ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.snd)).obj U)) ≫
      (V D.toGlueData (k, i)).presheaf.map
          (eqToHom
              (_ :
                (IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.fst)).obj
                    ((Opens.map pullback.fst.base).obj
                      ((Opens.map (t D.toGlueData k i).base).obj
                        (op ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.snd)).obj U)).unop)) =
                  (Opens.map (t D.toGlueData k i).base).obj
                    (op ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.snd)).obj U)).unop)).op ≫
        (V D.toGlueData (k, i)).presheaf.map
            ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.fst)).op.map
              (eqToHom
                (_ :
                  (Opens.map (pullback.fst ≫ t D.toGlueData k i).base).op.obj
                      (op ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.snd)).obj U)) =
                    (Opens.map (t' D.toGlueData k i j ≫ pullback.snd).base).op.obj
                      (op ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.snd)).obj U))))) ≫
          (V D.toGlueData (k, i)).presheaf.map
            ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.fst)).op.map
              ((Opens.map (t' D.toGlueData k i j).base).op.map
                (eqToHom
                  (_ :
                    op
                        ((Opens.map pullback.snd.base).obj
                          (op ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.snd)).obj U)).unop) =
                      op U))))
case h.hU
C : Type u
inst✝ : Category.{v, u} C
D : GlueData C
i j k : D.J
U : Opens ↑↑(pullback (f D.toGlueData i j) (f D.toGlueData i k))
⊢ ↑((Opens.map (t D.toGlueData k i).base).obj
        (op ((IsOpenImmersion.openFunctor (_ : IsOpenImmersion pullback.snd)).obj U)).unop) ⊆
    Set.range ⇑pullback.fst.base

Next tactic:
simp_rw [← (𝖣.V (k, i)).presheaf.map_comp, eqToHom_map (Functor.op _), eqToHom_op,
      eqToHom_trans]