l3lab/ntp-mathlib huggingface dataset:
theorem IsLocalization.surj_of_gcd_domain (M : Submonoid R) [IsLocalization M A] (z : A) :
    ∃ a b : R, IsUnit (gcd a b) ∧ z * algebraMap R A b = algebraMap R A a := by
  obtain ⟨x, ⟨y, hy⟩, rfl⟩ := IsLocalization.mk'_surjective M z
  obtain ⟨x', y', hx', hy', hu⟩ := extract_gcd x y
  use x', y', hu
  

Proof state:
case right
R : Type u_1
A : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : GCDMonoid R
inst✝² : CommRing A
inst✝¹ : Algebra R A
M : Submonoid R
inst✝ : IsLocalization M A
x y : R
hy : y ∈ M
x' y' : R
hx' : x = gcd x y * x'
hy' : y = gcd x y * y'
hu : IsUnit (gcd x' y')
⊢ mk' A x { val := y, property := hy } * (algebraMap R A) y' = (algebraMap R A) x'

Next tactic:
rw [mul_comm, IsLocalization.mul_mk'_eq_mk'_of_mul]
theorem IsLocalization.surj_of_gcd_domain (M : Submonoid R) [IsLocalization M A] (z : A) :
    ∃ a b : R, IsUnit (gcd a b) ∧ z * algebraMap R A b = algebraMap R A a := by
  obtain ⟨x, ⟨y, hy⟩, rfl⟩ := IsLocalization.mk'_surjective M z
  obtain ⟨x', y', hx', hy', hu⟩ := extract_gcd x y
  use x', y', hu
  rw [mul_comm, IsLocalization.mul_mk'_eq_mk'_of_mul]
  

Proof state:
case right
R : Type u_1
A : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : GCDMonoid R
inst✝² : CommRing A
inst✝¹ : Algebra R A
M : Submonoid R
inst✝ : IsLocalization M A
x y : R
hy : y ∈ M
x' y' : R
hx' : x = gcd x y * x'
hy' : y = gcd x y * y'
hu : IsUnit (gcd x' y')
⊢ mk' A (y' * x) { val := y, property := hy } = (algebraMap R A) x'

Next tactic:
convert IsLocalization.mk'_mul_cancel_left (M := M) (S := A) _ _ using 2
theorem IsLocalization.surj_of_gcd_domain (M : Submonoid R) [IsLocalization M A] (z : A) :
    ∃ a b : R, IsUnit (gcd a b) ∧ z * algebraMap R A b = algebraMap R A a := by
  obtain ⟨x, ⟨y, hy⟩, rfl⟩ := IsLocalization.mk'_surjective M z
  obtain ⟨x', y', hx', hy', hu⟩ := extract_gcd x y
  use x', y', hu
  rw [mul_comm, IsLocalization.mul_mk'_eq_mk'_of_mul]
  convert IsLocalization.mk'_mul_cancel_left (M := M) (S := A) _ _ using 2
  

Proof state:
case h.e'_2.h.e'_8
R : Type u_1
A : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : GCDMonoid R
inst✝² : CommRing A
inst✝¹ : Algebra R A
M : Submonoid R
inst✝ : IsLocalization M A
x y : R
hy : y ∈ M
x' y' : R
hx' : x = gcd x y * x'
hy' : y = gcd x y * y'
hu : IsUnit (gcd x' y')
⊢ y' * x = ↑{ val := y, property := hy } * x'

Next tactic:
rw [Subtype.coe_mk, hy', ← mul_comm y', mul_assoc]
theorem IsLocalization.surj_of_gcd_domain (M : Submonoid R) [IsLocalization M A] (z : A) :
    ∃ a b : R, IsUnit (gcd a b) ∧ z * algebraMap R A b = algebraMap R A a := by
  obtain ⟨x, ⟨y, hy⟩, rfl⟩ := IsLocalization.mk'_surjective M z
  obtain ⟨x', y', hx', hy', hu⟩ := extract_gcd x y
  use x', y', hu
  rw [mul_comm, IsLocalization.mul_mk'_eq_mk'_of_mul]
  convert IsLocalization.mk'_mul_cancel_left (M := M) (S := A) _ _ using 2
  rw [Subtype.coe_mk, hy', ← mul_comm y', mul_assoc]; 

