l3lab/ntp-mathlib huggingface dataset:
/-- If `S` is finite and `IsCyclotomicExtension S A B`, then `B` is a finite `A`-algebra. -/
protected
theorem finite [IsDomain B] [h₁ : Finite S] [h₂ : IsCyclotomicExtension S A B] :
    Module.Finite A B := by
  cases' nonempty_fintype S with h
  revert h₂ A B
  refine' Set.Finite.induction_on (Set.Finite.intro h) (fun A B => _) @fun n S _ _ H A B => _
  · intro _ _ _ _ _
    refine' Module.finite_def.2 ⟨({1} : Finset B), _⟩
    simp [← top_toSubmodule, ← empty, toSubmodule_bot, Submodule.one_eq_span]
  · intro _ _ _ _ h
    haveI : IsCyclotomicExtension S A (adjoin A {b : B | ∃ n : ℕ+, n ∈ S ∧ b ^ (n : ℕ) = 1}) :=
      union_left _ (insert n S) _ _ (subset_insert n S)
    haveI := H A (adjoin A {b : B | ∃ n : ℕ+, n ∈ S ∧ b ^ (n : ℕ) = 1})
    have : Module.Finite (adjoin A {b : B | ∃ n : ℕ+, n ∈ S ∧ b ^ (n : ℕ) = 1}) B := by
      rw [← union_singleton] at h
      letI := @union_right S {n} A B _ _ _ h
      

Proof state:
n✝ : ℕ+
S✝ T : Set ℕ+
K : Type w
L : Type z
inst✝⁶ : Field K
inst✝⁵ : Field L
inst✝⁴ : Algebra K L
h₁ : Finite ↑S✝
h✝ : Fintype ↑S✝
n : ℕ+
S : Set ℕ+
x✝¹ : n ∉ S
x✝ : Set.Finite S
H :
  ∀ (A : Type u) (B : Type v) [inst : CommRing A] [inst_1 : CommRing B] [inst_2 : Algebra A B] [inst_3 : IsDomain B]
    [h₂ : IsCyclotomicExtension S A B], Module.Finite A B
A : Type u
B : Type v
inst✝³ : CommRing A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : IsDomain B
h : IsCyclotomicExtension (S ∪ {n}) A B
this✝¹ : IsCyclotomicExtension S A ↥(adjoin A {b | ∃ n ∈ S, b ^ ↑n = 1})
this✝ : Module.Finite A ↥(adjoin A {b | ∃ n ∈ S, b ^ ↑n = 1})
this : IsCyclotomicExtension {n} (↥(adjoin A {b | ∃ a ∈ S, b ^ ↑a = 1})) B := union_right S {n} A B
⊢ Module.Finite (↥(adjoin A {b | ∃ n ∈ S, b ^ ↑n = 1})) B

Next tactic:
exact finite_of_singleton n _ _
/-- If `S` is finite and `IsCyclotomicExtension S A B`, then `B` is a finite `A`-algebra. -/
protected
theorem finite [IsDomain B] [h₁ : Finite S] [h₂ : IsCyclotomicExtension S A B] :
    Module.Finite A B := by
  cases' nonempty_fintype S with h
  revert h₂ A B
  refine' Set.Finite.induction_on (Set.Finite.intro h) (fun A B => _) @fun n S _ _ H A B => _
  · intro _ _ _ _ _
    refine' Module.finite_def.2 ⟨({1} : Finset B), _⟩
    simp [← top_toSubmodule, ← empty, toSubmodule_bot, Submodule.one_eq_span]
  · intro _ _ _ _ h
    haveI : IsCyclotomicExtension S A (adjoin A {b : B | ∃ n : ℕ+, n ∈ S ∧ b ^ (n : ℕ) = 1}) :=
      union_left _ (insert n S) _ _ (subset_insert n S)
    haveI := H A (adjoin A {b : B | ∃ n : ℕ+, n ∈ S ∧ b ^ (n : ℕ) = 1})
    have : Module.Finite (adjoin A {b : B | ∃ n : ℕ+, n ∈ S ∧ b ^ (n : ℕ) = 1}) B := by
      rw [← union_singleton] at h
      letI := @union_right S {n} A B _ _ _ h
      exact finite_of_singleton n _ _
    

