l3lab/ntp-mathlib huggingface dataset:
theorem Γ_map_morphismRestrict {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) :
    Scheme.Γ.map (f ∣_ U).op =
      Y.presheaf.map (eqToHom <| U.openEmbedding_obj_top.symm).op ≫
        f.1.c.app (op U) ≫ X.presheaf.map (eqToHom <| (f ⁻¹ᵁ U).openEmbedding_obj_top).op := by
  rw [Scheme.Γ_map_op, morphismRestrict_c_app f U ⊤, f.val.c.naturality_assoc]
  erw [← X.presheaf.map_comp]
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
⊢ f.val.c.app (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj ⊤)) ≫
      X.presheaf.map
        (eqToHom
            (_ :
              (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion (f⁻¹ᵁ U)))).obj ((f ∣_ U)⁻¹ᵁ ⊤) =
                f⁻¹ᵁ (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj ⊤)).op =
    f.val.c.app (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj ⊤)) ≫
      X.presheaf.map
        ((Opens.map f.val.base).op.map
            (eqToHom (_ : U = (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj ⊤)).op ≫
          (eqToHom (_ : (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion (f⁻¹ᵁ U)))).obj ⊤ = f⁻¹ᵁ U)).op)

Next tactic:
congr
/-- Restricting a morphism onto the image of an open immersion is isomorphic to the base change
along the immersion. -/
def morphismRestrictOpensRange {X Y U : Scheme} (f : X ⟶ Y) (g : U ⟶ Y) [hg : IsOpenImmersion g] :
    Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk (pullback.snd : pullback f g ⟶ _) := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y U : Scheme
f : X ⟶ Y
g : U ⟶ Y
hg : IsOpenImmersion g
⊢ Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk pullback.snd

Next tactic:
let V : Opens Y := Scheme.Hom.opensRange g
/-- Restricting a morphism onto the image of an open immersion is isomorphic to the base change
along the immersion. -/
def morphismRestrictOpensRange {X Y U : Scheme} (f : X ⟶ Y) (g : U ⟶ Y) [hg : IsOpenImmersion g] :
    Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk (pullback.snd : pullback f g ⟶ _) := by
  let V : Opens Y := Scheme.Hom.opensRange g
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y U : Scheme
f : X ⟶ Y
g : U ⟶ Y
hg : IsOpenImmersion g
V : Opens ↑↑Y.toPresheafedSpace := Scheme.Hom.opensRange g
⊢ Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk pullback.snd

Next tactic:
let e :=
    IsOpenImmersion.isoOfRangeEq g (Y.ofRestrict V.openEmbedding) Subtype.range_coe.symm
/-- Restricting a morphism onto the image of an open immersion is isomorphic to the base change
along the immersion. -/
def morphismRestrictOpensRange {X Y U : Scheme} (f : X ⟶ Y) (g : U ⟶ Y) [hg : IsOpenImmersion g] :
    Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk (pullback.snd : pullback f g ⟶ _) := by
  let V : Opens Y := Scheme.Hom.opensRange g
  let e :=
    IsOpenImmersion.isoOfRangeEq g (Y.ofRestrict V.openEmbedding) Subtype.range_coe.symm
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y U : Scheme
f : X ⟶ Y
g : U ⟶ Y
hg : IsOpenImmersion g
V : Opens ↑↑Y.toPresheafedSpace := Scheme.Hom.opensRange g
e : U ≅ Y ∣_ᵤ V :=
  IsOpenImmersion.isoOfRangeEq g (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V)))
    (_ : Set.range ⇑g.val.base = Set.range Subtype.val)
⊢ Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk pullback.snd

Next tactic:
let t : pullback f g ⟶ pullback f (Y.ofRestrict V.openEmbedding) :=
    pullback.map _ _ _ _ (𝟙 _) e.hom (𝟙 _) (by rw [Category.comp_id, Category.id_comp])
      (by rw [Category.comp_id, IsOpenImmersion.isoOfRangeEq_hom_fac])
