l3lab/ntp-mathlib huggingface dataset:
instance Unique.subtypeEq (y : α) : Unique { x // x = y } where
  default := ⟨y, rfl⟩
  uniq := fun ⟨x, hx⟩ ↦ by 

Proof state:
α : Sort u
y : α
x✝ : { x // x = y }
x : α
hx : x = y
⊢ { val := x, property := hx } = default

Next tactic:
congr
instance Unique.subtypeEq' (y : α) : Unique { x // y = x } where
  default := ⟨y, rfl⟩
  uniq := fun ⟨x, hx⟩ ↦ by 

Proof state:
α : Sort u
y : α
x✝ : { x // y = x }
x : α
hx : y = x
⊢ { val := x, property := hx } = default

Next tactic:
subst hx
instance Unique.subtypeEq' (y : α) : Unique { x // y = x } where
  default := ⟨y, rfl⟩
  uniq := fun ⟨x, hx⟩ ↦ by subst hx; 

Proof state:
α : Sort u
y : α
x✝ : { x // y = x }
⊢ { val := y, property := (_ : y = y) } = default

Next tactic:
congr
@[simp]
theorem cast_pow_eq_one {R : Type*} [Semiring R] [CharZero R] (q : ℕ) (n : ℕ) (hn : n ≠ 0) :
    (q : R) ^ n = 1 ↔ q = 1 := by
  

Proof state:
R✝ : Type u_1
inst✝³ : AddMonoidWithOne R✝
inst✝² : CharZero R✝
R : Type u_2
inst✝¹ : Semiring R
inst✝ : CharZero R
q n : ℕ
hn : n ≠ 0
⊢ ↑q ^ n = 1 ↔ q = 1

Next tactic:
rw [← cast_pow, cast_eq_one]
@[simp]
theorem cast_pow_eq_one {R : Type*} [Semiring R] [CharZero R] (q : ℕ) (n : ℕ) (hn : n ≠ 0) :
    (q : R) ^ n = 1 ↔ q = 1 := by
  rw [← cast_pow, cast_eq_one]
  

Proof state:
R✝ : Type u_1
inst✝³ : AddMonoidWithOne R✝
inst✝² : CharZero R✝
R : Type u_2
inst✝¹ : Semiring R
inst✝ : CharZero R
q n : ℕ
hn : n ≠ 0
⊢ q ^ n = 1 ↔ q = 1

Next tactic:
exact pow_eq_one_iff hn
@[simp, norm_cast]
theorem cast_div_charZero {k : Type*} [DivisionSemiring k] [CharZero k] {m n : ℕ} (n_dvd : n ∣ m) :
    ((m / n : ℕ) : k) = m / n := by
  

Proof state:
R : Type u_1
inst✝³ : AddMonoidWithOne R
inst✝² : CharZero R
k : Type u_2
inst✝¹ : DivisionSemiring k
inst✝ : CharZero k
m n : ℕ
n_dvd : n ∣ m
⊢ ↑(m / n) = ↑m / ↑n

Next tactic:
rcases eq_or_ne n 0 with (rfl | hn)
@[simp, norm_cast]
theorem cast_div_charZero {k : Type*} [DivisionSemiring k] [CharZero k] {m n : ℕ} (n_dvd : n ∣ m) :
    ((m / n : ℕ) : k) = m / n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · 

Proof state:
case inl
R : Type u_1
inst✝³ : AddMonoidWithOne R
inst✝² : CharZero R
k : Type u_2
inst✝¹ : DivisionSemiring k
inst✝ : CharZero k
m : ℕ
n_dvd : 0 ∣ m
⊢ ↑(m / 0) = ↑m / ↑0

Next tactic:
simp
@[simp, norm_cast]
theorem cast_div_charZero {k : Type*} [DivisionSemiring k] [CharZero k] {m n : ℕ} (n_dvd : n ∣ m) :
    ((m / n : ℕ) : k) = m / n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  · 

Proof state:
case inr
R : Type u_1
inst✝³ : AddMonoidWithOne R
inst✝² : CharZero R
k : Type u_2
inst✝¹ : DivisionSemiring k
inst✝ : CharZero k
m n : ℕ
n_dvd : n ∣ m
hn : n ≠ 0
⊢ ↑(m / n) = ↑m / ↑n

Next tactic:
exact cast_div n_dvd (cast_ne_zero.2 hn)
instance CharZero.NeZero.two : NeZero (2 : M) :=
  ⟨by
    

Proof state:
α : Type u_1
M : Type u_2
inst✝¹ : AddMonoidWithOne M
inst✝ : CharZero M
n : ℕ
⊢ 2 ≠ 0

Next tactic:
have : ((2 : ℕ) : M) ≠ 0 := Nat.cast_ne_zero.2 (by decide)
instance CharZero.NeZero.two : NeZero (2 : M) :=
  ⟨by
    have : ((2 : ℕ) : M) ≠ 0 := Nat.cast_ne_zero.2 (by 

Proof state:
α : Type u_1
M : Type u_2
inst✝¹ : AddMonoidWithOne M
inst✝ : CharZero M
n : ℕ
⊢ 2 ≠ 0

Next tactic:
decide
instance CharZero.NeZero.two : NeZero (2 : M) :=
  ⟨by
    have : ((2 : ℕ) : M) ≠ 0 := Nat.cast_ne_zero.2 (by decide)
    

Proof state:
α : Type u_1
M : Type u_2
inst✝¹ : AddMonoidWithOne M
inst✝ : CharZero M
n : ℕ
this : ↑2 ≠ 0
⊢ 2 ≠ 0

Next tactic:
rwa [Nat.cast_two] at this
@[simp]
theorem add_self_eq_zero {a : R} : a + a = 0 ↔ a = 0 := by
  

Proof state:
R : Type u_1
inst✝² : NonAssocSemiring R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a✝ a : R
⊢ a + a = 0 ↔ a = 0

Next tactic:
simp only [(two_mul a).symm, mul_eq_zero, two_ne_zero, false_or_iff]
@[simp]
theorem zero_eq_bit0 {a : R} : 0 = bit0 a ↔ a = 0 := by
  

Proof state:
R : Type u_1
inst✝² : NonAssocSemiring R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a✝ a : R
⊢ 0 = bit0 a ↔ a = 0

Next tactic:
rw [eq_comm]
@[simp]
theorem zero_eq_bit0 {a : R} : 0 = bit0 a ↔ a = 0 := by
  rw [eq_comm]
  

Proof state:
R : Type u_1
inst✝² : NonAssocSemiring R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a✝ a : R
⊢ bit0 a = 0 ↔ a = 0

Next tactic:
exact bit0_eq_zero
theorem nat_mul_inj {n : ℕ} {a b : R} (h : (n : R) * a = (n : R) * b) : n = 0 ∨ a = b := by
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
n : ℕ
a b : R
h : ↑n * a = ↑n * b
⊢ n = 0 ∨ a = b

Next tactic:
rw [← sub_eq_zero, ← mul_sub, mul_eq_zero, sub_eq_zero] at h
theorem nat_mul_inj {n : ℕ} {a b : R} (h : (n : R) * a = (n : R) * b) : n = 0 ∨ a = b := by
  rw [← sub_eq_zero, ← mul_sub, mul_eq_zero, sub_eq_zero] at h
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
n : ℕ
a b : R
h : ↑n = 0 ∨ a = b
⊢ n = 0 ∨ a = b

Next tactic:
exact mod_cast h
theorem nat_mul_inj' {n : ℕ} {a b : R} (h : (n : R) * a = (n : R) * b) (w : n ≠ 0) : a = b := by
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
n : ℕ
a b : R
h : ↑n * a = ↑n * b
w : n ≠ 0
⊢ a = b

Next tactic:
simpa [w] using nat_mul_inj h
theorem bit0_injective : Function.Injective (bit0 : R → R) := fun a b h => by
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a b : R
h : bit0 a = bit0 b
⊢ a = b

Next tactic:
dsimp [bit0] at h
theorem bit0_injective : Function.Injective (bit0 : R → R) := fun a b h => by
  dsimp [bit0] at h
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a b : R
h : a + a = b + b
⊢ a = b

Next tactic:
simp only [(two_mul a).symm, (two_mul b).symm] at h
theorem bit0_injective : Function.Injective (bit0 : R → R) := fun a b h => by
  dsimp [bit0] at h
  simp only [(two_mul a).symm, (two_mul b).symm] at h
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a b : R
h : 2 * a = 2 * b
⊢ a = b

Next tactic:
refine' nat_mul_inj' _ two_ne_zero
theorem bit0_injective : Function.Injective (bit0 : R → R) := fun a b h => by
  dsimp [bit0] at h
  simp only [(two_mul a).symm, (two_mul b).symm] at h
  refine' nat_mul_inj' _ two_ne_zero
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a b : R
h : 2 * a = 2 * b
⊢ ↑2 * a = ↑2 * b

Next tactic:
exact mod_cast h
theorem bit1_injective : Function.Injective (bit1 : R → R) := fun a b h => by
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a b : R
h : bit1 a = bit1 b
⊢ a = b

Next tactic:
simp only [bit1, add_left_inj] at h
theorem bit1_injective : Function.Injective (bit1 : R → R) := fun a b h => by
  simp only [bit1, add_left_inj] at h
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a b : R
h : bit0 a = bit0 b
⊢ a = b

Next tactic:
exact bit0_injective h
@[simp]
theorem bit1_eq_one {a : R} : bit1 a = 1 ↔ a = 0 := by
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a : R
⊢ bit1 a = 1 ↔ a = 0

Next tactic:
rw [show (1 : R) = bit1 0 by simp, bit1_eq_bit1]
@[simp]
theorem bit1_eq_one {a : R} : bit1 a = 1 ↔ a = 0 := by
  rw [show (1 : R) = bit1 0 by 

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a : R
⊢ 1 = bit1 0

Next tactic:
simp
@[simp]
theorem one_eq_bit1 {a : R} : 1 = bit1 a ↔ a = 0 := by
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a : R
⊢ 1 = bit1 a ↔ a = 0

Next tactic:
rw [eq_comm]
@[simp]
theorem one_eq_bit1 {a : R} : 1 = bit1 a ↔ a = 0 := by
  rw [eq_comm]
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : CharZero R
a : R
⊢ bit1 a = 1 ↔ a = 0

Next tactic:
exact bit1_eq_one
@[simp]
theorem half_add_self (a : R) : (a + a) / 2 = a := by 

Proof state:
R : Type u_1
inst✝¹ : DivisionRing R
inst✝ : CharZero R
a : R
⊢ (a + a) / 2 = a

Next tactic:
rw [← mul_two, mul_div_cancel a two_ne_zero]
@[simp]
theorem add_halves' (a : R) : a / 2 + a / 2 = a := by 

Proof state:
R : Type u_1
inst✝¹ : DivisionRing R
inst✝ : CharZero R
a : R
⊢ a / 2 + a / 2 = a

Next tactic:
rw [← add_div, half_add_self]
theorem sub_half (a : R) : a - a / 2 = a / 2 := by 

Proof state:
R : Type u_1
inst✝¹ : DivisionRing R
inst✝ : CharZero R
a : R
⊢ a - a / 2 = a / 2

Next tactic:
rw [sub_eq_iff_eq_add, add_halves']
theorem half_sub (a : R) : a / 2 - a = -(a / 2) := by 

Proof state:
R : Type u_1
inst✝¹ : DivisionRing R
inst✝ : CharZero R
a : R
⊢ a / 2 - a = -(a / 2)

Next tactic:
rw [← neg_sub, sub_half]
instance {R : Type*} [AddMonoidWithOne R] [CharZero R] :
    CharZero (WithTop R) where
  cast_injective m n h := by
    

Proof state:
R : Type u_1
inst✝¹ : AddMonoidWithOne R
inst✝ : CharZero R
m n : ℕ
h : ↑m = ↑n
⊢ m = n

Next tactic:
rwa [← coe_nat, ← coe_nat n, coe_eq_coe, Nat.cast_inj] at h
instance {R : Type*} [AddMonoidWithOne R] [CharZero R] :
    CharZero (WithBot R) where
  cast_injective m n h := by
    

Proof state:
R : Type u_1
inst✝¹ : AddMonoidWithOne R
inst✝ : CharZero R
m n : ℕ
h : ↑m = ↑n
⊢ m = n

Next tactic:
rwa [← coe_nat, ← coe_nat n, coe_eq_coe, Nat.cast_inj] at h
theorem RingHom.charZero (ϕ : R →+* S) [hS : CharZero S] : CharZero R :=
  ⟨fun a b h => CharZero.cast_injective (by 

Proof state:
R : Type u_1
S : Type u_2
inst✝¹ : NonAssocSemiring R
inst✝ : NonAssocSemiring S
ϕ : R →+* S
hS : CharZero S
a b : ℕ
h : ↑a = ↑b
⊢ ↑a = ↑b

Next tactic:
rw [← map_natCast ϕ, ← map_natCast ϕ, h]
theorem RingHom.charZero_iff {ϕ : R →+* S} (hϕ : Function.Injective ϕ) : CharZero R ↔ CharZero S :=
  ⟨fun hR =>
    ⟨by 

Proof state:
R : Type u_1
S : Type u_2
inst✝¹ : NonAssocSemiring R
inst✝ : NonAssocSemiring S
ϕ : R →+* S
hϕ : Injective ⇑ϕ
hR : CharZero R
⊢ Injective Nat.cast

Next tactic:
intro a b h
theorem RingHom.charZero_iff {ϕ : R →+* S} (hϕ : Function.Injective ϕ) : CharZero R ↔ CharZero S :=
  ⟨fun hR =>
    ⟨by intro a b h; 

Proof state:
R : Type u_1
S : Type u_2
inst✝¹ : NonAssocSemiring R
inst✝ : NonAssocSemiring S
ϕ : R →+* S
hϕ : Injective ⇑ϕ
hR : CharZero R
a b : ℕ
h : ↑a = ↑b
⊢ a = b

Next tactic:
rwa [← @Nat.cast_inj R, ← hϕ.eq_iff, map_natCast ϕ, map_natCast ϕ]
instance : T0Space X.carrier := by
  

Proof state:
X : Scheme
⊢ T0Space ↑↑X.toPresheafedSpace

Next tactic:
refine' T0Space.of_open_cover fun x => _
instance : T0Space X.carrier := by
  refine' T0Space.of_open_cover fun x => _
  

Proof state:
X : Scheme
x : ↑↑X.toPresheafedSpace
⊢ ∃ s, x ∈ s ∧ IsOpen s ∧ T0Space ↑s

Next tactic:
obtain ⟨U, R, ⟨e⟩⟩ := X.local_affine x
instance : T0Space X.carrier := by
  refine' T0Space.of_open_cover fun x => _
  obtain ⟨U, R, ⟨e⟩⟩ := X.local_affine x
  

Proof state:
case intro.intro.intro
X : Scheme
x : ↑↑X.toPresheafedSpace
U : OpenNhds x
R : CommRingCat
e :
  LocallyRingedSpace.restrict X.toLocallyRingedSpace (_ : OpenEmbedding ⇑(Opens.inclusion U.obj)) ≅
    Spec.toLocallyRingedSpace.obj (op R)
⊢ ∃ s, x ∈ s ∧ IsOpen s ∧ T0Space ↑s

Next tactic:
let e' : U.1 ≃ₜ PrimeSpectrum R :=
    homeoOfIso ((LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forget _).mapIso e)
instance : T0Space X.carrier := by
  refine' T0Space.of_open_cover fun x => _
  obtain ⟨U, R, ⟨e⟩⟩ := X.local_affine x
  let e' : U.1 ≃ₜ PrimeSpectrum R :=
    homeoOfIso ((LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forget _).mapIso e)
  

Proof state:
case intro.intro.intro
X : Scheme
x : ↑↑X.toPresheafedSpace
U : OpenNhds x
R : CommRingCat
e :
  LocallyRingedSpace.restrict X.toLocallyRingedSpace (_ : OpenEmbedding ⇑(Opens.inclusion U.obj)) ≅
    Spec.toLocallyRingedSpace.obj (op R)
e' : ↥U.obj ≃ₜ PrimeSpectrum ↑R :=
  homeoOfIso ((LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forget CommRingCat).mapIso e)
⊢ ∃ s, x ∈ s ∧ IsOpen s ∧ T0Space ↑s

Next tactic:
exact ⟨U.1.1, U.2, U.1.2, e'.embedding.t0Space⟩
instance : QuasiSober X.carrier := by
  

Proof state:
X : Scheme
⊢ QuasiSober ↑↑X.toPresheafedSpace

Next tactic:
apply (config := { allowSynthFailures := true })
    quasiSober_of_open_cover (Set.range fun x => Set.range <| (X.affineCover.map x).1.base)
instance : QuasiSober X.carrier := by
  apply (config := { allowSynthFailures := true })
    quasiSober_of_open_cover (Set.range fun x => Set.range <| (X.affineCover.map x).1.base)
  · 

Proof state:
case hS
X : Scheme
⊢ ∀ (s : ↑(Set.range fun x => Set.range ⇑(Scheme.OpenCover.map (Scheme.affineCover X) x).val.base)), IsOpen ↑s

Next tactic:
rintro ⟨_, i, rfl⟩
instance : QuasiSober X.carrier := by
  apply (config := { allowSynthFailures := true })
    quasiSober_of_open_cover (Set.range fun x => Set.range <| (X.affineCover.map x).1.base)
  · rintro ⟨_, i, rfl⟩; 

Proof state:
case hS.mk.intro
X : Scheme
i : (Scheme.affineCover X).J
⊢ IsOpen
    ↑{ val := (fun x => Set.range ⇑(Scheme.OpenCover.map (Scheme.affineCover X) x).val.base) i,
        property :=
          (_ :
            ∃ y,
              (fun x => Set.range ⇑(Scheme.OpenCover.map (Scheme.affineCover X) x).val.base) y =
                (fun x => Set.range ⇑(Scheme.OpenCover.map (Scheme.affineCover X) x).val.base) i) }

Next tactic:
exact (X.affineCover.IsOpen i).base_open.open_range
instance : QuasiSober X.carrier := by
  apply (config := { allowSynthFailures := true })
    quasiSober_of_open_cover (Set.range fun x => Set.range <| (X.affineCover.map x).1.base)
  · rintro ⟨_, i, rfl⟩; exact (X.affineCover.IsOpen i).base_open.open_range
  · 

Proof state:
case hS'
X : Scheme
⊢ ∀ (s : ↑(Set.range fun x => Set.range ⇑(Scheme.OpenCover.map (Scheme.affineCover X) x).val.base)), QuasiSober ↑↑s

Next tactic:
rintro ⟨_, i, rfl⟩
instance : QuasiSober X.carrier := by
  apply (config := { allowSynthFailures := true })
    quasiSober_of_open_cover (Set.range fun x => Set.range <| (X.affineCover.map x).1.base)
  · rintro ⟨_, i, rfl⟩; exact (X.affineCover.IsOpen i).base_open.open_range
  · rintro ⟨_, i, rfl⟩
    

Proof state:
case hS'.mk.intro
X : Scheme
i : (Scheme.affineCover X).J
⊢ QuasiSober
    ↑↑{ val := (fun x => Set.range ⇑(Scheme.OpenCover.map (Scheme.affineCover X) x).val.base) i,
          property :=
            (_ :
              ∃ y,
                (fun x => Set.range ⇑(Scheme.OpenCover.map (Scheme.affineCover X) x).val.base) y =
                  (fun x => Set.range ⇑(Scheme.OpenCover.map (Scheme.affineCover X) x).val.base) i) }

Next tactic:
exact @OpenEmbedding.quasiSober _ _ _ _ _ (Homeomorph.ofEmbedding _
      (X.affineCover.IsOpen i).base_open.toEmbedding).symm.openEmbedding PrimeSpectrum.quasiSober
instance : QuasiSober X.carrier := by
  apply (config := { allowSynthFailures := true })
    quasiSober_of_open_cover (Set.range fun x => Set.range <| (X.affineCover.map x).1.base)
  · rintro ⟨_, i, rfl⟩; exact (X.affineCover.IsOpen i).base_open.open_range
  · rintro ⟨_, i, rfl⟩
    exact @OpenEmbedding.quasiSober _ _ _ _ _ (Homeomorph.ofEmbedding _
      (X.affineCover.IsOpen i).base_open.toEmbedding).symm.openEmbedding PrimeSpectrum.quasiSober
  · 

Proof state:
case hS''
X : Scheme
⊢ (⋃₀ Set.range fun x => Set.range ⇑(Scheme.OpenCover.map (Scheme.affineCover X) x).val.base) = ⊤

Next tactic:
rw [Set.top_eq_univ, Set.sUnion_range, Set.eq_univ_iff_forall]
instance : QuasiSober X.carrier := by
  apply (config := { allowSynthFailures := true })
    quasiSober_of_open_cover (Set.range fun x => Set.range <| (X.affineCover.map x).1.base)
  · rintro ⟨_, i, rfl⟩; exact (X.affineCover.IsOpen i).base_open.open_range
  · rintro ⟨_, i, rfl⟩
    exact @OpenEmbedding.quasiSober _ _ _ _ _ (Homeomorph.ofEmbedding _
      (X.affineCover.IsOpen i).base_open.toEmbedding).symm.openEmbedding PrimeSpectrum.quasiSober
  · rw [Set.top_eq_univ, Set.sUnion_range, Set.eq_univ_iff_forall]
    

Proof state:
case hS''
X : Scheme
⊢ ∀ (x : (forget TopCat).obj ↑X.toPresheafedSpace),
    x ∈ ⋃ x, Set.range ⇑(Scheme.OpenCover.map (Scheme.affineCover X) x).val.base

Next tactic:
intro x
instance : QuasiSober X.carrier := by
  apply (config := { allowSynthFailures := true })
    quasiSober_of_open_cover (Set.range fun x => Set.range <| (X.affineCover.map x).1.base)
  · rintro ⟨_, i, rfl⟩; exact (X.affineCover.IsOpen i).base_open.open_range
  · rintro ⟨_, i, rfl⟩
    exact @OpenEmbedding.quasiSober _ _ _ _ _ (Homeomorph.ofEmbedding _
      (X.affineCover.IsOpen i).base_open.toEmbedding).symm.openEmbedding PrimeSpectrum.quasiSober
  · rw [Set.top_eq_univ, Set.sUnion_range, Set.eq_univ_iff_forall]
    intro x; 

Proof state:
case hS''
X : Scheme
x : (forget TopCat).obj ↑X.toPresheafedSpace
⊢ x ∈ ⋃ x, Set.range ⇑(Scheme.OpenCover.map (Scheme.affineCover X) x).val.base

Next tactic:
exact ⟨_, ⟨_, rfl⟩, X.affineCover.Covers x⟩
theorem isReducedOfStalkIsReduced [∀ x : X.carrier, _root_.IsReduced (X.presheaf.stalk x)] :
    IsReduced X := by
  

Proof state:
X : Scheme
inst✝ : ∀ (x : ↑↑X.toPresheafedSpace), _root_.IsReduced ↑(Presheaf.stalk X.presheaf x)
⊢ IsReduced X

Next tactic:
refine' ⟨fun U => ⟨fun s hs => _⟩⟩
theorem isReducedOfStalkIsReduced [∀ x : X.carrier, _root_.IsReduced (X.presheaf.stalk x)] :
    IsReduced X := by
  refine' ⟨fun U => ⟨fun s hs => _⟩⟩
  

Proof state:
X : Scheme
inst✝ : ∀ (x : ↑↑X.toPresheafedSpace), _root_.IsReduced ↑(Presheaf.stalk X.presheaf x)
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : IsNilpotent s
⊢ s = 0

Next tactic:
apply Presheaf.section_ext X.sheaf U s 0
theorem isReducedOfStalkIsReduced [∀ x : X.carrier, _root_.IsReduced (X.presheaf.stalk x)] :
    IsReduced X := by
  refine' ⟨fun U => ⟨fun s hs => _⟩⟩
  apply Presheaf.section_ext X.sheaf U s 0
  

Proof state:
X : Scheme
inst✝ : ∀ (x : ↑↑X.toPresheafedSpace), _root_.IsReduced ↑(Presheaf.stalk X.presheaf x)
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : IsNilpotent s
⊢ ∀ (x : ↥U),
    (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) 0

Next tactic:
intro x
theorem isReducedOfStalkIsReduced [∀ x : X.carrier, _root_.IsReduced (X.presheaf.stalk x)] :
    IsReduced X := by
  refine' ⟨fun U => ⟨fun s hs => _⟩⟩
  apply Presheaf.section_ext X.sheaf U s 0
  intro x
  

Proof state:
X : Scheme
inst✝ : ∀ (x : ↑↑X.toPresheafedSpace), _root_.IsReduced ↑(Presheaf.stalk X.presheaf x)
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : IsNilpotent s
x : ↥U
⊢ (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) 0

Next tactic:
rw [RingHom.map_zero]
theorem isReducedOfStalkIsReduced [∀ x : X.carrier, _root_.IsReduced (X.presheaf.stalk x)] :
    IsReduced X := by
  refine' ⟨fun U => ⟨fun s hs => _⟩⟩
  apply Presheaf.section_ext X.sheaf U s 0
  intro x
  rw [RingHom.map_zero]
  

Proof state:
X : Scheme
inst✝ : ∀ (x : ↑↑X.toPresheafedSpace), _root_.IsReduced ↑(Presheaf.stalk X.presheaf x)
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : IsNilpotent s
x : ↥U
⊢ (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0

Next tactic:
change X.presheaf.germ x s = 0
theorem isReducedOfStalkIsReduced [∀ x : X.carrier, _root_.IsReduced (X.presheaf.stalk x)] :
    IsReduced X := by
  refine' ⟨fun U => ⟨fun s hs => _⟩⟩
  apply Presheaf.section_ext X.sheaf U s 0
  intro x
  rw [RingHom.map_zero]
  change X.presheaf.germ x s = 0
  

Proof state:
X : Scheme
inst✝ : ∀ (x : ↑↑X.toPresheafedSpace), _root_.IsReduced ↑(Presheaf.stalk X.presheaf x)
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : IsNilpotent s
x : ↥U
⊢ (Presheaf.germ X.presheaf x) s = 0

Next tactic:
exact (hs.map _).eq_zero
instance stalk_isReduced_of_reduced [IsReduced X] (x : X.carrier) :
    _root_.IsReduced (X.presheaf.stalk x) := by
  

Proof state:
X : Scheme
inst✝ : IsReduced X
x : ↑↑X.toPresheafedSpace
⊢ _root_.IsReduced ↑(Presheaf.stalk X.presheaf x)

Next tactic:
constructor
instance stalk_isReduced_of_reduced [IsReduced X] (x : X.carrier) :
    _root_.IsReduced (X.presheaf.stalk x) := by
  constructor
  

Proof state:
case eq_zero
X : Scheme
inst✝ : IsReduced X
x : ↑↑X.toPresheafedSpace
⊢ ∀ (x_1 : ↑(Presheaf.stalk X.presheaf x)), IsNilpotent x_1 → x_1 = 0

Next tactic:
rintro g ⟨n, e⟩
instance stalk_isReduced_of_reduced [IsReduced X] (x : X.carrier) :
    _root_.IsReduced (X.presheaf.stalk x) := by
  constructor
  rintro g ⟨n, e⟩
  

Proof state:
case eq_zero.intro
X : Scheme
inst✝ : IsReduced X
x : ↑↑X.toPresheafedSpace
g : ↑(Presheaf.stalk X.presheaf x)
n : ℕ
e : g ^ n = 0
⊢ g = 0

Next tactic:
obtain ⟨U, hxU, s, rfl⟩ := X.presheaf.germ_exist x g
instance stalk_isReduced_of_reduced [IsReduced X] (x : X.carrier) :
    _root_.IsReduced (X.presheaf.stalk x) := by
  constructor
  rintro g ⟨n, e⟩
  obtain ⟨U, hxU, s, rfl⟩ := X.presheaf.germ_exist x g
  

Proof state:
case eq_zero.intro.intro.intro.intro
X : Scheme
inst✝ : IsReduced X
x : ↑↑X.toPresheafedSpace
n : ℕ
U : Opens ↑↑X.toPresheafedSpace
hxU : x ∈ U
s : (forget CommRingCat).obj (X.presheaf.obj (op U))
e : (Presheaf.germ X.presheaf { val := x, property := hxU }) s ^ n = 0
⊢ (Presheaf.germ X.presheaf { val := x, property := hxU }) s = 0

Next tactic:
rw [← map_pow, ← map_zero (X.presheaf.germ ⟨x, hxU⟩)] at e
instance stalk_isReduced_of_reduced [IsReduced X] (x : X.carrier) :
    _root_.IsReduced (X.presheaf.stalk x) := by
  constructor
  rintro g ⟨n, e⟩
  obtain ⟨U, hxU, s, rfl⟩ := X.presheaf.germ_exist x g
  rw [← map_pow, ← map_zero (X.presheaf.germ ⟨x, hxU⟩)] at e
  

Proof state:
case eq_zero.intro.intro.intro.intro
X : Scheme
inst✝ : IsReduced X
x : ↑↑X.toPresheafedSpace
n : ℕ
U : Opens ↑↑X.toPresheafedSpace
hxU : x ∈ U
s : (forget CommRingCat).obj (X.presheaf.obj (op U))
e :
  (Presheaf.germ X.presheaf { val := x, property := hxU }) (s ^ n) =
    (Presheaf.germ X.presheaf { val := x, property := hxU }) 0
⊢ (Presheaf.germ X.presheaf { val := x, property := hxU }) s = 0

Next tactic:
obtain ⟨V, hxV, iU, iV, e'⟩ := X.presheaf.germ_eq x hxU hxU _ 0 e
instance stalk_isReduced_of_reduced [IsReduced X] (x : X.carrier) :
    _root_.IsReduced (X.presheaf.stalk x) := by
  constructor
  rintro g ⟨n, e⟩
  obtain ⟨U, hxU, s, rfl⟩ := X.presheaf.germ_exist x g
  rw [← map_pow, ← map_zero (X.presheaf.germ ⟨x, hxU⟩)] at e
  obtain ⟨V, hxV, iU, iV, e'⟩ := X.presheaf.germ_eq x hxU hxU _ 0 e
  

Proof state:
case eq_zero.intro.intro.intro.intro.intro.intro.intro.intro
X : Scheme
inst✝ : IsReduced X
x : ↑↑X.toPresheafedSpace
n : ℕ
U : Opens ↑↑X.toPresheafedSpace
hxU : x ∈ U
s : (forget CommRingCat).obj (X.presheaf.obj (op U))
e :
  (Presheaf.germ X.presheaf { val := x, property := hxU }) (s ^ n) =
    (Presheaf.germ X.presheaf { val := x, property := hxU }) 0
V : Opens ↑↑X.toPresheafedSpace
hxV : x ∈ V
iU iV : V ⟶ U
e' : (X.presheaf.map iU.op) (s ^ n) = (X.presheaf.map iV.op) 0
⊢ (Presheaf.germ X.presheaf { val := x, property := hxU }) s = 0

Next tactic:
rw [map_pow, map_zero] at e'
instance stalk_isReduced_of_reduced [IsReduced X] (x : X.carrier) :
    _root_.IsReduced (X.presheaf.stalk x) := by
  constructor
  rintro g ⟨n, e⟩
  obtain ⟨U, hxU, s, rfl⟩ := X.presheaf.germ_exist x g
  rw [← map_pow, ← map_zero (X.presheaf.germ ⟨x, hxU⟩)] at e
  obtain ⟨V, hxV, iU, iV, e'⟩ := X.presheaf.germ_eq x hxU hxU _ 0 e
  rw [map_pow, map_zero] at e'
  

Proof state:
case eq_zero.intro.intro.intro.intro.intro.intro.intro.intro
X : Scheme
inst✝ : IsReduced X
x : ↑↑X.toPresheafedSpace
n : ℕ
U : Opens ↑↑X.toPresheafedSpace
hxU : x ∈ U
s : (forget CommRingCat).obj (X.presheaf.obj (op U))
e :
  (Presheaf.germ X.presheaf { val := x, property := hxU }) (s ^ n) =
    (Presheaf.germ X.presheaf { val := x, property := hxU }) 0
V : Opens ↑↑X.toPresheafedSpace
hxV : x ∈ V
iU iV : V ⟶ U
e' : (X.presheaf.map iU.op) s ^ n = 0
⊢ (Presheaf.germ X.presheaf { val := x, property := hxU }) s = 0

Next tactic:
replace e' := (IsNilpotent.mk _ _ e').eq_zero (R := X.presheaf.obj <| op V)