Proof state:
case intro.refine'_2
n✝ : ℕ+
S✝ T : Set ℕ+
K : Type w
L : Type z
inst✝⁶ : Field K
inst✝⁵ : Field L
inst✝⁴ : Algebra K L
h₁ : Finite ↑S✝
h✝ : Fintype ↑S✝
n : ℕ+
S : Set ℕ+
x✝¹ : n ∉ S
x✝ : Set.Finite S
H :
  ∀ (A : Type u) (B : Type v) [inst : CommRing A] [inst_1 : CommRing B] [inst_2 : Algebra A B] [inst_3 : IsDomain B]
    [h₂ : IsCyclotomicExtension S A B], Module.Finite A B
A : Type u
B : Type v
inst✝³ : CommRing A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : IsDomain B
h : IsCyclotomicExtension (insert n S) A B
this✝¹ : IsCyclotomicExtension S A ↥(adjoin A {b | ∃ n ∈ S, b ^ ↑n = 1})
this✝ : Module.Finite A ↥(adjoin A {b | ∃ n ∈ S, b ^ ↑n = 1})
this : Module.Finite (↥(adjoin A {b | ∃ n ∈ S, b ^ ↑n = 1})) B
⊢ Module.Finite A B

Next tactic:
exact Module.Finite.trans (adjoin A {b : B | ∃ n : ℕ+, n ∈ S ∧ b ^ (n : ℕ) = 1}) _
/-- A cyclotomic finite extension of a number field is a number field. -/
theorem numberField [h : NumberField K] [Finite S] [IsCyclotomicExtension S K L] : NumberField L :=
  { to_charZero := charZero_of_injective_algebraMap (algebraMap K L).injective
    to_finiteDimensional := by
      

Proof state:
n : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁷ : CommRing A
inst✝⁶ : CommRing B
inst✝⁵ : Algebra A B
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra K L
h : NumberField K
inst✝¹ : Finite ↑S
inst✝ : IsCyclotomicExtension S K L
⊢ FiniteDimensional ℚ L

Next tactic:
haveI := charZero_of_injective_algebraMap (algebraMap K L).injective
/-- A cyclotomic finite extension of a number field is a number field. -/
theorem numberField [h : NumberField K] [Finite S] [IsCyclotomicExtension S K L] : NumberField L :=
  { to_charZero := charZero_of_injective_algebraMap (algebraMap K L).injective
    to_finiteDimensional := by
      haveI := charZero_of_injective_algebraMap (algebraMap K L).injective
      

Proof state:
n : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁷ : CommRing A
inst✝⁶ : CommRing B
inst✝⁵ : Algebra A B
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra K L
h : NumberField K
inst✝¹ : Finite ↑S
inst✝ : IsCyclotomicExtension S K L
this : CharZero L
⊢ FiniteDimensional ℚ L

Next tactic:
haveI := IsCyclotomicExtension.finite S K L
/-- A cyclotomic finite extension of a number field is a number field. -/
theorem numberField [h : NumberField K] [Finite S] [IsCyclotomicExtension S K L] : NumberField L :=
  { to_charZero := charZero_of_injective_algebraMap (algebraMap K L).injective
    to_finiteDimensional := by
      haveI := charZero_of_injective_algebraMap (algebraMap K L).injective
      haveI := IsCyclotomicExtension.finite S K L
      

Proof state:
n : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁷ : CommRing A
inst✝⁶ : CommRing B
inst✝⁵ : Algebra A B
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Algebra K L
h : NumberField K
inst✝¹ : Finite ↑S
inst✝ : IsCyclotomicExtension S K L
this✝ : CharZero L
this : Module.Finite K L
⊢ FiniteDimensional ℚ L

Next tactic:
exact Module.Finite.trans K _
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  

Proof state:
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
⊢ adjoin A (rootSet (cyclotomic (↑n) A) B) = adjoin A {b | ∃ a ∈ {n}, b ^ ↑a = 1}

Next tactic:
simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  

Proof state:
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
⊢ adjoin A (rootSet (cyclotomic (↑n) A) B) = adjoin A {b | b ^ ↑n = 1}

Next tactic:
refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
  · 

Proof state:
case refine'_1
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : x ∈ rootSet (cyclotomic (↑n) A) B
⊢ x ∈ {b | b ^ ↑n = 1}

Next tactic:
rw [mem_rootSet'] at hx
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
  · rw [mem_rootSet'] at hx
    

Proof state:
case refine'_1
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : map (algebraMap A B) (cyclotomic (↑n) A) ≠ 0 ∧ (aeval x) (cyclotomic (↑n) A) = 0
⊢ x ∈ {b | b ^ ↑n = 1}

Next tactic:
simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq]
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
  · rw [mem_rootSet'] at hx
    simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq]
    

Proof state:
case refine'_1
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : map (algebraMap A B) (cyclotomic (↑n) A) ≠ 0 ∧ (aeval x) (cyclotomic (↑n) A) = 0
⊢ x ^ ↑n = 1

Next tactic:
rw [isRoot_of_unity_iff n.pos]
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
  · rw [mem_rootSet'] at hx
    simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq]
    rw [isRoot_of_unity_iff n.pos]
    

Proof state:
case refine'_1
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : map (algebraMap A B) (cyclotomic (↑n) A) ≠ 0 ∧ (aeval x) (cyclotomic (↑n) A) = 0
⊢ ∃ i ∈ Nat.divisors ↑n, IsRoot (cyclotomic i B) x

Next tactic:
refine' ⟨n, Nat.mem_divisors_self n n.ne_zero, _⟩
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
  · rw [mem_rootSet'] at hx
    simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq]
    rw [isRoot_of_unity_iff n.pos]
    refine' ⟨n, Nat.mem_divisors_self n n.ne_zero, _⟩
    

Proof state:
case refine'_1
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : map (algebraMap A B) (cyclotomic (↑n) A) ≠ 0 ∧ (aeval x) (cyclotomic (↑n) A) = 0
⊢ IsRoot (cyclotomic (↑n) B) x

Next tactic:
rw [IsRoot.def, ← map_cyclotomic n (algebraMap A B), eval_map, ← aeval_def]
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
  · rw [mem_rootSet'] at hx
    simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq]
    rw [isRoot_of_unity_iff n.pos]
    refine' ⟨n, Nat.mem_divisors_self n n.ne_zero, _⟩
    rw [IsRoot.def, ← map_cyclotomic n (algebraMap A B), eval_map, ← aeval_def]
    

Proof state:
case refine'_1
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : map (algebraMap A B) (cyclotomic (↑n) A) ≠ 0 ∧ (aeval x) (cyclotomic (↑n) A) = 0
⊢ (aeval x) (cyclotomic (↑n) A) = 0

Next tactic:
exact hx.2
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
  · rw [mem_rootSet'] at hx
    simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq]
    rw [isRoot_of_unity_iff n.pos]
    refine' ⟨n, Nat.mem_divisors_self n n.ne_zero, _⟩
    rw [IsRoot.def, ← map_cyclotomic n (algebraMap A B), eval_map, ← aeval_def]
    exact hx.2
  · 

Proof state:
case refine'_2
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : x ∈ {b | b ^ ↑n = 1}
⊢ x ∈ ↑(adjoin A (rootSet (cyclotomic (↑n) A) B))

Next tactic:
simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq] at hx
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
  · rw [mem_rootSet'] at hx
    simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq]
    rw [isRoot_of_unity_iff n.pos]
    refine' ⟨n, Nat.mem_divisors_self n n.ne_zero, _⟩
    rw [IsRoot.def, ← map_cyclotomic n (algebraMap A B), eval_map, ← aeval_def]
    exact hx.2
  · simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq] at hx
    

Proof state:
case refine'_2
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : x ^ ↑n = 1
⊢ x ∈ ↑(adjoin A (rootSet (cyclotomic (↑n) A) B))

Next tactic:
obtain ⟨i, _, rfl⟩ := hζ.eq_pow_of_pow_eq_one hx n.pos
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
  · rw [mem_rootSet'] at hx
    simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq]
    rw [isRoot_of_unity_iff n.pos]
    refine' ⟨n, Nat.mem_divisors_self n n.ne_zero, _⟩
    rw [IsRoot.def, ← map_cyclotomic n (algebraMap A B), eval_map, ← aeval_def]
    exact hx.2
  · simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq] at hx
    obtain ⟨i, _, rfl⟩ := hζ.eq_pow_of_pow_eq_one hx n.pos
    

Proof state:
case refine'_2.intro.intro
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
i : ℕ
left✝ : i < ↑n
hx : (ζ ^ i) ^ ↑n = 1
⊢ ζ ^ i ∈ ↑(adjoin A (rootSet (cyclotomic (↑n) A) B))

Next tactic:
refine' SetLike.mem_coe.2 (Subalgebra.pow_mem _ (subset_adjoin _) _)
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
  · rw [mem_rootSet'] at hx
    simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq]
    rw [isRoot_of_unity_iff n.pos]
    refine' ⟨n, Nat.mem_divisors_self n n.ne_zero, _⟩
    rw [IsRoot.def, ← map_cyclotomic n (algebraMap A B), eval_map, ← aeval_def]
    exact hx.2
  · simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq] at hx
    obtain ⟨i, _, rfl⟩ := hζ.eq_pow_of_pow_eq_one hx n.pos
    refine' SetLike.mem_coe.2 (Subalgebra.pow_mem _ (subset_adjoin _) _)
    

