l3lab/ntp-mathlib huggingface dataset:
/-- When `i = j`, projections `Pi.eval C i` and `Pi.eval C j` are related by the equivalence
`Pi.eqToEquivalence C h : C i ≌ C j`. -/
@[simps!]
def Pi.evalCompEqToEquivalenceFunctor {i j : I} (h : i = j) :
    Pi.eval C i ⋙ (Pi.eqToEquivalence C h).functor ≅
      Pi.eval C j :=
  eqToIso (by 

Proof state:
I : Type w₀
J : Type w₁
C : I → Type u₁
inst✝ : (i : I) → Category.{v₁, u₁} (C i)
i j : I
h : i = j
⊢ eval C i ⋙ (eqToEquivalence C h).functor = eval C j

Next tactic:
subst h
/-- When `i = j`, projections `Pi.eval C i` and `Pi.eval C j` are related by the equivalence
`Pi.eqToEquivalence C h : C i ≌ C j`. -/
@[simps!]
def Pi.evalCompEqToEquivalenceFunctor {i j : I} (h : i = j) :
    Pi.eval C i ⋙ (Pi.eqToEquivalence C h).functor ≅
      Pi.eval C j :=
  eqToIso (by subst h; 

Proof state:
I : Type w₀
J : Type w₁
C : I → Type u₁
inst✝ : (i : I) → Category.{v₁, u₁} (C i)
i : I
⊢ eval C i ⋙ (eqToEquivalence C (_ : i = i)).functor = eval C i

Next tactic:
rfl
/-- The equivalences given by `Pi.eqToEquivalence` are compatible with reindexing. -/
@[simps!]
def Pi.eqToEquivalenceFunctorIso (f : J → I) {i' j' : J} (h : i' = j') :
    (Pi.eqToEquivalence C (congr_arg f h)).functor ≅
      (Pi.eqToEquivalence (fun i' => C (f i')) h).functor :=
  eqToIso (by 

Proof state:
I : Type w₀
J : Type w₁
C : I → Type u₁
inst✝ : (i : I) → Category.{v₁, u₁} (C i)
f : J → I
i' j' : J
h : i' = j'
⊢ (eqToEquivalence C (_ : f i' = f j')).functor = (eqToEquivalence (fun i' => C (f i')) h).functor

Next tactic:
subst h
/-- The equivalences given by `Pi.eqToEquivalence` are compatible with reindexing. -/
@[simps!]
def Pi.eqToEquivalenceFunctorIso (f : J → I) {i' j' : J} (h : i' = j') :
    (Pi.eqToEquivalence C (congr_arg f h)).functor ≅
      (Pi.eqToEquivalence (fun i' => C (f i')) h).functor :=
  eqToIso (by subst h; 

Proof state:
I : Type w₀
J : Type w₁
C : I → Type u₁
inst✝ : (i : I) → Category.{v₁, u₁} (C i)
f : J → I
i' : J
⊢ (eqToEquivalence C (_ : f i' = f i')).functor = (eqToEquivalence (fun i' => C (f i')) (_ : i' = i')).functor

