l3lab/ntp-mathlib huggingface dataset:
@[reassoc]
theorem Scheme.restrictFunctor_map_ofRestrict {U V : Opens X} (i : U ⟶ V) :
    (X.restrictFunctor.map i).1 ≫ ιOpens V = ιOpens U :=
  IsOpenImmersion.lift_fac _ _ (by
    dsimp [restrict, ofRestrict, LocallyRingedSpace.ofRestrict]
    rw [Subtype.range_val, Subtype.range_val]
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
⊢ ↑U ⊆ ↑V

Next tactic:
exact i.le
theorem Scheme.restrictFunctor_map_base {U V : Opens X} (i : U ⟶ V) :
    (X.restrictFunctor.map i).1.1.base = (Opens.toTopCat _).map i := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
⊢ ((restrictFunctor X).map i).left.val.base = (Opens.toTopCat ↑X.toPresheafedSpace).map i

Next tactic:
ext a
theorem Scheme.restrictFunctor_map_base {U V : Opens X} (i : U ⟶ V) :
    (X.restrictFunctor.map i).1.1.base = (Opens.toTopCat _).map i := by
  ext a; 

Proof state:
case w
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
a : (forget TopCat).obj ↑((restrictFunctor X).obj U).left.toPresheafedSpace
⊢ ((restrictFunctor X).map i).left.val.base a = ((Opens.toTopCat ↑X.toPresheafedSpace).map i) a

Next tactic:
refine Subtype.ext ?_
theorem Scheme.restrictFunctor_map_base {U V : Opens X} (i : U ⟶ V) :
    (X.restrictFunctor.map i).1.1.base = (Opens.toTopCat _).map i := by
  ext a; refine Subtype.ext ?_ -- Porting note : `ext` did not pick up `Subtype.ext`
  

Proof state:
case w
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
a : (forget TopCat).obj ↑((restrictFunctor X).obj U).left.toPresheafedSpace
⊢ ↑(((restrictFunctor X).map i).left.val.base a) = ↑(((Opens.toTopCat ↑X.toPresheafedSpace).map i) a)

Next tactic:
exact (congr_arg (fun f : X.restrict U.openEmbedding ⟶ X => f.1.base a)
        (X.restrictFunctor_map_ofRestrict i))
theorem Scheme.restrictFunctor_map_app_aux {U V : Opens X} (i : U ⟶ V) (W : Opens V) :
    U.openEmbedding.isOpenMap.functor.obj ((X.restrictFunctor.map i).1 ⁻¹ᵁ W) ≤
      V.openEmbedding.isOpenMap.functor.obj W := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
W : Opens ↥V
⊢ (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj (((restrictFunctor X).map i).left⁻¹ᵁ W) ≤
    (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W

Next tactic:
simp only [← SetLike.coe_subset_coe, IsOpenMap.functor_obj_coe, Set.image_subset_iff,
    Scheme.restrictFunctor_map_base, Opens.map_coe, Opens.inclusion_apply]
theorem Scheme.restrictFunctor_map_app_aux {U V : Opens X} (i : U ⟶ V) (W : Opens V) :
    U.openEmbedding.isOpenMap.functor.obj ((X.restrictFunctor.map i).1 ⁻¹ᵁ W) ≤
      V.openEmbedding.isOpenMap.functor.obj W := by
  simp only [← SetLike.coe_subset_coe, IsOpenMap.functor_obj_coe, Set.image_subset_iff,
    Scheme.restrictFunctor_map_base, Opens.map_coe, Opens.inclusion_apply]
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
W : Opens ↥V
⊢ ⇑((Opens.toTopCat ↑X.toPresheafedSpace).map i) ⁻¹' ↑W ⊆ ⇑(Opens.inclusion U) ⁻¹' (⇑(Opens.inclusion V) '' ↑W)

Next tactic:
rintro _ h
theorem Scheme.restrictFunctor_map_app_aux {U V : Opens X} (i : U ⟶ V) (W : Opens V) :
    U.openEmbedding.isOpenMap.functor.obj ((X.restrictFunctor.map i).1 ⁻¹ᵁ W) ≤
      V.openEmbedding.isOpenMap.functor.obj W := by
  simp only [← SetLike.coe_subset_coe, IsOpenMap.functor_obj_coe, Set.image_subset_iff,
    Scheme.restrictFunctor_map_base, Opens.map_coe, Opens.inclusion_apply]
  rintro _ h
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
W : Opens ↥V
a✝ : (forget TopCat).obj ((Opens.toTopCat ↑X.toPresheafedSpace).obj U)
h : a✝ ∈ ⇑((Opens.toTopCat ↑X.toPresheafedSpace).map i) ⁻¹' ↑W
⊢ a✝ ∈ ⇑(Opens.inclusion U) ⁻¹' (⇑(Opens.inclusion V) '' ↑W)

Next tactic:
exact ⟨_, h, rfl⟩
theorem Scheme.restrictFunctor_map_app {U V : Opens X} (i : U ⟶ V) (W : Opens V) :
    (X.restrictFunctor.map i).1.1.c.app (op W) =
      X.presheaf.map (homOfLE <| X.restrictFunctor_map_app_aux i W).op := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
W : Opens ↥V
⊢ ((restrictFunctor X).map i).left.val.c.app (op W) =
    X.presheaf.map
      (homOfLE
          (_ :
            (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj (((restrictFunctor X).map i).left⁻¹ᵁ W) ≤
              (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)).op

Next tactic:
have e₁ :=
    Scheme.congr_app (X.restrictFunctor_map_ofRestrict i)
      (op <| V.openEmbedding.isOpenMap.functor.obj W)
theorem Scheme.restrictFunctor_map_app {U V : Opens X} (i : U ⟶ V) (W : Opens V) :
    (X.restrictFunctor.map i).1.1.c.app (op W) =
      X.presheaf.map (homOfLE <| X.restrictFunctor_map_app_aux i W).op := by
  have e₁ :=
    Scheme.congr_app (X.restrictFunctor_map_ofRestrict i)
      (op <| V.openEmbedding.isOpenMap.functor.obj W)
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
W : Opens ↥V
e₁ :
  (((restrictFunctor X).map i).left ≫ ιOpens V).val.c.app
      (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) =
    (ιOpens U).val.c.app (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) ≫
      ((restrictFunctor X).obj U).left.presheaf.map
        (eqToHom
          (_ :
            (Opens.map (ιOpens U).val.base).op.obj
                (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) =
              (Opens.map (((restrictFunctor X).map i).left ≫ ιOpens V).val.base).op.obj
                (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W))))
⊢ ((restrictFunctor X).map i).left.val.c.app (op W) =
    X.presheaf.map
      (homOfLE
          (_ :
            (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj (((restrictFunctor X).map i).left⁻¹ᵁ W) ≤
              (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)).op

Next tactic:
rw [Scheme.comp_val_c_app] at e₁
theorem Scheme.restrictFunctor_map_app {U V : Opens X} (i : U ⟶ V) (W : Opens V) :
    (X.restrictFunctor.map i).1.1.c.app (op W) =
      X.presheaf.map (homOfLE <| X.restrictFunctor_map_app_aux i W).op := by
  have e₁ :=
    Scheme.congr_app (X.restrictFunctor_map_ofRestrict i)
      (op <| V.openEmbedding.isOpenMap.functor.obj W)
  rw [Scheme.comp_val_c_app] at e₁
  -- Porting note : `Opens.map_functor_eq` need more help
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
W : Opens ↥V
e₁ :
  (ιOpens V).val.c.app (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) ≫
      ((restrictFunctor X).map i).left.val.c.app
        ((Opens.map (ιOpens V).val.base).op.obj (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W))) =
    (ιOpens U).val.c.app (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) ≫
      ((restrictFunctor X).obj U).left.presheaf.map
        (eqToHom
          (_ :
            (Opens.map (ιOpens U).val.base).op.obj
                (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) =
              (Opens.map (((restrictFunctor X).map i).left ≫ ιOpens V).val.base).op.obj
                (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W))))
⊢ ((restrictFunctor X).map i).left.val.c.app (op W) =
    X.presheaf.map
      (homOfLE
          (_ :
            (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj (((restrictFunctor X).map i).left⁻¹ᵁ W) ≤
              (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)).op

Next tactic:
have e₂ := (X.restrictFunctor.map i).1.val.c.naturality (eqToHom <| W.map_functor_eq (U := V)).op
theorem Scheme.restrictFunctor_map_app {U V : Opens X} (i : U ⟶ V) (W : Opens V) :
    (X.restrictFunctor.map i).1.1.c.app (op W) =
      X.presheaf.map (homOfLE <| X.restrictFunctor_map_app_aux i W).op := by
  have e₁ :=
    Scheme.congr_app (X.restrictFunctor_map_ofRestrict i)
      (op <| V.openEmbedding.isOpenMap.functor.obj W)
  rw [Scheme.comp_val_c_app] at e₁
  -- Porting note : `Opens.map_functor_eq` need more help
  have e₂ := (X.restrictFunctor.map i).1.val.c.naturality (eqToHom <| W.map_functor_eq (U := V)).op
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
W : Opens ↥V
e₁ :
  (ιOpens V).val.c.app (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) ≫
      ((restrictFunctor X).map i).left.val.c.app
        ((Opens.map (ιOpens V).val.base).op.obj (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W))) =
    (ιOpens U).val.c.app (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) ≫
      ((restrictFunctor X).obj U).left.presheaf.map
        (eqToHom
          (_ :
            (Opens.map (ιOpens U).val.base).op.obj
                (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) =
              (Opens.map (((restrictFunctor X).map i).left ≫ ιOpens V).val.base).op.obj
                (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W))))
e₂ :
  ((restrictFunctor X).obj V).left.presheaf.map
        (eqToHom
            (_ :
              (Opens.map (Opens.inclusion V)).obj ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W) =
                W)).op ≫
      ((restrictFunctor X).map i).left.val.c.app
        (op ((Opens.map (Opens.inclusion V)).obj ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W))) =
    ((restrictFunctor X).map i).left.val.c.app (op W) ≫
      (((restrictFunctor X).map i).left.val.base _* ((restrictFunctor X).obj U).left.presheaf).map
        (eqToHom
            (_ :
              (Opens.map (Opens.inclusion V)).obj ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W) =
                W)).op
⊢ ((restrictFunctor X).map i).left.val.c.app (op W) =
    X.presheaf.map
      (homOfLE
          (_ :
            (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj (((restrictFunctor X).map i).left⁻¹ᵁ W) ≤
              (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)).op

Next tactic:
rw [← IsIso.eq_inv_comp] at e₂
theorem Scheme.restrictFunctor_map_app {U V : Opens X} (i : U ⟶ V) (W : Opens V) :
    (X.restrictFunctor.map i).1.1.c.app (op W) =
      X.presheaf.map (homOfLE <| X.restrictFunctor_map_app_aux i W).op := by
  have e₁ :=
    Scheme.congr_app (X.restrictFunctor_map_ofRestrict i)
      (op <| V.openEmbedding.isOpenMap.functor.obj W)
  rw [Scheme.comp_val_c_app] at e₁
  -- Porting note : `Opens.map_functor_eq` need more help
  have e₂ := (X.restrictFunctor.map i).1.val.c.naturality (eqToHom <| W.map_functor_eq (U := V)).op
  rw [← IsIso.eq_inv_comp] at e₂
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
i : U ⟶ V
W : Opens ↥V
e₁ :
  (ιOpens V).val.c.app (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) ≫
      ((restrictFunctor X).map i).left.val.c.app
        ((Opens.map (ιOpens V).val.base).op.obj (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W))) =
    (ιOpens U).val.c.app (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) ≫
      ((restrictFunctor X).obj U).left.presheaf.map
        (eqToHom
          (_ :
            (Opens.map (ιOpens U).val.base).op.obj
                (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)) =
              (Opens.map (((restrictFunctor X).map i).left ≫ ιOpens V).val.base).op.obj
                (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W))))