Proof state:
case h.e'_2.h.e'_8
R : Type u_1
A : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : GCDMonoid R
inst✝² : CommRing A
inst✝¹ : Algebra R A
M : Submonoid R
inst✝ : IsLocalization M A
x y : R
hy : y ∈ M
x' y' : R
hx' : x = gcd x y * x'
hy' : y = gcd x y * y'
hu : IsUnit (gcd x' y')
⊢ y' * x = y' * (gcd x y * x')

Next tactic:
conv_lhs => rw [hx']
theorem IsLocalization.surj_of_gcd_domain (M : Submonoid R) [IsLocalization M A] (z : A) :
    ∃ a b : R, IsUnit (gcd a b) ∧ z * algebraMap R A b = algebraMap R A a := by
  obtain ⟨x, ⟨y, hy⟩, rfl⟩ := IsLocalization.mk'_surjective M z
  obtain ⟨x', y', hx', hy', hu⟩ := extract_gcd x y
  use x', y', hu
  rw [mul_comm, IsLocalization.mul_mk'_eq_mk'_of_mul]
  convert IsLocalization.mk'_mul_cancel_left (M := M) (S := A) _ _ using 2
  rw [Subtype.coe_mk, hy', ← mul_comm y', mul_assoc]; conv_lhs => 

Proof state:
R : Type u_1
A : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : GCDMonoid R
inst✝² : CommRing A
inst✝¹ : Algebra R A
M : Submonoid R
inst✝ : IsLocalization M A
x y : R
hy : y ∈ M
x' y' : R
hx' : x = gcd x y * x'
hy' : y = gcd x y * y'
hu : IsUnit (gcd x' y')
| y' * x

Next tactic:
rw [hx']
instance (priority := 100) GCDMonoid.toIsIntegrallyClosed : IsIntegrallyClosed R :=
  ⟨fun {X} ⟨p, hp₁, hp₂⟩ => by
    

Proof state:
R : Type u_1
A : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : GCDMonoid R
inst✝¹ : CommRing A
inst✝ : Algebra R A
X : FractionRing R
x✝ : IsIntegral R X
p : R[X]
hp₁ : Polynomial.Monic p
hp₂ : Polynomial.eval₂ (algebraMap R (FractionRing R)) X p = 0
⊢ ∃ y, (algebraMap R (FractionRing R)) y = X

Next tactic:
obtain ⟨x, y, hg, he⟩ := IsLocalization.surj_of_gcd_domain (nonZeroDivisors R) X
instance (priority := 100) GCDMonoid.toIsIntegrallyClosed : IsIntegrallyClosed R :=
  ⟨fun {X} ⟨p, hp₁, hp₂⟩ => by
    obtain ⟨x, y, hg, he⟩ := IsLocalization.surj_of_gcd_domain (nonZeroDivisors R) X
    

Proof state:
case intro.intro.intro
R : Type u_1
A : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : GCDMonoid R
inst✝¹ : CommRing A
inst✝ : Algebra R A
X : FractionRing R
x✝ : IsIntegral R X
p : R[X]
hp₁ : Polynomial.Monic p
hp₂ : Polynomial.eval₂ (algebraMap R (FractionRing R)) X p = 0
x y : R
hg : IsUnit (gcd x y)
he : X * (algebraMap R (FractionRing R)) y = (algebraMap R (FractionRing R)) x
⊢ ∃ y, (algebraMap R (FractionRing R)) y = X

Next tactic:
have :=
      Polynomial.dvd_pow_natDegree_of_eval₂_eq_zero (IsFractionRing.injective R <| FractionRing R)
        hp₁ y x _ hp₂ (by rw [mul_comm, he])
instance (priority := 100) GCDMonoid.toIsIntegrallyClosed : IsIntegrallyClosed R :=
  ⟨fun {X} ⟨p, hp₁, hp₂⟩ => by
    obtain ⟨x, y, hg, he⟩ := IsLocalization.surj_of_gcd_domain (nonZeroDivisors R) X
    have :=
      Polynomial.dvd_pow_natDegree_of_eval₂_eq_zero (IsFractionRing.injective R <| FractionRing R)
        hp₁ y x _ hp₂ (by 

Proof state:
R : Type u_1
A : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : GCDMonoid R
inst✝¹ : CommRing A
inst✝ : Algebra R A
X : FractionRing R
x✝ : IsIntegral R X
p : R[X]
hp₁ : Polynomial.Monic p
hp₂ : Polynomial.eval₂ (algebraMap R (FractionRing R)) X p = 0
x y : R
hg : IsUnit (gcd x y)
he : X * (algebraMap R (FractionRing R)) y = (algebraMap R (FractionRing R)) x
⊢ (algebraMap R (FractionRing R)) y * X = (algebraMap R (FractionRing R)) x

Next tactic:
rw [mul_comm, he]
instance (priority := 100) GCDMonoid.toIsIntegrallyClosed : IsIntegrallyClosed R :=
  ⟨fun {X} ⟨p, hp₁, hp₂⟩ => by
    obtain ⟨x, y, hg, he⟩ := IsLocalization.surj_of_gcd_domain (nonZeroDivisors R) X
    have :=
      Polynomial.dvd_pow_natDegree_of_eval₂_eq_zero (IsFractionRing.injective R <| FractionRing R)
        hp₁ y x _ hp₂ (by rw [mul_comm, he])
    

Proof state:
case intro.intro.intro
R : Type u_1
A : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : GCDMonoid R
inst✝¹ : CommRing A
inst✝ : Algebra R A
X : FractionRing R
x✝ : IsIntegral R X
p : R[X]
hp₁ : Polynomial.Monic p
hp₂ : Polynomial.eval₂ (algebraMap R (FractionRing R)) X p = 0
x y : R
hg : IsUnit (gcd x y)
he : X * (algebraMap R (FractionRing R)) y = (algebraMap R (FractionRing R)) x
this : y ∣ x ^ Polynomial.natDegree p
⊢ ∃ y, (algebraMap R (FractionRing R)) y = X

Next tactic:
have : IsUnit y := by
      rw [isUnit_iff_dvd_one, ← one_pow]
      exact
        (dvd_gcd this <| dvd_refl y).trans
          (gcd_pow_left_dvd_pow_gcd.trans <| pow_dvd_pow_of_dvd (isUnit_iff_dvd_one.1 hg) _)
instance (priority := 100) GCDMonoid.toIsIntegrallyClosed : IsIntegrallyClosed R :=
  ⟨fun {X} ⟨p, hp₁, hp₂⟩ => by
    obtain ⟨x, y, hg, he⟩ := IsLocalization.surj_of_gcd_domain (nonZeroDivisors R) X
    have :=
      Polynomial.dvd_pow_natDegree_of_eval₂_eq_zero (IsFractionRing.injective R <| FractionRing R)
        hp₁ y x _ hp₂ (by rw [mul_comm, he])
    have : IsUnit y := by
      

Proof state:
R : Type u_1
A : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : GCDMonoid R
inst✝¹ : CommRing A
inst✝ : Algebra R A
X : FractionRing R
x✝ : IsIntegral R X
p : R[X]
hp₁ : Polynomial.Monic p
hp₂ : Polynomial.eval₂ (algebraMap R (FractionRing R)) X p = 0
x y : R
hg : IsUnit (gcd x y)
he : X * (algebraMap R (FractionRing R)) y = (algebraMap R (FractionRing R)) x
this : y ∣ x ^ Polynomial.natDegree p
⊢ IsUnit y

Next tactic:
rw [isUnit_iff_dvd_one, ← one_pow]
instance (priority := 100) GCDMonoid.toIsIntegrallyClosed : IsIntegrallyClosed R :=
  ⟨fun {X} ⟨p, hp₁, hp₂⟩ => by
    obtain ⟨x, y, hg, he⟩ := IsLocalization.surj_of_gcd_domain (nonZeroDivisors R) X
    have :=
      Polynomial.dvd_pow_natDegree_of_eval₂_eq_zero (IsFractionRing.injective R <| FractionRing R)
        hp₁ y x _ hp₂ (by rw [mul_comm, he])
    have : IsUnit y := by
      rw [isUnit_iff_dvd_one, ← one_pow]
      

Proof state:
R : Type u_1
A : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : GCDMonoid R
inst✝¹ : CommRing A
inst✝ : Algebra R A
X : FractionRing R
x✝ : IsIntegral R X
p : R[X]
hp₁ : Polynomial.Monic p
hp₂ : Polynomial.eval₂ (algebraMap R (FractionRing R)) X p = 0
x y : R
hg : IsUnit (gcd x y)
he : X * (algebraMap R (FractionRing R)) y = (algebraMap R (FractionRing R)) x
this : y ∣ x ^ Polynomial.natDegree p
⊢ y ∣ 1 ^ ?m.58159
R : Type u_1
A : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : GCDMonoid R
inst✝¹ : CommRing A
inst✝ : Algebra R A
X : FractionRing R
x✝ : IsIntegral R X
p : R[X]
hp₁ : Polynomial.Monic p
hp₂ : Polynomial.eval₂ (algebraMap R (FractionRing R)) X p = 0
x y : R
hg : IsUnit (gcd x y)
he : X * (algebraMap R (FractionRing R)) y = (algebraMap R (FractionRing R)) x
this : y ∣ x ^ Polynomial.natDegree p
⊢ ℕ

Next tactic:
exact
        (dvd_gcd this <| dvd_refl y).trans
          (gcd_pow_left_dvd_pow_gcd.trans <| pow_dvd_pow_of_dvd (isUnit_iff_dvd_one.1 hg) _)
instance (priority := 100) GCDMonoid.toIsIntegrallyClosed : IsIntegrallyClosed R :=
  ⟨fun {X} ⟨p, hp₁, hp₂⟩ => by
    obtain ⟨x, y, hg, he⟩ := IsLocalization.surj_of_gcd_domain (nonZeroDivisors R) X
    have :=
      Polynomial.dvd_pow_natDegree_of_eval₂_eq_zero (IsFractionRing.injective R <| FractionRing R)
        hp₁ y x _ hp₂ (by rw [mul_comm, he])
    have : IsUnit y := by
      rw [isUnit_iff_dvd_one, ← one_pow]
      exact
        (dvd_gcd this <| dvd_refl y).trans
          (gcd_pow_left_dvd_pow_gcd.trans <| pow_dvd_pow_of_dvd (isUnit_iff_dvd_one.1 hg) _)
    

Proof state:
case intro.intro.intro
R : Type u_1
A : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : GCDMonoid R
inst✝¹ : CommRing A
inst✝ : Algebra R A
X : FractionRing R
x✝ : IsIntegral R X
p : R[X]
hp₁ : Polynomial.Monic p
hp₂ : Polynomial.eval₂ (algebraMap R (FractionRing R)) X p = 0
x y : R
hg : IsUnit (gcd x y)
he : X * (algebraMap R (FractionRing R)) y = (algebraMap R (FractionRing R)) x
this✝ : y ∣ x ^ Polynomial.natDegree p
this : IsUnit y
⊢ ∃ y, (algebraMap R (FractionRing R)) y = X

Next tactic:
use x * (this.unit⁻¹ : _)
instance (priority := 100) GCDMonoid.toIsIntegrallyClosed : IsIntegrallyClosed R :=
  ⟨fun {X} ⟨p, hp₁, hp₂⟩ => by
    obtain ⟨x, y, hg, he⟩ := IsLocalization.surj_of_gcd_domain (nonZeroDivisors R) X
    have :=
      Polynomial.dvd_pow_natDegree_of_eval₂_eq_zero (IsFractionRing.injective R <| FractionRing R)
        hp₁ y x _ hp₂ (by rw [mul_comm, he])
    have : IsUnit y := by
      rw [isUnit_iff_dvd_one, ← one_pow]
      exact
        (dvd_gcd this <| dvd_refl y).trans
          (gcd_pow_left_dvd_pow_gcd.trans <| pow_dvd_pow_of_dvd (isUnit_iff_dvd_one.1 hg) _)
    use x * (this.unit⁻¹ : _)
    

Proof state:
case h
R : Type u_1
A : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : GCDMonoid R
inst✝¹ : CommRing A
inst✝ : Algebra R A
X : FractionRing R
x✝ : IsIntegral R X
p : R[X]
hp₁ : Polynomial.Monic p
hp₂ : Polynomial.eval₂ (algebraMap R (FractionRing R)) X p = 0
x y : R
hg : IsUnit (gcd x y)
he : X * (algebraMap R (FractionRing R)) y = (algebraMap R (FractionRing R)) x
this✝ : y ∣ x ^ Polynomial.natDegree p
this : IsUnit y
⊢ (algebraMap R (FractionRing R)) (x * ↑(IsUnit.unit this)⁻¹) = X

Next tactic:
erw [map_mul, ← Units.coe_map_inv, eq_comm, Units.eq_mul_inv_iff_mul_eq]
instance (priority := 100) GCDMonoid.toIsIntegrallyClosed : IsIntegrallyClosed R :=
  ⟨fun {X} ⟨p, hp₁, hp₂⟩ => by
    obtain ⟨x, y, hg, he⟩ := IsLocalization.surj_of_gcd_domain (nonZeroDivisors R) X
    have :=
      Polynomial.dvd_pow_natDegree_of_eval₂_eq_zero (IsFractionRing.injective R <| FractionRing R)
        hp₁ y x _ hp₂ (by rw [mul_comm, he])
    have : IsUnit y := by
      rw [isUnit_iff_dvd_one, ← one_pow]
      exact
        (dvd_gcd this <| dvd_refl y).trans
          (gcd_pow_left_dvd_pow_gcd.trans <| pow_dvd_pow_of_dvd (isUnit_iff_dvd_one.1 hg) _)
    use x * (this.unit⁻¹ : _)
    erw [map_mul, ← Units.coe_map_inv, eq_comm, Units.eq_mul_inv_iff_mul_eq]
    

Proof state:
case h
R : Type u_1
A : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : GCDMonoid R
inst✝¹ : CommRing A
inst✝ : Algebra R A
X : FractionRing R
x✝ : IsIntegral R X
p : R[X]
hp₁ : Polynomial.Monic p
hp₂ : Polynomial.eval₂ (algebraMap R (FractionRing R)) X p = 0
x y : R
hg : IsUnit (gcd x y)
he : X * (algebraMap R (FractionRing R)) y = (algebraMap R (FractionRing R)) x
this✝ : y ∣ x ^ Polynomial.natDegree p
this : IsUnit y
⊢ X * ↑((Units.map ↑(algebraMap R (FractionRing R))) (IsUnit.unit this)) = (algebraMap R (FractionRing R)) x

Next tactic:
exact he
theorem IsSubfield.div_mem {S : Set F} (hS : IsSubfield S) {x y : F} (hx : x ∈ S) (hy : y ∈ S) :
    x / y ∈ S := by
  

Proof state:
F : Type u_1
inst✝ : Field F
S✝ S : Set F
hS : IsSubfield S
x y : F
hx : x ∈ S
hy : y ∈ S
⊢ x / y ∈ S

Next tactic:
rw [div_eq_mul_inv]
theorem IsSubfield.div_mem {S : Set F} (hS : IsSubfield S) {x y : F} (hx : x ∈ S) (hy : y ∈ S) :
    x / y ∈ S := by
  rw [div_eq_mul_inv]
  

Proof state:
F : Type u_1
inst✝ : Field F
S✝ S : Set F
hS : IsSubfield S
x y : F
hx : x ∈ S
hy : y ∈ S
⊢ x * y⁻¹ ∈ S

Next tactic:
exact hS.toIsSubring.toIsSubmonoid.mul_mem hx (hS.inv_mem hy)
theorem IsSubfield.pow_mem {a : F} {n : ℤ} {s : Set F} (hs : IsSubfield s) (h : a ∈ s) :
    a ^ n ∈ s := by
  

Proof state:
F : Type u_1
inst✝ : Field F
S : Set F
a : F
n : ℤ
s : Set F
hs : IsSubfield s
h : a ∈ s
⊢ a ^ n ∈ s

Next tactic:
cases' n with n n
theorem IsSubfield.pow_mem {a : F} {n : ℤ} {s : Set F} (hs : IsSubfield s) (h : a ∈ s) :
    a ^ n ∈ s := by
  cases' n with n n
  · 

Proof state:
case ofNat
F : Type u_1
inst✝ : Field F
S : Set F
a : F
s : Set F
hs : IsSubfield s
h : a ∈ s
n : ℕ
⊢ a ^ Int.ofNat n ∈ s

Next tactic:
suffices a ^ (n : ℤ) ∈ s by exact this
theorem IsSubfield.pow_mem {a : F} {n : ℤ} {s : Set F} (hs : IsSubfield s) (h : a ∈ s) :
    a ^ n ∈ s := by
  cases' n with n n
  · suffices a ^ (n : ℤ) ∈ s by 

Proof state:
F : Type u_1
inst✝ : Field F
S : Set F
a : F
s : Set F
hs : IsSubfield s
h : a ∈ s
n : ℕ
this : a ^ ↑n ∈ s
⊢ a ^ Int.ofNat n ∈ s

Next tactic:
exact this
theorem IsSubfield.pow_mem {a : F} {n : ℤ} {s : Set F} (hs : IsSubfield s) (h : a ∈ s) :
    a ^ n ∈ s := by
  cases' n with n n
  · suffices a ^ (n : ℤ) ∈ s by exact this
    

Proof state:
case ofNat
F : Type u_1
inst✝ : Field F
S : Set F
a : F
s : Set F
hs : IsSubfield s
h : a ∈ s
n : ℕ
⊢ a ^ ↑n ∈ s

Next tactic:
rw [zpow_ofNat]
theorem IsSubfield.pow_mem {a : F} {n : ℤ} {s : Set F} (hs : IsSubfield s) (h : a ∈ s) :
    a ^ n ∈ s := by
  cases' n with n n
  · suffices a ^ (n : ℤ) ∈ s by exact this
    rw [zpow_ofNat]
    

Proof state:
case ofNat
F : Type u_1
inst✝ : Field F
S : Set F
a : F
s : Set F
hs : IsSubfield s
h : a ∈ s
n : ℕ
⊢ a ^ n ∈ s

Next tactic:
exact hs.toIsSubring.toIsSubmonoid.pow_mem h
theorem IsSubfield.pow_mem {a : F} {n : ℤ} {s : Set F} (hs : IsSubfield s) (h : a ∈ s) :
    a ^ n ∈ s := by
  cases' n with n n
  · suffices a ^ (n : ℤ) ∈ s by exact this
    rw [zpow_ofNat]
    exact hs.toIsSubring.toIsSubmonoid.pow_mem h
  · 

Proof state:
case negSucc
F : Type u_1
inst✝ : Field F
S : Set F
a : F
s : Set F
hs : IsSubfield s
h : a ∈ s
n : ℕ
⊢ a ^ Int.negSucc n ∈ s

Next tactic:
rw [zpow_negSucc]
theorem IsSubfield.pow_mem {a : F} {n : ℤ} {s : Set F} (hs : IsSubfield s) (h : a ∈ s) :
    a ^ n ∈ s := by
  cases' n with n n
  · suffices a ^ (n : ℤ) ∈ s by exact this
    rw [zpow_ofNat]
    exact hs.toIsSubring.toIsSubmonoid.pow_mem h
  · rw [zpow_negSucc]
    

Proof state:
case negSucc
F : Type u_1
inst✝ : Field F
S : Set F
a : F
s : Set F
hs : IsSubfield s
h : a ∈ s
n : ℕ
⊢ (a ^ (n + 1))⁻¹ ∈ s

Next tactic:
exact hs.inv_mem (hs.toIsSubring.toIsSubmonoid.pow_mem h)
theorem Preimage.isSubfield {K : Type*} [Field K] (f : F →+* K) {s : Set K} (hs : IsSubfield s) :
    IsSubfield (f ⁻¹' s) :=
  { f.isSubring_preimage hs.toIsSubring with
    inv_mem := fun {a} (ha : f a ∈ s) ↦ show f a⁻¹ ∈ s by
      

Proof state:
F : Type u_1
inst✝¹ : Field F
S : Set F
K : Type u_2
inst✝ : Field K
f : F →+* K
s : Set K
hs : IsSubfield s
src✝ : IsSubring (⇑f ⁻¹' s) := RingHom.isSubring_preimage f hs.toIsSubring
a : F
ha : f a ∈ s
⊢ f a⁻¹ ∈ s

Next tactic:
rw [map_inv₀]
theorem Preimage.isSubfield {K : Type*} [Field K] (f : F →+* K) {s : Set K} (hs : IsSubfield s) :
    IsSubfield (f ⁻¹' s) :=
  { f.isSubring_preimage hs.toIsSubring with
    inv_mem := fun {a} (ha : f a ∈ s) ↦ show f a⁻¹ ∈ s by
      rw [map_inv₀]
      

Proof state:
F : Type u_1
inst✝¹ : Field F
S : Set F
K : Type u_2
inst✝ : Field K
f : F →+* K
s : Set K
hs : IsSubfield s
src✝ : IsSubring (⇑f ⁻¹' s) := RingHom.isSubring_preimage f hs.toIsSubring
a : F
ha : f a ∈ s
⊢ (f a)⁻¹ ∈ s

Next tactic:
exact hs.inv_mem ha
theorem Range.isSubfield {K : Type*} [Field K] (f : F →+* K) : IsSubfield (Set.range f) := by
  

Proof state:
F : Type u_1
inst✝¹ : Field F
S : Set F
K : Type u_2
inst✝ : Field K
f : F →+* K
⊢ IsSubfield (Set.range ⇑f)

Next tactic:
rw [← Set.image_univ]
theorem Range.isSubfield {K : Type*} [Field K] (f : F →+* K) : IsSubfield (Set.range f) := by
  rw [← Set.image_univ]
  

Proof state:
F : Type u_1
inst✝¹ : Field F
S : Set F
K : Type u_2
inst✝ : Field K
f : F →+* K
⊢ IsSubfield (⇑f '' Set.univ)

Next tactic:
apply Image.isSubfield _ Univ.isSubfield
theorem closure.isSubmonoid : IsSubmonoid (closure S) :=
  { mul_mem := by
      

Proof state:
F : Type u_1
inst✝ : Field F
S : Set F
⊢ ∀ {a b : F}, a ∈ closure S → b ∈ closure S → a * b ∈ closure S

Next tactic:
rintro _ _ ⟨p, hp, q, hq, hq0, rfl⟩ ⟨r, hr, s, hs, hs0, rfl⟩
theorem closure.isSubmonoid : IsSubmonoid (closure S) :=
  { mul_mem := by
      rintro _ _ ⟨p, hp, q, hq, hq0, rfl⟩ ⟨r, hr, s, hs, hs0, rfl⟩
      

Proof state:
case intro.intro.intro.intro.refl.intro.intro.intro.intro.refl
F : Type u_1
inst✝ : Field F
S : Set F
p : F
hp : p ∈ Ring.closure S
q : F
hq : q ∈ Ring.closure S
r : F
hr : r ∈ Ring.closure S
s : F
hs : s ∈ Ring.closure S
⊢ p / q * (r / s) ∈ closure S

Next tactic:
exact ⟨p * r, IsSubmonoid.mul_mem Ring.closure.isSubring.toIsSubmonoid hp hr, q * s,
        IsSubmonoid.mul_mem Ring.closure.isSubring.toIsSubmonoid hq hs,
        (div_mul_div_comm _ _ _ _).symm⟩
theorem closure.isSubfield : IsSubfield (closure S) :=
  { closure.isSubmonoid with
    add_mem := by
      

Proof state:
F : Type u_1
inst✝ : Field F
S : Set F
src✝ : IsSubmonoid (closure S) := isSubmonoid
⊢ ∀ {a b : F}, a ∈ closure S → b ∈ closure S → a + b ∈ closure S

Next tactic:
intro a b ha hb
theorem closure.isSubfield : IsSubfield (closure S) :=
  { closure.isSubmonoid with
    add_mem := by
      intro a b ha hb
      

Proof state:
F : Type u_1
inst✝ : Field F
S : Set F
src✝ : IsSubmonoid (closure S) := isSubmonoid
a b : F
ha : a ∈ closure S
hb : b ∈ closure S
⊢ a + b ∈ closure S

Next tactic:
rcases id ha with ⟨p, hp, q, hq, rfl⟩
theorem closure.isSubfield : IsSubfield (closure S) :=
  { closure.isSubmonoid with
    add_mem := by
      intro a b ha hb
      rcases id ha with ⟨p, hp, q, hq, rfl⟩
      

Proof state:
case intro.intro.intro.intro
F : Type u_1
inst✝ : Field F
S : Set F
src✝ : IsSubmonoid (closure S) := isSubmonoid
b : F
hb : b ∈ closure S
p : F
hp : p ∈ Ring.closure S
q : F
hq : q ∈ Ring.closure S
ha : p / q ∈ closure S
⊢ p / q + b ∈ closure S

Next tactic:
rcases id hb with ⟨r, hr, s, hs, rfl⟩
theorem closure.isSubfield : IsSubfield (closure S) :=
  { closure.isSubmonoid with
    add_mem := by
      intro a b ha hb
      rcases id ha with ⟨p, hp, q, hq, rfl⟩
      rcases id hb with ⟨r, hr, s, hs, rfl⟩
      

Proof state:
case intro.intro.intro.intro.intro.intro.intro.intro
F : Type u_1
inst✝ : Field F
S : Set F
src✝ : IsSubmonoid (closure S) := isSubmonoid
p : F
hp : p ∈ Ring.closure S
q : F
hq : q ∈ Ring.closure S
ha : p / q ∈ closure S
r : F
hr : r ∈ Ring.closure S
s : F
hs : s ∈ Ring.closure S
hb : r / s ∈ closure S
⊢ p / q + r / s ∈ closure S

Next tactic:
by_cases hq0 : q = 0
theorem closure.isSubfield : IsSubfield (closure S) :=
  { closure.isSubmonoid with
    add_mem := by
      intro a b ha hb
      rcases id ha with ⟨p, hp, q, hq, rfl⟩
      rcases id hb with ⟨r, hr, s, hs, rfl⟩
      by_cases hq0 : q = 0
      · 

Proof state:
case pos
F : Type u_1
inst✝ : Field F
S : Set F
src✝ : IsSubmonoid (closure S) := isSubmonoid
p : F
hp : p ∈ Ring.closure S
q : F
hq : q ∈ Ring.closure S
ha : p / q ∈ closure S
r : F
hr : r ∈ Ring.closure S
s : F
hs : s ∈ Ring.closure S
hb : r / s ∈ closure S
hq0 : q = 0
⊢ p / q + r / s ∈ closure S

Next tactic:
rwa [hq0, div_zero, zero_add]
theorem closure.isSubfield : IsSubfield (closure S) :=
  { closure.isSubmonoid with
    add_mem := by
      intro a b ha hb
      rcases id ha with ⟨p, hp, q, hq, rfl⟩
      rcases id hb with ⟨r, hr, s, hs, rfl⟩
      by_cases hq0 : q = 0
      · rwa [hq0, div_zero, zero_add]
      

Proof state:
case neg
F : Type u_1
inst✝ : Field F
S : Set F
src✝ : IsSubmonoid (closure S) := isSubmonoid
p : F
hp : p ∈ Ring.closure S
q : F
hq : q ∈ Ring.closure S
ha : p / q ∈ closure S
r : F
hr : r ∈ Ring.closure S
s : F
hs : s ∈ Ring.closure S
hb : r / s ∈ closure S
hq0 : ¬q = 0
⊢ p / q + r / s ∈ closure S

Next tactic:
by_cases hs0 : s = 0
theorem closure.isSubfield : IsSubfield (closure S) :=
  { closure.isSubmonoid with
    add_mem := by
      intro a b ha hb
      rcases id ha with ⟨p, hp, q, hq, rfl⟩
      rcases id hb with ⟨r, hr, s, hs, rfl⟩
      by_cases hq0 : q = 0
      · rwa [hq0, div_zero, zero_add]
      by_cases hs0 : s = 0
      · 

Proof state:
case pos
F : Type u_1
inst✝ : Field F
S : Set F
src✝ : IsSubmonoid (closure S) := isSubmonoid
p : F
hp : p ∈ Ring.closure S
q : F
hq : q ∈ Ring.closure S
ha : p / q ∈ closure S
r : F
hr : r ∈ Ring.closure S
s : F
hs : s ∈ Ring.closure S
hb : r / s ∈ closure S
hq0 : ¬q = 0
hs0 : s = 0
⊢ p / q + r / s ∈ closure S

Next tactic:
rwa [hs0, div_zero, add_zero]
theorem closure.isSubfield : IsSubfield (closure S) :=
  { closure.isSubmonoid with
    add_mem := by
      intro a b ha hb
      rcases id ha with ⟨p, hp, q, hq, rfl⟩
      rcases id hb with ⟨r, hr, s, hs, rfl⟩
      by_cases hq0 : q = 0
      · rwa [hq0, div_zero, zero_add]
      by_cases hs0 : s = 0
      · rwa [hs0, div_zero, add_zero]
      

Proof state:
case neg
F : Type u_1
inst✝ : Field F
S : Set F
src✝ : IsSubmonoid (closure S) := isSubmonoid
p : F
hp : p ∈ Ring.closure S
q : F
hq : q ∈ Ring.closure S
ha : p / q ∈ closure S
r : F
hr : r ∈ Ring.closure S
s : F
hs : s ∈ Ring.closure S
hb : r / s ∈ closure S
hq0 : ¬q = 0
hs0 : ¬s = 0
⊢ p / q + r / s ∈ closure S

Next tactic:
exact ⟨p * s + q * r,
        IsAddSubmonoid.add_mem Ring.closure.isSubring.toIsAddSubgroup.toIsAddSubmonoid
          (Ring.closure.isSubring.toIsSubmonoid.mul_mem hp hs)
          (Ring.closure.isSubring.toIsSubmonoid.mul_mem hq hr),
        q * s, Ring.closure.isSubring.toIsSubmonoid.mul_mem hq hs, (div_add_div p r hq0 hs0).symm⟩