l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem roots_pow (p : R[X]) (n : ℕ) : (p ^ n).roots = n • p.roots := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q p : R[X]
n : ℕ
⊢ roots (p ^ n) = n • roots p

Next tactic:
induction' n with n ihn
@[simp]
theorem roots_pow (p : R[X]) (n : ℕ) : (p ^ n).roots = n • p.roots := by
  induction' n with n ihn
  · 

Proof state:
case zero
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q p : R[X]
⊢ roots (p ^ Nat.zero) = Nat.zero • roots p

Next tactic:
rw [pow_zero, roots_one, Nat.zero_eq, zero_smul, empty_eq_zero]
@[simp]
theorem roots_pow (p : R[X]) (n : ℕ) : (p ^ n).roots = n • p.roots := by
  induction' n with n ihn
  · rw [pow_zero, roots_one, Nat.zero_eq, zero_smul, empty_eq_zero]
  · 

Proof state:
case succ
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q p : R[X]
n : ℕ
ihn : roots (p ^ n) = n • roots p
⊢ roots (p ^ Nat.succ n) = Nat.succ n • roots p

Next tactic:
rcases eq_or_ne p 0 with (rfl | hp)
@[simp]
theorem roots_pow (p : R[X]) (n : ℕ) : (p ^ n).roots = n • p.roots := by
  induction' n with n ihn
  · rw [pow_zero, roots_one, Nat.zero_eq, zero_smul, empty_eq_zero]
  · rcases eq_or_ne p 0 with (rfl | hp)
    · 

Proof state:
case succ.inl
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
ihn : roots (0 ^ n) = n • roots 0
⊢ roots (0 ^ Nat.succ n) = Nat.succ n • roots 0

Next tactic:
rw [zero_pow n.succ_pos, roots_zero, smul_zero]
@[simp]
theorem roots_pow (p : R[X]) (n : ℕ) : (p ^ n).roots = n • p.roots := by
  induction' n with n ihn
  · rw [pow_zero, roots_one, Nat.zero_eq, zero_smul, empty_eq_zero]
  · rcases eq_or_ne p 0 with (rfl | hp)
    · rw [zero_pow n.succ_pos, roots_zero, smul_zero]
    · 

Proof state:
case succ.inr
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q p : R[X]
n : ℕ
ihn : roots (p ^ n) = n • roots p
hp : p ≠ 0
⊢ roots (p ^ Nat.succ n) = Nat.succ n • roots p

Next tactic:
rw [pow_succ', roots_mul (mul_ne_zero (pow_ne_zero _ hp) hp), ihn, Nat.succ_eq_add_one,
        add_smul, one_smul]
theorem roots_X_pow (n : ℕ) : (X ^ n : R[X]).roots = n • ({0} : Multiset R) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
⊢ roots (X ^ n) = n • {0}

Next tactic:
rw [roots_pow, roots_X]
theorem roots_C_mul_X_pow (ha : a ≠ 0) (n : ℕ) :
    Polynomial.roots (C a * X ^ n) = n • ({0} : Multiset R) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
ha : a ≠ 0
n : ℕ
⊢ roots (C a * X ^ n) = n • {0}

Next tactic:
rw [roots_C_mul _ ha, roots_X_pow]
@[simp]
theorem roots_monomial (ha : a ≠ 0) (n : ℕ) : (monomial n a).roots = n • ({0} : Multiset R) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
ha : a ≠ 0
n : ℕ
⊢ roots ((monomial n) a) = n • {0}

Next tactic:
rw [← C_mul_X_pow_eq_monomial, roots_C_mul_X_pow ha]
theorem roots_prod_X_sub_C (s : Finset R) : (s.prod fun a => X - C a).roots = s.val := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Finset R
⊢ roots (Finset.prod s fun a => X - C a) = s.val

Next tactic:
apply (roots_prod (fun a => X - C a) s ?_).trans
theorem roots_prod_X_sub_C (s : Finset R) : (s.prod fun a => X - C a).roots = s.val := by
  apply (roots_prod (fun a => X - C a) s ?_).trans
  · 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Finset R
