l3lab/ntp-mathlib huggingface dataset:
/-- When `F` and `F'` are finite fields and `χ : F → F'` is a nontrivial quadratic character,
then `(χ(-1) * #F)^(#F'/2) = χ(#F')`. -/
theorem Char.card_pow_card {F : Type*} [Field F] [Fintype F] {F' : Type*} [Field F'] [Fintype F']
    {χ : MulChar F F'} (hχ₁ : IsNontrivial χ) (hχ₂ : IsQuadratic χ)
    (hch₁ : ringChar F' ≠ ringChar F) (hch₂ : ringChar F' ≠ 2) :
    (χ (-1) * Fintype.card F) ^ (Fintype.card F' / 2) = χ (Fintype.card F') := by
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)
  obtain ⟨n', hp', hc'⟩ := FiniteField.card F' (ringChar F')
  let ψ := primitiveCharFiniteField F F' hch₁
  -- Porting note: this was a `let` but then Lean would time out at
  -- unification so it is changed to as `set` and `FF'` is replaced by its
  -- definition before unification
  set FF' := CyclotomicField ψ.n F' with FF'_def
  have hchar := Algebra.ringChar_eq F' FF'
  apply (algebraMap F' FF').injective
  rw [map_pow, map_mul, map_natCast, hc', hchar, Nat.cast_pow]
  simp only [← MulChar.ringHomComp_apply]
  

Proof state:
case intro.intro.intro.intro.a
R : Type u
inst✝⁷ : CommRing R
inst✝⁶ : Fintype R
R' : Type v
inst✝⁵ : CommRing R'
inst✝⁴ : IsDomain R'
F : Type u_1
inst✝³ : Field F
inst✝² : Fintype F
F' : Type u_2
inst✝¹ : Field F'
inst✝ : Fintype F'
χ : MulChar F F'
hχ₁ : MulChar.IsNontrivial χ
hχ₂ : IsQuadratic χ
hch₁ : ringChar F' ≠ ringChar F
hch₂ : ringChar F' ≠ 2
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
n' : ℕ+
hp' : Nat.Prime (ringChar F')
hc' : Fintype.card F' = ringChar F' ^ ↑n'
ψ : PrimitiveAddChar F F' := primitiveCharFiniteField F F' hch₁
FF' : Type u_2 := CyclotomicField (PrimitiveAddChar.n ψ) F'
FF'_def : FF' = CyclotomicField (PrimitiveAddChar.n ψ) F'
hchar : ringChar F' = ringChar FF'
⊢ ((ringHomComp χ (algebraMap F' (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F'))) (-1) *
        ↑(Fintype.card F)) ^
      (ringChar (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F') ^ ↑n' / 2) =
    (ringHomComp χ (algebraMap F' (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F')))
      (↑(ringChar (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F')) ^ ↑n')

Next tactic:
haveI := Fact.mk hp'
/-- When `F` and `F'` are finite fields and `χ : F → F'` is a nontrivial quadratic character,
then `(χ(-1) * #F)^(#F'/2) = χ(#F')`. -/
theorem Char.card_pow_card {F : Type*} [Field F] [Fintype F] {F' : Type*} [Field F'] [Fintype F']
    {χ : MulChar F F'} (hχ₁ : IsNontrivial χ) (hχ₂ : IsQuadratic χ)
    (hch₁ : ringChar F' ≠ ringChar F) (hch₂ : ringChar F' ≠ 2) :
    (χ (-1) * Fintype.card F) ^ (Fintype.card F' / 2) = χ (Fintype.card F') := by
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)
  obtain ⟨n', hp', hc'⟩ := FiniteField.card F' (ringChar F')
  let ψ := primitiveCharFiniteField F F' hch₁
  -- Porting note: this was a `let` but then Lean would time out at
  -- unification so it is changed to as `set` and `FF'` is replaced by its
  -- definition before unification
  set FF' := CyclotomicField ψ.n F' with FF'_def
  have hchar := Algebra.ringChar_eq F' FF'
  apply (algebraMap F' FF').injective
  rw [map_pow, map_mul, map_natCast, hc', hchar, Nat.cast_pow]
  simp only [← MulChar.ringHomComp_apply]
  haveI := Fact.mk hp'
  

Proof state:
case intro.intro.intro.intro.a
R : Type u
inst✝⁷ : CommRing R
inst✝⁶ : Fintype R
R' : Type v
inst✝⁵ : CommRing R'
inst✝⁴ : IsDomain R'
F : Type u_1
inst✝³ : Field F
inst✝² : Fintype F
F' : Type u_2
inst✝¹ : Field F'
inst✝ : Fintype F'
χ : MulChar F F'
hχ₁ : MulChar.IsNontrivial χ
hχ₂ : IsQuadratic χ
hch₁ : ringChar F' ≠ ringChar F
hch₂ : ringChar F' ≠ 2
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
n' : ℕ+
hp' : Nat.Prime (ringChar F')
hc' : Fintype.card F' = ringChar F' ^ ↑n'
ψ : PrimitiveAddChar F F' := primitiveCharFiniteField F F' hch₁
FF' : Type u_2 := CyclotomicField (PrimitiveAddChar.n ψ) F'
FF'_def : FF' = CyclotomicField (PrimitiveAddChar.n ψ) F'
hchar : ringChar F' = ringChar FF'
this : Fact (Nat.Prime (ringChar F'))
⊢ ((ringHomComp χ (algebraMap F' (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F'))) (-1) *
        ↑(Fintype.card F)) ^
      (ringChar (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F') ^ ↑n' / 2) =
    (ringHomComp χ (algebraMap F' (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F')))
      (↑(ringChar (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F')) ^ ↑n')

Next tactic:
haveI := Fact.mk (hchar.subst hp')
/-- When `F` and `F'` are finite fields and `χ : F → F'` is a nontrivial quadratic character,
then `(χ(-1) * #F)^(#F'/2) = χ(#F')`. -/
theorem Char.card_pow_card {F : Type*} [Field F] [Fintype F] {F' : Type*} [Field F'] [Fintype F']
    {χ : MulChar F F'} (hχ₁ : IsNontrivial χ) (hχ₂ : IsQuadratic χ)
    (hch₁ : ringChar F' ≠ ringChar F) (hch₂ : ringChar F' ≠ 2) :
    (χ (-1) * Fintype.card F) ^ (Fintype.card F' / 2) = χ (Fintype.card F') := by
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)
  obtain ⟨n', hp', hc'⟩ := FiniteField.card F' (ringChar F')
  let ψ := primitiveCharFiniteField F F' hch₁
  -- Porting note: this was a `let` but then Lean would time out at
  -- unification so it is changed to as `set` and `FF'` is replaced by its
  -- definition before unification
  set FF' := CyclotomicField ψ.n F' with FF'_def
  have hchar := Algebra.ringChar_eq F' FF'
  apply (algebraMap F' FF').injective
  rw [map_pow, map_mul, map_natCast, hc', hchar, Nat.cast_pow]
  simp only [← MulChar.ringHomComp_apply]
  haveI := Fact.mk hp'
  haveI := Fact.mk (hchar.subst hp')
  

Proof state:
case intro.intro.intro.intro.a
R : Type u
inst✝⁷ : CommRing R
inst✝⁶ : Fintype R
R' : Type v
inst✝⁵ : CommRing R'
inst✝⁴ : IsDomain R'
F : Type u_1
inst✝³ : Field F
inst✝² : Fintype F
F' : Type u_2
inst✝¹ : Field F'
inst✝ : Fintype F'
χ : MulChar F F'
hχ₁ : MulChar.IsNontrivial χ
hχ₂ : IsQuadratic χ
hch₁ : ringChar F' ≠ ringChar F
hch₂ : ringChar F' ≠ 2
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
n' : ℕ+
hp' : Nat.Prime (ringChar F')
hc' : Fintype.card F' = ringChar F' ^ ↑n'
ψ : PrimitiveAddChar F F' := primitiveCharFiniteField F F' hch₁
FF' : Type u_2 := CyclotomicField (PrimitiveAddChar.n ψ) F'
FF'_def : FF' = CyclotomicField (PrimitiveAddChar.n ψ) F'
hchar : ringChar F' = ringChar FF'
this✝ : Fact (Nat.Prime (ringChar F'))
this : Fact (Nat.Prime (ringChar FF'))
⊢ ((ringHomComp χ (algebraMap F' (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F'))) (-1) *
        ↑(Fintype.card F)) ^
      (ringChar (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F') ^ ↑n' / 2) =
    (ringHomComp χ (algebraMap F' (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F')))
      (↑(ringChar (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁)) F')) ^ ↑n')

Next tactic:
rw [Ne, ← Nat.prime_dvd_prime_iff_eq hp' hp, ← isUnit_iff_not_dvd_char, hchar] at hch₁
/-- When `F` and `F'` are finite fields and `χ : F → F'` is a nontrivial quadratic character,
then `(χ(-1) * #F)^(#F'/2) = χ(#F')`. -/
theorem Char.card_pow_card {F : Type*} [Field F] [Fintype F] {F' : Type*} [Field F'] [Fintype F']
    {χ : MulChar F F'} (hχ₁ : IsNontrivial χ) (hχ₂ : IsQuadratic χ)
    (hch₁ : ringChar F' ≠ ringChar F) (hch₂ : ringChar F' ≠ 2) :
    (χ (-1) * Fintype.card F) ^ (Fintype.card F' / 2) = χ (Fintype.card F') := by
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)
  obtain ⟨n', hp', hc'⟩ := FiniteField.card F' (ringChar F')
  let ψ := primitiveCharFiniteField F F' hch₁
  -- Porting note: this was a `let` but then Lean would time out at
  -- unification so it is changed to as `set` and `FF'` is replaced by its
  -- definition before unification
  set FF' := CyclotomicField ψ.n F' with FF'_def
  have hchar := Algebra.ringChar_eq F' FF'
  apply (algebraMap F' FF').injective
  rw [map_pow, map_mul, map_natCast, hc', hchar, Nat.cast_pow]
  simp only [← MulChar.ringHomComp_apply]
  haveI := Fact.mk hp'
  haveI := Fact.mk (hchar.subst hp')
  rw [Ne, ← Nat.prime_dvd_prime_iff_eq hp' hp, ← isUnit_iff_not_dvd_char, hchar] at hch₁
  -- Porting note: original proof is below and, as noted above, `FF'` needs to
  -- be replaced by its definition before unification to avoid time out
  -- exact Char.card_pow_char_pow (hχ₂.comp _) ψ.char (ringChar FF') n' hch₁ (hchar ▸ hch₂)
  --      (gaussSum_sq (hχ₁.comp <| RingHom.injective _) (hχ₂.comp _) ψ.prim)
  

Proof state:
case intro.intro.intro.intro.a
R : Type u
inst✝⁷ : CommRing R
inst✝⁶ : Fintype R
R' : Type v
inst✝⁵ : CommRing R'
inst✝⁴ : IsDomain R'
F : Type u_1
inst✝³ : Field F
inst✝² : Fintype F
F' : Type u_2
inst✝¹ : Field F'
inst✝ : Fintype F'
χ : MulChar F F'
hχ₁ : MulChar.IsNontrivial χ
hχ₂ : IsQuadratic χ
hch₁✝ : ringChar F' ≠ ringChar F
hch₂ : ringChar F' ≠ 2
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
n' : ℕ+
hp' : Nat.Prime (ringChar F')
hc' : Fintype.card F' = ringChar F' ^ ↑n'
ψ : PrimitiveAddChar F F' := primitiveCharFiniteField F F' hch₁✝
FF' : Type u_2 := CyclotomicField (PrimitiveAddChar.n ψ) F'
hch₁ : IsUnit ↑(ringChar FF')
FF'_def : FF' = CyclotomicField (PrimitiveAddChar.n ψ) F'
hchar : ringChar F' = ringChar FF'
this✝ : Fact (Nat.Prime (ringChar F'))
this : Fact (Nat.Prime (ringChar FF'))
⊢ ((ringHomComp χ (algebraMap F' (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁✝)) F')))
          (-1) *
        ↑(Fintype.card F)) ^
      (ringChar (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁✝)) F') ^ ↑n' / 2) =
    (ringHomComp χ (algebraMap F' (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁✝)) F')))
      (↑(ringChar (CyclotomicField (PrimitiveAddChar.n (primitiveCharFiniteField F F' hch₁✝)) F')) ^ ↑n')

Next tactic:
have := Char.card_pow_char_pow (hχ₂.comp (algebraMap F' FF')) ψ.char
    (ringChar FF') n' hch₁ (hchar ▸ hch₂)
    (gaussSum_sq (hχ₁.comp <| RingHom.injective _) (hχ₂.comp _) ψ.prim)
/-- For every finite field `F` of odd characteristic, we have `2^(#F/2) = χ₈#F` in `F`. -/
theorem FiniteField.two_pow_card {F : Type*} [Fintype F] [Field F] (hF : ringChar F ≠ 2) :
    (2 : F) ^ (Fintype.card F / 2) = χ₈ (Fintype.card F) := by
  

Proof state:
F : Type u_1
inst✝¹ : Fintype F
inst✝ : Field F
hF : ringChar F ≠ 2
⊢ 2 ^ (Fintype.card F / 2) = ↑(χ₈ ↑(Fintype.card F))

Next tactic:
have hp2 : ∀ n : ℕ, (2 ^ n : F) ≠ 0 := fun n => pow_ne_zero n (Ring.two_ne_zero hF)
/-- For every finite field `F` of odd characteristic, we have `2^(#F/2) = χ₈#F` in `F`. -/
theorem FiniteField.two_pow_card {F : Type*} [Fintype F] [Field F] (hF : ringChar F ≠ 2) :
    (2 : F) ^ (Fintype.card F / 2) = χ₈ (Fintype.card F) := by
  have hp2 : ∀ n : ℕ, (2 ^ n : F) ≠ 0 := fun n => pow_ne_zero n (Ring.two_ne_zero hF)
  

Proof state:
F : Type u_1
inst✝¹ : Fintype F
inst✝ : Field F
hF : ringChar F ≠ 2
hp2 : ∀ (n : ℕ), 2 ^ n ≠ 0
⊢ 2 ^ (Fintype.card F / 2) = ↑(χ₈ ↑(Fintype.card F))

Next tactic:
obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)
/-- For every finite field `F` of odd characteristic, we have `2^(#F/2) = χ₈#F` in `F`. -/
theorem FiniteField.two_pow_card {F : Type*} [Fintype F] [Field F] (hF : ringChar F ≠ 2) :
    (2 : F) ^ (Fintype.card F / 2) = χ₈ (Fintype.card F) := by
  have hp2 : ∀ n : ℕ, (2 ^ n : F) ≠ 0 := fun n => pow_ne_zero n (Ring.two_ne_zero hF)
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)

  -- we work in `FF`, the eighth cyclotomic field extension of `F`
  -- Porting note: was
  -- let FF := (Polynomial.cyclotomic 8 F).SplittingField
  -- but we want to unify with `CyclotomicField` below.
  

Proof state:
case intro.intro
F : Type u_1
inst✝¹ : Fintype F
inst✝ : Field F
hF : ringChar F ≠ 2
hp2 : ∀ (n : ℕ), 2 ^ n ≠ 0
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
⊢ 2 ^ (Fintype.card F / 2) = ↑(χ₈ ↑(Fintype.card F))

Next tactic:
let FF := CyclotomicField 8 F
/-- For every finite field `F` of odd characteristic, we have `2^(#F/2) = χ₈#F` in `F`. -/
theorem FiniteField.two_pow_card {F : Type*} [Fintype F] [Field F] (hF : ringChar F ≠ 2) :
    (2 : F) ^ (Fintype.card F / 2) = χ₈ (Fintype.card F) := by
  have hp2 : ∀ n : ℕ, (2 ^ n : F) ≠ 0 := fun n => pow_ne_zero n (Ring.two_ne_zero hF)
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)

  -- we work in `FF`, the eighth cyclotomic field extension of `F`
  -- Porting note: was
  -- let FF := (Polynomial.cyclotomic 8 F).SplittingField
  -- but we want to unify with `CyclotomicField` below.
  let FF := CyclotomicField 8 F
  

Proof state:
case intro.intro
F : Type u_1
inst✝¹ : Fintype F
inst✝ : Field F
hF : ringChar F ≠ 2
hp2 : ∀ (n : ℕ), 2 ^ n ≠ 0
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
FF : Type u_1 := CyclotomicField 8 F
⊢ 2 ^ (Fintype.card F / 2) = ↑(χ₈ ↑(Fintype.card F))

Next tactic:
haveI : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F) :=
    Polynomial.IsSplittingField.splittingField _
/-- For every finite field `F` of odd characteristic, we have `2^(#F/2) = χ₈#F` in `F`. -/
theorem FiniteField.two_pow_card {F : Type*} [Fintype F] [Field F] (hF : ringChar F ≠ 2) :
    (2 : F) ^ (Fintype.card F / 2) = χ₈ (Fintype.card F) := by
  have hp2 : ∀ n : ℕ, (2 ^ n : F) ≠ 0 := fun n => pow_ne_zero n (Ring.two_ne_zero hF)
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)

  -- we work in `FF`, the eighth cyclotomic field extension of `F`
  -- Porting note: was
  -- let FF := (Polynomial.cyclotomic 8 F).SplittingField
  -- but we want to unify with `CyclotomicField` below.
  let FF := CyclotomicField 8 F
  haveI : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F) :=
    Polynomial.IsSplittingField.splittingField _
  

Proof state:
case intro.intro
F : Type u_1
inst✝¹ : Fintype F
inst✝ : Field F
hF : ringChar F ≠ 2
hp2 : ∀ (n : ℕ), 2 ^ n ≠ 0
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
FF : Type u_1 := CyclotomicField 8 F
this : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F)
⊢ 2 ^ (Fintype.card F / 2) = ↑(χ₈ ↑(Fintype.card F))

Next tactic:
haveI : FiniteDimensional F FF :=
    Polynomial.IsSplittingField.finiteDimensional FF (Polynomial.cyclotomic 8 F)
/-- For every finite field `F` of odd characteristic, we have `2^(#F/2) = χ₈#F` in `F`. -/
theorem FiniteField.two_pow_card {F : Type*} [Fintype F] [Field F] (hF : ringChar F ≠ 2) :
    (2 : F) ^ (Fintype.card F / 2) = χ₈ (Fintype.card F) := by
  have hp2 : ∀ n : ℕ, (2 ^ n : F) ≠ 0 := fun n => pow_ne_zero n (Ring.two_ne_zero hF)
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)

  -- we work in `FF`, the eighth cyclotomic field extension of `F`
  -- Porting note: was
  -- let FF := (Polynomial.cyclotomic 8 F).SplittingField
  -- but we want to unify with `CyclotomicField` below.
  let FF := CyclotomicField 8 F
  haveI : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F) :=
    Polynomial.IsSplittingField.splittingField _
  haveI : FiniteDimensional F FF :=
    Polynomial.IsSplittingField.finiteDimensional FF (Polynomial.cyclotomic 8 F)
  

Proof state:
case intro.intro
F : Type u_1
inst✝¹ : Fintype F
inst✝ : Field F
hF : ringChar F ≠ 2
hp2 : ∀ (n : ℕ), 2 ^ n ≠ 0
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
FF : Type u_1 := CyclotomicField 8 F
this✝ : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F)
this : FiniteDimensional F FF
⊢ 2 ^ (Fintype.card F / 2) = ↑(χ₈ ↑(Fintype.card F))

Next tactic:
haveI : Fintype FF := FiniteDimensional.fintypeOfFintype F FF
/-- For every finite field `F` of odd characteristic, we have `2^(#F/2) = χ₈#F` in `F`. -/
theorem FiniteField.two_pow_card {F : Type*} [Fintype F] [Field F] (hF : ringChar F ≠ 2) :
    (2 : F) ^ (Fintype.card F / 2) = χ₈ (Fintype.card F) := by
  have hp2 : ∀ n : ℕ, (2 ^ n : F) ≠ 0 := fun n => pow_ne_zero n (Ring.two_ne_zero hF)
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)

  -- we work in `FF`, the eighth cyclotomic field extension of `F`
  -- Porting note: was
  -- let FF := (Polynomial.cyclotomic 8 F).SplittingField
  -- but we want to unify with `CyclotomicField` below.
  let FF := CyclotomicField 8 F
  haveI : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F) :=
    Polynomial.IsSplittingField.splittingField _
  haveI : FiniteDimensional F FF :=
    Polynomial.IsSplittingField.finiteDimensional FF (Polynomial.cyclotomic 8 F)
  haveI : Fintype FF := FiniteDimensional.fintypeOfFintype F FF
  

Proof state:
case intro.intro
F : Type u_1
inst✝¹ : Fintype F
inst✝ : Field F
hF : ringChar F ≠ 2
hp2 : ∀ (n : ℕ), 2 ^ n ≠ 0
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
FF : Type u_1 := CyclotomicField 8 F
this✝¹ : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F)
this✝ : FiniteDimensional F FF
this : Fintype FF
⊢ 2 ^ (Fintype.card F / 2) = ↑(χ₈ ↑(Fintype.card F))

Next tactic:
have hchar := Algebra.ringChar_eq F FF
/-- For every finite field `F` of odd characteristic, we have `2^(#F/2) = χ₈#F` in `F`. -/
theorem FiniteField.two_pow_card {F : Type*} [Fintype F] [Field F] (hF : ringChar F ≠ 2) :
    (2 : F) ^ (Fintype.card F / 2) = χ₈ (Fintype.card F) := by
  have hp2 : ∀ n : ℕ, (2 ^ n : F) ≠ 0 := fun n => pow_ne_zero n (Ring.two_ne_zero hF)
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)

  -- we work in `FF`, the eighth cyclotomic field extension of `F`
  -- Porting note: was
  -- let FF := (Polynomial.cyclotomic 8 F).SplittingField
  -- but we want to unify with `CyclotomicField` below.
  let FF := CyclotomicField 8 F
  haveI : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F) :=
    Polynomial.IsSplittingField.splittingField _
  haveI : FiniteDimensional F FF :=
    Polynomial.IsSplittingField.finiteDimensional FF (Polynomial.cyclotomic 8 F)
  haveI : Fintype FF := FiniteDimensional.fintypeOfFintype F FF
  have hchar := Algebra.ringChar_eq F FF
  

Proof state:
case intro.intro
F : Type u_1
inst✝¹ : Fintype F
inst✝ : Field F
hF : ringChar F ≠ 2
hp2 : ∀ (n : ℕ), 2 ^ n ≠ 0
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
FF : Type u_1 := CyclotomicField 8 F
this✝¹ : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F)
this✝ : FiniteDimensional F FF
this : Fintype FF
hchar : ringChar F = ringChar FF
⊢ 2 ^ (Fintype.card F / 2) = ↑(χ₈ ↑(Fintype.card F))

Next tactic:
have FFp := hchar.subst hp
/-- For every finite field `F` of odd characteristic, we have `2^(#F/2) = χ₈#F` in `F`. -/
theorem FiniteField.two_pow_card {F : Type*} [Fintype F] [Field F] (hF : ringChar F ≠ 2) :
    (2 : F) ^ (Fintype.card F / 2) = χ₈ (Fintype.card F) := by
  have hp2 : ∀ n : ℕ, (2 ^ n : F) ≠ 0 := fun n => pow_ne_zero n (Ring.two_ne_zero hF)
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)

  -- we work in `FF`, the eighth cyclotomic field extension of `F`
  -- Porting note: was
  -- let FF := (Polynomial.cyclotomic 8 F).SplittingField
  -- but we want to unify with `CyclotomicField` below.
  let FF := CyclotomicField 8 F
  haveI : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F) :=
    Polynomial.IsSplittingField.splittingField _
  haveI : FiniteDimensional F FF :=
    Polynomial.IsSplittingField.finiteDimensional FF (Polynomial.cyclotomic 8 F)
  haveI : Fintype FF := FiniteDimensional.fintypeOfFintype F FF
  have hchar := Algebra.ringChar_eq F FF
  have FFp := hchar.subst hp
  

Proof state:
case intro.intro
F : Type u_1
inst✝¹ : Fintype F
inst✝ : Field F
hF : ringChar F ≠ 2
hp2 : ∀ (n : ℕ), 2 ^ n ≠ 0
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
FF : Type u_1 := CyclotomicField 8 F
this✝¹ : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F)
this✝ : FiniteDimensional F FF
this : Fintype FF
hchar : ringChar F = ringChar FF
FFp : Nat.Prime (ringChar FF)
⊢ 2 ^ (Fintype.card F / 2) = ↑(χ₈ ↑(Fintype.card F))

Next tactic:
haveI := Fact.mk FFp
/-- For every finite field `F` of odd characteristic, we have `2^(#F/2) = χ₈#F` in `F`. -/
theorem FiniteField.two_pow_card {F : Type*} [Fintype F] [Field F] (hF : ringChar F ≠ 2) :
    (2 : F) ^ (Fintype.card F / 2) = χ₈ (Fintype.card F) := by
  have hp2 : ∀ n : ℕ, (2 ^ n : F) ≠ 0 := fun n => pow_ne_zero n (Ring.two_ne_zero hF)
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)

  -- we work in `FF`, the eighth cyclotomic field extension of `F`
  -- Porting note: was
  -- let FF := (Polynomial.cyclotomic 8 F).SplittingField
  -- but we want to unify with `CyclotomicField` below.
  let FF := CyclotomicField 8 F
  haveI : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F) :=
    Polynomial.IsSplittingField.splittingField _
  haveI : FiniteDimensional F FF :=
    Polynomial.IsSplittingField.finiteDimensional FF (Polynomial.cyclotomic 8 F)
  haveI : Fintype FF := FiniteDimensional.fintypeOfFintype F FF
  have hchar := Algebra.ringChar_eq F FF
  have FFp := hchar.subst hp
  haveI := Fact.mk FFp
  

Proof state:
case intro.intro
F : Type u_1
inst✝¹ : Fintype F
inst✝ : Field F
hF : ringChar F ≠ 2
hp2 : ∀ (n : ℕ), 2 ^ n ≠ 0
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
FF : Type u_1 := CyclotomicField 8 F
this✝² : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F)
this✝¹ : FiniteDimensional F FF
this✝ : Fintype FF
hchar : ringChar F = ringChar FF
FFp : Nat.Prime (ringChar FF)
this : Fact (Nat.Prime (ringChar FF))
⊢ 2 ^ (Fintype.card F / 2) = ↑(χ₈ ↑(Fintype.card F))

Next tactic:
have hFF := ne_of_eq_of_ne hchar.symm hF
/-- For every finite field `F` of odd characteristic, we have `2^(#F/2) = χ₈#F` in `F`. -/
theorem FiniteField.two_pow_card {F : Type*} [Fintype F] [Field F] (hF : ringChar F ≠ 2) :
    (2 : F) ^ (Fintype.card F / 2) = χ₈ (Fintype.card F) := by
  have hp2 : ∀ n : ℕ, (2 ^ n : F) ≠ 0 := fun n => pow_ne_zero n (Ring.two_ne_zero hF)
  obtain ⟨n, hp, hc⟩ := FiniteField.card F (ringChar F)

  -- we work in `FF`, the eighth cyclotomic field extension of `F`
  -- Porting note: was
  -- let FF := (Polynomial.cyclotomic 8 F).SplittingField
  -- but we want to unify with `CyclotomicField` below.
  let FF := CyclotomicField 8 F
  haveI : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F) :=
    Polynomial.IsSplittingField.splittingField _
  haveI : FiniteDimensional F FF :=
    Polynomial.IsSplittingField.finiteDimensional FF (Polynomial.cyclotomic 8 F)
  haveI : Fintype FF := FiniteDimensional.fintypeOfFintype F FF
  have hchar := Algebra.ringChar_eq F FF
  have FFp := hchar.subst hp
  haveI := Fact.mk FFp
  have hFF := ne_of_eq_of_ne hchar.symm hF
  -- `ringChar FF ≠ 2`
  

Proof state:
case intro.intro
F : Type u_1
inst✝¹ : Fintype F
inst✝ : Field F
hF : ringChar F ≠ 2
hp2 : ∀ (n : ℕ), 2 ^ n ≠ 0
n : ℕ+
hp : Nat.Prime (ringChar F)
hc : Fintype.card F = ringChar F ^ ↑n
FF : Type u_1 := CyclotomicField 8 F
this✝² : Polynomial.IsSplittingField F FF (Polynomial.cyclotomic 8 F)
this✝¹ : FiniteDimensional F FF
this✝ : Fintype FF
hchar : ringChar F = ringChar FF
FFp : Nat.Prime (ringChar FF)
this : Fact (Nat.Prime (ringChar FF))
hFF : ringChar FF ≠ 2
⊢ 2 ^ (Fintype.card F / 2) = ↑(χ₈ ↑(Fintype.card F))

Next tactic:
have hu : IsUnit (ringChar FF : ZMod 8) := by
    rw [isUnit_iff_not_dvd_char, ringChar_zmod_n]
    rw [Ne, ← Nat.prime_dvd_prime_iff_eq FFp Nat.prime_two] at hFF
    change ¬_ ∣ 2 ^ 3
    exact mt FFp.dvd_of_dvd_pow hFF