Next tactic:
rfl
/-- Reindexing a family of categories gives equivalent `Pi` categories. -/
@[simps]
noncomputable def Pi.equivalenceOfEquiv (e : J ≃ I) :
    (∀ j, C (e j)) ≌ (∀ i, C i) where
  functor := Functor.pi' (fun i => Pi.eval _ (e.symm i) ⋙
    (Pi.eqToEquivalence C (by 

Proof state:
I : Type w₀
J : Type w₁
C : I → Type u₁
inst✝ : (i : I) → Category.{v₁, u₁} (C i)
e : J ≃ I
i : I
⊢ e (e.symm i) = i

Next tactic:
simp
/-- A product of categories indexed by `Option J` identifies to a binary product. -/
@[simps]
def Pi.optionEquivalence (C' : Option J → Type u₁) [∀ i, Category.{v₁} (C' i)] :
    (∀ i, C' i) ≌ C' none × (∀ (j : J), C' (some j)) where
  functor := Functor.prod' (Pi.eval C' none)
    (Functor.pi' (fun i => (Pi.eval _ (some i))))
  inverse := Functor.pi' (fun i => match i with
    | none => Prod.fst _ _
    | some i => Prod.snd _ _ ⋙ (Pi.eval _ i))
  unitIso :=  NatIso.pi' (fun i => match i with
    | none => Iso.refl _
    | some i => Iso.refl _)
  counitIso := by 

Proof state:
I : Type w₀
J : Type w₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
C' : Option J → Type u₁
inst✝ : (i : Option J) → Category.{v₁, u₁} (C' i)
⊢ (Functor.pi' fun i =>
        match i with
        | none => Prod.fst (C' none) ((j : J) → C' (some j))
        | some i => Prod.snd (C' none) ((j : J) → C' (some j)) ⋙ eval (fun j => C' (some j)) i) ⋙
      Functor.prod' (eval C' none) (Functor.pi' fun i => eval (fun i => C' i) (some i)) ≅
    𝟭 (C' none × ((j : J) → C' (some j)))

Next tactic:
exact Iso.refl _
/-- Define the nontrivial quadratic character on `ZMod 4`, `χ₄`.
It corresponds to the extension `ℚ(√-1)/ℚ`. -/
@[simps]
def χ₄ : MulChar (ZMod 4) ℤ where
  toFun := (![0, 1, 0, -1] : ZMod 4 → ℤ)
  map_one' := rfl
  map_mul' := by 

Proof state:
⊢ ∀ (x y : ZMod 4),
    OneHom.toFun
        { toFun := ![0, 1, 0, -1], map_one' := (_ : Matrix.vecCons 0 ![1, 0, -1] 1 = Matrix.vecCons 0 ![1, 0, -1] 1) }
        (x * y) =
      OneHom.toFun
          { toFun := ![0, 1, 0, -1], map_one' := (_ : Matrix.vecCons 0 ![1, 0, -1] 1 = Matrix.vecCons 0 ![1, 0, -1] 1) }
          x *
        OneHom.toFun
          { toFun := ![0, 1, 0, -1], map_one' := (_ : Matrix.vecCons 0 ![1, 0, -1] 1 = Matrix.vecCons 0 ![1, 0, -1] 1) }
          y

Next tactic:
decide
/-- Define the nontrivial quadratic character on `ZMod 4`, `χ₄`.
It corresponds to the extension `ℚ(√-1)/ℚ`. -/
@[simps]
def χ₄ : MulChar (ZMod 4) ℤ where
  toFun := (![0, 1, 0, -1] : ZMod 4 → ℤ)
  map_one' := rfl
  map_mul' := by decide
  map_nonunit' := by 

Proof state:
⊢ ∀ (a : ZMod 4),
    ¬IsUnit a →
      OneHom.toFun
          (↑{
              toOneHom :=
                { toFun := ![0, 1, 0, -1],
                  map_one' := (_ : Matrix.vecCons 0 ![1, 0, -1] 1 = Matrix.vecCons 0 ![1, 0, -1] 1) },
              map_mul' :=
                (_ :
                  ∀ (x y : ZMod 4),
                    OneHom.toFun
                        { toFun := ![0, 1, 0, -1],
                          map_one' := (_ : Matrix.vecCons 0 ![1, 0, -1] 1 = Matrix.vecCons 0 ![1, 0, -1] 1) }
                        (x * y) =
                      OneHom.toFun
                          { toFun := ![0, 1, 0, -1],
                            map_one' := (_ : Matrix.vecCons 0 ![1, 0, -1] 1 = Matrix.vecCons 0 ![1, 0, -1] 1) }
                          x *
                        OneHom.toFun
                          { toFun := ![0, 1, 0, -1],
                            map_one' := (_ : Matrix.vecCons 0 ![1, 0, -1] 1 = Matrix.vecCons 0 ![1, 0, -1] 1) }
                          y) })
          a =
        0

Next tactic:
decide
/-- `χ₄` takes values in `{0, 1, -1}` -/
theorem isQuadratic_χ₄ : χ₄.IsQuadratic := by
  

Proof state:
⊢ MulChar.IsQuadratic χ₄

Next tactic:
intro a
/-- `χ₄` takes values in `{0, 1, -1}` -/
theorem isQuadratic_χ₄ : χ₄.IsQuadratic := by
  intro a
  -- Porting note: was `decide!`
  

Proof state:
a : ZMod 4
⊢ χ₄ a = 0 ∨ χ₄ a = 1 ∨ χ₄ a = -1

Next tactic:
fin_cases a
/-- `χ₄` takes values in `{0, 1, -1}` -/
theorem isQuadratic_χ₄ : χ₄.IsQuadratic := by
  intro a
  -- Porting note: was `decide!`
  fin_cases a
  

Proof state:
case head
⊢ χ₄ { val := 0, isLt := (_ : 0 < 3 + 1) } = 0 ∨
    χ₄ { val := 0, isLt := (_ : 0 < 3 + 1) } = 1 ∨ χ₄ { val := 0, isLt := (_ : 0 < 3 + 1) } = -1
case tail.head
⊢ χ₄ { val := 1, isLt := (_ : (fun a => a < 3 + 1) 1) } = 0 ∨
    χ₄ { val := 1, isLt := (_ : (fun a => a < 3 + 1) 1) } = 1 ∨
      χ₄ { val := 1, isLt := (_ : (fun a => a < 3 + 1) 1) } = -1
case tail.tail.head
⊢ χ₄ { val := 2, isLt := (_ : (fun a => (fun a => a < 3 + 1) a) 2) } = 0 ∨
    χ₄ { val := 2, isLt := (_ : (fun a => (fun a => a < 3 + 1) a) 2) } = 1 ∨
      χ₄ { val := 2, isLt := (_ : (fun a => (fun a => a < 3 + 1) a) 2) } = -1
case tail.tail.tail.head
⊢ χ₄ { val := 3, isLt := (_ : (fun a => (fun a => (fun a => a < 3 + 1) a) a) 3) } = 0 ∨
    χ₄ { val := 3, isLt := (_ : (fun a => (fun a => (fun a => a < 3 + 1) a) a) 3) } = 1 ∨
      χ₄ { val := 3, isLt := (_ : (fun a => (fun a => (fun a => a < 3 + 1) a) a) 3) } = -1

Next tactic:
all_goals decide
/-- `χ₄` takes values in `{0, 1, -1}` -/
theorem isQuadratic_χ₄ : χ₄.IsQuadratic := by
  intro a
  -- Porting note: was `decide!`
  fin_cases a
  all_goals 

Proof state:
case head
⊢ χ₄ { val := 0, isLt := (_ : 0 < 3 + 1) } = 0 ∨
    χ₄ { val := 0, isLt := (_ : 0 < 3 + 1) } = 1 ∨ χ₄ { val := 0, isLt := (_ : 0 < 3 + 1) } = -1

Next tactic:
decide
/-- `χ₄` takes values in `{0, 1, -1}` -/
theorem isQuadratic_χ₄ : χ₄.IsQuadratic := by
  intro a
  -- Porting note: was `decide!`
  fin_cases a
  all_goals 

Proof state:
case tail.head
⊢ χ₄ { val := 1, isLt := (_ : (fun a => a < 3 + 1) 1) } = 0 ∨
    χ₄ { val := 1, isLt := (_ : (fun a => a < 3 + 1) 1) } = 1 ∨
      χ₄ { val := 1, isLt := (_ : (fun a => a < 3 + 1) 1) } = -1

Next tactic:
decide
/-- `χ₄` takes values in `{0, 1, -1}` -/
theorem isQuadratic_χ₄ : χ₄.IsQuadratic := by
  intro a
  -- Porting note: was `decide!`
  fin_cases a
  all_goals 

Proof state:
case tail.tail.head
⊢ χ₄ { val := 2, isLt := (_ : (fun a => (fun a => a < 3 + 1) a) 2) } = 0 ∨
    χ₄ { val := 2, isLt := (_ : (fun a => (fun a => a < 3 + 1) a) 2) } = 1 ∨
      χ₄ { val := 2, isLt := (_ : (fun a => (fun a => a < 3 + 1) a) 2) } = -1

Next tactic:
decide
/-- `χ₄` takes values in `{0, 1, -1}` -/
theorem isQuadratic_χ₄ : χ₄.IsQuadratic := by
  intro a
  -- Porting note: was `decide!`
  fin_cases a
  all_goals 

Proof state:
case tail.tail.tail.head
⊢ χ₄ { val := 3, isLt := (_ : (fun a => (fun a => (fun a => a < 3 + 1) a) a) 3) } = 0 ∨
    χ₄ { val := 3, isLt := (_ : (fun a => (fun a => (fun a => a < 3 + 1) a) a) 3) } = 1 ∨
      χ₄ { val := 3, isLt := (_ : (fun a => (fun a => (fun a => a < 3 + 1) a) a) 3) } = -1

Next tactic:
decide
/-- The value of `χ₄ n`, for `n : ℕ`, depends only on `n % 4`. -/
theorem χ₄_nat_mod_four (n : ℕ) : χ₄ n = χ₄ (n % 4 : ℕ) := by 

Proof state:
n : ℕ
⊢ χ₄ ↑n = χ₄ ↑(n % 4)

Next tactic:
rw [← ZMod.nat_cast_mod n 4]
/-- The value of `χ₄ n`, for `n : ℤ`, depends only on `n % 4`. -/
theorem χ₄_int_mod_four (n : ℤ) : χ₄ n = χ₄ (n % 4 : ℤ) := by
  

Proof state:
n : ℤ
⊢ χ₄ ↑n = χ₄ ↑(n % 4)

Next tactic:
rw [← ZMod.int_cast_mod n 4]
/-- The value of `χ₄ n`, for `n : ℤ`, depends only on `n % 4`. -/
theorem χ₄_int_mod_four (n : ℤ) : χ₄ n = χ₄ (n % 4 : ℤ) := by
  rw [← ZMod.int_cast_mod n 4]
  

Proof state:
n : ℤ
⊢ χ₄ ↑(n % ↑4) = χ₄ ↑(n % 4)

Next tactic:
norm_cast
/-- An explicit description of `χ₄` on integers / naturals -/
theorem χ₄_int_eq_if_mod_four (n : ℤ) :
    χ₄ n = if n % 2 = 0 then 0 else if n % 4 = 1 then 1 else -1 := by
  

Proof state:
n : ℤ
⊢ χ₄ ↑n = if n % 2 = 0 then 0 else if n % 4 = 1 then 1 else -1

Next tactic:
have help : ∀ m : ℤ, 0 ≤ m → m < 4 → χ₄ m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1 := by
    decide
/-- An explicit description of `χ₄` on integers / naturals -/
theorem χ₄_int_eq_if_mod_four (n : ℤ) :
    χ₄ n = if n % 2 = 0 then 0 else if n % 4 = 1 then 1 else -1 := by
  have help : ∀ m : ℤ, 0 ≤ m → m < 4 → χ₄ m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1 := by
    

Proof state:
n : ℤ
⊢ ∀ (m : ℤ), 0 ≤ m → m < 4 → χ₄ ↑m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1

Next tactic:
decide
/-- An explicit description of `χ₄` on integers / naturals -/
theorem χ₄_int_eq_if_mod_four (n : ℤ) :
    χ₄ n = if n % 2 = 0 then 0 else if n % 4 = 1 then 1 else -1 := by
  have help : ∀ m : ℤ, 0 ≤ m → m < 4 → χ₄ m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1 := by
    decide
  

Proof state:
n : ℤ
help : ∀ (m : ℤ), 0 ≤ m → m < 4 → χ₄ ↑m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1
⊢ χ₄ ↑n = if n % 2 = 0 then 0 else if n % 4 = 1 then 1 else -1

Next tactic:
rw [← Int.emod_emod_of_dvd n (by decide : (2 : ℤ) ∣ 4), ← ZMod.int_cast_mod n 4]
/-- An explicit description of `χ₄` on integers / naturals -/
theorem χ₄_int_eq_if_mod_four (n : ℤ) :
    χ₄ n = if n % 2 = 0 then 0 else if n % 4 = 1 then 1 else -1 := by
  have help : ∀ m : ℤ, 0 ≤ m → m < 4 → χ₄ m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1 := by
    decide
  rw [← Int.emod_emod_of_dvd n (by 

Proof state:
n : ℤ
help : ∀ (m : ℤ), 0 ≤ m → m < 4 → χ₄ ↑m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1
⊢ 2 ∣ 4

Next tactic:
decide
/-- An explicit description of `χ₄` on integers / naturals -/
theorem χ₄_int_eq_if_mod_four (n : ℤ) :
    χ₄ n = if n % 2 = 0 then 0 else if n % 4 = 1 then 1 else -1 := by
  have help : ∀ m : ℤ, 0 ≤ m → m < 4 → χ₄ m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1 := by
    decide
  rw [← Int.emod_emod_of_dvd n (by decide : (2 : ℤ) ∣ 4), ← ZMod.int_cast_mod n 4]
  

Proof state:
n : ℤ
help : ∀ (m : ℤ), 0 ≤ m → m < 4 → χ₄ ↑m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1
⊢ χ₄ ↑(n % ↑4) = if n % 4 % 2 = 0 then 0 else if n % 4 = 1 then 1 else -1

Next tactic:
exact help (n % 4) (Int.emod_nonneg n (by norm_num)) (Int.emod_lt n (by norm_num))
/-- An explicit description of `χ₄` on integers / naturals -/
theorem χ₄_int_eq_if_mod_four (n : ℤ) :
    χ₄ n = if n % 2 = 0 then 0 else if n % 4 = 1 then 1 else -1 := by
  have help : ∀ m : ℤ, 0 ≤ m → m < 4 → χ₄ m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1 := by
    decide
  rw [← Int.emod_emod_of_dvd n (by decide : (2 : ℤ) ∣ 4), ← ZMod.int_cast_mod n 4]
  exact help (n % 4) (Int.emod_nonneg n (by 

Proof state:
n : ℤ
help : ∀ (m : ℤ), 0 ≤ m → m < 4 → χ₄ ↑m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1
⊢ 4 ≠ 0

Next tactic:
norm_num
/-- An explicit description of `χ₄` on integers / naturals -/
theorem χ₄_int_eq_if_mod_four (n : ℤ) :
    χ₄ n = if n % 2 = 0 then 0 else if n % 4 = 1 then 1 else -1 := by
  have help : ∀ m : ℤ, 0 ≤ m → m < 4 → χ₄ m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1 := by
    decide
  rw [← Int.emod_emod_of_dvd n (by decide : (2 : ℤ) ∣ 4), ← ZMod.int_cast_mod n 4]
  exact help (n % 4) (Int.emod_nonneg n (by norm_num)) (Int.emod_lt n (by 

Proof state:
n : ℤ
help : ∀ (m : ℤ), 0 ≤ m → m < 4 → χ₄ ↑m = if m % 2 = 0 then 0 else if m = 1 then 1 else -1
⊢ 4 ≠ 0

Next tactic:
norm_num
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  

Proof state:
n : ℕ
hn : n % 2 = 1
⊢ χ₄ ↑n = (-1) ^ (n / 2)

Next tactic:
rw [χ₄_nat_eq_if_mod_four]
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  

Proof state:
n : ℕ
hn : n % 2 = 1
⊢ (if n % 2 = 0 then 0 else if n % 4 = 1 then 1 else -1) = (-1) ^ (n / 2)

Next tactic:
simp only [hn, Nat.one_ne_zero, if_false]
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  

Proof state:
n : ℕ
hn : n % 2 = 1
⊢ (if n % 4 = 1 then 1 else -1) = (-1) ^ (n / 2)

Next tactic:
conv_rhs => -- Porting note: was `nth_rw`
    arg 2; rw [← Nat.div_add_mod n 4]
    enter [1, 1, 1]; rw [(by norm_num : 4 = 2 * 2)]
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    

Proof state:
n : ℕ
hn : n % 2 = 1
| (-1) ^ (n / 2)

Next tactic:
arg 2; rw [← Nat.div_add_mod n 4]
    enter [1, 1, 1]; rw [(by norm_num : 4 = 2 * 2)]
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    

Proof state:
n : ℕ
hn : n % 2 = 1
| (-1) ^ (n / 2)

Next tactic:
arg 2
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    arg 2; 

Proof state:
n : ℕ
hn : n % 2 = 1
| n / 2

Next tactic:
rw [← Nat.div_add_mod n 4]
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    arg 2; rw [← Nat.div_add_mod n 4]
    

Proof state:
n : ℕ
hn : n % 2 = 1
| (4 * (n / 4) + n % 4) / 2

Next tactic:
enter [1, 1, 1]
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    arg 2; rw [← Nat.div_add_mod n 4]
    enter [1, 1, 1]; 

Proof state:
n : ℕ
hn : n % 2 = 1
| 4

Next tactic:
rw [(by norm_num : 4 = 2 * 2)]
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    arg 2; rw [← Nat.div_add_mod n 4]
    enter [1, 1, 1]; rw [(by 

Proof state:
n : ℕ
hn : n % 2 = 1
⊢ 4 = 2 * 2

Next tactic:
norm_num
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    arg 2; rw [← Nat.div_add_mod n 4]
    enter [1, 1, 1]; rw [(by norm_num : 4 = 2 * 2)]
  

Proof state:
n : ℕ
hn : n % 2 = 1
⊢ (if n % 4 = 1 then 1 else -1) = (-1) ^ ((2 * 2 * (n / 4) + n % 4) / 2)

Next tactic:
rw [mul_assoc, add_comm, Nat.add_mul_div_left _ _ (by norm_num : 0 < 2), pow_add, pow_mul,
    neg_one_sq, one_pow, mul_one]
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    arg 2; rw [← Nat.div_add_mod n 4]
    enter [1, 1, 1]; rw [(by norm_num : 4 = 2 * 2)]
  rw [mul_assoc, add_comm, Nat.add_mul_div_left _ _ (by 

Proof state:
n : ℕ
hn : n % 2 = 1
⊢ 0 < 2

Next tactic:
norm_num
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    arg 2; rw [← Nat.div_add_mod n 4]
    enter [1, 1, 1]; rw [(by norm_num : 4 = 2 * 2)]
  rw [mul_assoc, add_comm, Nat.add_mul_div_left _ _ (by norm_num : 0 < 2), pow_add, pow_mul,
    neg_one_sq, one_pow, mul_one]
  

Proof state:
n : ℕ
hn : n % 2 = 1
⊢ (if n % 4 = 1 then 1 else -1) = (-1) ^ (n % 4 / 2)

Next tactic:
have help : ∀ m : ℕ, m < 4 → m % 2 = 1 → ite (m = 1) (1 : ℤ) (-1) = (-1) ^ (m / 2) := by decide
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    arg 2; rw [← Nat.div_add_mod n 4]
    enter [1, 1, 1]; rw [(by norm_num : 4 = 2 * 2)]
  rw [mul_assoc, add_comm, Nat.add_mul_div_left _ _ (by norm_num : 0 < 2), pow_add, pow_mul,
    neg_one_sq, one_pow, mul_one]
  have help : ∀ m : ℕ, m < 4 → m % 2 = 1 → ite (m = 1) (1 : ℤ) (-1) = (-1) ^ (m / 2) := by 

Proof state:
n : ℕ
hn : n % 2 = 1
⊢ ∀ m < 4, m % 2 = 1 → (if m = 1 then 1 else -1) = (-1) ^ (m / 2)

Next tactic:
decide
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    arg 2; rw [← Nat.div_add_mod n 4]
    enter [1, 1, 1]; rw [(by norm_num : 4 = 2 * 2)]
  rw [mul_assoc, add_comm, Nat.add_mul_div_left _ _ (by norm_num : 0 < 2), pow_add, pow_mul,
    neg_one_sq, one_pow, mul_one]
  have help : ∀ m : ℕ, m < 4 → m % 2 = 1 → ite (m = 1) (1 : ℤ) (-1) = (-1) ^ (m / 2) := by decide
  

Proof state:
n : ℕ
hn : n % 2 = 1
help : ∀ m < 4, m % 2 = 1 → (if m = 1 then 1 else -1) = (-1) ^ (m / 2)
⊢ (if n % 4 = 1 then 1 else -1) = (-1) ^ (n % 4 / 2)

Next tactic:
exact
    help (n % 4) (Nat.mod_lt n (by norm_num))
      ((Nat.mod_mod_of_dvd n (by decide : 2 ∣ 4)).trans hn)
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    arg 2; rw [← Nat.div_add_mod n 4]
    enter [1, 1, 1]; rw [(by norm_num : 4 = 2 * 2)]
  rw [mul_assoc, add_comm, Nat.add_mul_div_left _ _ (by norm_num : 0 < 2), pow_add, pow_mul,
    neg_one_sq, one_pow, mul_one]
  have help : ∀ m : ℕ, m < 4 → m % 2 = 1 → ite (m = 1) (1 : ℤ) (-1) = (-1) ^ (m / 2) := by decide
  exact
    help (n % 4) (Nat.mod_lt n (by 

Proof state:
n : ℕ
hn : n % 2 = 1
help : ∀ m < 4, m % 2 = 1 → (if m = 1 then 1 else -1) = (-1) ^ (m / 2)
⊢ 4 > 0

Next tactic:
norm_num
/-- Alternative description of `χ₄ n` for odd `n : ℕ` in terms of powers of `-1` -/
theorem χ₄_eq_neg_one_pow {n : ℕ} (hn : n % 2 = 1) : χ₄ n = (-1) ^ (n / 2) := by
  rw [χ₄_nat_eq_if_mod_four]
  simp only [hn, Nat.one_ne_zero, if_false]
  conv_rhs => -- Porting note: was `nth_rw`
    arg 2; rw [← Nat.div_add_mod n 4]
    enter [1, 1, 1]; rw [(by norm_num : 4 = 2 * 2)]
  rw [mul_assoc, add_comm, Nat.add_mul_div_left _ _ (by norm_num : 0 < 2), pow_add, pow_mul,
    neg_one_sq, one_pow, mul_one]
  have help : ∀ m : ℕ, m < 4 → m % 2 = 1 → ite (m = 1) (1 : ℤ) (-1) = (-1) ^ (m / 2) := by decide
  exact
    help (n % 4) (Nat.mod_lt n (by norm_num))
      ((Nat.mod_mod_of_dvd n (by 

Proof state:
n : ℕ
hn : n % 2 = 1
help : ∀ m < 4, m % 2 = 1 → (if m = 1 then 1 else -1) = (-1) ^ (m / 2)
⊢ 2 ∣ 4

Next tactic:
decide
/-- If `n % 4 = 1`, then `χ₄ n = 1`. -/
theorem χ₄_nat_one_mod_four {n : ℕ} (hn : n % 4 = 1) : χ₄ n = 1 := by
  

Proof state:
n : ℕ
hn : n % 4 = 1
⊢ χ₄ ↑n = 1

Next tactic:
rw [χ₄_nat_mod_four, hn]
/-- If `n % 4 = 1`, then `χ₄ n = 1`. -/
theorem χ₄_nat_one_mod_four {n : ℕ} (hn : n % 4 = 1) : χ₄ n = 1 := by
  rw [χ₄_nat_mod_four, hn]
  

Proof state:
n : ℕ
hn : n % 4 = 1
⊢ χ₄ ↑1 = 1

Next tactic:
rfl
/-- If `n % 4 = 3`, then `χ₄ n = -1`. -/
theorem χ₄_nat_three_mod_four {n : ℕ} (hn : n % 4 = 3) : χ₄ n = -1 := by
  

Proof state:
n : ℕ
hn : n % 4 = 3
⊢ χ₄ ↑n = -1

Next tactic:
rw [χ₄_nat_mod_four, hn]
/-- If `n % 4 = 3`, then `χ₄ n = -1`. -/
theorem χ₄_nat_three_mod_four {n : ℕ} (hn : n % 4 = 3) : χ₄ n = -1 := by
  rw [χ₄_nat_mod_four, hn]
  

Proof state:
n : ℕ
hn : n % 4 = 3
⊢ χ₄ ↑3 = -1

Next tactic:
rfl
/-- If `n % 4 = 1`, then `χ₄ n = 1`. -/
theorem χ₄_int_one_mod_four {n : ℤ} (hn : n % 4 = 1) : χ₄ n = 1 := by
  

Proof state:
n : ℤ
hn : n % 4 = 1
⊢ χ₄ ↑n = 1

Next tactic:
rw [χ₄_int_mod_four, hn]
/-- If `n % 4 = 1`, then `χ₄ n = 1`. -/
theorem χ₄_int_one_mod_four {n : ℤ} (hn : n % 4 = 1) : χ₄ n = 1 := by
  rw [χ₄_int_mod_four, hn]
  

Proof state:
n : ℤ
hn : n % 4 = 1
⊢ χ₄ ↑1 = 1

Next tactic:
rfl
/-- If `n % 4 = 3`, then `χ₄ n = -1`. -/
theorem χ₄_int_three_mod_four {n : ℤ} (hn : n % 4 = 3) : χ₄ n = -1 := by
  

Proof state:
n : ℤ
hn : n % 4 = 3
⊢ χ₄ ↑n = -1

Next tactic:
rw [χ₄_int_mod_four, hn]
/-- If `n % 4 = 3`, then `χ₄ n = -1`. -/
theorem χ₄_int_three_mod_four {n : ℤ} (hn : n % 4 = 3) : χ₄ n = -1 := by
  rw [χ₄_int_mod_four, hn]
  

Proof state:
n : ℤ
hn : n % 4 = 3
⊢ χ₄ ↑3 = -1

Next tactic:
rfl
/-- If `n % 4 = 1`, then `(-1)^(n/2) = 1`. -/
theorem neg_one_pow_div_two_of_one_mod_four {n : ℕ} (hn : n % 4 = 1) : (-1 : ℤ) ^ (n / 2) = 1 := by
  

Proof state:
n : ℕ
hn : n % 4 = 1
⊢ (-1) ^ (n / 2) = 1

Next tactic:
rw [← χ₄_eq_neg_one_pow (Nat.odd_of_mod_four_eq_one hn), ← nat_cast_mod, hn]
/-- If `n % 4 = 1`, then `(-1)^(n/2) = 1`. -/
theorem neg_one_pow_div_two_of_one_mod_four {n : ℕ} (hn : n % 4 = 1) : (-1 : ℤ) ^ (n / 2) = 1 := by
  rw [← χ₄_eq_neg_one_pow (Nat.odd_of_mod_four_eq_one hn), ← nat_cast_mod, hn]
  

Proof state:
n : ℕ
hn : n % 4 = 1
⊢ χ₄ ↑1 = 1

Next tactic:
rfl
/-- If `n % 4 = 3`, then `(-1)^(n/2) = -1`. -/
theorem neg_one_pow_div_two_of_three_mod_four {n : ℕ} (hn : n % 4 = 3) :
    (-1 : ℤ) ^ (n / 2) = -1 := by
  

Proof state:
n : ℕ
hn : n % 4 = 3
⊢ (-1) ^ (n / 2) = -1

Next tactic:
rw [← χ₄_eq_neg_one_pow (Nat.odd_of_mod_four_eq_three hn), ← nat_cast_mod, hn]
/-- If `n % 4 = 3`, then `(-1)^(n/2) = -1`. -/
theorem neg_one_pow_div_two_of_three_mod_four {n : ℕ} (hn : n % 4 = 3) :
    (-1 : ℤ) ^ (n / 2) = -1 := by
  rw [← χ₄_eq_neg_one_pow (Nat.odd_of_mod_four_eq_three hn), ← nat_cast_mod, hn]
  

Proof state:
n : ℕ
hn : n % 4 = 3
⊢ χ₄ ↑3 = -1

Next tactic:
rfl