l3lab/ntp-mathlib huggingface dataset:
/-- If `X ⟶ Y` is an open immersion, and `Y` is a scheme, then so is `X`. -/
def toScheme : Scheme := by
  apply LocallyRingedSpace.IsOpenImmersion.scheme (toLocallyRingedSpace _ f)
  intro x
  obtain ⟨_, ⟨i, rfl⟩, hx, hi⟩ :=
    Y.affineBasisCover_is_basis.exists_subset_of_mem_open (Set.mem_range_self x)
      H.base_open.open_range
  use Y.affineBasisCoverRing i
  use LocallyRingedSpace.IsOpenImmersion.lift (toLocallyRingedSpaceHom _ f) _ hi
  constructor
  · rw [LocallyRingedSpace.IsOpenImmersion.lift_range]; exact hx
  · 

Proof state:
case h.right
C : Type u
inst✝ : Category.{v, u} C
X : PresheafedSpace CommRingCat
Y : Scheme
f : X ⟶ Y.toPresheafedSpace
H : IsOpenImmersion f
x : ↑(LocallyRingedSpace.toTopCat (toLocallyRingedSpace Y.toLocallyRingedSpace f))
i : (Scheme.affineBasisCover Y).J
hx : f.base x ∈ Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover Y) i).val.base
hi : Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover Y) i).val.base ⊆ Set.range ⇑f.base
⊢ LocallyRingedSpace.IsOpenImmersion
    (LocallyRingedSpace.IsOpenImmersion.lift (toLocallyRingedSpaceHom Y.toLocallyRingedSpace f)
      (Scheme.OpenCover.map (Scheme.affineBasisCover Y) i) hi)

Next tactic:
delta LocallyRingedSpace.IsOpenImmersion.lift
/-- If `X ⟶ Y` is an open immersion, and `Y` is a scheme, then so is `X`. -/
def toScheme : Scheme := by
  apply LocallyRingedSpace.IsOpenImmersion.scheme (toLocallyRingedSpace _ f)
  intro x
  obtain ⟨_, ⟨i, rfl⟩, hx, hi⟩ :=
    Y.affineBasisCover_is_basis.exists_subset_of_mem_open (Set.mem_range_self x)
      H.base_open.open_range
  use Y.affineBasisCoverRing i
  use LocallyRingedSpace.IsOpenImmersion.lift (toLocallyRingedSpaceHom _ f) _ hi
  constructor
  · rw [LocallyRingedSpace.IsOpenImmersion.lift_range]; exact hx
  · delta LocallyRingedSpace.IsOpenImmersion.lift; 

Proof state:
case h.right
C : Type u
inst✝ : Category.{v, u} C
X : PresheafedSpace CommRingCat
Y : Scheme
f : X ⟶ Y.toPresheafedSpace
H : IsOpenImmersion f
x : ↑(LocallyRingedSpace.toTopCat (toLocallyRingedSpace Y.toLocallyRingedSpace f))
i : (Scheme.affineBasisCover Y).J
hx : f.base x ∈ Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover Y) i).val.base
hi : Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover Y) i).val.base ⊆ Set.range ⇑f.base
⊢ LocallyRingedSpace.IsOpenImmersion
    (let_fun this := (_ : IsIso pullback.snd);
    inv pullback.snd ≫ pullback.fst)

Next tactic:
infer_instance
theorem scheme_eq_of_locallyRingedSpace_eq {X Y : Scheme}
    (H : X.toLocallyRingedSpace = Y.toLocallyRingedSpace) : X = Y := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ : PresheafedSpace CommRingCat
Y✝ : Scheme
f : X✝ ⟶ Y✝.toPresheafedSpace
H✝ : IsOpenImmersion f
X Y : Scheme
H : X.toLocallyRingedSpace = Y.toLocallyRingedSpace
⊢ X = Y

Next tactic:
cases X
theorem scheme_eq_of_locallyRingedSpace_eq {X Y : Scheme}
    (H : X.toLocallyRingedSpace = Y.toLocallyRingedSpace) : X = Y := by
  cases X; 

