l3lab/ntp-mathlib huggingface dataset:
theorem enumerate_inj {n₁ n₂ : ℕ} {a : α} {s : Set α} (h_sel : ∀ s a, sel s = some a → a ∈ s)
    (h₁ : enumerate sel s n₁ = some a) (h₂ : enumerate sel s n₂ = some a) : n₁ = n₂ := by
  /- porting note : The `rcase, on_goal, all_goals` has been used instead of
     the not-yet-ported `wlog` -/
  rcases le_total n₁ n₂ with (hn|hn)
  on_goal 2 => swap_var n₁ ↔ n₂, h₁ ↔ h₂
  all_goals
    rcases Nat.le.dest hn with ⟨m, rfl⟩
    clear hn
    induction n₁ generalizing s
    case zero =>
      cases m
      case zero => rfl
      case succ m =>
        have h' : enumerate sel (s \ {a}) m = some a := by
          simp_all only [enumerate, Nat.zero_eq, Nat.add_eq, zero_add]; exact h₂
        have : a ∈ s \ {a} := enumerate_mem sel h_sel h'
        simp_all [Set.mem_diff_singleton]
    case succ k ih =>
      cases h : sel s
      /- porting note : The original covered both goals with just `simp_all <;> tauto` -/
      case none =>
        simp_all only [add_comm, self_eq_add_left, Nat.add_succ, enumerate_eq_none_of_sel _ h]
      

Proof state:
α : Type u_1
sel : Set α → Option α
a : α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
m k : ℕ
ih : ∀ {s : Set α}, enumerate sel s k = some a → enumerate sel s (k + m) = some a → k + m = k
s : Set α
h₁ : enumerate sel s (Nat.succ k) = some a
h₂ : enumerate sel s (Nat.succ k + m) = some a
val✝ : α
h : sel s = some val✝
⊢ Nat.succ k + m = Nat.succ k

Next tactic:
case some _ =>
        simp_all only [add_comm, self_eq_add_left, enumerate, Option.some.injEq,
                       Nat.add_succ, enumerate._eq_2, Nat.succ.injEq]
        exact ih h₁ h₂
theorem enumerate_inj {n₁ n₂ : ℕ} {a : α} {s : Set α} (h_sel : ∀ s a, sel s = some a → a ∈ s)
    (h₁ : enumerate sel s n₁ = some a) (h₂ : enumerate sel s n₂ = some a) : n₁ = n₂ := by
  /- porting note : The `rcase, on_goal, all_goals` has been used instead of
     the not-yet-ported `wlog` -/
  rcases le_total n₁ n₂ with (hn|hn)
  on_goal 2 => swap_var n₁ ↔ n₂, h₁ ↔ h₂
  all_goals
    rcases Nat.le.dest hn with ⟨m, rfl⟩
    clear hn
    induction n₁ generalizing s
    case zero =>
      cases m
      case zero => rfl
      case succ m =>
        have h' : enumerate sel (s \ {a}) m = some a := by
          simp_all only [enumerate, Nat.zero_eq, Nat.add_eq, zero_add]; exact h₂
        have : a ∈ s \ {a} := enumerate_mem sel h_sel h'
        simp_all [Set.mem_diff_singleton]
    case succ k ih =>
      cases h : sel s
      /- porting note : The original covered both goals with just `simp_all <;> tauto` -/
      case none =>
        simp_all only [add_comm, self_eq_add_left, Nat.add_succ, enumerate_eq_none_of_sel _ h]
      case some _ =>
        

Proof state:
α : Type u_1
sel : Set α → Option α
a : α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
m k : ℕ
ih : ∀ {s : Set α}, enumerate sel s k = some a → enumerate sel s (k + m) = some a → k + m = k
s : Set α
h₁ : enumerate sel s (Nat.succ k) = some a
h₂ : enumerate sel s (Nat.succ k + m) = some a
val✝ : α
h : sel s = some val✝
⊢ Nat.succ k + m = Nat.succ k

