File: Mathlib/RingTheory/RootsOfUnity/Basic.lean

full_name: rootsOfUnity
code: /-- `rootsOfUnity k M` is the subgroup of elements `m : Mˣ` that satisfy `m ^ k = 1`. -/
def rootsOfUnity (k : ℕ+) (M : Type*) [CommMonoid M] : Subgroup Mˣ 
goal: Subgroup Mˣ

full_name: mem_rootsOfUnity
code: @[simp]
theorem mem_rootsOfUnity (k : ℕ+) (ζ : Mˣ) : ζ ∈ rootsOfUnity k M ↔ ζ ^ (k : ℕ) = 1 
goal: ζ ∈ rootsOfUnity k M ↔ ζ ^ ↑k = 1

full_name: mem_rootsOfUnity'
code: theorem mem_rootsOfUnity' (k : ℕ+) (ζ : Mˣ) : ζ ∈ rootsOfUnity k M ↔ (ζ : M) ^ (k : ℕ) = 1 
goal: ζ ∈ rootsOfUnity k M ↔ ↑ζ ^ ↑k = 1

full_name: rootsOfUnity_one
code: @[simp]
theorem rootsOfUnity_one (M : Type*) [CommMonoid M] : rootsOfUnity 1 M = ⊥ 
goal: rootsOfUnity 1 M = ⊥

full_name: rootsOfUnity.coe_injective
code: theorem rootsOfUnity.coe_injective {n : ℕ+} :
    Function.Injective (fun x : rootsOfUnity n M ↦ x.val.val) 
goal: Function.Injective fun x => ↑↑x

full_name: rootsOfUnity.val_mkOfPowEq_coe
code: /-- Make an element of `rootsOfUnity` from a member of the base ring, and a proof that it has
a positive power equal to one. -/
@[simps! coe_val]
def rootsOfUnity.mkOfPowEq (ζ : M) {n : ℕ+} (h : ζ ^ (n : ℕ) = 1) : rootsOfUnity n M 
goal: ↑↑(rootsOfUnity.mkOfPowEq ζ h) = ζ

full_name: rootsOfUnity.mkOfPowEq
code: /-- Make an element of `rootsOfUnity` from a member of the base ring, and a proof that it has
a positive power equal to one. -/
@[simps! coe_val]
def rootsOfUnity.mkOfPowEq (ζ : M) {n : ℕ+} (h : ζ ^ (n : ℕ) = 1) : rootsOfUnity n M 
goal: ↥(rootsOfUnity n M)

full_name: rootsOfUnity.coe_mkOfPowEq
code: @[simp]
theorem rootsOfUnity.coe_mkOfPowEq {ζ : M} {n : ℕ+} (h : ζ ^ (n : ℕ) = 1) :
    ((rootsOfUnity.mkOfPowEq _ h : Mˣ) : M) = ζ 
goal: ↑↑(rootsOfUnity.mkOfPowEq ζ h) = ζ

full_name: rootsOfUnity_le_of_dvd
code: theorem rootsOfUnity_le_of_dvd (h : k ∣ l) : rootsOfUnity k M ≤ rootsOfUnity l M 
goal: rootsOfUnity k M ≤ rootsOfUnity l M

full_name: map_rootsOfUnity
code: theorem map_rootsOfUnity (f : Mˣ →* Nˣ) (k : ℕ+) : (rootsOfUnity k M).map f ≤ rootsOfUnity k N 
goal: Subgroup.map f (rootsOfUnity k M) ≤ rootsOfUnity k N

full_name: rootsOfUnity.coe_pow
code: @[norm_cast]
theorem rootsOfUnity.coe_pow [CommMonoid R] (ζ : rootsOfUnity k R) (m : ℕ) :
    (((ζ ^ m :) : Rˣ) : R) = ((ζ : Rˣ) : R) ^ m 
goal: ↑↑(ζ ^ m) = ↑↑ζ ^ m

full_name: restrictRootsOfUnity
code: /-- Restrict a ring homomorphism to the nth roots of unity. -/
def restrictRootsOfUnity [MonoidHomClass F R S] (σ : F) (n : ℕ+) :
    rootsOfUnity n R →* rootsOfUnity n S 
goal: ↥(rootsOfUnity n R) →* ↥(rootsOfUnity n S)

full_name: restrictRootsOfUnity_coe_apply
code: @[simp]
theorem restrictRootsOfUnity_coe_apply [MonoidHomClass F R S] (σ : F) (ζ : rootsOfUnity k R) :
    (restrictRootsOfUnity σ k ζ : Sˣ) = σ (ζ : Rˣ) 
goal: ↑↑((restrictRootsOfUnity σ k) ζ) = σ ↑↑ζ

full_name: MulEquiv.restrictRootsOfUnity
code: /-- Restrict a monoid isomorphism to the nth roots of unity. -/
nonrec def MulEquiv.restrictRootsOfUnity (σ : R ≃* S) (n : ℕ+) :
    rootsOfUnity n R ≃* rootsOfUnity n S 
goal: ↥(rootsOfUnity n R) ≃* ↥(rootsOfUnity n S)

full_name: MulEquiv.restrictRootsOfUnity_coe_apply
code: @[simp]
theorem MulEquiv.restrictRootsOfUnity_coe_apply (σ : R ≃* S) (ζ : rootsOfUnity k R) :
    (σ.restrictRootsOfUnity k ζ : Sˣ) = σ (ζ : Rˣ) 
goal: ↑↑((σ.restrictRootsOfUnity k) ζ) = σ ↑↑ζ