Proof state:
case refine'_2.intro.intro
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
i : ℕ
left✝ : i < ↑n
hx : (ζ ^ i) ^ ↑n = 1
⊢ ζ ∈ rootSet (cyclotomic (↑n) A) B

Next tactic:
rw [mem_rootSet', map_cyclotomic, aeval_def, ← eval_map, map_cyclotomic, ← IsRoot]
theorem adjoin_roots_cyclotomic_eq_adjoin_nth_roots [IsDomain B] {ζ : B} {n : ℕ+}
    (hζ : IsPrimitiveRoot ζ n) :
    adjoin A ((cyclotomic n A).rootSet B) =
      adjoin A {b : B | ∃ a : ℕ+, a ∈ ({n} : Set ℕ+) ∧ b ^ (a : ℕ) = 1} := by
  simp only [mem_singleton_iff, exists_eq_left, map_cyclotomic]
  refine' le_antisymm (adjoin_mono fun x hx => _) (adjoin_le fun x hx => _)
  · rw [mem_rootSet'] at hx
    simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq]
    rw [isRoot_of_unity_iff n.pos]
    refine' ⟨n, Nat.mem_divisors_self n n.ne_zero, _⟩
    rw [IsRoot.def, ← map_cyclotomic n (algebraMap A B), eval_map, ← aeval_def]
    exact hx.2
  · simp only [mem_singleton_iff, exists_eq_left, mem_setOf_eq] at hx
    obtain ⟨i, _, rfl⟩ := hζ.eq_pow_of_pow_eq_one hx n.pos
    refine' SetLike.mem_coe.2 (Subalgebra.pow_mem _ (subset_adjoin _) _)
    rw [mem_rootSet', map_cyclotomic, aeval_def, ← eval_map, map_cyclotomic, ← IsRoot]
    

Proof state:
case refine'_2.intro.intro
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
inst✝ : IsDomain B
ζ : B
n : ℕ+
hζ : IsPrimitiveRoot ζ ↑n
i : ℕ
left✝ : i < ↑n
hx : (ζ ^ i) ^ ↑n = 1
⊢ cyclotomic (↑n) B ≠ 0 ∧ IsRoot (cyclotomic (↑n) B) ζ

Next tactic:
refine' ⟨cyclotomic_ne_zero n B, hζ.isRoot_cyclotomic n.pos⟩
theorem adjoin_roots_cyclotomic_eq_adjoin_root_cyclotomic {n : ℕ+} [IsDomain B] {ζ : B}
    (hζ : IsPrimitiveRoot ζ n) : adjoin A ((cyclotomic n A).rootSet B) = adjoin A {ζ} := by
  

Proof state:
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
n : ℕ+
inst✝ : IsDomain B
ζ : B
hζ : IsPrimitiveRoot ζ ↑n
⊢ adjoin A (rootSet (cyclotomic (↑n) A) B) = adjoin A {ζ}

Next tactic:
refine' le_antisymm (adjoin_le fun x hx => _) (adjoin_mono fun x hx => _)
theorem adjoin_roots_cyclotomic_eq_adjoin_root_cyclotomic {n : ℕ+} [IsDomain B] {ζ : B}
    (hζ : IsPrimitiveRoot ζ n) : adjoin A ((cyclotomic n A).rootSet B) = adjoin A {ζ} := by
  refine' le_antisymm (adjoin_le fun x hx => _) (adjoin_mono fun x hx => _)
  · 

Proof state:
case refine'_1
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
n : ℕ+
inst✝ : IsDomain B
ζ : B
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : x ∈ rootSet (cyclotomic (↑n) A) B
⊢ x ∈ ↑(adjoin A {ζ})

Next tactic:
suffices hx : x ^ n.1 = 1
theorem adjoin_roots_cyclotomic_eq_adjoin_root_cyclotomic {n : ℕ+} [IsDomain B] {ζ : B}
    (hζ : IsPrimitiveRoot ζ n) : adjoin A ((cyclotomic n A).rootSet B) = adjoin A {ζ} := by
  refine' le_antisymm (adjoin_le fun x hx => _) (adjoin_mono fun x hx => _)
  · suffices hx : x ^ n.1 = 1
    

Proof state:
case refine'_1
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
n : ℕ+
inst✝ : IsDomain B
ζ : B
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx✝ : x ∈ rootSet (cyclotomic (↑n) A) B
hx : x ^ ↑n = 1
⊢ x ∈ ↑(adjoin A {ζ})
case hx
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
n : ℕ+
inst✝ : IsDomain B
ζ : B
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : x ∈ rootSet (cyclotomic (↑n) A) B
⊢ x ^ ↑n = 1

Next tactic:
obtain ⟨i, _, rfl⟩ := hζ.eq_pow_of_pow_eq_one hx n.pos
theorem adjoin_roots_cyclotomic_eq_adjoin_root_cyclotomic {n : ℕ+} [IsDomain B] {ζ : B}
    (hζ : IsPrimitiveRoot ζ n) : adjoin A ((cyclotomic n A).rootSet B) = adjoin A {ζ} := by
  refine' le_antisymm (adjoin_le fun x hx => _) (adjoin_mono fun x hx => _)
  · suffices hx : x ^ n.1 = 1
    obtain ⟨i, _, rfl⟩ := hζ.eq_pow_of_pow_eq_one hx n.pos
    

Proof state:
case refine'_1.intro.intro
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
n : ℕ+
inst✝ : IsDomain B
ζ : B
hζ : IsPrimitiveRoot ζ ↑n
i : ℕ
left✝ : i < ↑n
hx✝ : ζ ^ i ∈ rootSet (cyclotomic (↑n) A) B
hx : (ζ ^ i) ^ ↑n = 1
⊢ ζ ^ i ∈ ↑(adjoin A {ζ})
case hx
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
n : ℕ+
inst✝ : IsDomain B
ζ : B
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : x ∈ rootSet (cyclotomic (↑n) A) B
⊢ x ^ ↑n = 1

Next tactic:
exact SetLike.mem_coe.2 (Subalgebra.pow_mem _ (subset_adjoin <| mem_singleton ζ) _)
theorem adjoin_roots_cyclotomic_eq_adjoin_root_cyclotomic {n : ℕ+} [IsDomain B] {ζ : B}
    (hζ : IsPrimitiveRoot ζ n) : adjoin A ((cyclotomic n A).rootSet B) = adjoin A {ζ} := by
  refine' le_antisymm (adjoin_le fun x hx => _) (adjoin_mono fun x hx => _)
  · suffices hx : x ^ n.1 = 1
    obtain ⟨i, _, rfl⟩ := hζ.eq_pow_of_pow_eq_one hx n.pos
    exact SetLike.mem_coe.2 (Subalgebra.pow_mem _ (subset_adjoin <| mem_singleton ζ) _)
    

Proof state:
case hx
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
n : ℕ+
inst✝ : IsDomain B
ζ : B
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : x ∈ rootSet (cyclotomic (↑n) A) B
⊢ x ^ ↑n = 1

Next tactic:
refine' (isRoot_of_unity_iff n.pos B).2 _
theorem adjoin_roots_cyclotomic_eq_adjoin_root_cyclotomic {n : ℕ+} [IsDomain B] {ζ : B}
    (hζ : IsPrimitiveRoot ζ n) : adjoin A ((cyclotomic n A).rootSet B) = adjoin A {ζ} := by
  refine' le_antisymm (adjoin_le fun x hx => _) (adjoin_mono fun x hx => _)
  · suffices hx : x ^ n.1 = 1
    obtain ⟨i, _, rfl⟩ := hζ.eq_pow_of_pow_eq_one hx n.pos
    exact SetLike.mem_coe.2 (Subalgebra.pow_mem _ (subset_adjoin <| mem_singleton ζ) _)
    refine' (isRoot_of_unity_iff n.pos B).2 _
    

Proof state:
case hx
n✝ : ℕ+
S T : Set ℕ+
A : Type u
B : Type v
K : Type w
L : Type z
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra A B
inst✝³ : Field K
inst✝² : Field L
inst✝¹ : Algebra K L
n : ℕ+
inst✝ : IsDomain B
ζ : B
hζ : IsPrimitiveRoot ζ ↑n
x : B
hx : x ∈ rootSet (cyclotomic (↑n) A) B
⊢ ∃ i ∈ Nat.divisors ↑n, IsRoot (cyclotomic i B) x

Next tactic:
refine' ⟨n, Nat.mem_divisors_self n n.ne_zero, _⟩