e₂ :
  ((restrictFunctor X).map i).left.val.c.app
      (op ((Opens.map (Opens.inclusion V)).obj ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W))) =
    inv
        (((restrictFunctor X).obj V).left.presheaf.map
          (eqToHom
              (_ :
                (Opens.map (Opens.inclusion V)).obj ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W) =
                  W)).op) ≫
      ((restrictFunctor X).map i).left.val.c.app (op W) ≫
        (((restrictFunctor X).map i).left.val.base _* ((restrictFunctor X).obj U).left.presheaf).map
          (eqToHom
              (_ :
                (Opens.map (Opens.inclusion V)).obj ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W) =
                  W)).op
⊢ ((restrictFunctor X).map i).left.val.c.app (op W) =
    X.presheaf.map
      (homOfLE
          (_ :
            (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj (((restrictFunctor X).map i).left⁻¹ᵁ W) ≤
              (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V))).obj W)).op

Next tactic:
dsimp [restrict] at e₁ e₂ ⊢
/-- The functor that restricts to open subschemes and then takes global section is
isomorphic to the structure sheaf. -/
@[simps!]
def Scheme.restrictFunctorΓ : X.restrictFunctor.op ⋙ (Over.forget X).op ⋙ Scheme.Γ ≅ X.presheaf :=
  NatIso.ofComponents
    (fun U => X.presheaf.mapIso ((eqToIso (unop U).openEmbedding_obj_top).symm.op : _))
    (by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
⊢ ∀ {X_1 Y : (Opens ↑↑X.toPresheafedSpace)ᵒᵖ} (f : X_1 ⟶ Y),
    ((restrictFunctor X).op ⋙ (Over.forget X).op ⋙ Γ).map f ≫
        ((fun U =>
              X.presheaf.mapIso
                (Iso.op
                  (eqToIso (_ : (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U.unop))).obj ⊤ = U.unop)).symm))
            Y).hom =
      ((fun U =>
              X.presheaf.mapIso
                (Iso.op
                  (eqToIso (_ : (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U.unop))).obj ⊤ = U.unop)).symm))
            X_1).hom ≫
        X.presheaf.map f