Proof state:
case mk
C : Type u
inst✝ : Category.{v, u} C
X : PresheafedSpace CommRingCat
Y✝ : Scheme
f : X ⟶ Y✝.toPresheafedSpace
H✝ : IsOpenImmersion f
Y : Scheme
toLocallyRingedSpace✝ : LocallyRingedSpace
local_affine✝ :
  ∀ (x : ↑(LocallyRingedSpace.toTopCat toLocallyRingedSpace✝)),
    ∃ U R,
      Nonempty
        (LocallyRingedSpace.restrict toLocallyRingedSpace✝ (_ : OpenEmbedding ⇑(Opens.inclusion U.obj)) ≅
          Spec.toLocallyRingedSpace.obj (op R))
H :
  { toLocallyRingedSpace := toLocallyRingedSpace✝, local_affine := local_affine✝ }.toLocallyRingedSpace =
    Y.toLocallyRingedSpace
⊢ { toLocallyRingedSpace := toLocallyRingedSpace✝, local_affine := local_affine✝ } = Y

Next tactic:
cases Y
theorem scheme_eq_of_locallyRingedSpace_eq {X Y : Scheme}
    (H : X.toLocallyRingedSpace = Y.toLocallyRingedSpace) : X = Y := by
  cases X; cases Y; 

Proof state:
case mk.mk
C : Type u
inst✝ : Category.{v, u} C
X : PresheafedSpace CommRingCat
Y : Scheme
f : X ⟶ Y.toPresheafedSpace
H✝ : IsOpenImmersion f
toLocallyRingedSpace✝¹ : LocallyRingedSpace
local_affine✝¹ :
  ∀ (x : ↑(LocallyRingedSpace.toTopCat toLocallyRingedSpace✝¹)),
    ∃ U R,
      Nonempty
        (LocallyRingedSpace.restrict toLocallyRingedSpace✝¹ (_ : OpenEmbedding ⇑(Opens.inclusion U.obj)) ≅
          Spec.toLocallyRingedSpace.obj (op R))
toLocallyRingedSpace✝ : LocallyRingedSpace
local_affine✝ :
  ∀ (x : ↑(LocallyRingedSpace.toTopCat toLocallyRingedSpace✝)),
    ∃ U R,
      Nonempty
        (LocallyRingedSpace.restrict toLocallyRingedSpace✝ (_ : OpenEmbedding ⇑(Opens.inclusion U.obj)) ≅
          Spec.toLocallyRingedSpace.obj (op R))
H :
  { toLocallyRingedSpace := toLocallyRingedSpace✝¹, local_affine := local_affine✝¹ }.toLocallyRingedSpace =
    { toLocallyRingedSpace := toLocallyRingedSpace✝, local_affine := local_affine✝ }.toLocallyRingedSpace
⊢ { toLocallyRingedSpace := toLocallyRingedSpace✝¹, local_affine := local_affine✝¹ } =
    { toLocallyRingedSpace := toLocallyRingedSpace✝, local_affine := local_affine✝ }

Next tactic:
congr
theorem scheme_toScheme {X Y : Scheme} (f : X ⟶ Y) [AlgebraicGeometry.IsOpenImmersion f] :
    toScheme Y f.1 = X := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X✝ : PresheafedSpace CommRingCat
Y✝ : Scheme
f✝ : X✝ ⟶ Y✝.toPresheafedSpace
H : IsOpenImmersion f✝
X Y : Scheme
f : X ⟶ Y
inst✝ : AlgebraicGeometry.IsOpenImmersion f
⊢ toScheme Y f.val = X

Next tactic:
apply scheme_eq_of_locallyRingedSpace_eq
theorem scheme_toScheme {X Y : Scheme} (f : X ⟶ Y) [AlgebraicGeometry.IsOpenImmersion f] :
    toScheme Y f.1 = X := by
  apply scheme_eq_of_locallyRingedSpace_eq
  

Proof state:
case H
C : Type u
inst✝¹ : Category.{v, u} C
X✝ : PresheafedSpace CommRingCat
Y✝ : Scheme
f✝ : X✝ ⟶ Y✝.toPresheafedSpace
H : IsOpenImmersion f✝
X Y : Scheme
f : X ⟶ Y
inst✝ : AlgebraicGeometry.IsOpenImmersion f
⊢ (toScheme Y f.val).toLocallyRingedSpace = X.toLocallyRingedSpace