Next tactic:
simp_all only [add_comm, self_eq_add_left, enumerate, Option.some.injEq,
                       Nat.add_succ, enumerate._eq_2, Nat.succ.injEq]
theorem enumerate_inj {n₁ n₂ : ℕ} {a : α} {s : Set α} (h_sel : ∀ s a, sel s = some a → a ∈ s)
    (h₁ : enumerate sel s n₁ = some a) (h₂ : enumerate sel s n₂ = some a) : n₁ = n₂ := by
  /- porting note : The `rcase, on_goal, all_goals` has been used instead of
     the not-yet-ported `wlog` -/
  rcases le_total n₁ n₂ with (hn|hn)
  on_goal 2 => swap_var n₁ ↔ n₂, h₁ ↔ h₂
  all_goals
    rcases Nat.le.dest hn with ⟨m, rfl⟩
    clear hn
    induction n₁ generalizing s
    case zero =>
      cases m
      case zero => rfl
      case succ m =>
        have h' : enumerate sel (s \ {a}) m = some a := by
          simp_all only [enumerate, Nat.zero_eq, Nat.add_eq, zero_add]; exact h₂
        have : a ∈ s \ {a} := enumerate_mem sel h_sel h'
        simp_all [Set.mem_diff_singleton]
    case succ k ih =>
      cases h : sel s
      /- porting note : The original covered both goals with just `simp_all <;> tauto` -/
      case none =>
        simp_all only [add_comm, self_eq_add_left, Nat.add_succ, enumerate_eq_none_of_sel _ h]
      case some _ =>
        simp_all only [add_comm, self_eq_add_left, enumerate, Option.some.injEq,
                       Nat.add_succ, enumerate._eq_2, Nat.succ.injEq]
        

Proof state:
α : Type u_1
sel : Set α → Option α
a : α
h_sel : ∀ (s : Set α) (a : α), sel s = some a → a ∈ s
m k : ℕ
s : Set α
val✝ : α
ih : ∀ {s : Set α}, enumerate sel s k = some a → enumerate sel s (m + k) = some a → m + k = k
h₁ :
  (do
      let a ← some val✝
      enumerate sel (s \ {a}) k) =
    some a
h₂ :
  (do
      let a ← some val✝
      enumerate sel (s \ {a}) (m + k)) =
    some a
h : sel s = some val✝
⊢ m + k = k