⊢ (Multiset.bind s.val fun i => roots (X - C i)) = s.val

Next tactic:
simp_rw [roots_X_sub_C]
theorem roots_prod_X_sub_C (s : Finset R) : (s.prod fun a => X - C a).roots = s.val := by
  apply (roots_prod (fun a => X - C a) s ?_).trans
  · simp_rw [roots_X_sub_C]
    

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Finset R
⊢ (Multiset.bind s.val fun i => {i}) = s.val

Next tactic:
rw [Multiset.bind_singleton, Multiset.map_id']
theorem roots_prod_X_sub_C (s : Finset R) : (s.prod fun a => X - C a).roots = s.val := by
  apply (roots_prod (fun a => X - C a) s ?_).trans
  · simp_rw [roots_X_sub_C]
    rw [Multiset.bind_singleton, Multiset.map_id']
  · 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Finset R
⊢ (Finset.prod s fun a => X - C a) ≠ 0

Next tactic:
refine prod_ne_zero_iff.mpr (fun a _ => X_sub_C_ne_zero a)
@[simp]
theorem roots_multiset_prod_X_sub_C (s : Multiset R) : (s.map fun a => X - C a).prod.roots = s := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Multiset R
⊢ roots (prod (Multiset.map (fun a => X - C a) s)) = s

Next tactic:
rw [roots_multiset_prod, Multiset.bind_map]
@[simp]
theorem roots_multiset_prod_X_sub_C (s : Multiset R) : (s.map fun a => X - C a).prod.roots = s := by
  rw [roots_multiset_prod, Multiset.bind_map]
  · 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Multiset R
⊢ (Multiset.bind s fun a => roots (X - C a)) = s

Next tactic:
simp_rw [roots_X_sub_C]
@[simp]
theorem roots_multiset_prod_X_sub_C (s : Multiset R) : (s.map fun a => X - C a).prod.roots = s := by
  rw [roots_multiset_prod, Multiset.bind_map]
  · simp_rw [roots_X_sub_C]
    

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Multiset R
⊢ (Multiset.bind s fun a => {a}) = s

Next tactic:
rw [Multiset.bind_singleton, Multiset.map_id']
@[simp]
theorem roots_multiset_prod_X_sub_C (s : Multiset R) : (s.map fun a => X - C a).prod.roots = s := by
  rw [roots_multiset_prod, Multiset.bind_map]
  · simp_rw [roots_X_sub_C]
    rw [Multiset.bind_singleton, Multiset.map_id']
  · 

Proof state:
case a
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Multiset R
⊢ 0 ∉ Multiset.map (fun a => X - C a) s

Next tactic:
rw [Multiset.mem_map]
@[simp]
theorem roots_multiset_prod_X_sub_C (s : Multiset R) : (s.map fun a => X - C a).prod.roots = s := by
  rw [roots_multiset_prod, Multiset.bind_map]
  · simp_rw [roots_X_sub_C]
    rw [Multiset.bind_singleton, Multiset.map_id']
  · rw [Multiset.mem_map]
    

Proof state:
case a
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Multiset R
⊢ ¬∃ a ∈ s, X - C a = 0

Next tactic:
rintro ⟨a, -, h⟩
@[simp]
theorem roots_multiset_prod_X_sub_C (s : Multiset R) : (s.map fun a => X - C a).prod.roots = s := by
  rw [roots_multiset_prod, Multiset.bind_map]
  · simp_rw [roots_X_sub_C]
    rw [Multiset.bind_singleton, Multiset.map_id']
  · rw [Multiset.mem_map]
    rintro ⟨a, -, h⟩
    

Proof state:
case a.intro.intro
R : Type u
S : Type v
T : Type w
a✝ b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Multiset R
a : R
h : X - C a = 0
⊢ False

Next tactic:
exact X_sub_C_ne_zero a h
@[simp]
theorem natDegree_multiset_prod_X_sub_C_eq_card (s : Multiset R) :
    (s.map fun a => X - C a).prod.natDegree = Multiset.card s := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Multiset R
⊢ natDegree (prod (Multiset.map (fun a => X - C a) s)) = Multiset.card s

Next tactic:
rw [natDegree_multiset_prod_of_monic, Multiset.map_map]
@[simp]
theorem natDegree_multiset_prod_X_sub_C_eq_card (s : Multiset R) :
    (s.map fun a => X - C a).prod.natDegree = Multiset.card s := by
  rw [natDegree_multiset_prod_of_monic, Multiset.map_map]
  · 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Multiset R
⊢ Multiset.sum (Multiset.map (natDegree ∘ fun a => X - C a) s) = Multiset.card s

Next tactic:
simp only [(· ∘ ·), natDegree_X_sub_C, Multiset.map_const', Multiset.sum_replicate, smul_eq_mul,
      mul_one]
@[simp]
theorem natDegree_multiset_prod_X_sub_C_eq_card (s : Multiset R) :
    (s.map fun a => X - C a).prod.natDegree = Multiset.card s := by
  rw [natDegree_multiset_prod_of_monic, Multiset.map_map]
  · simp only [(· ∘ ·), natDegree_X_sub_C, Multiset.map_const', Multiset.sum_replicate, smul_eq_mul,
      mul_one]
  · 

Proof state:
case h
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
s : Multiset R
⊢ ∀ f ∈ Multiset.map (fun a => X - C a) s, Monic f

Next tactic:
exact Multiset.forall_mem_map_iff.2 fun a _ => monic_X_sub_C a
@[simp]
theorem mem_nthRoots {n : ℕ} (hn : 0 < n) {a x : R} : x ∈ nthRoots n a ↔ x ^ n = a := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
hn : 0 < n
a x : R
⊢ x ∈ nthRoots n a ↔ x ^ n = a

Next tactic:
rw [nthRoots, mem_roots (X_pow_sub_C_ne_zero hn a), IsRoot.def, eval_sub, eval_C, eval_pow,
    eval_X, sub_eq_zero]
@[simp]
theorem nthRoots_zero (r : R) : nthRoots 0 r = 0 := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
r : R
⊢ nthRoots 0 r = 0

Next tactic:
simp only [empty_eq_zero, pow_zero, nthRoots, ← C_1, ← C_sub, roots_C]
theorem card_nthRoots (n : ℕ) (a : R) : Multiset.card (nthRoots n a) ≤ n := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
a : R
⊢ Multiset.card (nthRoots n a) ≤ n

Next tactic:
classical exact
  (if hn : n = 0 then
    if h : (X : R[X]) ^ n - C a = 0 then by
      simp [Nat.zero_le, nthRoots, roots, h, dif_pos rfl, empty_eq_zero, Multiset.card_zero]
    else
      WithBot.coe_le_coe.1
        (le_trans (card_roots h)
          (by
            rw [hn, pow_zero, ← C_1, ← RingHom.map_sub]
            exact degree_C_le))
  else by
    rw [← Nat.cast_le (α := WithBot ℕ)]
    rw [← degree_X_pow_sub_C (Nat.pos_of_ne_zero hn) a]
    exact card_roots (X_pow_sub_C_ne_zero (Nat.pos_of_ne_zero hn) a))
theorem card_nthRoots (n : ℕ) (a : R) : Multiset.card (nthRoots n a) ≤ n := by
  classical 

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
a : R
⊢ Multiset.card (nthRoots n a) ≤ n

Next tactic:
exact
  (if hn : n = 0 then
    if h : (X : R[X]) ^ n - C a = 0 then by
      simp [Nat.zero_le, nthRoots, roots, h, dif_pos rfl, empty_eq_zero, Multiset.card_zero]
    else
      WithBot.coe_le_coe.1
        (le_trans (card_roots h)
          (by
            rw [hn, pow_zero, ← C_1, ← RingHom.map_sub]
            exact degree_C_le))
  else by
    rw [← Nat.cast_le (α := WithBot ℕ)]
    rw [← degree_X_pow_sub_C (Nat.pos_of_ne_zero hn) a]
    exact card_roots (X_pow_sub_C_ne_zero (Nat.pos_of_ne_zero hn) a))
theorem card_nthRoots (n : ℕ) (a : R) : Multiset.card (nthRoots n a) ≤ n := by
  classical exact
  (if hn : n = 0 then
    if h : (X : R[X]) ^ n - C a = 0 then by
      

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
a : R
hn : n = 0
h : X ^ n - C a = 0
⊢ Multiset.card (nthRoots n a) ≤ n

Next tactic:
simp [Nat.zero_le, nthRoots, roots, h, dif_pos rfl, empty_eq_zero, Multiset.card_zero]
theorem card_nthRoots (n : ℕ) (a : R) : Multiset.card (nthRoots n a) ≤ n := by
  classical exact
  (if hn : n = 0 then
    if h : (X : R[X]) ^ n - C a = 0 then by
      simp [Nat.zero_le, nthRoots, roots, h, dif_pos rfl, empty_eq_zero, Multiset.card_zero]
    else
      WithBot.coe_le_coe.1
        (le_trans (card_roots h)
          (by
            

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
a : R
hn : n = 0
h : ¬X ^ n - C a = 0
⊢ degree (X ^ n - C a) ≤ ↑n

Next tactic:
rw [hn, pow_zero, ← C_1, ← RingHom.map_sub]
theorem card_nthRoots (n : ℕ) (a : R) : Multiset.card (nthRoots n a) ≤ n := by
  classical exact
  (if hn : n = 0 then
    if h : (X : R[X]) ^ n - C a = 0 then by
      simp [Nat.zero_le, nthRoots, roots, h, dif_pos rfl, empty_eq_zero, Multiset.card_zero]
    else
      WithBot.coe_le_coe.1
        (le_trans (card_roots h)
          (by
            rw [hn, pow_zero, ← C_1, ← RingHom.map_sub]
            

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
a : R
hn : n = 0
h : ¬X ^ n - C a = 0
⊢ degree (C (1 - a)) ≤ ↑0

Next tactic:
exact degree_C_le
theorem card_nthRoots (n : ℕ) (a : R) : Multiset.card (nthRoots n a) ≤ n := by
  classical exact
  (if hn : n = 0 then
    if h : (X : R[X]) ^ n - C a = 0 then by
      simp [Nat.zero_le, nthRoots, roots, h, dif_pos rfl, empty_eq_zero, Multiset.card_zero]
    else
      WithBot.coe_le_coe.1
        (le_trans (card_roots h)
          (by
            rw [hn, pow_zero, ← C_1, ← RingHom.map_sub]
            exact degree_C_le))
  else by
    

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
a : R
hn : ¬n = 0
⊢ Multiset.card (nthRoots n a) ≤ n

Next tactic:
rw [← Nat.cast_le (α := WithBot ℕ)]
theorem card_nthRoots (n : ℕ) (a : R) : Multiset.card (nthRoots n a) ≤ n := by
  classical exact
  (if hn : n = 0 then
    if h : (X : R[X]) ^ n - C a = 0 then by
      simp [Nat.zero_le, nthRoots, roots, h, dif_pos rfl, empty_eq_zero, Multiset.card_zero]
    else
      WithBot.coe_le_coe.1
        (le_trans (card_roots h)
          (by
            rw [hn, pow_zero, ← C_1, ← RingHom.map_sub]
            exact degree_C_le))
  else by
    rw [← Nat.cast_le (α := WithBot ℕ)]
    

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
a : R
hn : ¬n = 0
⊢ ↑(Multiset.card (nthRoots n a)) ≤ ↑n

Next tactic:
rw [← degree_X_pow_sub_C (Nat.pos_of_ne_zero hn) a]
theorem card_nthRoots (n : ℕ) (a : R) : Multiset.card (nthRoots n a) ≤ n := by
  classical exact
  (if hn : n = 0 then
    if h : (X : R[X]) ^ n - C a = 0 then by
      simp [Nat.zero_le, nthRoots, roots, h, dif_pos rfl, empty_eq_zero, Multiset.card_zero]
    else
      WithBot.coe_le_coe.1
        (le_trans (card_roots h)
          (by
            rw [hn, pow_zero, ← C_1, ← RingHom.map_sub]
            exact degree_C_le))
  else by
    rw [← Nat.cast_le (α := WithBot ℕ)]
    rw [← degree_X_pow_sub_C (Nat.pos_of_ne_zero hn) a]
    

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
a : R
hn : ¬n = 0
⊢ ↑(Multiset.card (nthRoots n a)) ≤ degree (X ^ n - C a)

Next tactic:
exact card_roots (X_pow_sub_C_ne_zero (Nat.pos_of_ne_zero hn) a)
@[simp]
theorem nthRoots_two_eq_zero_iff {r : R} : nthRoots 2 r = 0 ↔ ¬IsSquare r := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
r : R
⊢ nthRoots 2 r = 0 ↔ ¬IsSquare r

Next tactic:
simp_rw [isSquare_iff_exists_sq, eq_zero_iff_forall_not_mem, mem_nthRoots (by norm_num : 0 < 2),
    ← not_exists, eq_comm]
@[simp]
theorem nthRoots_two_eq_zero_iff {r : R} : nthRoots 2 r = 0 ↔ ¬IsSquare r := by
  simp_rw [isSquare_iff_exists_sq, eq_zero_iff_forall_not_mem, mem_nthRoots (by 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
r : R
⊢ 0 < 2

Next tactic:
norm_num
lemma nthRootsFinset_def (n : ℕ) (R : Type*) [CommRing R] [IsDomain R] [DecidableEq R] :
    nthRootsFinset n R = Multiset.toFinset (nthRoots n (1 : R)) := by
  

Proof state:
R✝ : Type u
S : Type v
T : Type w
a b : R✝
n✝ : ℕ
inst✝⁴ : CommRing R✝
inst✝³ : IsDomain R✝
p q : R✝[X]
n : ℕ
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : DecidableEq R
⊢ nthRootsFinset n R = toFinset (nthRoots n 1)

Next tactic:
unfold nthRootsFinset
lemma nthRootsFinset_def (n : ℕ) (R : Type*) [CommRing R] [IsDomain R] [DecidableEq R] :
    nthRootsFinset n R = Multiset.toFinset (nthRoots n (1 : R)) := by
  unfold nthRootsFinset
  

Proof state:
R✝ : Type u
S : Type v
T : Type w
a b : R✝
n✝ : ℕ
inst✝⁴ : CommRing R✝
inst✝³ : IsDomain R✝
p q : R✝[X]
n : ℕ
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : DecidableEq R
⊢ toFinset (nthRoots n 1) = toFinset (nthRoots n 1)

Next tactic:
convert rfl
@[simp]
theorem mem_nthRootsFinset {n : ℕ} (h : 0 < n) {x : R} :
    x ∈ nthRootsFinset n R ↔ x ^ (n : ℕ) = 1 := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
h : 0 < n
x : R
⊢ x ∈ nthRootsFinset n R ↔ x ^ n = 1

Next tactic:
classical
  rw [nthRootsFinset_def, mem_toFinset, mem_nthRoots h]
@[simp]
theorem mem_nthRootsFinset {n : ℕ} (h : 0 < n) {x : R} :
    x ∈ nthRootsFinset n R ↔ x ^ (n : ℕ) = 1 := by
  classical
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
n : ℕ
h : 0 < n
x : R
⊢ x ∈ nthRootsFinset n R ↔ x ^ n = 1

Next tactic:
rw [nthRootsFinset_def, mem_toFinset, mem_nthRoots h]
@[simp]
theorem nthRootsFinset_zero : nthRootsFinset 0 R = ∅ := by 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
⊢ nthRootsFinset 0 R = ∅

Next tactic:
classical simp [nthRootsFinset_def]
@[simp]
theorem nthRootsFinset_zero : nthRootsFinset 0 R = ∅ := by classical 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
⊢ nthRootsFinset 0 R = ∅

Next tactic:
simp [nthRootsFinset_def]
theorem mul_mem_nthRootsFinset
    {η₁ η₂ : R} (hη₁ : η₁ ∈ nthRootsFinset n R) (hη₂ : η₂ ∈ nthRootsFinset n R) :
    η₁ * η₂ ∈ nthRootsFinset n R := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
η₁ η₂ : R
hη₁ : η₁ ∈ nthRootsFinset n R
hη₂ : η₂ ∈ nthRootsFinset n R
⊢ η₁ * η₂ ∈ nthRootsFinset n R

Next tactic:
cases n with
  | zero =>
    simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη₁
  | succ n =>
    rw [mem_nthRootsFinset n.succ_pos] at hη₁ hη₂ ⊢
    rw [mul_pow, hη₁, hη₂, one_mul]
theorem mul_mem_nthRootsFinset
    {η₁ η₂ : R} (hη₁ : η₁ ∈ nthRootsFinset n R) (hη₂ : η₂ ∈ nthRootsFinset n R) :
    η₁ * η₂ ∈ nthRootsFinset n R := by
  cases n with
  

Proof state:
case zero
R : Type u
S : Type v
T : Type w
a b : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
η₁ η₂ : R
hη₁ : η₁ ∈ nthRootsFinset Nat.zero R
hη₂ : η₂ ∈ nthRootsFinset Nat.zero R
⊢ η₁ * η₂ ∈ nthRootsFinset Nat.zero R

Next tactic:
| zero =>
    simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη₁
theorem mul_mem_nthRootsFinset
    {η₁ η₂ : R} (hη₁ : η₁ ∈ nthRootsFinset n R) (hη₂ : η₂ ∈ nthRootsFinset n R) :
    η₁ * η₂ ∈ nthRootsFinset n R := by
  cases n with
  | zero =>
    

Proof state:
case zero
R : Type u
S : Type v
T : Type w
a b : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
η₁ η₂ : R
hη₁ : η₁ ∈ nthRootsFinset Nat.zero R
hη₂ : η₂ ∈ nthRootsFinset Nat.zero R
⊢ η₁ * η₂ ∈ nthRootsFinset Nat.zero R

Next tactic:
simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη₁
theorem mul_mem_nthRootsFinset
    {η₁ η₂ : R} (hη₁ : η₁ ∈ nthRootsFinset n R) (hη₂ : η₂ ∈ nthRootsFinset n R) :
    η₁ * η₂ ∈ nthRootsFinset n R := by
  cases n with
  | zero =>
    simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη₁
  

Proof state:
case succ
R : Type u
S : Type v
T : Type w
a b : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
η₁ η₂ : R
n : ℕ
hη₁ : η₁ ∈ nthRootsFinset (Nat.succ n) R
hη₂ : η₂ ∈ nthRootsFinset (Nat.succ n) R
⊢ η₁ * η₂ ∈ nthRootsFinset (Nat.succ n) R

Next tactic:
| succ n =>
    rw [mem_nthRootsFinset n.succ_pos] at hη₁ hη₂ ⊢
    rw [mul_pow, hη₁, hη₂, one_mul]
theorem mul_mem_nthRootsFinset
    {η₁ η₂ : R} (hη₁ : η₁ ∈ nthRootsFinset n R) (hη₂ : η₂ ∈ nthRootsFinset n R) :
    η₁ * η₂ ∈ nthRootsFinset n R := by
  cases n with
  | zero =>
    simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη₁
  | succ n =>
    

Proof state:
case succ
R : Type u
S : Type v
T : Type w
a b : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
η₁ η₂ : R
n : ℕ
hη₁ : η₁ ∈ nthRootsFinset (Nat.succ n) R
hη₂ : η₂ ∈ nthRootsFinset (Nat.succ n) R
⊢ η₁ * η₂ ∈ nthRootsFinset (Nat.succ n) R

Next tactic:
rw [mem_nthRootsFinset n.succ_pos] at hη₁ hη₂ ⊢
theorem mul_mem_nthRootsFinset
    {η₁ η₂ : R} (hη₁ : η₁ ∈ nthRootsFinset n R) (hη₂ : η₂ ∈ nthRootsFinset n R) :
    η₁ * η₂ ∈ nthRootsFinset n R := by
  cases n with
  | zero =>
    simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη₁
  | succ n =>
    rw [mem_nthRootsFinset n.succ_pos] at hη₁ hη₂ ⊢
    

Proof state:
case succ
R : Type u
S : Type v
T : Type w
a b : R
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
η₁ η₂ : R
n : ℕ
hη₁ : η₁ ^ Nat.succ n = 1
hη₂ : η₂ ^ Nat.succ n = 1
⊢ (η₁ * η₂) ^ Nat.succ n = 1

Next tactic:
rw [mul_pow, hη₁, hη₂, one_mul]
theorem ne_zero_of_mem_nthRootsFinset {η : R} (hη : η ∈ nthRootsFinset n R) : η ≠ 0 := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
η : R
hη : η ∈ nthRootsFinset n R
⊢ η ≠ 0

Next tactic:
nontriviality R
theorem ne_zero_of_mem_nthRootsFinset {η : R} (hη : η ∈ nthRootsFinset n R) : η ≠ 0 := by
  nontriviality R
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
p q : R[X]
η : R
hη : η ∈ nthRootsFinset n R
inst✝ : Nontrivial R
⊢ η ≠ 0

Next tactic:
rintro rfl
theorem ne_zero_of_mem_nthRootsFinset {η : R} (hη : η ∈ nthRootsFinset n R) : η ≠ 0 := by
  nontriviality R
  rintro rfl
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
p q : R[X]
inst✝ : Nontrivial R
hη : 0 ∈ nthRootsFinset n R
⊢ False

Next tactic:
cases n with
  | zero =>
    simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη
  | succ n =>
    rw [mem_nthRootsFinset n.succ_pos, zero_pow n.succ_pos] at hη
    exact zero_ne_one hη
theorem ne_zero_of_mem_nthRootsFinset {η : R} (hη : η ∈ nthRootsFinset n R) : η ≠ 0 := by
  nontriviality R
  rintro rfl
  cases n with
  

Proof state:
case zero
R : Type u
S : Type v
T : Type w
a b : R
inst✝² : CommRing R
inst✝¹ : IsDomain R
p q : R[X]
inst✝ : Nontrivial R
hη : 0 ∈ nthRootsFinset Nat.zero R
⊢ False

Next tactic:
| zero =>
    simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη
theorem ne_zero_of_mem_nthRootsFinset {η : R} (hη : η ∈ nthRootsFinset n R) : η ≠ 0 := by
  nontriviality R
  rintro rfl
  cases n with
  | zero =>
    

Proof state:
case zero
R : Type u
S : Type v
T : Type w
a b : R
inst✝² : CommRing R
inst✝¹ : IsDomain R
p q : R[X]
inst✝ : Nontrivial R
hη : 0 ∈ nthRootsFinset Nat.zero R
⊢ False

Next tactic:
simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη
theorem ne_zero_of_mem_nthRootsFinset {η : R} (hη : η ∈ nthRootsFinset n R) : η ≠ 0 := by
  nontriviality R
  rintro rfl
  cases n with
  | zero =>
    simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη
  

Proof state:
case succ
R : Type u
S : Type v
T : Type w
a b : R
inst✝² : CommRing R
inst✝¹ : IsDomain R
p q : R[X]
inst✝ : Nontrivial R
n : ℕ
hη : 0 ∈ nthRootsFinset (Nat.succ n) R
⊢ False

Next tactic:
| succ n =>
    rw [mem_nthRootsFinset n.succ_pos, zero_pow n.succ_pos] at hη
    exact zero_ne_one hη
theorem ne_zero_of_mem_nthRootsFinset {η : R} (hη : η ∈ nthRootsFinset n R) : η ≠ 0 := by
  nontriviality R
  rintro rfl
  cases n with
  | zero =>
    simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη
  | succ n =>
    

Proof state:
case succ
R : Type u
S : Type v
T : Type w
a b : R
inst✝² : CommRing R
inst✝¹ : IsDomain R
p q : R[X]
inst✝ : Nontrivial R
n : ℕ
hη : 0 ∈ nthRootsFinset (Nat.succ n) R
⊢ False

Next tactic:
rw [mem_nthRootsFinset n.succ_pos, zero_pow n.succ_pos] at hη