/-- Restricting a morphism onto the image of an open immersion is isomorphic to the base change
along the immersion. -/
def morphismRestrictOpensRange {X Y U : Scheme} (f : X ⟶ Y) (g : U ⟶ Y) [hg : IsOpenImmersion g] :
    Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk (pullback.snd : pullback f g ⟶ _) := by
  let V : Opens Y := Scheme.Hom.opensRange g
  let e :=
    IsOpenImmersion.isoOfRangeEq g (Y.ofRestrict V.openEmbedding) Subtype.range_coe.symm
  let t : pullback f g ⟶ pullback f (Y.ofRestrict V.openEmbedding) :=
    pullback.map _ _ _ _ (𝟙 _) e.hom (𝟙 _) (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y U : Scheme
f : X ⟶ Y
g : U ⟶ Y
hg : IsOpenImmersion g
V : Opens ↑↑Y.toPresheafedSpace := Scheme.Hom.opensRange g
e : U ≅ Y ∣_ᵤ V :=
  IsOpenImmersion.isoOfRangeEq g (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V)))
    (_ : Set.range ⇑g.val.base = Set.range Subtype.val)
⊢ f ≫ 𝟙 Y = 𝟙 X ≫ f

Next tactic:
rw [Category.comp_id, Category.id_comp]
/-- Restricting a morphism onto the image of an open immersion is isomorphic to the base change
along the immersion. -/
def morphismRestrictOpensRange {X Y U : Scheme} (f : X ⟶ Y) (g : U ⟶ Y) [hg : IsOpenImmersion g] :
    Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk (pullback.snd : pullback f g ⟶ _) := by
  let V : Opens Y := Scheme.Hom.opensRange g
  let e :=
    IsOpenImmersion.isoOfRangeEq g (Y.ofRestrict V.openEmbedding) Subtype.range_coe.symm
  let t : pullback f g ⟶ pullback f (Y.ofRestrict V.openEmbedding) :=
    pullback.map _ _ _ _ (𝟙 _) e.hom (𝟙 _) (by rw [Category.comp_id, Category.id_comp])
      (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y U : Scheme
f : X ⟶ Y
g : U ⟶ Y
hg : IsOpenImmersion g
V : Opens ↑↑Y.toPresheafedSpace := Scheme.Hom.opensRange g
e : U ≅ Y ∣_ᵤ V :=
  IsOpenImmersion.isoOfRangeEq g (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V)))
    (_ : Set.range ⇑g.val.base = Set.range Subtype.val)
⊢ g ≫ 𝟙 Y = e.hom ≫ Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V))

Next tactic:
rw [Category.comp_id, IsOpenImmersion.isoOfRangeEq_hom_fac]
/-- Restricting a morphism onto the image of an open immersion is isomorphic to the base change
along the immersion. -/
def morphismRestrictOpensRange {X Y U : Scheme} (f : X ⟶ Y) (g : U ⟶ Y) [hg : IsOpenImmersion g] :
    Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk (pullback.snd : pullback f g ⟶ _) := by
  let V : Opens Y := Scheme.Hom.opensRange g
  let e :=
    IsOpenImmersion.isoOfRangeEq g (Y.ofRestrict V.openEmbedding) Subtype.range_coe.symm
  let t : pullback f g ⟶ pullback f (Y.ofRestrict V.openEmbedding) :=
    pullback.map _ _ _ _ (𝟙 _) e.hom (𝟙 _) (by rw [Category.comp_id, Category.id_comp])
      (by rw [Category.comp_id, IsOpenImmersion.isoOfRangeEq_hom_fac])
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y U : Scheme
f : X ⟶ Y
g : U ⟶ Y
hg : IsOpenImmersion g
V : Opens ↑↑Y.toPresheafedSpace := Scheme.Hom.opensRange g
e : U ≅ Y ∣_ᵤ V :=
  IsOpenImmersion.isoOfRangeEq g (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V)))
    (_ : Set.range ⇑g.val.base = Set.range Subtype.val)
t : pullback f g ⟶ pullback f (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V))) :=
  pullback.map f g f (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V))) (𝟙 X) e.hom (𝟙 Y)
    (_ : f ≫ 𝟙 Y = 𝟙 X ≫ f) (_ : g ≫ 𝟙 Y = e.hom ≫ Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V)))