Next tactic:
exact ih h₁ h₂
theorem scaleRoots_aeval_eq_zero_of_aeval_mk'_eq_zero {p : A[X]} {r : A} {s : M}
    (hr : aeval (mk' S r s) p = 0) : aeval (algebraMap A S r) (scaleRoots p s) = 0 := by
  

Proof state:
A : Type u_1
K : Type u_2
R : Type u_3
S : Type u_4
inst✝⁷ : CommRing A
inst✝⁶ : Field K
inst✝⁵ : CommRing R
inst✝⁴ : CommRing S
M : Submonoid A
inst✝³ : Algebra A S
inst✝² : IsLocalization M S
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : A
s : ↥M
hr : (aeval (mk' S r s)) p = 0
⊢ (aeval ((algebraMap A S) r)) (scaleRoots p ↑s) = 0

Next tactic:
convert scaleRoots_eval₂_eq_zero (algebraMap A S) hr
theorem scaleRoots_aeval_eq_zero_of_aeval_mk'_eq_zero {p : A[X]} {r : A} {s : M}
    (hr : aeval (mk' S r s) p = 0) : aeval (algebraMap A S r) (scaleRoots p s) = 0 := by
  convert scaleRoots_eval₂_eq_zero (algebraMap A S) hr
  -- Porting note: added
  

Proof state:
case h.e'_2.h.e
A : Type u_1
K : Type u_2
R : Type u_3
S : Type u_4
inst✝⁷ : CommRing A
inst✝⁶ : Field K
inst✝⁵ : CommRing R
inst✝⁴ : CommRing S
M : Submonoid A
inst✝³ : Algebra A S
inst✝² : IsLocalization M S
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : A
s : ↥M
hr : (aeval (mk' S r s)) p = 0
⊢ ⇑(aeval ((algebraMap A S) r)) = eval₂ (algebraMap A S) ((algebraMap A S) ↑s * mk' S r s)

Next tactic:
funext
theorem scaleRoots_aeval_eq_zero_of_aeval_mk'_eq_zero {p : A[X]} {r : A} {s : M}
    (hr : aeval (mk' S r s) p = 0) : aeval (algebraMap A S r) (scaleRoots p s) = 0 := by
  convert scaleRoots_eval₂_eq_zero (algebraMap A S) hr
  -- Porting note: added
  funext
  

Proof state:
case h.e'_2.h.e.h
A : Type u_1
K : Type u_2
R : Type u_3
S : Type u_4
inst✝⁷ : CommRing A
inst✝⁶ : Field K
inst✝⁵ : CommRing R
inst✝⁴ : CommRing S
M : Submonoid A
inst✝³ : Algebra A S
inst✝² : IsLocalization M S
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : A
s : ↥M
hr : (aeval (mk' S r s)) p = 0
x✝ : A[X]
⊢ (aeval ((algebraMap A S) r)) x✝ = eval₂ (algebraMap A S) ((algebraMap A S) ↑s * mk' S r s) x✝

Next tactic:
rw [aeval_def, mk'_spec' _ r s]
theorem num_isRoot_scaleRoots_of_aeval_eq_zero [UniqueFactorizationMonoid A] {p : A[X]} {x : K}
    (hr : aeval x p = 0) : IsRoot (scaleRoots p (den A x)) (num A x) := by
  

Proof state:
A : Type u_1
K : Type u_2
R : Type u_3
S : Type u_4
inst✝⁹ : CommRing A
inst✝⁸ : Field K
inst✝⁷ : CommRing R
inst✝⁶ : CommRing S
M : Submonoid A
inst✝⁵ : Algebra A S
inst✝⁴ : IsLocalization M S
inst✝³ : Algebra A K
inst✝² : IsFractionRing A K
inst✝¹ : IsDomain A
inst✝ : UniqueFactorizationMonoid A
p : A[X]
x : K
hr : (aeval x) p = 0
⊢ IsRoot (scaleRoots p ↑(den A x)) (num A x)

Next tactic:
apply isRoot_of_eval₂_map_eq_zero (IsFractionRing.injective A K)
theorem num_isRoot_scaleRoots_of_aeval_eq_zero [UniqueFactorizationMonoid A] {p : A[X]} {x : K}
    (hr : aeval x p = 0) : IsRoot (scaleRoots p (den A x)) (num A x) := by
  apply isRoot_of_eval₂_map_eq_zero (IsFractionRing.injective A K)
  

Proof state:
A : Type u_1
K : Type u_2
R : Type u_3
S : Type u_4
inst✝⁹ : CommRing A
inst✝⁸ : Field K
inst✝⁷ : CommRing R
inst✝⁶ : CommRing S
M : Submonoid A
inst✝⁵ : Algebra A S
inst✝⁴ : IsLocalization M S
inst✝³ : Algebra A K
inst✝² : IsFractionRing A K
inst✝¹ : IsDomain A
inst✝ : UniqueFactorizationMonoid A
p : A[X]
x : K
hr : (aeval x) p = 0
⊢ eval₂ (algebraMap A K) ((algebraMap A K) (num A x)) (scaleRoots p ↑(den A x)) = 0

Next tactic:
refine' scaleRoots_aeval_eq_zero_of_aeval_mk'_eq_zero _
theorem num_isRoot_scaleRoots_of_aeval_eq_zero [UniqueFactorizationMonoid A] {p : A[X]} {x : K}
    (hr : aeval x p = 0) : IsRoot (scaleRoots p (den A x)) (num A x) := by
  apply isRoot_of_eval₂_map_eq_zero (IsFractionRing.injective A K)
  refine' scaleRoots_aeval_eq_zero_of_aeval_mk'_eq_zero _
  

Proof state:
A : Type u_1
K : Type u_2
R : Type u_3
S : Type u_4
inst✝⁹ : CommRing A
inst✝⁸ : Field K
inst✝⁷ : CommRing R
inst✝⁶ : CommRing S
M : Submonoid A
inst✝⁵ : Algebra A S
inst✝⁴ : IsLocalization M S
inst✝³ : Algebra A K
inst✝² : IsFractionRing A K
inst✝¹ : IsDomain A
inst✝ : UniqueFactorizationMonoid A
p : A[X]
x : K
hr : (aeval x) p = 0
⊢ (aeval (mk' K (num A x) (den A x))) p = 0

Next tactic:
rw [mk'_num_den]
theorem num_isRoot_scaleRoots_of_aeval_eq_zero [UniqueFactorizationMonoid A] {p : A[X]} {x : K}
    (hr : aeval x p = 0) : IsRoot (scaleRoots p (den A x)) (num A x) := by
  apply isRoot_of_eval₂_map_eq_zero (IsFractionRing.injective A K)
  refine' scaleRoots_aeval_eq_zero_of_aeval_mk'_eq_zero _
  rw [mk'_num_den]
  

Proof state:
A : Type u_1
K : Type u_2
R : Type u_3
S : Type u_4
inst✝⁹ : CommRing A
inst✝⁸ : Field K
inst✝⁷ : CommRing R
inst✝⁶ : CommRing S
M : Submonoid A
inst✝⁵ : Algebra A S
inst✝⁴ : IsLocalization M S
inst✝³ : Algebra A K
inst✝² : IsFractionRing A K
inst✝¹ : IsDomain A
inst✝ : UniqueFactorizationMonoid A
p : A[X]
x : K
hr : (aeval x) p = 0
⊢ (aeval x) p = 0

Next tactic:
exact hr
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  

Proof state:
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr : (aeval r) p = 0
⊢ num A r ∣ coeff p 0

Next tactic:
suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    by_cases hr : num A r = 0
    · obtain ⟨u, hu⟩ := (isUnit_den_of_num_eq_zero hr).pow p.natDegree
      rw [← hu] at this
      exact Units.dvd_mul_right.mp this
    · refine' dvd_of_dvd_mul_left_of_no_prime_factors hr _ this
      intro q dvd_num dvd_denom_pow hq
      apply hq.not_unit
      exact num_den_reduced A r dvd_num (hq.dvd_of_dvd_pow dvd_denom_pow)
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    

Proof state:
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr : (aeval r) p = 0
this : num A r ∣ coeff (scaleRoots p ↑(den A r)) 0
⊢ num A r ∣ coeff p 0

Next tactic:
simp only [coeff_scaleRoots, tsub_zero] at this
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    

Proof state:
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr : (aeval r) p = 0
this : num A r ∣ coeff p 0 * ↑(den A r) ^ natDegree p
⊢ num A r ∣ coeff p 0

Next tactic:
haveI inst := Classical.propDecidable
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    

Proof state:
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr : (aeval r) p = 0
this : num A r ∣ coeff p 0 * ↑(den A r) ^ natDegree p
inst : (a : Prop) → Decidable a
⊢ num A r ∣ coeff p 0

Next tactic:
by_cases hr : num A r = 0
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    by_cases hr : num A r = 0
    · 

Proof state:
case pos
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr✝ : (aeval r) p = 0
this : num A r ∣ coeff p 0 * ↑(den A r) ^ natDegree p
inst : (a : Prop) → Decidable a
hr : num A r = 0
⊢ num A r ∣ coeff p 0

Next tactic:
obtain ⟨u, hu⟩ := (isUnit_den_of_num_eq_zero hr).pow p.natDegree
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    by_cases hr : num A r = 0
    · obtain ⟨u, hu⟩ := (isUnit_den_of_num_eq_zero hr).pow p.natDegree
      

Proof state:
case pos.intro
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr✝ : (aeval r) p = 0
this : num A r ∣ coeff p 0 * ↑(den A r) ^ natDegree p
inst : (a : Prop) → Decidable a
hr : num A r = 0
u : Aˣ
hu : ↑u = ↑(den A r) ^ natDegree p
⊢ num A r ∣ coeff p 0

Next tactic:
rw [← hu] at this
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    by_cases hr : num A r = 0
    · obtain ⟨u, hu⟩ := (isUnit_den_of_num_eq_zero hr).pow p.natDegree
      rw [← hu] at this
      

Proof state:
case pos.intro
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr✝ : (aeval r) p = 0
inst : (a : Prop) → Decidable a
hr : num A r = 0
u : Aˣ
this : num A r ∣ coeff p 0 * ↑u
hu : ↑u = ↑(den A r) ^ natDegree p
⊢ num A r ∣ coeff p 0

Next tactic:
exact Units.dvd_mul_right.mp this
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    by_cases hr : num A r = 0
    · obtain ⟨u, hu⟩ := (isUnit_den_of_num_eq_zero hr).pow p.natDegree
      rw [← hu] at this
      exact Units.dvd_mul_right.mp this
    · 

Proof state:
case neg
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr✝ : (aeval r) p = 0
this : num A r ∣ coeff p 0 * ↑(den A r) ^ natDegree p
inst : (a : Prop) → Decidable a
hr : ¬num A r = 0
⊢ num A r ∣ coeff p 0

Next tactic:
refine' dvd_of_dvd_mul_left_of_no_prime_factors hr _ this
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    by_cases hr : num A r = 0
    · obtain ⟨u, hu⟩ := (isUnit_den_of_num_eq_zero hr).pow p.natDegree
      rw [← hu] at this
      exact Units.dvd_mul_right.mp this
    · refine' dvd_of_dvd_mul_left_of_no_prime_factors hr _ this
      

Proof state:
case neg
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr✝ : (aeval r) p = 0
this : num A r ∣ coeff p 0 * ↑(den A r) ^ natDegree p
inst : (a : Prop) → Decidable a
hr : ¬num A r = 0
⊢ ∀ {d : A}, d ∣ num A r → d ∣ ↑(den A r) ^ natDegree p → ¬Prime d

Next tactic:
intro q dvd_num dvd_denom_pow hq
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    by_cases hr : num A r = 0
    · obtain ⟨u, hu⟩ := (isUnit_den_of_num_eq_zero hr).pow p.natDegree
      rw [← hu] at this
      exact Units.dvd_mul_right.mp this
    · refine' dvd_of_dvd_mul_left_of_no_prime_factors hr _ this
      intro q dvd_num dvd_denom_pow hq
      

Proof state:
case neg
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr✝ : (aeval r) p = 0
this : num A r ∣ coeff p 0 * ↑(den A r) ^ natDegree p
inst : (a : Prop) → Decidable a
hr : ¬num A r = 0
q : A
dvd_num : q ∣ num A r
dvd_denom_pow : q ∣ ↑(den A r) ^ natDegree p
hq : Prime q
⊢ False

Next tactic:
apply hq.not_unit
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    by_cases hr : num A r = 0
    · obtain ⟨u, hu⟩ := (isUnit_den_of_num_eq_zero hr).pow p.natDegree
      rw [← hu] at this
      exact Units.dvd_mul_right.mp this
    · refine' dvd_of_dvd_mul_left_of_no_prime_factors hr _ this
      intro q dvd_num dvd_denom_pow hq
      apply hq.not_unit
      

Proof state:
case neg
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr✝ : (aeval r) p = 0
this : num A r ∣ coeff p 0 * ↑(den A r) ^ natDegree p
inst : (a : Prop) → Decidable a
hr : ¬num A r = 0
q : A
dvd_num : q ∣ num A r
dvd_denom_pow : q ∣ ↑(den A r) ^ natDegree p
hq : Prime q
⊢ IsUnit q

Next tactic:
exact num_den_reduced A r dvd_num (hq.dvd_of_dvd_pow dvd_denom_pow)
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    by_cases hr : num A r = 0
    · obtain ⟨u, hu⟩ := (isUnit_den_of_num_eq_zero hr).pow p.natDegree
      rw [← hu] at this
      exact Units.dvd_mul_right.mp this
    · refine' dvd_of_dvd_mul_left_of_no_prime_factors hr _ this
      intro q dvd_num dvd_denom_pow hq
      apply hq.not_unit
      exact num_den_reduced A r dvd_num (hq.dvd_of_dvd_pow dvd_denom_pow)
  

Proof state:
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr : (aeval r) p = 0
⊢ num A r ∣ coeff (scaleRoots p ↑(den A r)) 0

Next tactic:
convert dvd_term_of_isRoot_of_dvd_terms 0 (num_isRoot_scaleRoots_of_aeval_eq_zero hr) _
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    by_cases hr : num A r = 0
    · obtain ⟨u, hu⟩ := (isUnit_den_of_num_eq_zero hr).pow p.natDegree
      rw [← hu] at this
      exact Units.dvd_mul_right.mp this
    · refine' dvd_of_dvd_mul_left_of_no_prime_factors hr _ this
      intro q dvd_num dvd_denom_pow hq
      apply hq.not_unit
      exact num_den_reduced A r dvd_num (hq.dvd_of_dvd_pow dvd_denom_pow)
  convert dvd_term_of_isRoot_of_dvd_terms 0 (num_isRoot_scaleRoots_of_aeval_eq_zero hr) _
  · 

Proof state:
case h.e'_4
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr : (aeval r) p = 0
⊢ coeff (scaleRoots p ↑(den A r)) 0 = coeff (scaleRoots p ↑(den A r)) 0 * num A r ^ 0

Next tactic:
rw [pow_zero, mul_one]
/-- **Rational root theorem** part 1:
if `r : f.codomain` is a root of a polynomial over the ufd `A`,
then the numerator of `r` divides the constant coefficient -/
theorem num_dvd_of_is_root {p : A[X]} {r : K} (hr : aeval r p = 0) : num A r ∣ p.coeff 0 := by
  suffices num A r ∣ (scaleRoots p (den A r)).coeff 0 by
    simp only [coeff_scaleRoots, tsub_zero] at this
    haveI inst := Classical.propDecidable
    by_cases hr : num A r = 0
    · obtain ⟨u, hu⟩ := (isUnit_den_of_num_eq_zero hr).pow p.natDegree
      rw [← hu] at this
      exact Units.dvd_mul_right.mp this
    · refine' dvd_of_dvd_mul_left_of_no_prime_factors hr _ this
      intro q dvd_num dvd_denom_pow hq
      apply hq.not_unit
      exact num_den_reduced A r dvd_num (hq.dvd_of_dvd_pow dvd_denom_pow)
  convert dvd_term_of_isRoot_of_dvd_terms 0 (num_isRoot_scaleRoots_of_aeval_eq_zero hr) _
  · rw [pow_zero, mul_one]
  

Proof state:
case convert_2
A : Type u_1
K : Type u_2
inst✝⁵ : CommRing A
inst✝⁴ : IsDomain A
inst✝³ : UniqueFactorizationMonoid A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
p : A[X]
r : K
hr : (aeval r) p = 0
⊢ ∀ (j : ℕ), j ≠ 0 → num A r ∣ coeff (scaleRoots p ↑(den A r)) j * num A r ^ j

Next tactic:
intro j hj