Next tactic:
exact locallyRingedSpace_toLocallyRingedSpace f
instance IsOpenImmersion.ofRestrict {U : TopCat} (X : Scheme) {f : U ⟶ TopCat.of X}
    (h : OpenEmbedding f) : IsOpenImmersion (X.ofRestrict h) :=
  show PresheafedSpace.IsOpenImmersion (X.toPresheafedSpace.ofRestrict h) by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
U : TopCat
X : Scheme
f : U ⟶ TopCat.of ↑↑X.toPresheafedSpace
h : OpenEmbedding ⇑f
⊢ PresheafedSpace.IsOpenImmersion (PresheafedSpace.ofRestrict X.toPresheafedSpace h)

Next tactic:
infer_instance
instance (priority := 100) of_isIso [IsIso g] : IsOpenImmersion g :=
  @LocallyRingedSpace.IsOpenImmersion.of_isIso _ _ _
    (show IsIso ((inducedFunctor _).map g) by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
inst✝ : IsIso g
⊢ IsIso ((inducedFunctor Scheme.toLocallyRingedSpace).map g)

Next tactic:
infer_instance
theorem _root_.AlgebraicGeometry.isIso_iff_stalk_iso {X Y : Scheme} (f : X ⟶ Y) :
    IsIso f ↔ IsIso f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Z
g : Y✝ ⟶ Z
H : IsOpenImmersion f✝
X Y : Scheme
f : X ⟶ Y
⊢ IsIso f ↔ IsIso f.val.base ∧ ∀ (x : ↑↑X.toPresheafedSpace), IsIso (PresheafedSpace.stalkMap f.val x)

Next tactic:
rw [isIso_iff_isOpenImmersion, IsOpenImmersion.iff_stalk_iso, and_comm, ← and_assoc]
theorem _root_.AlgebraicGeometry.isIso_iff_stalk_iso {X Y : Scheme} (f : X ⟶ Y) :
    IsIso f ↔ IsIso f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  rw [isIso_iff_isOpenImmersion, IsOpenImmersion.iff_stalk_iso, and_comm, ← and_assoc]
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Z
g : Y✝ ⟶ Z
H : IsOpenImmersion f✝
X Y : Scheme
f : X ⟶ Y
⊢ ((Epi f.val.base ∧ OpenEmbedding ⇑f.val.base) ∧
      ∀ (x : ↑↑X.toPresheafedSpace), IsIso (PresheafedSpace.stalkMap f.val x)) ↔
    IsIso f.val.base ∧ ∀ (x : ↑↑X.toPresheafedSpace), IsIso (PresheafedSpace.stalkMap f.val x)

Next tactic:
refine' and_congr ⟨_, _⟩ Iff.rfl
theorem _root_.AlgebraicGeometry.isIso_iff_stalk_iso {X Y : Scheme} (f : X ⟶ Y) :
    IsIso f ↔ IsIso f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  rw [isIso_iff_isOpenImmersion, IsOpenImmersion.iff_stalk_iso, and_comm, ← and_assoc]
  refine' and_congr ⟨_, _⟩ Iff.rfl
  · 

Proof state:
case refine'_1
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Z
g : Y✝ ⟶ Z
H : IsOpenImmersion f✝
X Y : Scheme
f : X ⟶ Y
⊢ Epi f.val.base ∧ OpenEmbedding ⇑f.val.base → IsIso f.val.base

Next tactic:
rintro ⟨h₁, h₂⟩
theorem _root_.AlgebraicGeometry.isIso_iff_stalk_iso {X Y : Scheme} (f : X ⟶ Y) :
    IsIso f ↔ IsIso f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  rw [isIso_iff_isOpenImmersion, IsOpenImmersion.iff_stalk_iso, and_comm, ← and_assoc]
  refine' and_congr ⟨_, _⟩ Iff.rfl
  · rintro ⟨h₁, h₂⟩
    

Proof state:
case refine'_1.intro
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Z
g : Y✝ ⟶ Z
H : IsOpenImmersion f✝
X Y : Scheme
f : X ⟶ Y
h₁ : Epi f.val.base
h₂ : OpenEmbedding ⇑f.val.base
⊢ IsIso f.val.base

Next tactic:
convert_to
      IsIso
        (TopCat.isoOfHomeo
            (Homeomorph.homeomorphOfContinuousOpen
              (Equiv.ofBijective _ ⟨h₂.inj, (TopCat.epi_iff_surjective _).mp h₁⟩) h₂.continuous
              h₂.isOpenMap)).hom
theorem _root_.AlgebraicGeometry.isIso_iff_stalk_iso {X Y : Scheme} (f : X ⟶ Y) :
    IsIso f ↔ IsIso f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  rw [isIso_iff_isOpenImmersion, IsOpenImmersion.iff_stalk_iso, and_comm, ← and_assoc]
  refine' and_congr ⟨_, _⟩ Iff.rfl
  · rintro ⟨h₁, h₂⟩
    convert_to
      IsIso
        (TopCat.isoOfHomeo
            (Homeomorph.homeomorphOfContinuousOpen
              (Equiv.ofBijective _ ⟨h₂.inj, (TopCat.epi_iff_surjective _).mp h₁⟩) h₂.continuous
              h₂.isOpenMap)).hom
    

Proof state:
case refine'_1.intro
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Z
g : Y✝ ⟶ Z
H : IsOpenImmersion f✝
X Y : Scheme
f : X ⟶ Y
h₁ : Epi f.val.base
h₂ : OpenEmbedding ⇑f.val.base
⊢ IsIso
    (TopCat.isoOfHomeo
        (Homeomorph.homeomorphOfContinuousOpen
          (Equiv.ofBijective ⇑f.val.base (_ : Function.Injective ⇑f.val.base ∧ Function.Surjective ⇑f.val.base))
          (_ : Continuous ⇑f.val.base) (_ : IsOpenMap ⇑f.val.base))).hom

Next tactic:
infer_instance
theorem _root_.AlgebraicGeometry.isIso_iff_stalk_iso {X Y : Scheme} (f : X ⟶ Y) :
    IsIso f ↔ IsIso f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  rw [isIso_iff_isOpenImmersion, IsOpenImmersion.iff_stalk_iso, and_comm, ← and_assoc]
  refine' and_congr ⟨_, _⟩ Iff.rfl
  · rintro ⟨h₁, h₂⟩
    convert_to
      IsIso
        (TopCat.isoOfHomeo
            (Homeomorph.homeomorphOfContinuousOpen
              (Equiv.ofBijective _ ⟨h₂.inj, (TopCat.epi_iff_surjective _).mp h₁⟩) h₂.continuous
              h₂.isOpenMap)).hom
    infer_instance
  · 

Proof state:
case refine'_2
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Z
g : Y✝ ⟶ Z
H : IsOpenImmersion f✝
X Y : Scheme
f : X ⟶ Y
⊢ IsIso f.val.base → Epi f.val.base ∧ OpenEmbedding ⇑f.val.base

Next tactic:
intro H
theorem _root_.AlgebraicGeometry.isIso_iff_stalk_iso {X Y : Scheme} (f : X ⟶ Y) :
    IsIso f ↔ IsIso f.1.base ∧ ∀ x, IsIso (PresheafedSpace.stalkMap f.1 x) := by
  rw [isIso_iff_isOpenImmersion, IsOpenImmersion.iff_stalk_iso, and_comm, ← and_assoc]
  refine' and_congr ⟨_, _⟩ Iff.rfl
  · rintro ⟨h₁, h₂⟩
    convert_to
      IsIso
        (TopCat.isoOfHomeo
            (Homeomorph.homeomorphOfContinuousOpen
              (Equiv.ofBijective _ ⟨h₂.inj, (TopCat.epi_iff_surjective _).mp h₁⟩) h₂.continuous
              h₂.isOpenMap)).hom
    infer_instance
  · intro H; 

Proof state:
case refine'_2
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ Z : Scheme
f✝ : X✝ ⟶ Z
g : Y✝ ⟶ Z
H✝ : IsOpenImmersion f✝
X Y : Scheme
f : X ⟶ Y
H : IsIso f.val.base
⊢ Epi f.val.base ∧ OpenEmbedding ⇑f.val.base

Next tactic:
exact ⟨inferInstance, (TopCat.homeoOfIso (asIso f.1.base)).openEmbedding⟩
instance mono : Mono f :=
  (inducedFunctor _).mono_of_mono_map (show @Mono LocallyRingedSpace _ _ _ f by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ Mono f

Next tactic:
infer_instance
instance hasLimit_cospan_forget_of_left :
    HasLimit (cospan f g ⋙ Scheme.forgetToLocallyRingedSpace) := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ HasLimit (cospan f g ⋙ forget)

Next tactic:
apply @hasLimitOfIso _ _ _ _ _ _ ?_ (diagramIsoCospan.{u} _).symm
instance hasLimit_cospan_forget_of_left :
    HasLimit (cospan f g ⋙ Scheme.forgetToLocallyRingedSpace) := by
  apply @hasLimitOfIso _ _ _ _ _ _ ?_ (diagramIsoCospan.{u} _).symm
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ HasLimit (cospan ((cospan f g ⋙ forget).map WalkingCospan.Hom.inl) ((cospan f g ⋙ forget).map WalkingCospan.Hom.inr))

Next tactic:
change HasLimit (cospan ((forget).map f) ((forget).map g))
instance hasLimit_cospan_forget_of_left :
    HasLimit (cospan f g ⋙ Scheme.forgetToLocallyRingedSpace) := by
  apply @hasLimitOfIso _ _ _ _ _ _ ?_ (diagramIsoCospan.{u} _).symm
  change HasLimit (cospan ((forget).map f) ((forget).map g))
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ HasLimit (cospan (forget.map f) (forget.map g))

Next tactic:
infer_instance
instance hasLimit_cospan_forget_of_right : HasLimit (cospan g f ⋙ forget) := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ HasLimit (cospan g f ⋙ forget)

Next tactic:
apply @hasLimitOfIso _ _ _ _ _ _ ?_ (diagramIsoCospan.{u} _).symm
instance hasLimit_cospan_forget_of_right : HasLimit (cospan g f ⋙ forget) := by
  apply @hasLimitOfIso _ _ _ _ _ _ ?_ (diagramIsoCospan.{u} _).symm
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ HasLimit (cospan ((cospan g f ⋙ forget).map Hom.inl) ((cospan g f ⋙ forget).map Hom.inr))

Next tactic:
change HasLimit (cospan ((forget).map g) ((forget).map f))
instance hasLimit_cospan_forget_of_right : HasLimit (cospan g f ⋙ forget) := by
  apply @hasLimitOfIso _ _ _ _ _ _ ?_ (diagramIsoCospan.{u} _).symm
  change HasLimit (cospan ((forget).map g) ((forget).map f))
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ HasLimit (cospan (forget.map g) (forget.map f))

Next tactic:
infer_instance
instance forgetCreatesPullbackOfLeft : CreatesLimit (cospan f g) forget :=
  createsLimitOfFullyFaithfulOfIso
    (PresheafedSpace.IsOpenImmersion.toScheme Y (@pullback.snd LocallyRingedSpace _ _ _ _ f g _).1)
    (eqToIso (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ forget.obj (PresheafedSpace.IsOpenImmersion.toScheme Y pullback.snd.val) =
    limit (cospan ((cospan f g ⋙ forget).map Hom.inl) ((cospan f g ⋙ forget).map Hom.inr))

Next tactic:
simp
instance forgetCreatesPullbackOfRight : CreatesLimit (cospan g f) forget :=
  createsLimitOfFullyFaithfulOfIso
    (PresheafedSpace.IsOpenImmersion.toScheme Y (@pullback.fst LocallyRingedSpace _ _ _ _ g f _).1)
    (eqToIso (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ forget.obj (PresheafedSpace.IsOpenImmersion.toScheme Y pullback.fst.val) =
    limit (cospan ((cospan g f ⋙ forget).map Hom.inl) ((cospan g f ⋙ forget).map Hom.inr))

Next tactic:
simp
instance pullback_snd_of_left : IsOpenImmersion (pullback.snd : pullback f g ⟶ _) := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ IsOpenImmersion pullback.snd

Next tactic:
have := PreservesPullback.iso_hom_snd forget f g
instance pullback_snd_of_left : IsOpenImmersion (pullback.snd : pullback f g ⟶ _) := by
  have := PreservesPullback.iso_hom_snd forget f g
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
this : (PreservesPullback.iso forget f g).hom ≫ pullback.snd = forget.map pullback.snd
⊢ IsOpenImmersion pullback.snd

Next tactic:
dsimp only [Scheme.forgetToLocallyRingedSpace, inducedFunctor_map] at this
instance pullback_snd_of_left : IsOpenImmersion (pullback.snd : pullback f g ⟶ _) := by
  have := PreservesPullback.iso_hom_snd forget f g
  dsimp only [Scheme.forgetToLocallyRingedSpace, inducedFunctor_map] at this
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
this : (PreservesPullback.iso (inducedFunctor Scheme.toLocallyRingedSpace) f g).hom ≫ pullback.snd = pullback.snd
⊢ IsOpenImmersion pullback.snd

Next tactic:
rw [← this]
instance pullback_snd_of_left : IsOpenImmersion (pullback.snd : pullback f g ⟶ _) := by
  have := PreservesPullback.iso_hom_snd forget f g
  dsimp only [Scheme.forgetToLocallyRingedSpace, inducedFunctor_map] at this
  rw [← this]
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
this : (PreservesPullback.iso (inducedFunctor Scheme.toLocallyRingedSpace) f g).hom ≫ pullback.snd = pullback.snd
⊢ IsOpenImmersion ((PreservesPullback.iso (inducedFunctor Scheme.toLocallyRingedSpace) f g).hom ≫ pullback.snd)

Next tactic:
change LocallyRingedSpace.IsOpenImmersion _
instance pullback_snd_of_left : IsOpenImmersion (pullback.snd : pullback f g ⟶ _) := by
  have := PreservesPullback.iso_hom_snd forget f g
  dsimp only [Scheme.forgetToLocallyRingedSpace, inducedFunctor_map] at this
  rw [← this]
  change LocallyRingedSpace.IsOpenImmersion _
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
this : (PreservesPullback.iso (inducedFunctor Scheme.toLocallyRingedSpace) f g).hom ≫ pullback.snd = pullback.snd
⊢ LocallyRingedSpace.IsOpenImmersion
    ((PreservesPullback.iso (inducedFunctor Scheme.toLocallyRingedSpace) f g).hom ≫ pullback.snd)

Next tactic:
infer_instance
instance pullback_fst_of_right : IsOpenImmersion (pullback.fst : pullback g f ⟶ _) := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ IsOpenImmersion pullback.fst

Next tactic:
rw [← pullbackSymmetry_hom_comp_snd]
instance pullback_fst_of_right : IsOpenImmersion (pullback.fst : pullback g f ⟶ _) := by
  rw [← pullbackSymmetry_hom_comp_snd]
  -- Porting note : was just `infer_instance`, it is a bit weird that no explicit class instance is
  -- provided but still class inference fail to find this
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ IsOpenImmersion ((pullbackSymmetry g f).hom ≫ pullback.snd)

Next tactic:
exact LocallyRingedSpace.IsOpenImmersion.comp (H := inferInstance) _
instance pullback_to_base [IsOpenImmersion g] :
    IsOpenImmersion (limit.π (cospan f g) WalkingCospan.one) := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
inst✝ : IsOpenImmersion g
⊢ IsOpenImmersion (limit.π (cospan f g) one)

Next tactic:
rw [← limit.w (cospan f g) WalkingCospan.Hom.inl]
instance pullback_to_base [IsOpenImmersion g] :
    IsOpenImmersion (limit.π (cospan f g) WalkingCospan.one) := by
  rw [← limit.w (cospan f g) WalkingCospan.Hom.inl]
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
inst✝ : IsOpenImmersion g
⊢ IsOpenImmersion (limit.π (cospan f g) left ≫ (cospan f g).map Hom.inl)

Next tactic:
change IsOpenImmersion (_ ≫ f)
instance pullback_to_base [IsOpenImmersion g] :
    IsOpenImmersion (limit.π (cospan f g) WalkingCospan.one) := by
  rw [← limit.w (cospan f g) WalkingCospan.Hom.inl]
  change IsOpenImmersion (_ ≫ f)
  -- Porting note : was just `infer_instance`, it is a bit weird that no explicit class instance is
  -- provided but still class inference fail to find this
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
inst✝ : IsOpenImmersion g
⊢ IsOpenImmersion (limit.π (cospan f g) left ≫ f)

Next tactic:
exact LocallyRingedSpace.IsOpenImmersion.comp (H := inferInstance) _
instance forgetToTopPreservesOfLeft : PreservesLimit (cospan f g) Scheme.forgetToTop := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ PreservesLimit (cospan f g) Scheme.forgetToTop

Next tactic:
delta Scheme.forgetToTop
instance forgetToTopPreservesOfLeft : PreservesLimit (cospan f g) Scheme.forgetToTop := by
  delta Scheme.forgetToTop
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ PreservesLimit (cospan f g) (forget ⋙ LocallyRingedSpace.forgetToTop)

Next tactic:
apply @Limits.compPreservesLimit (K := cospan f g) (F := forget)
    (G := LocallyRingedSpace.forgetToTop) ?_ ?_
instance forgetToTopPreservesOfLeft : PreservesLimit (cospan f g) Scheme.forgetToTop := by
  delta Scheme.forgetToTop
  apply @Limits.compPreservesLimit (K := cospan f g) (F := forget)
    (G := LocallyRingedSpace.forgetToTop) ?_ ?_
  · 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ PreservesLimit (cospan f g) forget

Next tactic:
infer_instance
instance forgetToTopPreservesOfLeft : PreservesLimit (cospan f g) Scheme.forgetToTop := by
  delta Scheme.forgetToTop
  apply @Limits.compPreservesLimit (K := cospan f g) (F := forget)
    (G := LocallyRingedSpace.forgetToTop) ?_ ?_
  · infer_instance
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ PreservesLimit (cospan f g ⋙ forget) LocallyRingedSpace.forgetToTop

Next tactic:
apply @preservesLimitOfIsoDiagram (F := _) _ _ _ _ _ _ (diagramIsoCospan.{u} _).symm ?_
instance forgetToTopPreservesOfLeft : PreservesLimit (cospan f g) Scheme.forgetToTop := by
  delta Scheme.forgetToTop
  apply @Limits.compPreservesLimit (K := cospan f g) (F := forget)
    (G := LocallyRingedSpace.forgetToTop) ?_ ?_
  · infer_instance
  apply @preservesLimitOfIsoDiagram (F := _) _ _ _ _ _ _ (diagramIsoCospan.{u} _).symm ?_
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ PreservesLimit (cospan ((cospan f g ⋙ forget).map Hom.inl) ((cospan f g ⋙ forget).map Hom.inr))
    LocallyRingedSpace.forgetToTop

Next tactic:
dsimp [LocallyRingedSpace.forgetToTop]
instance forgetToTopPreservesOfLeft : PreservesLimit (cospan f g) Scheme.forgetToTop := by
  delta Scheme.forgetToTop
  apply @Limits.compPreservesLimit (K := cospan f g) (F := forget)
    (G := LocallyRingedSpace.forgetToTop) ?_ ?_
  · infer_instance
  apply @preservesLimitOfIsoDiagram (F := _) _ _ _ _ _ _ (diagramIsoCospan.{u} _).symm ?_
  dsimp [LocallyRingedSpace.forgetToTop]
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ PreservesLimit (cospan f g) (LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forget CommRingCat)

Next tactic:
infer_instance
theorem range_pullback_snd_of_left :
    Set.range (pullback.snd : pullback f g ⟶ Y).1.base =
      ((Opens.map g.1.base).obj ⟨Set.range f.1.base, H.base_open.open_range⟩).1 := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y Z : Scheme
f : X ⟶ Z
g : Y ⟶ Z
H : IsOpenImmersion f
⊢ Set.range ⇑pullback.snd.val.base =
    ((Opens.map g.val.base).obj
        { carrier := Set.range ⇑f.val.base, is_open' := (_ : IsOpen (Set.range ⇑f.val.base)) }).carrier

Next tactic:
rw [←
    show _ = (pullback.snd : pullback f g ⟶ _).1.base from
      PreservesPullback.iso_hom_snd Scheme.forgetToTop f g]