File: Mathlib/NumberTheory/LegendreSymbol/AddCharacter.lean

full_name: AddChar.val_mem_rootsOfUnity
code: /-- The values of an additive character on a ring of positive characteristic are roots of unity. -/
lemma val_mem_rootsOfUnity (φ : AddChar R R') (a : R) (h : 0 < ringChar R) :
    (φ.val_isUnit a).unit ∈ rootsOfUnity (ringChar R).toPNat' R' 
goal: ⋯.unit ∈ rootsOfUnity (ringChar R).toPNat' R'

full_name: AddChar.IsPrimitive
code: /-- An additive character is *primitive* iff all its multiplicative shifts by nonzero
elements are nontrivial. -/
def IsPrimitive (ψ : AddChar R R') : Prop 
goal: Prop

full_name: AddChar.IsPrimitive.compMulHom_of_isPrimitive
code: /-- The composition of a primitive additive character with an injective mooid homomorphism
is also primitive. -/
lemma IsPrimitive.compMulHom_of_isPrimitive {R'' : Type*} [CommMonoid R''] {φ : AddChar R R'}
    {f : R' →* R''} (hφ : φ.IsPrimitive) (hf : Function.Injective f) :
    (f.compAddChar φ).IsPrimitive 
goal: (f.compAddChar φ).IsPrimitive

full_name: AddChar.to_mulShift_inj_of_isPrimitive
code: /-- The map associating to `a : R` the multiplicative shift of `ψ` by `a`
is injective when `ψ` is primitive. -/
theorem to_mulShift_inj_of_isPrimitive {ψ : AddChar R R'} (hψ : IsPrimitive ψ) :
    Function.Injective ψ.mulShift 
goal: Function.Injective ψ.mulShift

full_name: AddChar.IsPrimitive.of_ne_one
code: /-- When `R` is a field `F`, then a nontrivial additive character is primitive -/
theorem IsPrimitive.of_ne_one {F : Type u} [Field F] {ψ : AddChar F R'} (hψ : ψ ≠ 1) :
    IsPrimitive ψ 
goal: ψ.IsPrimitive

full_name: AddChar.not_isPrimitive_mulShift
code: /-- If `r` is not a unit, then `e.mulShift r` is not primitive. -/
lemma not_isPrimitive_mulShift [Finite R] (e : AddChar R R') {r : R}
    (hr : ¬ IsUnit r) : ¬ IsPrimitive (e.mulShift r) 
goal: ¬(e.mulShift r).IsPrimitive

full_name: AddChar.PrimitiveAddChar.n
code: /-- Definition for a primitive additive character on a finite ring `R` into a cyclotomic extension
of a field `R'`. It records which cyclotomic extension it is, the character, and the
fact that the character is primitive. -/
-- Porting note(#5171): this linter isn't ported yet.
-- can't prove that they always exist (referring to providing an `Inhabited` instance)
-- @[nolint has_nonempty_instance]
structure PrimitiveAddChar (R : Type u) [CommRing R] (R' : Type v) [Field R'] where
  /-- The first projection from `PrimitiveAddChar`, giving the cyclotomic field. -/
  n : ℕ+
  /-- The second projection from `PrimitiveAddChar`, giving the character. -/
  char : AddChar R (CyclotomicField n R')
  /-- The third projection from `PrimitiveAddChar`, showing that `χ.char` is primitive. -/
  prim : IsPrimitive char
goal: ℕ+

full_name: AddChar.PrimitiveAddChar.prim
code: /-- Definition for a primitive additive character on a finite ring `R` into a cyclotomic extension
of a field `R'`. It records which cyclotomic extension it is, the character, and the
fact that the character is primitive. -/
-- Porting note(#5171): this linter isn't ported yet.
-- can't prove that they always exist (referring to providing an `Inhabited` instance)
-- @[nolint has_nonempty_instance]
structure PrimitiveAddChar (R : Type u) [CommRing R] (R' : Type v) [Field R'] where
  /-- The first projection from `PrimitiveAddChar`, giving the cyclotomic field. -/
  n : ℕ+
  /-- The second projection from `PrimitiveAddChar`, giving the character. -/
  char : AddChar R (CyclotomicField n R')
  /-- The third projection from `PrimitiveAddChar`, showing that `χ.char` is primitive. -/
  prim : IsPrimitive char
goal: self.char.IsPrimitive

full_name: AddChar.PrimitiveAddChar
code: /-- Definition for a primitive additive character on a finite ring `R` into a cyclotomic extension
of a field `R'`. It records which cyclotomic extension it is, the character, and the
fact that the character is primitive. -/
-- Porting note(#5171): this linter isn't ported yet.
-- can't prove that they always exist (referring to providing an `Inhabited` instance)
-- @[nolint has_nonempty_instance]
structure PrimitiveAddChar (R : Type u) [CommRing R] (R' : Type v) [Field R'] where
  /-- The first projection from `PrimitiveAddChar`, giving the cyclotomic field. -/
  n : ℕ+
  /-- The second projection from `PrimitiveAddChar`, giving the character. -/
  char : AddChar R (CyclotomicField n R')
  /-- The third projection from `PrimitiveAddChar`, showing that `χ.char` is primitive. -/
  prim : IsPrimitive char
goal: Type (max u v)

full_name: AddChar.PrimitiveAddChar.char
code: /-- Definition for a primitive additive character on a finite ring `R` into a cyclotomic extension
of a field `R'`. It records which cyclotomic extension it is, the character, and the
fact that the character is primitive. -/
-- Porting note(#5171): this linter isn't ported yet.
-- can't prove that they always exist (referring to providing an `Inhabited` instance)
-- @[nolint has_nonempty_instance]
structure PrimitiveAddChar (R : Type u) [CommRing R] (R' : Type v) [Field R'] where
  /-- The first projection from `PrimitiveAddChar`, giving the cyclotomic field. -/
  n : ℕ+
  /-- The second projection from `PrimitiveAddChar`, giving the character. -/
  char : AddChar R (CyclotomicField n R')
  /-- The third projection from `PrimitiveAddChar`, showing that `χ.char` is primitive. -/
  prim : IsPrimitive char
goal: AddChar R (CyclotomicField self.n R')

full_name: AddChar.exists_divisor_of_not_isPrimitive
code: /-- If `e` is not primitive, then `e.mulShift d = 1` for some proper divisor `d` of `N`. -/
lemma exists_divisor_of_not_isPrimitive (he : ¬e.IsPrimitive) :
    ∃ d : ℕ, d ∣ N ∧ d < N ∧ e.mulShift d = 1 
goal: ∃ d, d ∣ N ∧ d < N ∧ e.mulShift ↑d = 1

full_name: AddChar.zmodChar
code: /-- We can define an additive character on `ZMod n` when we have an `n`th root of unity `ζ : C`. -/
def zmodChar (n : ℕ) [NeZero n] {ζ : C} (hζ : ζ ^ n = 1) : AddChar (ZMod n) C 
goal: AddChar (ZMod n) C

full_name: AddChar.zmodChar_apply
code: /-- The additive character on `ZMod n` defined using `ζ` sends `a` to `ζ^a`. -/
theorem zmodChar_apply {n : ℕ} [NeZero n] {ζ : C} (hζ : ζ ^ n = 1) (a : ZMod n) :
    zmodChar n hζ a = ζ ^ a.val 
goal: (AddChar.zmodChar n hζ) a = ζ ^ a.val

full_name: AddChar.zmodChar_apply'
code: theorem zmodChar_apply' {n : ℕ} [NeZero n] {ζ : C} (hζ : ζ ^ n = 1) (a : ℕ) :
    zmodChar n hζ a = ζ ^ a 
goal: (AddChar.zmodChar n hζ) ↑a = ζ ^ a

full_name: AddChar.zmod_char_ne_one_iff
code: /-- An additive character on `ZMod n` is nontrivial iff it takes a value `≠ 1` on `1`. -/
theorem zmod_char_ne_one_iff (n : ℕ) [NeZero n] (ψ : AddChar (ZMod n) C) : ψ ≠ 1 ↔ ψ 1 ≠ 1 
goal: ψ ≠ 1 ↔ ψ 1 ≠ 1

full_name: AddChar.IsPrimitive.zmod_char_eq_one_iff
code: /-- A primitive additive character on `ZMod n` takes the value `1` only at `0`. -/
theorem IsPrimitive.zmod_char_eq_one_iff (n : ℕ) [NeZero n]
    {ψ : AddChar (ZMod n) C} (hψ : IsPrimitive ψ) (a : ZMod n) :
    ψ a = 1 ↔ a = 0 
goal: ψ a = 1 ↔ a = 0

full_name: AddChar.zmod_char_primitive_of_eq_one_only_at_zero
code: /-- The converse: if the additive character takes the value `1` only at `0`,
then it is primitive. -/
theorem zmod_char_primitive_of_eq_one_only_at_zero (n : ℕ) (ψ : AddChar (ZMod n) C)
    (hψ : ∀ a, ψ a = 1 → a = 0) : IsPrimitive ψ 
goal: ψ.IsPrimitive

full_name: AddChar.zmodChar_primitive_of_primitive_root
code: /-- The additive character on `ZMod n` associated to a primitive `n`th root of unity
is primitive -/
theorem zmodChar_primitive_of_primitive_root (n : ℕ) [NeZero n] {ζ : C} (h : IsPrimitiveRoot ζ n) :
    IsPrimitive (zmodChar n ((IsPrimitiveRoot.iff_def ζ n).mp h).left) 
goal: (AddChar.zmodChar n ⋯).IsPrimitive

full_name: AddChar.primitiveZModChar
code: /-- There is a primitive additive character on `ZMod n` if the characteristic of the target
does not divide `n` -/
noncomputable def primitiveZModChar (n : ℕ+) (F' : Type v) [Field F'] (h : (n : F') ≠ 0) :
    PrimitiveAddChar (ZMod n) F' 
goal: AddChar.PrimitiveAddChar (ZMod ↑n) F'

full_name: AddChar.FiniteField.primitiveChar
code: /-- There is a primitive additive character on the finite field `F` if the characteristic
of the target is different from that of `F`.

We obtain it as the composition of the trace from `F` to `ZMod p` with a primitive
additive character on `ZMod p`, where `p` is the characteristic of `F`. -/
noncomputable def FiniteField.primitiveChar (F F' : Type*) [Field F] [Finite F] [Field F']
    (h : ringChar F' ≠ ringChar F) : PrimitiveAddChar F F' 
goal: AddChar.PrimitiveAddChar F F'

full_name: AddChar.sum_eq_zero_of_ne_one
code: /-- The sum over the values of a nontrivial additive character vanishes if the target ring
is a domain. -/
theorem sum_eq_zero_of_ne_one [IsDomain R'] {ψ : AddChar R R'} (hψ : ψ ≠ 1) : ∑ a, ψ a = 0 
goal: ∑ a : R, ψ a = 0

full_name: AddChar.sum_eq_card_of_eq_one
code: /-- The sum over the values of the trivial additive character is the cardinality of the source. -/
theorem sum_eq_card_of_eq_one {ψ : AddChar R R'} (hψ : ψ = 1) :
    ∑ a, ψ a = Fintype.card R 
goal: ∑ a : R, ψ a = ↑(Fintype.card R)

full_name: AddChar.sum_mulShift
code: /-- The sum over the values of `mulShift ψ b` for `ψ` primitive is zero when `b ≠ 0`
and `#R` otherwise. -/
theorem sum_mulShift {R : Type*} [CommRing R] [Fintype R] [DecidableEq R]
    {R' : Type*} [CommRing R'] [IsDomain R'] {ψ : AddChar R R'} (b : R)
    (hψ : IsPrimitive ψ) : ∑ x : R, ψ (x * b) = if b = 0 then Fintype.card R else 0 
goal: ∑ x : R, ψ (x * b) = ↑(if b = 0 then Fintype.card R else 0)

full_name: AddChar.starComp_eq_inv
code: /-- Post-composing an additive character to `ℂ` with complex conjugation gives the inverse
character. -/
lemma starComp_eq_inv (hR : 0 < ringChar R) {φ : AddChar R ℂ} :
    (starRingEnd ℂ).compAddChar φ = φ⁻¹ 
goal: (↑(starRingEnd ℂ)).compAddChar φ = φ⁻¹

full_name: AddChar.starComp_apply
code: lemma starComp_apply (hR : 0 < ringChar R) {φ : AddChar R ℂ} (a : R) :
    (starRingEnd ℂ) (φ a) = φ⁻¹ a 
goal: (starRingEnd ℂ) (φ a) = φ⁻¹ a

full_name: _private.Mathlib.NumberTheory.LegendreSymbol.AddCharacter.0.AddChar.ringChar_ne
code: private lemma ringChar_ne : ringChar ℂ ≠ ringChar F 
goal: ringChar ℂ ≠ ringChar F

full_name: AddChar.FiniteField.primitiveChar_to_Complex
code: /--  A primitive additive character on the finite field `F` with values in `ℂ`. -/
noncomputable def FiniteField.primitiveChar_to_Complex : AddChar F ℂ 
goal: AddChar F ℂ

full_name: AddChar.FiniteField.primitiveChar_to_Complex_isPrimitive
code: lemma FiniteField.primitiveChar_to_Complex_isPrimitive :
    (primitiveChar_to_Complex F).IsPrimitive 
goal: (AddChar.FiniteField.primitiveChar_to_Complex F).IsPrimitive