Next tactic:
intro U V i
/-- The functor that restricts to open subschemes and then takes global section is
isomorphic to the structure sheaf. -/
@[simps!]
def Scheme.restrictFunctorΓ : X.restrictFunctor.op ⋙ (Over.forget X).op ⋙ Scheme.Γ ≅ X.presheaf :=
  NatIso.ofComponents
    (fun U => X.presheaf.mapIso ((eqToIso (unop U).openEmbedding_obj_top).symm.op : _))
    (by
      intro U V i
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : (Opens ↑↑X.toPresheafedSpace)ᵒᵖ
i : U ⟶ V
⊢ ((restrictFunctor X).op ⋙ (Over.forget X).op ⋙ Γ).map i ≫
      ((fun U =>
            X.presheaf.mapIso
              (Iso.op
                (eqToIso (_ : (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U.unop))).obj ⊤ = U.unop)).symm))
          V).hom =
    ((fun U =>
            X.presheaf.mapIso
              (Iso.op
                (eqToIso (_ : (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U.unop))).obj ⊤ = U.unop)).symm))
          U).hom ≫
      X.presheaf.map i

Next tactic:
dsimp [-Scheme.restrictFunctor_map_left]
/-- The functor that restricts to open subschemes and then takes global section is
isomorphic to the structure sheaf. -/
@[simps!]
def Scheme.restrictFunctorΓ : X.restrictFunctor.op ⋙ (Over.forget X).op ⋙ Scheme.Γ ≅ X.presheaf :=
  NatIso.ofComponents
    (fun U => X.presheaf.mapIso ((eqToIso (unop U).openEmbedding_obj_top).symm.op : _))
    (by
      intro U V i
      dsimp [-Scheme.restrictFunctor_map_left]
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : (Opens ↑↑X.toPresheafedSpace)ᵒᵖ
i : U ⟶ V
⊢ ((restrictFunctor X).map i.unop).left.val.c.app (op ⊤) ≫
      X.presheaf.map (eqToHom (_ : V.unop = (IsOpenMap.functor (_ : IsOpenMap Subtype.val)).obj ⊤)).op =
    X.presheaf.map (eqToHom (_ : U.unop = (IsOpenMap.functor (_ : IsOpenMap Subtype.val)).obj ⊤)).op ≫ X.presheaf.map i

Next tactic:
rw [X.restrictFunctor_map_app, ← Functor.map_comp, ← Functor.map_comp]
/-- The functor that restricts to open subschemes and then takes global section is
isomorphic to the structure sheaf. -/
@[simps!]
def Scheme.restrictFunctorΓ : X.restrictFunctor.op ⋙ (Over.forget X).op ⋙ Scheme.Γ ≅ X.presheaf :=
  NatIso.ofComponents
    (fun U => X.presheaf.mapIso ((eqToIso (unop U).openEmbedding_obj_top).symm.op : _))
    (by
      intro U V i
      dsimp [-Scheme.restrictFunctor_map_left]
      rw [X.restrictFunctor_map_app, ← Functor.map_comp, ← Functor.map_comp]
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : Scheme
U V : (Opens ↑↑X.toPresheafedSpace)ᵒᵖ
i : U ⟶ V
⊢ X.presheaf.map
      ((homOfLE
            (_ :
              (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion V.unop))).obj
                  (((restrictFunctor X).map i.unop).left⁻¹ᵁ ⊤) ≤
                (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U.unop))).obj ⊤)).op ≫
        (eqToHom (_ : V.unop = (IsOpenMap.functor (_ : IsOpenMap Subtype.val)).obj ⊤)).op) =
    X.presheaf.map ((eqToHom (_ : U.unop = (IsOpenMap.functor (_ : IsOpenMap Subtype.val)).obj ⊤)).op ≫ i)

