l3lab/ntp-mathlib huggingface dataset:
/-- For an open immersion `f : X ⟶ Y` and an open set `U ⊆ X`, we have the map `X(U) ⟶ Y(U)`. -/
noncomputable def invApp (U : Opens X) :
    X.presheaf.obj (op U) ⟶ Y.presheaf.obj (op (H.openFunctor.obj U)) :=
  X.presheaf.map (eqToHom (by
    -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
    -- See https://github.com/leanprover-community/mathlib4/issues/5026
    -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
    -- structure
    congr; ext
    dsimp [openFunctor, IsOpenMap.functor]
    

Proof state:
case e_x.h.h
C : Type u_1
inst✝ : Category.{?u.27455, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
x✝ : ↑↑X
⊢ x✝ ∈ ↑U ↔ x✝ ∈ ⇑f.base ⁻¹' (⇑f.base '' ↑U)

Next tactic:
rw [Set.preimage_image_eq _ H.base_open.inj]
@[simp, reassoc]
theorem inv_naturality {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) :
    X.presheaf.map i ≫ H.invApp (unop V) =
      H.invApp (unop U) ≫ Y.presheaf.map (H.openFunctor.op.map i) := by
  

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U V : (Opens ↑↑X)ᵒᵖ
i : U ⟶ V
⊢ X.presheaf.map i ≫ invApp H V.unop = invApp H U.unop ≫ Y.presheaf.map ((openFunctor H).op.map i)

Next tactic:
simp only [invApp, ← Category.assoc]
@[simp, reassoc]
theorem inv_naturality {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) :
    X.presheaf.map i ≫ H.invApp (unop V) =
      H.invApp (unop U) ≫ Y.presheaf.map (H.openFunctor.op.map i) := by
  simp only [invApp, ← Category.assoc]
  

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U V : (Opens ↑↑X)ᵒᵖ
i : U ⟶ V
⊢ (X.presheaf.map i ≫
        X.presheaf.map (eqToHom (_ : op V.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj V.unop)).unop)))) ≫
      inv (f.c.app (op ((openFunctor H).obj V.unop))) =
    (X.presheaf.map (eqToHom (_ : op U.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj U.unop)).unop))) ≫
        inv (f.c.app (op ((openFunctor H).obj U.unop)))) ≫
      Y.presheaf.map ((openFunctor H).op.map i)

Next tactic:
rw [IsIso.comp_inv_eq]
@[simp, reassoc]
theorem inv_naturality {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) :
    X.presheaf.map i ≫ H.invApp (unop V) =
      H.invApp (unop U) ≫ Y.presheaf.map (H.openFunctor.op.map i) := by
  simp only [invApp, ← Category.assoc]
  rw [IsIso.comp_inv_eq]
  -- Porting note : `simp` can't pick up `f.c.naturality`
  -- See https://github.com/leanprover-community/mathlib4/issues/5026
  

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U V : (Opens ↑↑X)ᵒᵖ
i : U ⟶ V
⊢ X.presheaf.map i ≫
      X.presheaf.map (eqToHom (_ : op V.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj V.unop)).unop))) =
    ((X.presheaf.map (eqToHom (_ : op U.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj U.unop)).unop))) ≫
          inv (f.c.app (op ((openFunctor H).obj U.unop)))) ≫
        Y.presheaf.map ((openFunctor H).op.map i)) ≫
      f.c.app (op ((openFunctor H).obj V.unop))

Next tactic:
simp only [Category.assoc, ← X.presheaf.map_comp]
@[simp, reassoc]
theorem inv_naturality {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) :
    X.presheaf.map i ≫ H.invApp (unop V) =
      H.invApp (unop U) ≫ Y.presheaf.map (H.openFunctor.op.map i) := by
  simp only [invApp, ← Category.assoc]
  rw [IsIso.comp_inv_eq]
  -- Porting note : `simp` can't pick up `f.c.naturality`
  -- See https://github.com/leanprover-community/mathlib4/issues/5026
  simp only [Category.assoc, ← X.presheaf.map_comp]
  

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U V : (Opens ↑↑X)ᵒᵖ
i : U ⟶ V
⊢ X.presheaf.map (i ≫ eqToHom (_ : op V.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj V.unop)).unop))) =
    X.presheaf.map (eqToHom (_ : op U.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj U.unop)).unop))) ≫
      inv (f.c.app (op ((openFunctor H).obj U.unop))) ≫
        Y.presheaf.map ((openFunctor H).op.map i) ≫ f.c.app (op ((openFunctor H).obj V.unop))