⊢ Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk pullback.snd

Next tactic:
symm
/-- Restricting a morphism onto the image of an open immersion is isomorphic to the base change
along the immersion. -/
def morphismRestrictOpensRange {X Y U : Scheme} (f : X ⟶ Y) (g : U ⟶ Y) [hg : IsOpenImmersion g] :
    Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk (pullback.snd : pullback f g ⟶ _) := by
  let V : Opens Y := Scheme.Hom.opensRange g
  let e :=
    IsOpenImmersion.isoOfRangeEq g (Y.ofRestrict V.openEmbedding) Subtype.range_coe.symm
  let t : pullback f g ⟶ pullback f (Y.ofRestrict V.openEmbedding) :=
    pullback.map _ _ _ _ (𝟙 _) e.hom (𝟙 _) (by rw [Category.comp_id, Category.id_comp])
      (by rw [Category.comp_id, IsOpenImmersion.isoOfRangeEq_hom_fac])
  symm
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y U : Scheme
f : X ⟶ Y
g : U ⟶ Y
hg : IsOpenImmersion g
V : Opens ↑↑Y.toPresheafedSpace := Scheme.Hom.opensRange g
e : U ≅ Y ∣_ᵤ V :=
  IsOpenImmersion.isoOfRangeEq g (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V)))
    (_ : Set.range ⇑g.val.base = Set.range Subtype.val)
t : pullback f g ⟶ pullback f (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V))) :=
  pullback.map f g f (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V))) (𝟙 X) e.hom (𝟙 Y)
    (_ : f ≫ 𝟙 Y = 𝟙 X ≫ f) (_ : g ≫ 𝟙 Y = e.hom ≫ Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V)))
⊢ Arrow.mk pullback.snd ≅ Arrow.mk (f ∣_ Scheme.Hom.opensRange g)

Next tactic:
refine' Arrow.isoMk (asIso t ≪≫ pullbackRestrictIsoRestrict f V) e _
/-- Restricting a morphism onto the image of an open immersion is isomorphic to the base change
along the immersion. -/
def morphismRestrictOpensRange {X Y U : Scheme} (f : X ⟶ Y) (g : U ⟶ Y) [hg : IsOpenImmersion g] :
    Arrow.mk (f ∣_ Scheme.Hom.opensRange g) ≅ Arrow.mk (pullback.snd : pullback f g ⟶ _) := by
  let V : Opens Y := Scheme.Hom.opensRange g
  let e :=
    IsOpenImmersion.isoOfRangeEq g (Y.ofRestrict V.openEmbedding) Subtype.range_coe.symm
  let t : pullback f g ⟶ pullback f (Y.ofRestrict V.openEmbedding) :=
    pullback.map _ _ _ _ (𝟙 _) e.hom (𝟙 _) (by rw [Category.comp_id, Category.id_comp])
      (by rw [Category.comp_id, IsOpenImmersion.isoOfRangeEq_hom_fac])
  symm
  refine' Arrow.isoMk (asIso t ≪≫ pullbackRestrictIsoRestrict f V) e _
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y U : Scheme
f : X ⟶ Y
g : U ⟶ Y
hg : IsOpenImmersion g
V : Opens ↑↑Y.toPresheafedSpace := Scheme.Hom.opensRange g
e : U ≅ Y ∣_ᵤ V :=
  IsOpenImmersion.isoOfRangeEq g (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V)))
    (_ : Set.range ⇑g.val.base = Set.range Subtype.val)
t : pullback f g ⟶ pullback f (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V))) :=
  pullback.map f g f (Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V))) (𝟙 X) e.hom (𝟙 Y)
    (_ : f ≫ 𝟙 Y = 𝟙 X ≫ f) (_ : g ≫ 𝟙 Y = e.hom ≫ Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion V)))
⊢ (asIso t ≪≫ pullbackRestrictIsoRestrict f V).hom ≫ (Arrow.mk (f ∣_ Scheme.Hom.opensRange g)).hom =
    (Arrow.mk pullback.snd).hom ≫ e.hom