Next tactic:
congr 1
/-- `X ∣_ U ∣_ V` is isomorphic to `X ∣_ V ∣_ U` -/
noncomputable
def Scheme.restrictRestrictComm (X : Scheme) (U V : Opens X.carrier) :
    X ∣_ᵤ U ∣_ᵤ ιOpens U ⁻¹ᵁ V ≅ X ∣_ᵤ V ∣_ᵤ ιOpens V ⁻¹ᵁ U := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ : Scheme
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
⊢ X ∣_ᵤ U ∣_ᵤ ιOpens U⁻¹ᵁ V ≅ X ∣_ᵤ V ∣_ᵤ ιOpens V⁻¹ᵁ U

Next tactic:
refine IsOpenImmersion.isoOfRangeEq (ιOpens _ ≫ ιOpens U) (ιOpens _ ≫ ιOpens V) ?_
/-- `X ∣_ U ∣_ V` is isomorphic to `X ∣_ V ∣_ U` -/
noncomputable
def Scheme.restrictRestrictComm (X : Scheme) (U V : Opens X.carrier) :
    X ∣_ᵤ U ∣_ᵤ ιOpens U ⁻¹ᵁ V ≅ X ∣_ᵤ V ∣_ᵤ ιOpens V ⁻¹ᵁ U := by
  refine IsOpenImmersion.isoOfRangeEq (ιOpens _ ≫ ιOpens U) (ιOpens _ ≫ ιOpens V) ?_
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ : Scheme
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
⊢ Set.range ⇑(ιOpens (ιOpens U⁻¹ᵁ V) ≫ ιOpens U).val.base = Set.range ⇑(ιOpens (ιOpens V⁻¹ᵁ U) ≫ ιOpens V).val.base