Next tactic:
erw [f.c.naturality]
@[simp, reassoc]
theorem inv_naturality {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) :
    X.presheaf.map i ≫ H.invApp (unop V) =
      H.invApp (unop U) ≫ Y.presheaf.map (H.openFunctor.op.map i) := by
  simp only [invApp, ← Category.assoc]
  rw [IsIso.comp_inv_eq]
  -- Porting note : `simp` can't pick up `f.c.naturality`
  -- See https://github.com/leanprover-community/mathlib4/issues/5026
  simp only [Category.assoc, ← X.presheaf.map_comp]
  erw [f.c.naturality]
  

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U V : (Opens ↑↑X)ᵒᵖ
i : U ⟶ V
⊢ X.presheaf.map (i ≫ eqToHom (_ : op V.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj V.unop)).unop))) =
    X.presheaf.map (eqToHom (_ : op U.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj U.unop)).unop))) ≫
      inv (f.c.app (op ((openFunctor H).obj U.unop))) ≫
        f.c.app (op ((openFunctor H).obj U.unop)) ≫ (f.base _* X.presheaf).map ((openFunctor H).op.map i)

Next tactic:
simp only [IsIso.inv_hom_id_assoc, ← X.presheaf.map_comp]
@[simp, reassoc]
theorem inv_naturality {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) :
    X.presheaf.map i ≫ H.invApp (unop V) =
      H.invApp (unop U) ≫ Y.presheaf.map (H.openFunctor.op.map i) := by
  simp only [invApp, ← Category.assoc]
  rw [IsIso.comp_inv_eq]
  -- Porting note : `simp` can't pick up `f.c.naturality`
  -- See https://github.com/leanprover-community/mathlib4/issues/5026
  simp only [Category.assoc, ← X.presheaf.map_comp]
  erw [f.c.naturality]
  simp only [IsIso.inv_hom_id_assoc, ← X.presheaf.map_comp]
  

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U V : (Opens ↑↑X)ᵒᵖ
i : U ⟶ V
⊢ X.presheaf.map (i ≫ eqToHom (_ : op V.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj V.unop)).unop))) =
    X.presheaf.map (eqToHom (_ : op U.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj U.unop)).unop))) ≫
      (f.base _* X.presheaf).map ((openFunctor H).op.map i)

Next tactic:
erw [← X.presheaf.map_comp]
@[simp, reassoc]
theorem inv_naturality {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) :
    X.presheaf.map i ≫ H.invApp (unop V) =
      H.invApp (unop U) ≫ Y.presheaf.map (H.openFunctor.op.map i) := by
  simp only [invApp, ← Category.assoc]
  rw [IsIso.comp_inv_eq]
  -- Porting note : `simp` can't pick up `f.c.naturality`
  -- See https://github.com/leanprover-community/mathlib4/issues/5026
  simp only [Category.assoc, ← X.presheaf.map_comp]
  erw [f.c.naturality]
  simp only [IsIso.inv_hom_id_assoc, ← X.presheaf.map_comp]
  erw [← X.presheaf.map_comp]
  

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U V : (Opens ↑↑X)ᵒᵖ
i : U ⟶ V
⊢ X.presheaf.map (i ≫ eqToHom (_ : op V.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj V.unop)).unop))) =
    X.presheaf.map
      (eqToHom (_ : op U.unop = op ((Opens.map f.base).obj (op ((openFunctor H).obj U.unop)).unop)) ≫
        (Opens.map f.base).op.map ((openFunctor H).op.map i))

Next tactic:
congr 1
instance (U : Opens X) : IsIso (H.invApp U) := by 