Next tactic:
rw [Iso.trans_hom, asIso_hom, ← Iso.comp_inv_eq, ← cancel_mono g, Arrow.mk_hom, Arrow.mk_hom,
    Category.assoc, Category.assoc, Category.assoc, IsOpenImmersion.isoOfRangeEq_inv_fac,
    ← pullback.condition, morphismRestrict_ι,
    pullbackRestrictIsoRestrict_hom_restrict_assoc, pullback.lift_fst_assoc, Category.comp_id]
/-- The restrictions onto two equal open sets are isomorphic. This currently has bad defeqs when
unfolded, but it should not matter for now. Replace this definition if better defeqs are needed. -/
def morphismRestrictEq {X Y : Scheme} (f : X ⟶ Y) {U V : Opens Y} (e : U = V) :
    Arrow.mk (f ∣_ U) ≅ Arrow.mk (f ∣_ V) :=
  eqToIso (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U V : Opens ↑↑Y.toPresheafedSpace
e : U = V
⊢ Arrow.mk (f ∣_ U) = Arrow.mk (f ∣_ V)

Next tactic:
subst e
/-- The restrictions onto two equal open sets are isomorphic. This currently has bad defeqs when
unfolded, but it should not matter for now. Replace this definition if better defeqs are needed. -/
def morphismRestrictEq {X Y : Scheme} (f : X ⟶ Y) {U V : Opens Y} (e : U = V) :
    Arrow.mk (f ∣_ U) ≅ Arrow.mk (f ∣_ V) :=
  eqToIso (by subst e; 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
⊢ Arrow.mk (f ∣_ U) = Arrow.mk (f ∣_ U)

Next tactic:
rfl
/-- Restricting a morphism twice is isomorphic to one restriction. -/
def morphismRestrictRestrict {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (V : Opens (Y ∣_ᵤ U)) :
    Arrow.mk (f ∣_ U ∣_ V) ≅ Arrow.mk (f ∣_ U.openEmbedding.isOpenMap.functor.obj V) := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
⊢ Arrow.mk (f ∣_ U ∣_ V) ≅ Arrow.mk (f ∣_ (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj V)

Next tactic:
refine Arrow.isoMk' _ _ (Scheme.restrictRestrict _ _ _ ≪≫ Scheme.restrictIsoOfEq _ ?_)
    (Scheme.restrictRestrict _ _ _) ?_
/-- Restricting a morphism twice is isomorphic to one restriction. -/
def morphismRestrictRestrict {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (V : Opens (Y ∣_ᵤ U)) :
    Arrow.mk (f ∣_ U ∣_ V) ≅ Arrow.mk (f ∣_ U.openEmbedding.isOpenMap.functor.obj V) := by
  refine Arrow.isoMk' _ _ (Scheme.restrictRestrict _ _ _ ≪≫ Scheme.restrictIsoOfEq _ ?_)
    (Scheme.restrictRestrict _ _ _) ?_
  · 

Proof state:
case refine_1
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
⊢ (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion (f⁻¹ᵁ U)))).obj ((f ∣_ U)⁻¹ᵁ V) =
    f⁻¹ᵁ (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj V

Next tactic:
ext x
/-- Restricting a morphism twice is isomorphic to one restriction. -/
def morphismRestrictRestrict {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (V : Opens (Y ∣_ᵤ U)) :
    Arrow.mk (f ∣_ U ∣_ V) ≅ Arrow.mk (f ∣_ U.openEmbedding.isOpenMap.functor.obj V) := by
  refine Arrow.isoMk' _ _ (Scheme.restrictRestrict _ _ _ ≪≫ Scheme.restrictIsoOfEq _ ?_)
    (Scheme.restrictRestrict _ _ _) ?_
  · ext x
    

Proof state:
case refine_1.h.h
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
x : ↑↑X.toPresheafedSpace
⊢ x ∈ ↑((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion (f⁻¹ᵁ U)))).obj ((f ∣_ U)⁻¹ᵁ V)) ↔
    x ∈ ↑(f⁻¹ᵁ (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj V)

Next tactic:
simp only [IsOpenMap.functor_obj_coe, Opens.coe_inclusion,
      Opens.map_coe, Set.mem_image, Set.mem_preimage, SetLike.mem_coe, morphismRestrict_val_base]
/-- Restricting a morphism twice is isomorphic to one restriction. -/
def morphismRestrictRestrict {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (V : Opens (Y ∣_ᵤ U)) :
    Arrow.mk (f ∣_ U ∣_ V) ≅ Arrow.mk (f ∣_ U.openEmbedding.isOpenMap.functor.obj V) := by
  refine Arrow.isoMk' _ _ (Scheme.restrictRestrict _ _ _ ≪≫ Scheme.restrictIsoOfEq _ ?_)
    (Scheme.restrictRestrict _ _ _) ?_
  · ext x
    simp only [IsOpenMap.functor_obj_coe, Opens.coe_inclusion,
      Opens.map_coe, Set.mem_image, Set.mem_preimage, SetLike.mem_coe, morphismRestrict_val_base]
    

Proof state:
case refine_1.h.h
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
x : ↑↑X.toPresheafedSpace
⊢ (∃ x_1, Set.restrictPreimage U.carrier (⇑f.val.base) x_1 ∈ V ∧ ↑x_1 = x) ↔ ∃ x_1 ∈ V, ↑x_1 = f.val.base x

Next tactic:
constructor
/-- Restricting a morphism twice is isomorphic to one restriction. -/
def morphismRestrictRestrict {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (V : Opens (Y ∣_ᵤ U)) :
    Arrow.mk (f ∣_ U ∣_ V) ≅ Arrow.mk (f ∣_ U.openEmbedding.isOpenMap.functor.obj V) := by
  refine Arrow.isoMk' _ _ (Scheme.restrictRestrict _ _ _ ≪≫ Scheme.restrictIsoOfEq _ ?_)
    (Scheme.restrictRestrict _ _ _) ?_
  · ext x
    simp only [IsOpenMap.functor_obj_coe, Opens.coe_inclusion,
      Opens.map_coe, Set.mem_image, Set.mem_preimage, SetLike.mem_coe, morphismRestrict_val_base]
    constructor
    · 

Proof state:
case refine_1.h.h.mp
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
x : ↑↑X.toPresheafedSpace
⊢ (∃ x_1, Set.restrictPreimage U.carrier (⇑f.val.base) x_1 ∈ V ∧ ↑x_1 = x) → ∃ x_1 ∈ V, ↑x_1 = f.val.base x

Next tactic:
rintro ⟨⟨a, h₁⟩, h₂, rfl⟩
/-- Restricting a morphism twice is isomorphic to one restriction. -/
def morphismRestrictRestrict {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (V : Opens (Y ∣_ᵤ U)) :
    Arrow.mk (f ∣_ U ∣_ V) ≅ Arrow.mk (f ∣_ U.openEmbedding.isOpenMap.functor.obj V) := by
  refine Arrow.isoMk' _ _ (Scheme.restrictRestrict _ _ _ ≪≫ Scheme.restrictIsoOfEq _ ?_)
    (Scheme.restrictRestrict _ _ _) ?_
  · ext x
    simp only [IsOpenMap.functor_obj_coe, Opens.coe_inclusion,
      Opens.map_coe, Set.mem_image, Set.mem_preimage, SetLike.mem_coe, morphismRestrict_val_base]
    constructor
    · rintro ⟨⟨a, h₁⟩, h₂, rfl⟩
      

Proof state:
case refine_1.h.h.mp.intro.mk.intro
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
a : ↑↑X.toPresheafedSpace
h₁ : a ∈ f⁻¹ᵁ U
h₂ : Set.restrictPreimage U.carrier ⇑f.val.base { val := a, property := h₁ } ∈ V
⊢ ∃ x ∈ V, ↑x = f.val.base ↑{ val := a, property := h₁ }

Next tactic:
exact ⟨_, h₂, rfl⟩
/-- Restricting a morphism twice is isomorphic to one restriction. -/
def morphismRestrictRestrict {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (V : Opens (Y ∣_ᵤ U)) :
    Arrow.mk (f ∣_ U ∣_ V) ≅ Arrow.mk (f ∣_ U.openEmbedding.isOpenMap.functor.obj V) := by
  refine Arrow.isoMk' _ _ (Scheme.restrictRestrict _ _ _ ≪≫ Scheme.restrictIsoOfEq _ ?_)
    (Scheme.restrictRestrict _ _ _) ?_
  · ext x
    simp only [IsOpenMap.functor_obj_coe, Opens.coe_inclusion,
      Opens.map_coe, Set.mem_image, Set.mem_preimage, SetLike.mem_coe, morphismRestrict_val_base]
    constructor
    · rintro ⟨⟨a, h₁⟩, h₂, rfl⟩
      exact ⟨_, h₂, rfl⟩
    · 

Proof state:
case refine_1.h.h.mpr
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
x : ↑↑X.toPresheafedSpace
⊢ (∃ x_1 ∈ V, ↑x_1 = f.val.base x) → ∃ x_1, Set.restrictPreimage U.carrier (⇑f.val.base) x_1 ∈ V ∧ ↑x_1 = x

Next tactic:
rintro ⟨⟨a, h₁⟩, h₂, rfl : a = _⟩
/-- Restricting a morphism twice is isomorphic to one restriction. -/
def morphismRestrictRestrict {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (V : Opens (Y ∣_ᵤ U)) :
    Arrow.mk (f ∣_ U ∣_ V) ≅ Arrow.mk (f ∣_ U.openEmbedding.isOpenMap.functor.obj V) := by
  refine Arrow.isoMk' _ _ (Scheme.restrictRestrict _ _ _ ≪≫ Scheme.restrictIsoOfEq _ ?_)
    (Scheme.restrictRestrict _ _ _) ?_
  · ext x
    simp only [IsOpenMap.functor_obj_coe, Opens.coe_inclusion,
      Opens.map_coe, Set.mem_image, Set.mem_preimage, SetLike.mem_coe, morphismRestrict_val_base]
    constructor
    · rintro ⟨⟨a, h₁⟩, h₂, rfl⟩
      exact ⟨_, h₂, rfl⟩
    · rintro ⟨⟨a, h₁⟩, h₂, rfl : a = _⟩
      

Proof state:
case refine_1.h.h.mpr.intro.mk.intro
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
x : ↑↑X.toPresheafedSpace
h₁ : f.val.base x ∈ U
h₂ : { val := f.val.base x, property := h₁ } ∈ V
⊢ ∃ x_1, Set.restrictPreimage U.carrier (⇑f.val.base) x_1 ∈ V ∧ ↑x_1 = x

Next tactic:
exact ⟨⟨x, h₁⟩, h₂, rfl⟩
/-- Restricting a morphism twice is isomorphic to one restriction. -/
def morphismRestrictRestrict {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (V : Opens (Y ∣_ᵤ U)) :
    Arrow.mk (f ∣_ U ∣_ V) ≅ Arrow.mk (f ∣_ U.openEmbedding.isOpenMap.functor.obj V) := by
  refine Arrow.isoMk' _ _ (Scheme.restrictRestrict _ _ _ ≪≫ Scheme.restrictIsoOfEq _ ?_)
    (Scheme.restrictRestrict _ _ _) ?_
  · ext x
    simp only [IsOpenMap.functor_obj_coe, Opens.coe_inclusion,
      Opens.map_coe, Set.mem_image, Set.mem_preimage, SetLike.mem_coe, morphismRestrict_val_base]
    constructor
    · rintro ⟨⟨a, h₁⟩, h₂, rfl⟩
      exact ⟨_, h₂, rfl⟩
    · rintro ⟨⟨a, h₁⟩, h₂, rfl : a = _⟩
      exact ⟨⟨x, h₁⟩, h₂, rfl⟩
  · 

Proof state:
case refine_2
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
⊢ (Scheme.restrictRestrict X (f⁻¹ᵁ U) ((f ∣_ U)⁻¹ᵁ V) ≪≫
          Scheme.restrictIsoOfEq X
            (_ :
              (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion (f⁻¹ᵁ U)))).obj ((f ∣_ U)⁻¹ᵁ V) =
                f⁻¹ᵁ (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj V)).hom ≫
      f ∣_ (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj V =
    f ∣_ U ∣_ V ≫ (Scheme.restrictRestrict Y U V).hom

Next tactic:
rw [← cancel_mono (Scheme.ιOpens _), Iso.trans_hom, Category.assoc, Category.assoc,
      Category.assoc, morphismRestrict_ι, Scheme.restrictIsoOfEq,
      IsOpenImmersion.isoOfRangeEq_hom_fac_assoc,
      Scheme.restrictRestrict_hom_restrict_assoc,
      Scheme.restrictRestrict_hom_restrict,
      morphismRestrict_ι_assoc, morphismRestrict_ι]
/-- Restricting a morphism twice onto a basic open set is isomorphic to one restriction.  -/
def morphismRestrictRestrictBasicOpen {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y)
    (r : Y.presheaf.obj (op U)) :
    Arrow.mk
        (f ∣_ U ∣_
          (Y ∣_ᵤ U).basicOpen (Y.presheaf.map (eqToHom U.openEmbedding_obj_top).op r)) ≅
      Arrow.mk (f ∣_ Y.basicOpen r) := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
r : ↑(Y.presheaf.obj (op U))
⊢ Arrow.mk
      (f ∣_ U ∣_
        (Y ∣_ᵤ U).basicOpen
          ((Y.presheaf.map (eqToHom (_ : (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj ⊤ = U)).op) r)) ≅
    Arrow.mk (f ∣_ Y.basicOpen r)

Next tactic:
refine' morphismRestrictRestrict _ _ _ ≪≫ morphismRestrictEq _ _
/-- Restricting a morphism twice onto a basic open set is isomorphic to one restriction.  -/
def morphismRestrictRestrictBasicOpen {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y)
    (r : Y.presheaf.obj (op U)) :
    Arrow.mk
        (f ∣_ U ∣_
          (Y ∣_ᵤ U).basicOpen (Y.presheaf.map (eqToHom U.openEmbedding_obj_top).op r)) ≅
      Arrow.mk (f ∣_ Y.basicOpen r) := by
  refine' morphismRestrictRestrict _ _ _ ≪≫ morphismRestrictEq _ _
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
r : ↑(Y.presheaf.obj (op U))
⊢ (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj
      ((Y ∣_ᵤ U).basicOpen
        ((Y.presheaf.map (eqToHom (_ : (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj ⊤ = U)).op) r)) =
    Y.basicOpen r

Next tactic:
have e := Scheme.preimage_basicOpen (Y.ofRestrict U.openEmbedding) r
/-- Restricting a morphism twice onto a basic open set is isomorphic to one restriction.  -/
def morphismRestrictRestrictBasicOpen {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y)
    (r : Y.presheaf.obj (op U)) :
    Arrow.mk
        (f ∣_ U ∣_
          (Y ∣_ᵤ U).basicOpen (Y.presheaf.map (eqToHom U.openEmbedding_obj_top).op r)) ≅
      Arrow.mk (f ∣_ Y.basicOpen r) := by
  refine' morphismRestrictRestrict _ _ _ ≪≫ morphismRestrictEq _ _
  have e := Scheme.preimage_basicOpen (Y.ofRestrict U.openEmbedding) r
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
r : ↑(Y.presheaf.obj (op U))
e :
  Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion U))⁻¹ᵁ Y.basicOpen r =
    (Y ∣_ᵤ U).basicOpen (((Scheme.ofRestrict Y (_ : OpenEmbedding ⇑(Opens.inclusion U))).val.c.app (op U)) r)
⊢ (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj
      ((Y ∣_ᵤ U).basicOpen
        ((Y.presheaf.map (eqToHom (_ : (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj ⊤ = U)).op) r)) =
    Y.basicOpen r

Next tactic:
erw [Scheme.ofRestrict_val_c_app, Opens.adjunction_counit_app_self, eqToHom_op] at e