-- Mathlib/AlgebraicGeometry/SpreadingOut.lean
protected
lemma Scheme.IsGermInjective.Spec
    (H : ∀ I : Ideal R, I.IsPrime →
      ∃ f : R, f ∉ I ∧ ∀ (x y : R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0) :
    (Spec R).IsGermInjective

Proof state:
case intro.intro.refine_2.intro.intro.intro.mk
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
x : ↑R
s : ↥(Submonoid.powers f)
hx : (ConcreteCategory.hom (StructureSheaf.toStalk (↑R) p)) x = 0
y : ↑R
hy : y ∈ p.asIdeal.primeCompl
hy' : ↑⟨y, hy⟩ * x = 0
⊢ IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) x s = 0

Tactic:
obtain ⟨n, hn⟩ := H x y hy' hy

Result:
case intro.intro.refine_2.intro.intro.intro.mk.intro
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
x : ↑R
s : ↥(Submonoid.powers f)
hx : (ConcreteCategory.hom (StructureSheaf.toStalk (↑R) p)) x = 0
y : ↑R
hy : y ∈ p.asIdeal.primeCompl
hy' : ↑⟨y, hy⟩ * x = 0
n : ℕ
hn : f ^ n * x = 0
⊢ IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) x s = 0

Proof state:
case intro.intro.refine_2.intro.intro
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
x : ↑R
s : ↥(Submonoid.powers f)
hx :
  (ConcreteCategory.hom ((Spec R).presheaf.germ (PrimeSpectrum.basicOpen f) p hf))
      ((CommRingCat.Hom.hom (StructureSheaf.toOpen (↑R) (Opposite.unop (Opposite.op (PrimeSpectrum.basicOpen f))))) x) =
    0
⊢ IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) x s = 0

case intro.intro.refine_2.intro.intro.hy
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
x : ↑R
s : ↥(Submonoid.powers f)
hx :
  (algebraMap ↑R ↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) x *
      IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) 1 s ∈
    RingHom.ker (ConcreteCategory.hom ((Spec R).presheaf.germ (PrimeSpectrum.basicOpen f) p hf))
⊢ IsUnit (IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) 1 s)

Tactic:
swap

Result:
case intro.intro.refine_2.intro.intro.hy
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
x : ↑R
s : ↥(Submonoid.powers f)
hx :
  (algebraMap ↑R ↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) x *
      IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) 1 s ∈
    RingHom.ker (ConcreteCategory.hom ((Spec R).presheaf.germ (PrimeSpectrum.basicOpen f) p hf))
⊢ IsUnit (IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) 1 s)

case intro.intro.refine_2.intro.intro
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
x : ↑R
s : ↥(Submonoid.powers f)
hx :
  (ConcreteCategory.hom ((Spec R).presheaf.germ (PrimeSpectrum.basicOpen f) p hf))
      ((CommRingCat.Hom.hom (StructureSheaf.toOpen (↑R) (Opposite.unop (Opposite.op (PrimeSpectrum.basicOpen f))))) x) =
    0
⊢ IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) x s = 0

Proof state:
case intro.intro.refine_2.intro.intro.intro.mk.intro
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
x : ↑R
s : ↥(Submonoid.powers f)
hx : (ConcreteCategory.hom (StructureSheaf.toStalk (↑R) p)) x = 0
y : ↑R
hy : y ∈ p.asIdeal.primeCompl
hy' : ↑⟨y, hy⟩ * x = 0
n : ℕ
hn : f ^ n * x = 0
⊢ ∃ m, ↑m * x = 0

Tactic:
exact ⟨⟨_, n, rfl⟩, hn⟩

Result:
no goals

Proof state:
case intro.intro.refine_2.intro.intro.hy
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
x : ↑R
s : ↥(Submonoid.powers f)
hx :
  (algebraMap ↑R ↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) x *
      IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) 1 s ∈
    RingHom.ker (ConcreteCategory.hom ((Spec R).presheaf.germ (PrimeSpectrum.basicOpen f) p hf))
⊢ IsUnit (IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) 1 s)

Tactic:
exact @isUnit_of_invertible _ _ _ (@IsLocalization.invertible_mk'_one ..)

Result:
no goals

Proof state:
case intro.intro.refine_2.intro.intro
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
x : ↑R
s : ↥(Submonoid.powers f)
hx : (ConcreteCategory.hom (StructureSheaf.toStalk (↑R) p)) x = 0
⊢ IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) x s = 0

Tactic:
obtain ⟨⟨y, hy⟩, hy'⟩ := (IsLocalization.map_eq_zero_iff p.asIdeal.primeCompl
  ((Spec.structureSheaf R).presheaf.stalk p) _).mp hx

Result:
case intro.intro.refine_2.intro.intro.intro.mk
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
x : ↑R
s : ↥(Submonoid.powers f)
hx : (ConcreteCategory.hom (StructureSheaf.toStalk (↑R) p)) x = 0
y : ↑R
hy : y ∈ p.asIdeal.primeCompl
hy' : ↑⟨y, hy⟩ * x = 0
⊢ IsLocalization.mk' (↑((Spec.structureSheaf ↑R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))) x s = 0

Proof state:
case intro.intro.refine_1
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
⊢ IsAffineOpen (PrimeSpectrum.basicOpen f)

Tactic:
rw [← basicOpen_eq_of_affine]

Result:
case intro.intro.refine_1
R : CommRingCat
H✝ : ∀ (I : Ideal ↑R), I.IsPrime → ∃ f ∉ I, ∀ (x y : ↑R), y * x = 0 → y ∉ I → ∃ n, f ^ n * x = 0
p : ↑↑(Spec R).toPresheafedSpace
f : ↑R
hf : f ∉ p.asIdeal
H : ∀ (x y : ↑R), y * x = 0 → y ∉ p.asIdeal → ∃ n, f ^ n * x = 0
⊢ IsAffineOpen ((Spec R).basicOpen ((ConcreteCategory.hom (ΓSpecIso R).inv) f))