Proof state:
C : Type u_1
inst✝ : Category.{?u.34664, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
⊢ IsIso (invApp H U)

Next tactic:
delta invApp
instance (U : Opens X) : IsIso (H.invApp U) := by delta invApp; 

Proof state:
C : Type u_1
inst✝ : Category.{?u.34664, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
⊢ IsIso
    (X.presheaf.map (eqToHom (_ : op U = op ((Opens.map f.base).obj (op ((openFunctor H).obj U)).unop))) ≫
      inv (f.c.app (op ((openFunctor H).obj U))))

Next tactic:
infer_instance
theorem inv_invApp (U : Opens X) :
    inv (H.invApp U) =
      f.c.app (op (H.openFunctor.obj U)) ≫
        X.presheaf.map (eqToHom (by
          -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
          -- See https://github.com/leanprover-community/mathlib4/issues/5026
          -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
          -- structure
          

Proof state:
C : Type u_1
inst✝ : Category.{?u.35658, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
⊢ (Opens.map f.base).op.obj (op ((openFunctor H).obj U)) = op U

Next tactic:
apply congr_arg (op ·)
theorem inv_invApp (U : Opens X) :
    inv (H.invApp U) =
      f.c.app (op (H.openFunctor.obj U)) ≫
        X.presheaf.map (eqToHom (by
          -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
          -- See https://github.com/leanprover-community/mathlib4/issues/5026
          -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
          -- structure
          apply congr_arg (op ·); 

Proof state:
C : Type u_1
inst✝ : Category.{?u.35658, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
⊢ (Opens.map f.base).obj (op ((openFunctor H).obj U)).unop = U

Next tactic:
ext
theorem inv_invApp (U : Opens X) :
    inv (H.invApp U) =
      f.c.app (op (H.openFunctor.obj U)) ≫
        X.presheaf.map (eqToHom (by
          -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
          -- See https://github.com/leanprover-community/mathlib4/issues/5026
          -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
          -- structure
          apply congr_arg (op ·); ext
          

Proof state:
case h.h
C : Type u_1
inst✝ : Category.{?u.35658, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
x✝ : ↑↑X
⊢ x✝ ∈ ↑((Opens.map f.base).obj (op ((openFunctor H).obj U)).unop) ↔ x✝ ∈ ↑U

Next tactic:
dsimp [openFunctor, IsOpenMap.functor]
theorem inv_invApp (U : Opens X) :
    inv (H.invApp U) =
      f.c.app (op (H.openFunctor.obj U)) ≫
        X.presheaf.map (eqToHom (by
          -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
          -- See https://github.com/leanprover-community/mathlib4/issues/5026
          -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
          -- structure
          apply congr_arg (op ·); ext
          dsimp [openFunctor, IsOpenMap.functor]
          

Proof state:
case h.h
C : Type u_1
inst✝ : Category.{?u.35658, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
x✝ : ↑↑X
⊢ x✝ ∈ ⇑f.base ⁻¹' (⇑f.base '' ↑U) ↔ x✝ ∈ ↑U

Next tactic:
rw [Set.preimage_image_eq _ H.base_open.inj]
theorem inv_invApp (U : Opens X) :
    inv (H.invApp U) =
      f.c.app (op (H.openFunctor.obj U)) ≫
        X.presheaf.map (eqToHom (by
          -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
          -- See https://github.com/leanprover-community/mathlib4/issues/5026
          -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
          -- structure
          apply congr_arg (op ·); ext
          dsimp [openFunctor, IsOpenMap.functor]
          rw [Set.preimage_image_eq _ H.base_open.inj])) := by
  

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
⊢ inv (invApp H U) =
    f.c.app (op ((openFunctor H).obj U)) ≫
      X.presheaf.map (eqToHom (_ : op ((Opens.map f.base).obj (op ((openFunctor H).obj U)).unop) = op U))

Next tactic:
rw [← cancel_epi (H.invApp U), IsIso.hom_inv_id]
theorem inv_invApp (U : Opens X) :
    inv (H.invApp U) =
      f.c.app (op (H.openFunctor.obj U)) ≫
        X.presheaf.map (eqToHom (by
          -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
          -- See https://github.com/leanprover-community/mathlib4/issues/5026
          -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
          -- structure
          apply congr_arg (op ·); ext
          dsimp [openFunctor, IsOpenMap.functor]
          rw [Set.preimage_image_eq _ H.base_open.inj])) := by
  rw [← cancel_epi (H.invApp U), IsIso.hom_inv_id]
  

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
⊢ 𝟙 (X.presheaf.obj (op U)) =
    invApp H U ≫
      f.c.app (op ((openFunctor H).obj U)) ≫
        X.presheaf.map (eqToHom (_ : op ((Opens.map f.base).obj (op ((openFunctor H).obj U)).unop) = op U))

Next tactic:
delta invApp
theorem inv_invApp (U : Opens X) :
    inv (H.invApp U) =
      f.c.app (op (H.openFunctor.obj U)) ≫
        X.presheaf.map (eqToHom (by
          -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
          -- See https://github.com/leanprover-community/mathlib4/issues/5026
          -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
          -- structure
          apply congr_arg (op ·); ext
          dsimp [openFunctor, IsOpenMap.functor]
          rw [Set.preimage_image_eq _ H.base_open.inj])) := by
  rw [← cancel_epi (H.invApp U), IsIso.hom_inv_id]
  delta invApp
  

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
⊢ 𝟙 (X.presheaf.obj (op U)) =
    (X.presheaf.map (eqToHom (_ : op U = op ((Opens.map f.base).obj (op ((openFunctor H).obj U)).unop))) ≫
        inv (f.c.app (op ((openFunctor H).obj U)))) ≫
      f.c.app (op ((openFunctor H).obj U)) ≫
        X.presheaf.map (eqToHom (_ : op ((Opens.map f.base).obj (op ((openFunctor H).obj U)).unop) = op U))

Next tactic:
simp [← Functor.map_comp]
@[simp, reassoc, elementwise]
theorem invApp_app (U : Opens X) :
    H.invApp U ≫ f.c.app (op (H.openFunctor.obj U)) =
      X.presheaf.map (eqToHom (by
        -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
        -- See https://github.com/leanprover-community/mathlib4/issues/5026
        -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
        -- structure
        

Proof state:
C : Type u_1
inst✝ : Category.{?u.41237, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
⊢ op U = (Opens.map f.base).op.obj (op ((openFunctor H).obj U))

Next tactic:
apply congr_arg (op ·)
@[simp, reassoc, elementwise]
theorem invApp_app (U : Opens X) :
    H.invApp U ≫ f.c.app (op (H.openFunctor.obj U)) =
      X.presheaf.map (eqToHom (by
        -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
        -- See https://github.com/leanprover-community/mathlib4/issues/5026
        -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
        -- structure
        apply congr_arg (op ·); 

Proof state:
C : Type u_1
inst✝ : Category.{?u.41237, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
⊢ U = (Opens.map f.base).obj (op ((openFunctor H).obj U)).unop

Next tactic:
ext
@[simp, reassoc, elementwise]
theorem invApp_app (U : Opens X) :
    H.invApp U ≫ f.c.app (op (H.openFunctor.obj U)) =
      X.presheaf.map (eqToHom (by
        -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
        -- See https://github.com/leanprover-community/mathlib4/issues/5026
        -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
        -- structure
        apply congr_arg (op ·); ext
        

Proof state:
case h.h
C : Type u_1
inst✝ : Category.{?u.41237, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
x✝ : ↑↑X
⊢ x✝ ∈ ↑U ↔ x✝ ∈ ↑((Opens.map f.base).obj (op ((openFunctor H).obj U)).unop)

Next tactic:
dsimp [openFunctor, IsOpenMap.functor]
@[simp, reassoc, elementwise]
theorem invApp_app (U : Opens X) :
    H.invApp U ≫ f.c.app (op (H.openFunctor.obj U)) =
      X.presheaf.map (eqToHom (by
        -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
        -- See https://github.com/leanprover-community/mathlib4/issues/5026
        -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
        -- structure
        apply congr_arg (op ·); ext
        dsimp [openFunctor, IsOpenMap.functor]
        

Proof state:
case h.h
C : Type u_1
inst✝ : Category.{?u.41237, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
x✝ : ↑↑X
⊢ x✝ ∈ ↑U ↔ x✝ ∈ ⇑f.base ⁻¹' (⇑f.base '' ↑U)

Next tactic:
rw [Set.preimage_image_eq _ H.base_open.inj]
@[simp, reassoc, elementwise]
theorem invApp_app (U : Opens X) :
    H.invApp U ≫ f.c.app (op (H.openFunctor.obj U)) =
      X.presheaf.map (eqToHom (by
        -- Porting note : was just `simp [opens.map, Set.preimage_image_eq _ H.base_open.inj]`
        -- See https://github.com/leanprover-community/mathlib4/issues/5026
        -- I think this is because `Set.preimage_image_eq _ H.base_open.inj` can't see through a
        -- structure
        apply congr_arg (op ·); ext
        dsimp [openFunctor, IsOpenMap.functor]
        rw [Set.preimage_image_eq _ H.base_open.inj])) :=
  by 

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑X
⊢ invApp H U ≫ f.c.app (op ((openFunctor H).obj U)) =
    X.presheaf.map (eqToHom (_ : op U = op ((Opens.map f.base).obj (op ((openFunctor H).obj U)).unop)))

Next tactic:
rw [invApp, Category.assoc, IsIso.inv_hom_id, Category.comp_id]
@[simp, reassoc]
theorem app_invApp (U : Opens Y) :
    f.c.app (op U) ≫ H.invApp ((Opens.map f.base).obj U) =
      Y.presheaf.map
        ((homOfLE (Set.image_preimage_subset f.base U.1)).op :
          op U ⟶ op (H.openFunctor.obj ((Opens.map f.base).obj U))) :=
  by 

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑Y
⊢ f.c.app (op U) ≫ invApp H ((Opens.map f.base).obj U) =
    Y.presheaf.map (homOfLE (_ : ⇑f.base '' (⇑f.base ⁻¹' U.carrier) ⊆ U.carrier)).op

Next tactic:
erw [← Category.assoc]
@[simp, reassoc]
theorem app_invApp (U : Opens Y) :
    f.c.app (op U) ≫ H.invApp ((Opens.map f.base).obj U) =
      Y.presheaf.map
        ((homOfLE (Set.image_preimage_subset f.base U.1)).op :
          op U ⟶ op (H.openFunctor.obj ((Opens.map f.base).obj U))) :=
  by erw [← Category.assoc]; 

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑Y
⊢ (f.c.app (op U) ≫
        X.presheaf.map
          (eqToHom
            (_ :
              op ((Opens.map f.base).obj U) =
                op ((Opens.map f.base).obj (op ((openFunctor H).obj ((Opens.map f.base).obj U))).unop)))) ≫
      inv (f.c.app (op ((openFunctor H).obj ((Opens.map f.base).obj U)))) =
    Y.presheaf.map (homOfLE (_ : ⇑f.base '' (⇑f.base ⁻¹' U.carrier) ⊆ U.carrier)).op

Next tactic:
rw [IsIso.comp_inv_eq, f.c.naturality]
@[simp, reassoc]
theorem app_invApp (U : Opens Y) :
    f.c.app (op U) ≫ H.invApp ((Opens.map f.base).obj U) =
      Y.presheaf.map
        ((homOfLE (Set.image_preimage_subset f.base U.1)).op :
          op U ⟶ op (H.openFunctor.obj ((Opens.map f.base).obj U))) :=
  by erw [← Category.assoc]; rw [IsIso.comp_inv_eq, f.c.naturality]; 

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑Y
⊢ f.c.app (op U) ≫
      X.presheaf.map
        (eqToHom
          (_ :
            op ((Opens.map f.base).obj U) =
              op ((Opens.map f.base).obj (op ((openFunctor H).obj ((Opens.map f.base).obj U))).unop))) =
    f.c.app (op U) ≫ (f.base _* X.presheaf).map (homOfLE (_ : ⇑f.base '' (⇑f.base ⁻¹' U.carrier) ⊆ U.carrier)).op

Next tactic:
congr
/-- A variant of `app_inv_app` that gives an `eq_to_hom` instead of `hom_of_le`. -/
@[reassoc]
theorem app_inv_app' (U : Opens Y) (hU : (U : Set Y) ⊆ Set.range f.base) :
    f.c.app (op U) ≫ H.invApp ((Opens.map f.base).obj U) =
      Y.presheaf.map
        (eqToHom
            (by
              

Proof state:
C : Type u_1
inst✝ : Category.{?u.51158, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑Y
hU : ↑U ⊆ Set.range ⇑f.base
⊢ (openFunctor H).obj ((Opens.map f.base).obj U) = U

Next tactic:
apply le_antisymm
/-- A variant of `app_inv_app` that gives an `eq_to_hom` instead of `hom_of_le`. -/
@[reassoc]
theorem app_inv_app' (U : Opens Y) (hU : (U : Set Y) ⊆ Set.range f.base) :
    f.c.app (op U) ≫ H.invApp ((Opens.map f.base).obj U) =
      Y.presheaf.map
        (eqToHom
            (by
              apply le_antisymm
              · 

Proof state:
case a
C : Type u_1
inst✝ : Category.{?u.51158, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑Y
hU : ↑U ⊆ Set.range ⇑f.base
⊢ (openFunctor H).obj ((Opens.map f.base).obj U) ≤ U

Next tactic:
exact Set.image_preimage_subset f.base U.1
/-- A variant of `app_inv_app` that gives an `eq_to_hom` instead of `hom_of_le`. -/
@[reassoc]
theorem app_inv_app' (U : Opens Y) (hU : (U : Set Y) ⊆ Set.range f.base) :
    f.c.app (op U) ≫ H.invApp ((Opens.map f.base).obj U) =
      Y.presheaf.map
        (eqToHom
            (by
              apply le_antisymm
              · exact Set.image_preimage_subset f.base U.1
              · 

Proof state:
case a
C : Type u_1
inst✝ : Category.{?u.51158, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑Y
hU : ↑U ⊆ Set.range ⇑f.base
⊢ U ≤ (openFunctor H).obj ((Opens.map f.base).obj U)

Next tactic:
rw [← SetLike.coe_subset_coe]
/-- A variant of `app_inv_app` that gives an `eq_to_hom` instead of `hom_of_le`. -/
@[reassoc]
theorem app_inv_app' (U : Opens Y) (hU : (U : Set Y) ⊆ Set.range f.base) :
    f.c.app (op U) ≫ H.invApp ((Opens.map f.base).obj U) =
      Y.presheaf.map
        (eqToHom
            (by
              apply le_antisymm
              · exact Set.image_preimage_subset f.base U.1
              · rw [← SetLike.coe_subset_coe]
                

Proof state:
case a
C : Type u_1
inst✝ : Category.{?u.51158, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑Y
hU : ↑U ⊆ Set.range ⇑f.base
⊢ ↑U ⊆ ↑((openFunctor H).obj ((Opens.map f.base).obj U))

Next tactic:
refine' LE.le.trans_eq _ (@Set.image_preimage_eq_inter_range _ _ f.base U.1).symm
/-- A variant of `app_inv_app` that gives an `eq_to_hom` instead of `hom_of_le`. -/
@[reassoc]
theorem app_inv_app' (U : Opens Y) (hU : (U : Set Y) ⊆ Set.range f.base) :
    f.c.app (op U) ≫ H.invApp ((Opens.map f.base).obj U) =
      Y.presheaf.map
        (eqToHom
            (by
              apply le_antisymm
              · exact Set.image_preimage_subset f.base U.1
              · rw [← SetLike.coe_subset_coe]
                refine' LE.le.trans_eq _ (@Set.image_preimage_eq_inter_range _ _ f.base U.1).symm
                

Proof state:
case a
C : Type u_1
inst✝ : Category.{?u.51158, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑Y
hU : ↑U ⊆ Set.range ⇑f.base
⊢ ↑U ≤ U.carrier ∩ Set.range ⇑f.base

Next tactic:
exact Set.subset_inter_iff.mpr ⟨fun _ h => h, hU⟩
/-- A variant of `app_inv_app` that gives an `eq_to_hom` instead of `hom_of_le`. -/
@[reassoc]
theorem app_inv_app' (U : Opens Y) (hU : (U : Set Y) ⊆ Set.range f.base) :
    f.c.app (op U) ≫ H.invApp ((Opens.map f.base).obj U) =
      Y.presheaf.map
        (eqToHom
            (by
              apply le_antisymm
              · exact Set.image_preimage_subset f.base U.1
              · rw [← SetLike.coe_subset_coe]
                refine' LE.le.trans_eq _ (@Set.image_preimage_eq_inter_range _ _ f.base U.1).symm
                exact Set.subset_inter_iff.mpr ⟨fun _ h => h, hU⟩)).op :=
  by 

Proof state:
C : Type u_1
inst✝ : Category.{u_3, u_1} C
X Y : PresheafedSpace C
f : X ⟶ Y
H : IsOpenImmersion f
U : Opens ↑↑Y
hU : ↑U ⊆ Set.range ⇑f.base
⊢ f.c.app (op U) ≫ invApp H ((Opens.map f.base).obj U) =
    Y.presheaf.map (eqToHom (_ : (openFunctor H).obj ((Opens.map f.base).obj U) = U)).op

Next tactic:
erw [← Category.assoc]