Next tactic:
simp only [Scheme.restrict_carrier, Scheme.ofRestrict_val_base, Scheme.comp_coeBase,
    CategoryTheory.coe_comp, Opens.coe_inclusion, Set.range_comp, Opens.map]
/-- `X ∣_ U ∣_ V` is isomorphic to `X ∣_ V ∣_ U` -/
noncomputable
def Scheme.restrictRestrictComm (X : Scheme) (U V : Opens X.carrier) :
    X ∣_ᵤ U ∣_ᵤ ιOpens U ⁻¹ᵁ V ≅ X ∣_ᵤ V ∣_ᵤ ιOpens V ⁻¹ᵁ U := by
  refine IsOpenImmersion.isoOfRangeEq (ιOpens _ ≫ ιOpens U) (ιOpens _ ≫ ιOpens V) ?_
  simp only [Scheme.restrict_carrier, Scheme.ofRestrict_val_base, Scheme.comp_coeBase,
    CategoryTheory.coe_comp, Opens.coe_inclusion, Set.range_comp, Opens.map]
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ : Scheme
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
⊢ Subtype.val '' Set.range Subtype.val = Subtype.val '' Set.range Subtype.val

Next tactic:
rw [Subtype.range_val, Subtype.range_val]
/-- `X ∣_ U ∣_ V` is isomorphic to `X ∣_ V ∣_ U` -/
noncomputable
def Scheme.restrictRestrictComm (X : Scheme) (U V : Opens X.carrier) :
    X ∣_ᵤ U ∣_ᵤ ιOpens U ⁻¹ᵁ V ≅ X ∣_ᵤ V ∣_ᵤ ιOpens V ⁻¹ᵁ U := by
  refine IsOpenImmersion.isoOfRangeEq (ιOpens _ ≫ ιOpens U) (ιOpens _ ≫ ιOpens V) ?_
  simp only [Scheme.restrict_carrier, Scheme.ofRestrict_val_base, Scheme.comp_coeBase,
    CategoryTheory.coe_comp, Opens.coe_inclusion, Set.range_comp, Opens.map]
  rw [Subtype.range_val, Subtype.range_val]
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ : Scheme
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
⊢ Subtype.val '' ↑{ carrier := Subtype.val ⁻¹' ↑V, is_open' := (_ : IsOpen (⇑(Opens.inclusion U) ⁻¹' ↑V)) } =
    Subtype.val '' ↑{ carrier := Subtype.val ⁻¹' ↑U, is_open' := (_ : IsOpen (⇑(Opens.inclusion V) ⁻¹' ↑U)) }

Next tactic:
dsimp
/-- `X ∣_ U ∣_ V` is isomorphic to `X ∣_ V ∣_ U` -/
noncomputable
def Scheme.restrictRestrictComm (X : Scheme) (U V : Opens X.carrier) :
    X ∣_ᵤ U ∣_ᵤ ιOpens U ⁻¹ᵁ V ≅ X ∣_ᵤ V ∣_ᵤ ιOpens V ⁻¹ᵁ U := by
  refine IsOpenImmersion.isoOfRangeEq (ιOpens _ ≫ ιOpens U) (ιOpens _ ≫ ιOpens V) ?_
  simp only [Scheme.restrict_carrier, Scheme.ofRestrict_val_base, Scheme.comp_coeBase,
    CategoryTheory.coe_comp, Opens.coe_inclusion, Set.range_comp, Opens.map]
  rw [Subtype.range_val, Subtype.range_val]
  dsimp
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ : Scheme
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
⊢ Subtype.val '' (Subtype.val ⁻¹' ↑V) = Subtype.val '' (Subtype.val ⁻¹' ↑U)

Next tactic:
rw [Set.image_preimage_eq_inter_range, Set.image_preimage_eq_inter_range,
    Subtype.range_val, Subtype.range_val, Set.inter_comm]
/-- If `V` is an open subset of `U`, then `X ∣_ U ∣_ V` is isomorphic to `X ∣_ V`. -/
noncomputable
def Scheme.restrictRestrict (X : Scheme) (U : Opens X.carrier) (V : Opens (X ∣_ᵤ U).carrier) :
    X ∣_ᵤ U ∣_ᵤ V ≅ X ∣_ᵤ U.openEmbedding.isOpenMap.functor.obj V := by
  

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

Next tactic:
refine IsOpenImmersion.isoOfRangeEq (ιOpens _ ≫ ιOpens U) (ιOpens _) ?_
/-- If `V` is an open subset of `U`, then `X ∣_ U ∣_ V` is isomorphic to `X ∣_ V`. -/
noncomputable
def Scheme.restrictRestrict (X : Scheme) (U : Opens X.carrier) (V : Opens (X ∣_ᵤ U).carrier) :
    X ∣_ᵤ U ∣_ᵤ V ≅ X ∣_ᵤ U.openEmbedding.isOpenMap.functor.obj V := by
  refine IsOpenImmersion.isoOfRangeEq (ιOpens _ ≫ ιOpens U) (ιOpens _) ?_
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ : Scheme
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
V : Opens ↑↑(X ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
⊢ Set.range ⇑(ιOpens V ≫ ιOpens U).val.base =
    Set.range ⇑(ιOpens ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj V)).val.base

Next tactic:
simp only [Scheme.restrict_carrier, Scheme.ofRestrict_val_base, Scheme.comp_coeBase,
    CategoryTheory.coe_comp, Opens.coe_inclusion, Set.range_comp, Opens.map]
/-- If `V` is an open subset of `U`, then `X ∣_ U ∣_ V` is isomorphic to `X ∣_ V`. -/
noncomputable
def Scheme.restrictRestrict (X : Scheme) (U : Opens X.carrier) (V : Opens (X ∣_ᵤ U).carrier) :
    X ∣_ᵤ U ∣_ᵤ V ≅ X ∣_ᵤ U.openEmbedding.isOpenMap.functor.obj V := by
  refine IsOpenImmersion.isoOfRangeEq (ιOpens _ ≫ ιOpens U) (ιOpens _) ?_
  simp only [Scheme.restrict_carrier, Scheme.ofRestrict_val_base, Scheme.comp_coeBase,
    CategoryTheory.coe_comp, Opens.coe_inclusion, Set.range_comp, Opens.map]
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ : Scheme
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
V : Opens ↑↑(X ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
⊢ Subtype.val '' Set.range Subtype.val = Set.range Subtype.val

Next tactic:
rw [Subtype.range_val, Subtype.range_val]
/-- If `V` is an open subset of `U`, then `X ∣_ U ∣_ V` is isomorphic to `X ∣_ V`. -/
noncomputable
def Scheme.restrictRestrict (X : Scheme) (U : Opens X.carrier) (V : Opens (X ∣_ᵤ U).carrier) :
    X ∣_ᵤ U ∣_ᵤ V ≅ X ∣_ᵤ U.openEmbedding.isOpenMap.functor.obj V := by
  refine IsOpenImmersion.isoOfRangeEq (ιOpens _ ≫ ιOpens U) (ιOpens _) ?_
  simp only [Scheme.restrict_carrier, Scheme.ofRestrict_val_base, Scheme.comp_coeBase,
    CategoryTheory.coe_comp, Opens.coe_inclusion, Set.range_comp, Opens.map]
  rw [Subtype.range_val, Subtype.range_val]
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ : Scheme
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
V : Opens ↑↑(X ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
⊢ Subtype.val '' ↑V = ↑((IsOpenMap.functor (_ : IsOpenMap Subtype.val)).obj V)

Next tactic:
rfl
/-- If `U = V`, then `X ∣_ U` is isomorphic to `X ∣_ V`. -/
noncomputable
def Scheme.restrictIsoOfEq (X : Scheme) {U V : Opens X.carrier} (e : U = V) :
    X ∣_ᵤ U ≅ X ∣_ᵤ V := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ : Scheme
X : Scheme
U V : Opens ↑↑X.toPresheafedSpace
e : U = V
⊢ X ∣_ᵤ U ≅ X ∣_ᵤ V

Next tactic:
exact IsOpenImmersion.isoOfRangeEq (ιOpens U) (ιOpens V) (by rw [e])