full_name: MulEquiv.restrictRootsOfUnity_symm
code: @[simp]
theorem MulEquiv.restrictRootsOfUnity_symm (σ : R ≃* S) :
    (σ.restrictRootsOfUnity k).symm = σ.symm.restrictRootsOfUnity k 
goal: (σ.restrictRootsOfUnity k).symm = σ.symm.restrictRootsOfUnity k

full_name: mem_rootsOfUnity_iff_mem_nthRoots
code: theorem mem_rootsOfUnity_iff_mem_nthRoots {ζ : Rˣ} :
    ζ ∈ rootsOfUnity k R ↔ (ζ : R) ∈ nthRoots k (1 : R) 
goal: ζ ∈ rootsOfUnity k R ↔ ↑ζ ∈ Polynomial.nthRoots (↑k) 1

full_name: rootsOfUnityEquivNthRoots
code: /-- Equivalence between the `k`-th roots of unity in `R` and the `k`-th roots of `1`.

This is implemented as equivalence of subtypes,
because `rootsOfUnity` is a subgroup of the group of units,
whereas `nthRoots` is a multiset. -/
def rootsOfUnityEquivNthRoots : rootsOfUnity k R ≃ { x // x ∈ nthRoots k (1 : R) } 
goal: ↥(rootsOfUnity k R) ≃ { x // x ∈ Polynomial.nthRoots (↑k) 1 }

full_name: rootsOfUnityEquivNthRoots_apply
code: @[simp]
theorem rootsOfUnityEquivNthRoots_apply (x : rootsOfUnity k R) :
    (rootsOfUnityEquivNthRoots R k x : R) = ((x : Rˣ) : R) 
goal: ↑((rootsOfUnityEquivNthRoots R k) x) = ↑↑x

full_name: rootsOfUnityEquivNthRoots_symm_apply
code: @[simp]
theorem rootsOfUnityEquivNthRoots_symm_apply (x : { x // x ∈ nthRoots k (1 : R) }) :
    (((rootsOfUnityEquivNthRoots R k).symm x : Rˣ) : R) = (x : R) 
goal: ↑↑((rootsOfUnityEquivNthRoots R k).symm x) = ↑x

full_name: rootsOfUnity.fintype
code: instance rootsOfUnity.fintype : Fintype (rootsOfUnity k R) 
goal: Fintype ↥(rootsOfUnity k R)

full_name: rootsOfUnity.isCyclic
code: instance rootsOfUnity.isCyclic : IsCyclic (rootsOfUnity k R) 
goal: IsCyclic ↥(rootsOfUnity k R)

full_name: card_rootsOfUnity
code: theorem card_rootsOfUnity : Fintype.card (rootsOfUnity k R) ≤ k 
goal: Fintype.card ↥(rootsOfUnity k R) ≤ ↑k

full_name: map_rootsOfUnity_eq_pow_self
code: theorem map_rootsOfUnity_eq_pow_self [FunLike F R R] [RingHomClass F R R] (σ : F)
    (ζ : rootsOfUnity k R) :
    ∃ m : ℕ, σ (ζ : Rˣ) = ((ζ : Rˣ) : R) ^ m 
goal: ∃ m, σ ↑↑ζ = ↑↑ζ ^ m

full_name: mem_rootsOfUnity_prime_pow_mul_iff
code: theorem mem_rootsOfUnity_prime_pow_mul_iff (p k : ℕ) (m : ℕ+) [ExpChar R p]
    {ζ : Rˣ} : ζ ∈ rootsOfUnity (⟨p, expChar_pos R p⟩ ^ k * m) R ↔ ζ ∈ rootsOfUnity m R 
goal: ζ ∈ rootsOfUnity (⟨p, ⋯⟩ ^ k * m) R ↔ ζ ∈ rootsOfUnity m R

full_name: mem_rootsOfUnity_prime_pow_mul_iff'
code: @[simp]
theorem mem_rootsOfUnity_prime_pow_mul_iff' (p k : ℕ) (m : ℕ+) [ExpChar R p]
    {ζ : Rˣ} : ζ ^ (p ^ k * ↑m) = 1 ↔ ζ ∈ rootsOfUnity m R 
goal: ζ ^ (p ^ k * ↑m) = 1 ↔ ζ ∈ rootsOfUnity m R

full_name: IsPrimitiveRoot.iff_def
code: /-- An element `ζ` is a primitive `k`-th root of unity if `ζ ^ k = 1`,
and if `l` satisfies `ζ ^ l = 1` then `k ∣ l`. -/
@[mk_iff IsPrimitiveRoot.iff_def]
structure IsPrimitiveRoot (ζ : M) (k : ℕ) : Prop where
  pow_eq_one : ζ ^ (k : ℕ) = 1
  dvd_of_pow_eq_one : ∀ l : ℕ, ζ ^ l = 1 → k ∣ l
goal: IsPrimitiveRoot ζ k ↔ ζ ^ k = 1 ∧ ∀ (l : ℕ), ζ ^ l = 1 → k ∣ l

full_name: IsPrimitiveRoot.dvd_of_pow_eq_one
code: /-- An element `ζ` is a primitive `k`-th root of unity if `ζ ^ k = 1`,
and if `l` satisfies `ζ ^ l = 1` then `k ∣ l`. -/
@[mk_iff IsPrimitiveRoot.iff_def]
structure IsPrimitiveRoot (ζ : M) (k : ℕ) : Prop where
  pow_eq_one : ζ ^ (k : ℕ) = 1
  dvd_of_pow_eq_one : ∀ l : ℕ, ζ ^ l = 1 → k ∣ l
goal: ζ ^ l = 1 → k ∣ l

full_name: IsPrimitiveRoot
code: /-- An element `ζ` is a primitive `k`-th root of unity if `ζ ^ k = 1`,
and if `l` satisfies `ζ ^ l = 1` then `k ∣ l`. -/
@[mk_iff IsPrimitiveRoot.iff_def]
structure IsPrimitiveRoot (ζ : M) (k : ℕ) : Prop where
  pow_eq_one : ζ ^ (k : ℕ) = 1
  dvd_of_pow_eq_one : ∀ l : ℕ, ζ ^ l = 1 → k ∣ l
goal: Prop

full_name: IsPrimitiveRoot.pow_eq_one
code: /-- An element `ζ` is a primitive `k`-th root of unity if `ζ ^ k = 1`,
and if `l` satisfies `ζ ^ l = 1` then `k ∣ l`. -/
@[mk_iff IsPrimitiveRoot.iff_def]
structure IsPrimitiveRoot (ζ : M) (k : ℕ) : Prop where
  pow_eq_one : ζ ^ (k : ℕ) = 1
  dvd_of_pow_eq_one : ∀ l : ℕ, ζ ^ l = 1 → k ∣ l
goal: ζ ^ k = 1

full_name: IsPrimitiveRoot.toRootsOfUnity
code: /-- Turn a primitive root μ into a member of the `rootsOfUnity` subgroup. -/
@[simps!]
def IsPrimitiveRoot.toRootsOfUnity {μ : M} {n : ℕ+} (h : IsPrimitiveRoot μ n) : rootsOfUnity n M 
goal: ↥(rootsOfUnity n M)

full_name: IsPrimitiveRoot.val_inv_toRootsOfUnity_coe
code: /-- Turn a primitive root μ into a member of the `rootsOfUnity` subgroup. -/
@[simps!]
def IsPrimitiveRoot.toRootsOfUnity {μ : M} {n : ℕ+} (h : IsPrimitiveRoot μ n) : rootsOfUnity n M 
goal: ↑(↑h.toRootsOfUnity)⁻¹ = μ ^ (↑n - 1)

full_name: IsPrimitiveRoot.val_toRootsOfUnity_coe
code: /-- Turn a primitive root μ into a member of the `rootsOfUnity` subgroup. -/
@[simps!]
def IsPrimitiveRoot.toRootsOfUnity {μ : M} {n : ℕ+} (h : IsPrimitiveRoot μ n) : rootsOfUnity n M 
goal: ↑↑h.toRootsOfUnity = μ

full_name: primitiveRoots
code: /-- `primitiveRoots k R` is the finset of primitive `k`-th roots of unity
in the integral domain `R`. -/
def primitiveRoots (k : ℕ) (R : Type*) [CommRing R] [IsDomain R] : Finset R 
goal: Finset R

full_name: mem_primitiveRoots
code: @[simp]
theorem mem_primitiveRoots {ζ : R} (h0 : 0 < k) : ζ ∈ primitiveRoots k R ↔ IsPrimitiveRoot ζ k 
goal: ζ ∈ primitiveRoots k R ↔ IsPrimitiveRoot ζ k

full_name: primitiveRoots_zero
code: @[simp]
theorem primitiveRoots_zero : primitiveRoots 0 R = ∅ 
goal: primitiveRoots 0 R = ∅

full_name: isPrimitiveRoot_of_mem_primitiveRoots
code: theorem isPrimitiveRoot_of_mem_primitiveRoots {ζ : R} (h : ζ ∈ primitiveRoots k R) :
    IsPrimitiveRoot ζ k 
goal: IsPrimitiveRoot ζ k

full_name: IsPrimitiveRoot.mk_of_lt
code: theorem mk_of_lt (ζ : M) (hk : 0 < k) (h1 : ζ ^ k = 1) (h : ∀ l : ℕ, 0 < l → l < k → ζ ^ l ≠ 1) :
    IsPrimitiveRoot ζ k 
goal: IsPrimitiveRoot ζ k

full_name: IsPrimitiveRoot.of_subsingleton
code: @[nontriviality]
theorem of_subsingleton [Subsingleton M] (x : M) : IsPrimitiveRoot x 1 
goal: IsPrimitiveRoot x 1

full_name: IsPrimitiveRoot.pow_eq_one_iff_dvd
code: theorem pow_eq_one_iff_dvd (l : ℕ) : ζ ^ l = 1 ↔ k ∣ l 
goal: ζ ^ l = 1 ↔ k ∣ l

full_name: IsPrimitiveRoot.isUnit
code: theorem isUnit (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) : IsUnit ζ 
goal: IsUnit ζ

full_name: IsPrimitiveRoot.pow_ne_one_of_pos_of_lt
code: theorem pow_ne_one_of_pos_of_lt (h0 : 0 < l) (hl : l < k) : ζ ^ l ≠ 1 
goal: ζ ^ l ≠ 1

full_name: IsPrimitiveRoot.ne_one
code: theorem ne_one (hk : 1 < k) : ζ ≠ 1 
goal: ζ ≠ 1

full_name: IsPrimitiveRoot.pow_inj
code: theorem pow_inj (h : IsPrimitiveRoot ζ k) ⦃i j : ℕ⦄ (hi : i < k) (hj : j < k) (H : ζ ^ i = ζ ^ j) :
    i = j 
goal: i = j

full_name: IsPrimitiveRoot.one
code: theorem one : IsPrimitiveRoot (1 : M) 1 
goal: IsPrimitiveRoot 1 1

full_name: IsPrimitiveRoot.one_right_iff
code: @[simp]
theorem one_right_iff : IsPrimitiveRoot ζ 1 ↔ ζ = 1 
goal: IsPrimitiveRoot ζ 1 ↔ ζ = 1

full_name: IsPrimitiveRoot.coe_submonoidClass_iff
code: @[simp]
theorem coe_submonoidClass_iff {M B : Type*} [CommMonoid M] [SetLike B M] [SubmonoidClass B M]
    {N : B} {ζ : N} : IsPrimitiveRoot (ζ : M) k ↔ IsPrimitiveRoot ζ k 
goal: IsPrimitiveRoot (↑ζ) k ↔ IsPrimitiveRoot ζ k

full_name: IsPrimitiveRoot.coe_units_iff
code: @[simp]
theorem coe_units_iff {ζ : Mˣ} : IsPrimitiveRoot (ζ : M) k ↔ IsPrimitiveRoot ζ k 
goal: IsPrimitiveRoot (↑ζ) k ↔ IsPrimitiveRoot ζ k

full_name: IsPrimitiveRoot.isUnit_unit
code: lemma isUnit_unit {ζ : M} {n} (hn) (hζ : IsPrimitiveRoot ζ n) :
    IsPrimitiveRoot (hζ.isUnit hn).unit n 
goal: IsPrimitiveRoot ⋯.unit n

full_name: IsPrimitiveRoot.isUnit_unit'
code: lemma isUnit_unit' {ζ : G} {n} (hn) (hζ : IsPrimitiveRoot ζ n) :
    IsPrimitiveRoot (hζ.isUnit hn).unit' n 
goal: IsPrimitiveRoot ⋯.unit' n

full_name: IsPrimitiveRoot.pow_of_coprime
code: theorem pow_of_coprime (i : ℕ) (hi : i.Coprime k) : IsPrimitiveRoot (ζ ^ i) k 
goal: IsPrimitiveRoot (ζ ^ i) k

full_name: IsPrimitiveRoot.pow_of_prime
code: theorem pow_of_prime (h : IsPrimitiveRoot ζ k) {p : ℕ} (hprime : Nat.Prime p) (hdiv : ¬p ∣ k) :
    IsPrimitiveRoot (ζ ^ p) k 
goal: IsPrimitiveRoot (ζ ^ p) k

full_name: IsPrimitiveRoot.pow_iff_coprime
code: theorem pow_iff_coprime (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) (i : ℕ) :
    IsPrimitiveRoot (ζ ^ i) k ↔ i.Coprime k 
goal: IsPrimitiveRoot (ζ ^ i) k ↔ i.Coprime k

full_name: IsPrimitiveRoot.orderOf
code: protected theorem orderOf (ζ : M) : IsPrimitiveRoot ζ (orderOf ζ) 
goal: IsPrimitiveRoot ζ (orderOf ζ)

full_name: IsPrimitiveRoot.unique
code: theorem unique {ζ : M} (hk : IsPrimitiveRoot ζ k) (hl : IsPrimitiveRoot ζ l) : k = l 
goal: k = l

full_name: IsPrimitiveRoot.eq_orderOf
code: theorem eq_orderOf : k = orderOf ζ 
goal: k = orderOf ζ

full_name: IsPrimitiveRoot.iff
code: protected theorem iff (hk : 0 < k) :
    IsPrimitiveRoot ζ k ↔ ζ ^ k = 1 ∧ ∀ l : ℕ, 0 < l → l < k → ζ ^ l ≠ 1 
goal: IsPrimitiveRoot ζ k ↔ ζ ^ k = 1 ∧ ∀ (l : ℕ), 0 < l → l < k → ζ ^ l ≠ 1

full_name: IsPrimitiveRoot.not_iff
code: protected theorem not_iff : ¬IsPrimitiveRoot ζ k ↔ orderOf ζ ≠ k 
goal: ¬IsPrimitiveRoot ζ k ↔ orderOf ζ ≠ k

full_name: IsPrimitiveRoot.pow_mul_pow_lcm
code: theorem pow_mul_pow_lcm {ζ' : M} {k' : ℕ} (hζ : IsPrimitiveRoot ζ k) (hζ' : IsPrimitiveRoot ζ' k')
    (hk : k ≠ 0) (hk' : k' ≠ 0) :
    IsPrimitiveRoot
      (ζ ^ (k / Nat.factorizationLCMLeft k k') * ζ' ^ (k' / Nat.factorizationLCMRight k k'))
      (Nat.lcm k k') 
goal: IsPrimitiveRoot (ζ ^ (k / k.factorizationLCMLeft k') * ζ' ^ (k' / k.factorizationLCMRight k')) (k.lcm k')

full_name: IsPrimitiveRoot.pow_of_dvd
code: theorem pow_of_dvd (h : IsPrimitiveRoot ζ k) {p : ℕ} (hp : p ≠ 0) (hdiv : p ∣ k) :
    IsPrimitiveRoot (ζ ^ p) (k / p) 
goal: IsPrimitiveRoot (ζ ^ p) (k / p)

full_name: IsPrimitiveRoot.mem_rootsOfUnity
code: protected theorem mem_rootsOfUnity {ζ : Mˣ} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    ζ ∈ rootsOfUnity n M 
goal: ζ ∈ rootsOfUnity n M

full_name: IsPrimitiveRoot.pow
code: /-- If there is an `n`-th primitive root of unity in `R` and `b` divides `n`,
then there is a `b`-th primitive root of unity in `R`. -/
theorem pow {n : ℕ} {a b : ℕ} (hn : 0 < n) (h : IsPrimitiveRoot ζ n) (hprod : n = a * b) :
    IsPrimitiveRoot (ζ ^ a) b 
goal: IsPrimitiveRoot (ζ ^ a) b

full_name: IsPrimitiveRoot.injOn_pow
code: lemma injOn_pow {n : ℕ} {ζ : M} (hζ : IsPrimitiveRoot ζ n) :
    Set.InjOn (ζ ^ ·) (Finset.range n) 
goal: Set.InjOn (fun x => ζ ^ x) ↑(Finset.range n)

full_name: IsPrimitiveRoot.map_of_injective
code: theorem map_of_injective [MonoidHomClass F M N] (h : IsPrimitiveRoot ζ k) (hf : Injective f) :
    IsPrimitiveRoot (f ζ) k 
goal: IsPrimitiveRoot (f ζ) k

full_name: IsPrimitiveRoot.of_map_of_injective
code: theorem of_map_of_injective [MonoidHomClass F M N] (h : IsPrimitiveRoot (f ζ) k)
    (hf : Injective f) : IsPrimitiveRoot ζ k 
goal: IsPrimitiveRoot ζ k

full_name: IsPrimitiveRoot.map_iff_of_injective
code: theorem map_iff_of_injective [MonoidHomClass F M N] (hf : Injective f) :
    IsPrimitiveRoot (f ζ) k ↔ IsPrimitiveRoot ζ k 
goal: IsPrimitiveRoot (f ζ) k ↔ IsPrimitiveRoot ζ k

full_name: IsPrimitiveRoot.zero
code: theorem zero [Nontrivial M₀] : IsPrimitiveRoot (0 : M₀) 0 
goal: IsPrimitiveRoot 0 0

full_name: IsPrimitiveRoot.ne_zero
code: protected theorem ne_zero [Nontrivial M₀] {ζ : M₀} (h : IsPrimitiveRoot ζ k) : k ≠ 0 → ζ ≠ 0 
goal: k ≠ 0 → ζ ≠ 0

full_name: IsPrimitiveRoot.injOn_pow_mul
code: lemma injOn_pow_mul {n : ℕ} {ζ : M₀} (hζ : IsPrimitiveRoot ζ n)
    {α : M₀} (hα : α ≠ 0) :
    Set.InjOn (ζ ^ · * α) (Finset.range n) 
goal: Set.InjOn (fun x => ζ ^ x * α) ↑(Finset.range n)

full_name: IsPrimitiveRoot.zpow_eq_one
code: theorem zpow_eq_one (h : IsPrimitiveRoot ζ k) : ζ ^ (k : ℤ) = 1 
goal: ζ ^ ↑k = 1

full_name: IsPrimitiveRoot.zpow_eq_one_iff_dvd
code: theorem zpow_eq_one_iff_dvd (h : IsPrimitiveRoot ζ k) (l : ℤ) : ζ ^ l = 1 ↔ (k : ℤ) ∣ l 
goal: ζ ^ l = 1 ↔ ↑k ∣ l

full_name: IsPrimitiveRoot.inv
code: theorem inv (h : IsPrimitiveRoot ζ k) : IsPrimitiveRoot ζ⁻¹ k 
goal: IsPrimitiveRoot ζ⁻¹ k

full_name: IsPrimitiveRoot.inv_iff
code: @[simp]
theorem inv_iff : IsPrimitiveRoot ζ⁻¹ k ↔ IsPrimitiveRoot ζ k 
goal: IsPrimitiveRoot ζ⁻¹ k ↔ IsPrimitiveRoot ζ k

full_name: IsPrimitiveRoot.zpow_of_gcd_eq_one
code: theorem zpow_of_gcd_eq_one (h : IsPrimitiveRoot ζ k) (i : ℤ) (hi : i.gcd k = 1) :
    IsPrimitiveRoot (ζ ^ i) k 
goal: IsPrimitiveRoot (ζ ^ i) k

full_name: IsPrimitiveRoot.sub_one_ne_zero
code: theorem sub_one_ne_zero : ζ - 1 ≠ 0 
goal: ζ - 1 ≠ 0

full_name: IsPrimitiveRoot.primitiveRoots_one
code: @[simp]
theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} 
goal: primitiveRoots 1 R = {1}

full_name: IsPrimitiveRoot.neZero'
code: theorem neZero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R) 
goal: NeZero ↑↑n

full_name: IsPrimitiveRoot.mem_nthRootsFinset
code: nonrec theorem mem_nthRootsFinset (hζ : IsPrimitiveRoot ζ k) (hk : 0 < k) :
    ζ ∈ nthRootsFinset k R 
goal: ζ ∈ Polynomial.nthRootsFinset k R

full_name: IsPrimitiveRoot.eq_neg_one_of_two_right
code: theorem eq_neg_one_of_two_right [NoZeroDivisors R] {ζ : R} (h : IsPrimitiveRoot ζ 2) : ζ = -1 
goal: ζ = -1

full_name: IsPrimitiveRoot.neg_one
code: theorem neg_one (p : ℕ) [Nontrivial R] [h : CharP R p] (hp : p ≠ 2) :
    IsPrimitiveRoot (-1 : R) 2 
goal: IsPrimitiveRoot (-1) 2

full_name: IsPrimitiveRoot.geom_sum_eq_zero
code: /-- If `1 < k` then `(∑ i ∈ range k, ζ ^ i) = 0`. -/
theorem geom_sum_eq_zero [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk : 1 < k) :
    ∑ i ∈ range k, ζ ^ i = 0 
goal: ∑ i ∈ Finset.range k, ζ ^ i = 0

full_name: IsPrimitiveRoot.pow_sub_one_eq
code: /-- If `1 < k`, then `ζ ^ k.pred = -(∑ i ∈ range k.pred, ζ ^ i)`. -/
theorem pow_sub_one_eq [IsDomain R] {ζ : R} (hζ : IsPrimitiveRoot ζ k) (hk : 1 < k) :
    ζ ^ k.pred = -∑ i ∈ range k.pred, ζ ^ i 
goal: ζ ^ k.pred = -∑ i ∈ Finset.range k.pred, ζ ^ i

full_name: IsPrimitiveRoot.zmodEquivZPowers
code: /-- The (additive) monoid equivalence between `ZMod k`
and the powers of a primitive root of unity `ζ`. -/
def zmodEquivZPowers (h : IsPrimitiveRoot ζ k) : ZMod k ≃+ Additive (Subgroup.zpowers ζ) 
goal: ZMod k ≃+ Additive ↥(Subgroup.zpowers ζ)

full_name: IsPrimitiveRoot.zmodEquivZPowers_apply_coe_int
code: @[simp]
theorem zmodEquivZPowers_apply_coe_int (i : ℤ) :
    h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) 
goal: h.zmodEquivZPowers ↑i = Additive.ofMul ⟨ζ ^ i, ⋯⟩

full_name: IsPrimitiveRoot.zmodEquivZPowers_apply_coe_nat
code: @[simp]
theorem zmodEquivZPowers_apply_coe_nat (i : ℕ) :
    h.zmodEquivZPowers i = Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ) 
goal: h.zmodEquivZPowers ↑i = Additive.ofMul ⟨ζ ^ i, ⋯⟩

full_name: IsPrimitiveRoot.zmodEquivZPowers_symm_apply_zpow
code: @[simp]
theorem zmodEquivZPowers_symm_apply_zpow (i : ℤ) :
    h.zmodEquivZPowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i 
goal: h.zmodEquivZPowers.symm (Additive.ofMul ⟨ζ ^ i, ⋯⟩) = ↑i

full_name: IsPrimitiveRoot.zmodEquivZPowers_symm_apply_zpow'
code: @[simp]
theorem zmodEquivZPowers_symm_apply_zpow' (i : ℤ) : h.zmodEquivZPowers.symm ⟨ζ ^ i, i, rfl⟩ = i 
goal: h.zmodEquivZPowers.symm ⟨ζ ^ i, ⋯⟩ = ↑i

full_name: IsPrimitiveRoot.zmodEquivZPowers_symm_apply_pow
code: @[simp]
theorem zmodEquivZPowers_symm_apply_pow (i : ℕ) :
    h.zmodEquivZPowers.symm (Additive.ofMul (⟨ζ ^ i, i, rfl⟩ : Subgroup.zpowers ζ)) = i 
goal: h.zmodEquivZPowers.symm (Additive.ofMul ⟨ζ ^ i, ⋯⟩) = ↑i

full_name: IsPrimitiveRoot.zmodEquivZPowers_symm_apply_pow'
code: @[simp]
theorem zmodEquivZPowers_symm_apply_pow' (i : ℕ) : h.zmodEquivZPowers.symm ⟨ζ ^ i, i, rfl⟩ = i 
goal: h.zmodEquivZPowers.symm ⟨ζ ^ i, ⋯⟩ = ↑i

full_name: IsPrimitiveRoot.zpowers_eq
code: theorem zpowers_eq {k : ℕ+} {ζ : Rˣ} (h : IsPrimitiveRoot ζ k) :
    Subgroup.zpowers ζ = rootsOfUnity k R 
goal: Subgroup.zpowers ζ = rootsOfUnity k R

full_name: IsPrimitiveRoot.map_rootsOfUnity
code: lemma map_rootsOfUnity {S F} [CommRing S] [IsDomain S] [FunLike F R S] [MonoidHomClass F R S]
    {ζ : R} {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) {f : F} (hf : Function.Injective f) :
    (rootsOfUnity n R).map (Units.map f) = rootsOfUnity n S 
goal: Subgroup.map (Units.map ↑f) (rootsOfUnity n R) = rootsOfUnity n S

full_name: rootsOfUnityEquivOfPrimitiveRoots_apply_coe_inv_val
code: /-- If `R` contains a `n`-th primitive root, and `S/R` is a ring extension,
then the `n`-th roots of unity in `R` and `S` are isomorphic.
Also see `IsPrimitiveRoot.map_rootsOfUnity` for the equality as `Subgroup Sˣ`. -/
@[simps! (config := .lemmasOnly) apply_coe_val apply_coe_inv_val]
noncomputable
def _root_.rootsOfUnityEquivOfPrimitiveRoots {S F} [CommRing S] [IsDomain S]
    [FunLike F R S] [MonoidHomClass F R S]
    {n : ℕ+} {f : F} (hf : Function.Injective f) (hζ : (primitiveRoots n R).Nonempty) :
    (rootsOfUnity n R) ≃* rootsOfUnity n S 
goal: ∀ (a : ↥(rootsOfUnity n R)), ⋯ = ⋯

full_name: val_rootsOfUnityEquivOfPrimitiveRoots_apply_coe
code: /-- If `R` contains a `n`-th primitive root, and `S/R` is a ring extension,
then the `n`-th roots of unity in `R` and `S` are isomorphic.
Also see `IsPrimitiveRoot.map_rootsOfUnity` for the equality as `Subgroup Sˣ`. -/
@[simps! (config := .lemmasOnly) apply_coe_val apply_coe_inv_val]
noncomputable
def _root_.rootsOfUnityEquivOfPrimitiveRoots {S F} [CommRing S] [IsDomain S]
    [FunLike F R S] [MonoidHomClass F R S]
    {n : ℕ+} {f : F} (hf : Function.Injective f) (hζ : (primitiveRoots n R).Nonempty) :
    (rootsOfUnity n R) ≃* rootsOfUnity n S 
goal: ∀ (a : ↥(rootsOfUnity n R)), ↑↑((rootsOfUnityEquivOfPrimitiveRoots hf hζ) a) = f ↑↑a

full_name: rootsOfUnityEquivOfPrimitiveRoots
code: /-- If `R` contains a `n`-th primitive root, and `S/R` is a ring extension,
then the `n`-th roots of unity in `R` and `S` are isomorphic.
Also see `IsPrimitiveRoot.map_rootsOfUnity` for the equality as `Subgroup Sˣ`. -/
@[simps! (config := .lemmasOnly) apply_coe_val apply_coe_inv_val]
noncomputable
def _root_.rootsOfUnityEquivOfPrimitiveRoots {S F} [CommRing S] [IsDomain S]
    [FunLike F R S] [MonoidHomClass F R S]
    {n : ℕ+} {f : F} (hf : Function.Injective f) (hζ : (primitiveRoots n R).Nonempty) :
    (rootsOfUnity n R) ≃* rootsOfUnity n S 
goal: ↥(rootsOfUnity n R) ≃* ↥(rootsOfUnity n S)

full_name: rootsOfUnityEquivOfPrimitiveRoots_symm_apply
code: lemma _root_.rootsOfUnityEquivOfPrimitiveRoots_symm_apply
    {S F} [CommRing S] [IsDomain S] [FunLike F R S] [MonoidHomClass F R S]
    {n : ℕ+} {f : F} (hf : Function.Injective f) (hζ : (primitiveRoots n R).Nonempty) (η) :
    f ((rootsOfUnityEquivOfPrimitiveRoots hf hζ).symm η : Rˣ) = (η : Sˣ) 
goal: f ↑↑((rootsOfUnityEquivOfPrimitiveRoots hf hζ).symm η) = ↑↑η

full_name: IsPrimitiveRoot.eq_pow_of_mem_rootsOfUnity
code: theorem eq_pow_of_mem_rootsOfUnity {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k)
    (hξ : ξ ∈ rootsOfUnity k R) : ∃ (i : ℕ), i < k ∧ ζ ^ i = ξ 
goal: ∃ i < ↑k, ζ ^ i = ξ

full_name: IsPrimitiveRoot.eq_pow_of_mem_rootsOfUnity'
code: /-- A version of `IsPrimitiveRoot.eq_pow_of_mem_rootsOfUnity` that takes a natural number `k`
as argument instead of a `PNat` (and `ζ : R` instead of `ζ : Rˣ`). -/
lemma eq_pow_of_mem_rootsOfUnity' {k : ℕ} (hk : 0 < k) {ζ : R} (hζ : IsPrimitiveRoot ζ k) {ξ : Rˣ}
    (hξ : ξ ∈ rootsOfUnity (⟨k, hk⟩ : ℕ+) R) :
    ∃ i < k, ζ ^ i = ξ 
goal: ∃ i < k, ζ ^ i = ↑ξ

full_name: IsPrimitiveRoot.eq_pow_of_pow_eq_one
code: theorem eq_pow_of_pow_eq_one {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (hξ : ξ ^ k = 1)
    (h0 : 0 < k) : ∃ i < k, ζ ^ i = ξ 
goal: ∃ i < k, ζ ^ i = ξ

full_name: IsPrimitiveRoot.isPrimitiveRoot_iff'
code: theorem isPrimitiveRoot_iff' {k : ℕ+} {ζ ξ : Rˣ} (h : IsPrimitiveRoot ζ k) :
    IsPrimitiveRoot ξ k ↔ ∃ i < (k : ℕ), i.Coprime k ∧ ζ ^ i = ξ 
goal: IsPrimitiveRoot ξ ↑k ↔ ∃ i < ↑k, i.Coprime ↑k ∧ ζ ^ i = ξ

full_name: IsPrimitiveRoot.isPrimitiveRoot_iff
code: theorem isPrimitiveRoot_iff {k : ℕ} {ζ ξ : R} (h : IsPrimitiveRoot ζ k) (h0 : 0 < k) :
    IsPrimitiveRoot ξ k ↔ ∃ i < k, i.Coprime k ∧ ζ ^ i = ξ 
goal: IsPrimitiveRoot ξ k ↔ ∃ i < k, i.Coprime k ∧ ζ ^ i = ξ

full_name: IsPrimitiveRoot.nthRoots_eq
code: theorem nthRoots_eq {n : ℕ} {ζ : R} (hζ : IsPrimitiveRoot ζ n)
    {α a : R} (e : α ^ n = a) :
    nthRoots n a = (Multiset.range n).map (ζ ^ · * α) 
goal: Polynomial.nthRoots n a = Multiset.map (fun x => ζ ^ x * α) (Multiset.range n)

full_name: IsPrimitiveRoot.card_nthRoots
code: theorem card_nthRoots {n : ℕ} {ζ : R} (hζ : IsPrimitiveRoot ζ n) (a : R) :
    Multiset.card (nthRoots n a) = if ∃ α, α ^ n = a then n else 0 
goal: Multiset.card (Polynomial.nthRoots n a) = if ∃ α, α ^ n = a then n else 0

full_name: IsPrimitiveRoot.card_rootsOfUnity'
code: theorem card_rootsOfUnity' {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    Fintype.card (rootsOfUnity n R) = n 
goal: Fintype.card ↥(rootsOfUnity n R) = ↑n

full_name: IsPrimitiveRoot.card_rootsOfUnity
code: theorem card_rootsOfUnity {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    Fintype.card (rootsOfUnity n R) = n 
goal: Fintype.card ↥(rootsOfUnity n R) = ↑n

full_name: IsPrimitiveRoot.card_nthRoots_one
code: /-- The cardinality of the multiset `nthRoots ↑n (1 : R)` is `n`
if there is a primitive root of unity in `R`. -/
theorem card_nthRoots_one {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
    Multiset.card (nthRoots n (1 : R)) = n 
goal: Multiset.card (Polynomial.nthRoots n 1) = n

full_name: IsPrimitiveRoot.nthRoots_nodup
code: theorem nthRoots_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) {a : R} (ha : a ≠ 0) :
    (nthRoots n a).Nodup 
goal: (Polynomial.nthRoots n a).Nodup

full_name: IsPrimitiveRoot.nthRoots_one_nodup
code: /-- The multiset `nthRoots ↑n (1 : R)` has no repeated elements
if there is a primitive root of unity in `R`. -/
theorem nthRoots_one_nodup {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
    (nthRoots n (1 : R)).Nodup 
goal: (Polynomial.nthRoots n 1).Nodup

full_name: IsPrimitiveRoot.card_nthRootsFinset
code: @[simp]
theorem card_nthRootsFinset {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
    (nthRootsFinset n R).card = n 
goal: (Polynomial.nthRootsFinset n R).card = n

full_name: IsPrimitiveRoot.card_primitiveRoots
code: /-- If an integral domain has a primitive `k`-th root of unity, then it has `φ k` of them. -/
theorem card_primitiveRoots {ζ : R} {k : ℕ} (h : IsPrimitiveRoot ζ k) :
    (primitiveRoots k R).card = φ k 
goal: (primitiveRoots k R).card = k.totient

full_name: IsPrimitiveRoot.disjoint
code: /-- The sets `primitiveRoots k R` are pairwise disjoint. -/
theorem disjoint {k l : ℕ} (h : k ≠ l) : Disjoint (primitiveRoots k R) (primitiveRoots l R) 
goal: Disjoint (primitiveRoots k R) (primitiveRoots l R)

full_name: IsPrimitiveRoot.nthRoots_one_eq_biUnion_primitiveRoots'
code: /-- `nthRoots n` as a `Finset` is equal to the union of `primitiveRoots i R` for `i ∣ n`
if there is a primitive root of unity in `R`.
This holds for any `Nat`, not just `PNat`, see `nthRoots_one_eq_bUnion_primitive_roots`. -/
theorem nthRoots_one_eq_biUnion_primitiveRoots' {ζ : R} {n : ℕ+} (h : IsPrimitiveRoot ζ n) :
    nthRootsFinset n R = (Nat.divisors ↑n).biUnion fun i => primitiveRoots i R 
goal: Polynomial.nthRootsFinset (↑n) R = (↑n).divisors.biUnion fun i => primitiveRoots i R

full_name: IsPrimitiveRoot.nthRoots_one_eq_biUnion_primitiveRoots
code: /-- `nthRoots n` as a `Finset` is equal to the union of `primitiveRoots i R` for `i ∣ n`
if there is a primitive root of unity in `R`. -/
theorem nthRoots_one_eq_biUnion_primitiveRoots {ζ : R} {n : ℕ} (h : IsPrimitiveRoot ζ n) :
    nthRootsFinset n R = (Nat.divisors n).biUnion fun i => primitiveRoots i R 
goal: Polynomial.nthRootsFinset n R = n.divisors.biUnion fun i => primitiveRoots i R

full_name: IsPrimitiveRoot.autToPow
code: /-- The `MonoidHom` that takes an automorphism to the power of μ that μ gets mapped to under it. -/
noncomputable def autToPow : (S ≃ₐ[R] S) →* (ZMod n)ˣ 
goal: (S ≃ₐ[R] S) →* (ZMod ↑n)ˣ

full_name: IsPrimitiveRoot.coe_autToPow_apply
code: theorem coe_autToPow_apply (f : S ≃ₐ[R] S) :
    (autToPow R hμ f : ZMod n) =
      ((map_rootsOfUnity_eq_pow_self f hμ.toRootsOfUnity).choose : ZMod n) 
goal: ↑((IsPrimitiveRoot.autToPow R hμ) f) = ↑⋯.choose

full_name: IsPrimitiveRoot.autToPow_spec
code: @[simp]
theorem autToPow_spec (f : S ≃ₐ[R] S) : μ ^ (hμ.autToPow R f : ZMod n).val = f μ 
goal: μ ^ (↑((IsPrimitiveRoot.autToPow R hμ) f)).val = f μ