Clifford project

2. Roots of unity🔗

This section defines roots of unity and proves various basic facts about them. Throughout this section we assume that d ≥ 1.

Lean code-- This instance is referred to later, needs naming variable (d : ) [hnezero : NeZero d]
Lemma2.1
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Definition 2.2
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0used by 0L∃∀N

d is invertible in .

Proof for Lemma 2.1
uses 0

The inverse of d exists since d ∈ ℕ and d ≠ 0.

Lean code for Lemma2.1lemma d_invertible : IsUnit (d : ) := d:hnezero:NeZero dIsUnit d d:hnezero:NeZero d¬d = 0 All goals completed! 🐙

Define the primitive d-th root of unity.

Definition2.2
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Lemma 2.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0
Used by 3
Reverse dependency previews
Preview
Definition 4.5
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
L∃∀N

Let ω = \exp(2πi/d) be the primitive d-th root of unity.

Lean code for Definition2.2noncomputable def ω : ˣ := .mk (Complex.exp (2 * Real.pi * Complex.I / d)) (Complex.exp (- 2 * Real.pi * Complex.I / d)) (d:hnezero:NeZero dComplex.exp (2 * Real.pi * Complex.I / d) * Complex.exp (-2 * Real.pi * Complex.I / d) = 1 d:hnezero:NeZero dComplex.exp (2 * Real.pi * Complex.I / d + -2 * Real.pi * Complex.I / d) = 1; d:hnezero:NeZero dComplex.exp (2 * Real.pi * Complex.I / d + -(2 * Real.pi * Complex.I) / d) = 1; Try this: [apply] ring_nf The `ring` tactic failed to close the goal. Use `ring_nf` to obtain a normal form. Note that `ring` works primarily in *commutative* rings. If you have a noncommutative ring, abelian group or module, consider using `noncomm_ring`, `abel` or `module` instead.d:hnezero:NeZero dComplex.exp 0 = 1; All goals completed! 🐙) (d:hnezero:NeZero dComplex.exp (-2 * Real.pi * Complex.I / d) * Complex.exp (2 * Real.pi * Complex.I / d) = 1 d:hnezero:NeZero dComplex.exp (-2 * Real.pi * Complex.I / d + 2 * Real.pi * Complex.I / d) = 1; d:hnezero:NeZero dComplex.exp (-(2 * Real.pi * Complex.I) / d + 2 * Real.pi * Complex.I / d) = 1; Try this: [apply] ring_nf The `ring` tactic failed to close the goal. Use `ring_nf` to obtain a normal form. Note that `ring` works primarily in *commutative* rings. If you have a noncommutative ring, abelian group or module, consider using `noncomm_ring`, `abel` or `module` instead.d:hnezero:NeZero dComplex.exp 0 = 1; All goals completed! 🐙)

Some basic lemmas about \omega

Lemma2.3
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Lemma 2.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0used by 0L∃∀N

When d = 1, \omega = 1

Lean code for Lemma2.3@[simp] lemma omega_one : (ω 1) = 1 := ω 1 = 1 (ω 1) = 1; { val := Complex.exp (2 * Real.pi * Complex.I / 1), inv := Complex.exp (-2 * Real.pi * Complex.I / 1), val_inv := , inv_val := } = 1; All goals completed! 🐙; omit [NeZero d] in @[simp] lemma omega_one' (hd : d = 1) : ω d = 1 := d:hd:d = 1ω d = 1 d:hd:d = 1ω 1 = 1; All goals completed! 🐙
Lean codeomit [NeZero d] in lemma omega_val_pow_commutes (i : ) : ((ω d) ^ i).val = (ω d).val ^ i := d:i:(ω d ^ i) = (ω d) ^ i All goals completed! 🐙
Lemma2.4
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Lemma 2.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0used by 0L∃∀N

ω^d = 1.

Proof for Lemma 2.4
uses 0

ω^d = (\exp(2πi/d))^d = \exp(d(2πi/d)) = \exp(2πi) = 1 where we could cancel d since d ≠ 0.

Lean code for Lemma2.4omit [NeZero d] in @[simp] lemma omega_pow_d_eq_one : (ω d)^d = 1 := d:ω d ^ d = 1 d:{ val := Complex.exp (2 * Real.pi * Complex.I / d), inv := Complex.exp (-2 * Real.pi * Complex.I / d), val_inv := , inv_val := } ^ d = 1; d:({ val := Complex.exp (2 * Real.pi * Complex.I / d), inv := Complex.exp (-2 * Real.pi * Complex.I / d), val_inv := , inv_val := } ^ d) = 1; d:Complex.exp (2 * Real.pi * Complex.I / d) ^ d = 1 d:Complex.exp (d * (2 * Real.pi * Complex.I / d)) = 1; d:hd:d = 0Complex.exp (d * (2 * Real.pi * Complex.I / d)) = 1d:hd:¬d = 0Complex.exp (d * (2 * Real.pi * Complex.I / d)) = 1 d:hd:d = 0Complex.exp (d * (2 * Real.pi * Complex.I / d)) = 1 d:hd:d = 0Complex.exp (0 * (2 * Real.pi * Complex.I / 0)) = 1; All goals completed! 🐙 d:hd:¬d = 0Complex.exp (d * (2 * Real.pi * Complex.I / d)) = 1 d:hd:¬d = 0Complex.exp (d * Real.pi * Complex.I * (↑d)⁻¹ * 2) = 1; calc Complex.exp (d * Real.pi * Complex.I * (d)⁻¹ * 2) = Complex.exp (d * (d)⁻¹ * Real.pi * Complex.I * 2) := d:hd:¬d = 0Complex.exp (d * Real.pi * Complex.I * (↑d)⁻¹ * 2) = Complex.exp (d * (↑d)⁻¹ * Real.pi * Complex.I * 2) All goals completed! 🐙 _ = Complex.exp (Real.pi * Complex.I * 2) := d:hd:¬d = 0Complex.exp (d * (↑d)⁻¹ * Real.pi * Complex.I * 2) = Complex.exp (Real.pi * Complex.I * 2) d:hd:¬d = 0d 0; d:hd:¬d = 0¬d = 0; All goals completed! 🐙 _ = 1 := d:hd:¬d = 0Complex.exp (Real.pi * Complex.I * 2) = 1 All goals completed! 🐙; omit [NeZero d] in @[simp] lemma omega_val_pow_d_eq_one : ((ω d).val) ^ d = 1 := d:(ω d) ^ d = 1 d:1 = 1; All goals completed! 🐙
Lemma2.5
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Lemma 2.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0used by 0L∃∀N

Let i ∈ ℤ, then \left(\omega^{-1}\right)^i = \omega^{d - i}

Lean code for Lemma2.5omit [NeZero d] in lemma omega_pow_of_inv (i : ) : (ω d)⁻¹ ^ i = (ω d) ^ (-i) := d:i:(ω d)⁻¹ ^ i = ω d ^ (-i) d:i:(ω d)⁻¹ ^ i = (ω d ^ i)⁻¹; All goals completed! 🐙
Lemma2.6
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Lemma 2.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0used by 0L∃∀N

Let i ∈ ℤ_d, then \left(\omega^{i}\right)^{-1} = \omega^{-i}

Lean code for Lemma2.6lemma omega_inv_pow (i : ZMod d) : ((ω d) ^ i.val)⁻¹ = (ω d) ^ (-i).val := d:hnezero:NeZero di:ZMod d(ω d ^ i.val)⁻¹ = ω d ^ (-i).val d:hnezero:NeZero di:ZMod d(ω d)⁻¹ ^ i.val = ω d ^ (-i).val; d:hnezero:NeZero di:ZMod d{ val := Complex.exp (2 * Real.pi * Complex.I / d), inv := Complex.exp (-2 * Real.pi * Complex.I / d), val_inv := , inv_val := }⁻¹ ^ i.val = { val := Complex.exp (2 * Real.pi * Complex.I / d), inv := Complex.exp (-2 * Real.pi * Complex.I / d), val_inv := , inv_val := } ^ (-i).val; d:hnezero:NeZero di:ZMod d({ val := Complex.exp (2 * Real.pi * Complex.I / d), inv := Complex.exp (-2 * Real.pi * Complex.I / d), val_inv := , inv_val := }⁻¹ ^ i.val) = ({ val := Complex.exp (2 * Real.pi * Complex.I / d), inv := Complex.exp (-2 * Real.pi * Complex.I / d), val_inv := , inv_val := } ^ (-i).val); d:hnezero:NeZero di:ZMod dComplex.exp (-(2 * Real.pi * Complex.I) / d) ^ i.val = Complex.exp (2 * Real.pi * Complex.I / d) ^ (-i).val; d:hnezero:NeZero di:ZMod dComplex.exp (i.val * (-(2 * Real.pi * Complex.I) / d)) = Complex.exp ((-i).val * (2 * Real.pi * Complex.I / d)); d:hnezero:NeZero di:ZMod dComplex.exp (i.val * (-(2 * Real.pi * Complex.I) / d)) = Complex.exp ((if i = 0 then 0 else d - i.val) * (2 * Real.pi * Complex.I / d)); d:hnezero:NeZero di:ZMod dhi:i = 0Complex.exp (i.val * (-(2 * Real.pi * Complex.I) / d)) = Complex.exp ((if i = 0 then 0 else d - i.val) * (2 * Real.pi * Complex.I / d))d:hnezero:NeZero di:ZMod dhi:¬i = 0Complex.exp (i.val * (-(2 * Real.pi * Complex.I) / d)) = Complex.exp ((if i = 0 then 0 else d - i.val) * (2 * Real.pi * Complex.I / d)) d:hnezero:NeZero di:ZMod dhi:i = 0Complex.exp (i.val * (-(2 * Real.pi * Complex.I) / d)) = Complex.exp ((if i = 0 then 0 else d - i.val) * (2 * Real.pi * Complex.I / d)) d:hnezero:NeZero di:ZMod dhi:i = 0Complex.exp ((ZMod.val 0) * (-(2 * Real.pi * Complex.I) / d)) = Complex.exp ((if 0 = 0 then 0 else d - ZMod.val 0) * (2 * Real.pi * Complex.I / d)); All goals completed! 🐙 d:hnezero:NeZero di:ZMod dhi:¬i = 0Complex.exp (i.val * (-(2 * Real.pi * Complex.I) / d)) = Complex.exp ((if i = 0 then 0 else d - i.val) * (2 * Real.pi * Complex.I / d)) d:hnezero:NeZero di:ZMod dhi:¬i = 0Complex.exp (i.val * (-(2 * Real.pi * Complex.I) / d)) = Complex.exp (d * (2 * Real.pi * Complex.I / d) - i.val * (2 * Real.pi * Complex.I / d))d:hnezero:NeZero di:ZMod dhi:¬i = 0i.val dd:hnezero:NeZero di:ZMod dhi:¬i = 0(i = 0) = False; d:hnezero:NeZero di:ZMod dhi:¬i = 0Complex.exp (-(i.val * Real.pi * Complex.I * (↑d)⁻¹ * 2)) = Complex.exp (-(i.val * Real.pi * Complex.I * (↑d)⁻¹ * 2) + Real.pi * Complex.I * d * (↑d)⁻¹ * 2)d:hnezero:NeZero di:ZMod dhi:¬i = 0i.val dd:hnezero:NeZero di:ZMod dhi:¬i = 0(i = 0) = False; d:hnezero:NeZero di:ZMod dhi:¬i = 0Complex.exp (-(i.val * Real.pi * Complex.I * (↑d)⁻¹ * 2)) = Complex.exp (-(i.val * Real.pi * Complex.I * (↑d)⁻¹ * 2)) * Complex.exp (Real.pi * Complex.I * d * (↑d)⁻¹ * 2)d:hnezero:NeZero di:ZMod dhi:¬i = 0i.val dd:hnezero:NeZero di:ZMod dhi:¬i = 0(i = 0) = False; d:hnezero:NeZero di:ZMod dhi:¬i = 0Complex.exp (Real.pi * Complex.I * d * (↑d)⁻¹ * 2) = 1d:hnezero:NeZero di:ZMod dhi:¬i = 0i.val dd:hnezero:NeZero di:ZMod dhi:¬i = 0(i = 0) = False; d:hnezero:NeZero di:ZMod dhi:¬i = 0Complex.exp (2 * (Real.pi * Complex.I * (d * (↑d)⁻¹))) = 1d:hnezero:NeZero di:ZMod dhi:¬i = 0i.val dd:hnezero:NeZero di:ZMod dhi:¬i = 0(i = 0) = False; d:hnezero:NeZero di:ZMod dhi:¬i = 0Complex.exp (2 * (Real.pi * Complex.I)) = 1d:hnezero:NeZero di:ZMod dhi:¬i = 0i.val dd:hnezero:NeZero di:ZMod dhi:¬i = 0(i = 0) = False d:hnezero:NeZero di:ZMod dhi:¬i = 0i.val dd:hnezero:NeZero di:ZMod dhi:¬i = 0(i = 0) = False; d:hnezero:NeZero di:ZMod dhi:¬i = 0(i = 0) = False; All goals completed! 🐙 lemma omega_inv_pow_val (i : ZMod d) : ((ω d).val ^ i.val)⁻¹ = (ω d).val ^ (-i).val := d:hnezero:NeZero di:ZMod d((ω d) ^ i.val)⁻¹ = (ω d) ^ (-i).val calc ((ω d).val ^ i.val)⁻¹ = (((ω d) ^ i.val)⁻¹).val := d:hnezero:NeZero di:ZMod d((ω d) ^ i.val)⁻¹ = (ω d ^ i.val)⁻¹ All goals completed! 🐙 _ = ((ω d) ^ (-i).val).val := d:hnezero:NeZero di:ZMod d(ω d ^ i.val)⁻¹ = (ω d ^ (-i).val) All goals completed! 🐙 _ = (ω d).val ^ (-i).val := d:hnezero:NeZero di:ZMod d(ω d ^ (-i).val) = (ω d) ^ (-i).val All goals completed! 🐙
Lemma2.7
uses 0used by 0L∃∀N

For z ∈ \mathbb{C}, let z^* denote the usual complex conjugate of z. Then \omega^* = \omega^{-1}

Lean code for Lemma2.7omit [NeZero d] in @[simp] lemma omega_star : star ((ω d).val) = (ω d).val⁻¹ := d:star (ω d) = (↑(ω d))⁻¹ d:star (ω d) = (starRingEnd ) (ω d) * (Complex.normSq (ω d))⁻¹; d:Complex.normSq (ω d) = 1; d:Complex.normSq { val := Complex.exp (2 * Real.pi * Complex.I / d), inv := Complex.exp (-2 * Real.pi * Complex.I / d), val_inv := , inv_val := } = 1; d:Complex.normSq (Complex.exp (2 * Real.pi * Complex.I / d)) = 1; d:Real.exp (2 * Real.pi * Complex.I / d).re ^ 2 = 1; All goals completed! 🐙 omit [NeZero d] in @[simp] lemma omega_pow_star (i : ) : star (((ω d).val) ^ i) = ((ω d).val ^ i)⁻¹ := d:i:star ((ω d) ^ i) = ((ω d) ^ i)⁻¹ All goals completed! 🐙;
Lean codelemma declaration uses `sorry`order_omega : orderOf (ω d) = d := d:hnezero:NeZero dorderOf (ω d) = d d:hnezero:NeZero dω d ^ d = 1 m < d, 0 < m ω d ^ m 1d:hnezero:NeZero d0 < d; d:hnezero:NeZero dω d ^ d = 1d:hnezero:NeZero d m < d, 0 < m ω d ^ m 1d:hnezero:NeZero d0 < d; d:hnezero:NeZero d m < d, 0 < m ω d ^ m 1d:hnezero:NeZero d0 < d; d:hnezero:NeZero dm:hm:m < dhm':0 < mω d ^ m 1d:hnezero:NeZero d0 < d; d:hnezero:NeZero dm:hm:m < dhm':0 < mhAbs:ω d ^ m = 1Falsed:hnezero:NeZero d0 < d; d:hnezero:NeZero dm:hm:m < dhm':0 < mhAbs:(ω d ^ m) = 1Falsed:hnezero:NeZero d0 < d; d:hnezero:NeZero dm:hm:m < dhm':0 < mhAbs:(ω d) ^ m = 1Falsed:hnezero:NeZero d0 < d; d:hnezero:NeZero dm:hm:m < dhm':0 < mhAbs:{ val := Complex.exp (2 * Real.pi * Complex.I / d), inv := Complex.exp (-2 * Real.pi * Complex.I / d), val_inv := , inv_val := } ^ m = 1Falsed:hnezero:NeZero d0 < d; d:hnezero:NeZero dm:hm:m < dhm':0 < mhAbs:Complex.exp (2 * Real.pi * Complex.I / d) ^ m = 1Falsed:hnezero:NeZero d0 < d; d:hnezero:NeZero dm:hm:m < dhm':0 < mhAbs:Complex.exp (m (2 * Real.pi * Complex.I / d)) = 1Falsed:hnezero:NeZero d0 < d; d:hnezero:NeZero dm:hm:m < dhm':0 < mhAbs:Complex.exp (m * (2 * Real.pi * Complex.I / d)) = 1Falsed:hnezero:NeZero d0 < d; d:hnezero:NeZero dm:hm:m < dhm':0 < mhAbs: n, m * (2 * Real.pi * Complex.I / d) = n * (2 * Real.pi * Complex.I)Falsed:hnezero:NeZero d0 < d; d:hnezero:NeZero dm:hm:m < dhm':0 < mn:hn:m * (2 * Real.pi * Complex.I / d) = n * (2 * Real.pi * Complex.I)Falsed:hnezero:NeZero d0 < d; d:hnezero:NeZero dm:hm:m < dhm':0 < mn:hn:m * (2 * Real.pi * Complex.I / d) = n * (2 * Real.pi * Complex.I)calc_md:m / d = nFalsed:hnezero:NeZero d0 < d d:hnezero:NeZero dm:hm:m < dhm':0 < mn:hn:m * (2 * Real.pi * Complex.I / d) = n * (2 * Real.pi * Complex.I)calc_md:m / d = nd_ge_zero:0 < dFalsed:hnezero:NeZero d0 < d d:hnezero:NeZero dm:hm:m < dhm':0 < mn:hn:m * (2 * Real.pi * Complex.I / d) = n * (2 * Real.pi * Complex.I)calc_md:m / d = nd_ge_zero:0 < dratio_between:m / d > 0 m / d < 1Falsed:hnezero:NeZero d0 < d -- apply And.intro; d:hnezero:NeZero dm:hm:m < dhm':0 < mn:hn:m * (2 * Real.pi * Complex.I / d) = n * (2 * Real.pi * Complex.I)calc_md:m / d = nd_ge_zero:0 < dratio_between:m / d > 0 m / d < 1Falsed:hnezero:NeZero d0 < d; --rw[calc_md] at ratio_between; d:hnezero:NeZero d0 < d; d:hnezero:NeZero dd 0; All goals completed! 🐙 -- apply d_ge_zero; rw[div_lt_one m d]

This is an additional corrolary that is nice to have.

Lemma2.8
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Lemma 2.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0used by 0L∃∀N

ω^n = ω^{n \mod d}.

Lean code for Lemma2.8automatically included section variable(s) unused in theorem `omega_pow_n_mod_d`: hnezero consider restructuring your `variable` declarations so that the variables are not in scope or explicitly omit them: omit hnezero in theorem ... Note: This linter can be disabled with `set_option linter.unusedSectionVars false`lemma omega_pow_n_mod_d : n : , (ω d) ^ n = (ω d) ^ (n % d) := d:hnezero:NeZero d (n : ), ω d ^ n = ω d ^ (n % d) d:hnezero:NeZero dn:ω d ^ n = ω d ^ (n % d) nth_rw 1 [d:hnezero:NeZero dn:ω d ^ (n % d + d * (n / d)) = ω d ^ (n % d)d:hnezero:NeZero dn:ω d ^ (n % d + d * (n / d)) = ω d ^ (n % d) All goals completed! 🐙 automatically included section variable(s) unused in theorem `omega_val_pow_n_mod_d`: hnezero consider restructuring your `variable` declarations so that the variables are not in scope or explicitly omit them: omit hnezero in theorem ... Note: This linter can be disabled with `set_option linter.unusedSectionVars false`lemma omega_val_pow_n_mod_d : n : , (ω d).val ^ n = (ω d).val ^ (n % d) := d:hnezero:NeZero d (n : ), (ω d) ^ n = (ω d) ^ (n % d) d:hnezero:NeZero dn:(ω d) ^ n = (ω d) ^ (n % d) nth_rw 1 [d:hnezero:NeZero dn:(ω d) ^ (n % d + d * (n / d)) = (ω d) ^ (n % d)d:hnezero:NeZero dn:(ω d) ^ (n % d + d * (n / d)) = (ω d) ^ (n % d) All goals completed! 🐙
Lean codeautomatically included section variable(s) unused in theorem `omega_pow_k_mod_d_eq_pow_k_int`: hnezero consider restructuring your `variable` declarations so that the variables are not in scope or explicitly omit them: omit hnezero in theorem ... Note: This linter can be disabled with `set_option linter.unusedSectionVars false`lemma omega_pow_k_mod_d_eq_pow_k_int : k : , (ω d) ^ k = (ω d) ^ (k % d) := d:hnezero:NeZero d (k : ), ω d ^ k = ω d ^ (k % d) d:hnezero:NeZero dk:ω d ^ k = ω d ^ (k % d); --unfold ω; ext; simp nth_rw 1 [d:hnezero:NeZero dk:ω d ^ (k % d + k / d * d) = ω d ^ (k % d)d:hnezero:NeZero dk:ω d ^ (k % d + k / d * d) = ω d ^ (k % d) d:hnezero:NeZero dk:ω d ^ (k % d) * ω d ^ (k / d * d) = ω d ^ (k % d); d:hnezero:NeZero dk:ω d ^ (k / d * d) = 1 d:hnezero:NeZero dk:(ω d ^ d) ^ (k / d) = 1 All goals completed! 🐙
Lean codelemma omega_pow_k_mod_d_eq_pow_k_zmod : k : , (ω d) ^ k = (ω d) ^ (k : ZMod d).val := d:hnezero:NeZero d (k : ), ω d ^ k = ω d ^ (↑k).val d:hnezero:NeZero dk:ω d ^ k = ω d ^ (↑k).val d:hnezero:NeZero dk:ω d ^ (k % d) = ω d ^ (↑k).val d:hnezero:NeZero dk:ω d ^ (↑k).val = ω d ^ (↑k).val All goals completed! 🐙

We will also need another root of unity which we call τ.

Definition2.9
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Lemma 2.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0
Used by 3
Reverse dependency previews
Preview
Definition 5.1
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
L∃∀N

Let τ = -\exp(πi/d).

Lean code for Definition2.9noncomputable def τ : ˣ := .mk (- Complex.exp (Real.pi * Complex.I / d)) (- Complex.exp (- Real.pi * Complex.I / d)) (d:hnezero:NeZero d-Complex.exp (Real.pi * Complex.I / d) * -Complex.exp (-Real.pi * Complex.I / d) = 1 d:hnezero:NeZero dComplex.exp (Real.pi * Complex.I / d) * Complex.exp (-(Real.pi * Complex.I) / d) = 1; d:hnezero:NeZero dComplex.exp (Real.pi * Complex.I / d + -(Real.pi * Complex.I) / d) = 1; Try this: [apply] ring_nf The `ring` tactic failed to close the goal. Use `ring_nf` to obtain a normal form. Note that `ring` works primarily in *commutative* rings. If you have a noncommutative ring, abelian group or module, consider using `noncomm_ring`, `abel` or `module` instead.d:hnezero:NeZero dComplex.exp 0 = 1; All goals completed! 🐙) (d:hnezero:NeZero d-Complex.exp (-Real.pi * Complex.I / d) * -Complex.exp (Real.pi * Complex.I / d) = 1 d:hnezero:NeZero dComplex.exp (-(Real.pi * Complex.I) / d) * Complex.exp (Real.pi * Complex.I / d) = 1; d:hnezero:NeZero dComplex.exp (-(Real.pi * Complex.I) / d + Real.pi * Complex.I / d) = 1; Try this: [apply] ring_nf The `ring` tactic failed to close the goal. Use `ring_nf` to obtain a normal form. Note that `ring` works primarily in *commutative* rings. If you have a noncommutative ring, abelian group or module, consider using `noncomm_ring`, `abel` or `module` instead.d:hnezero:NeZero dComplex.exp 0 = 1; All goals completed! 🐙)

Some basic lemmas about \tau

Lemma2.10
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Lemma 2.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0used by 0XL∃∀N

Much like \omega, since τ lies on the Unit circle, one has \tau^* = \tau^{-1}

Lean codeomit [NeZero d] in @[simp] lemma tau_star_val : star (τ d).val = (τ d).val⁻¹ := d:star (τ d) = (↑(τ d))⁻¹ d:star (τ d) = (starRingEnd ) (τ d) * (Complex.normSq (τ d))⁻¹; d:Complex.normSq (τ d) = 1; d:Complex.normSq { val := -Complex.exp (Real.pi * Complex.I / d), inv := -Complex.exp (-Real.pi * Complex.I / d), val_inv := , inv_val := } = 1; d:Complex.normSq (Complex.exp (Real.pi * Complex.I / d)) = 1; d:Real.exp (Real.pi * Complex.I / d).re ^ 2 = 1; All goals completed! 🐙 omit [NeZero d] in @[simp] lemma tau_star : star (τ d) = (τ d)⁻¹ := d:star (τ d) = (τ d)⁻¹ d:(star (τ d)) = (τ d)⁻¹; All goals completed! 🐙 lemma declaration uses `sorry`tau_star_pow (d : ) (n : ) [NeZero d] : star (τ d ^ n) = (τ d)^(-n) := d:n:inst✝:NeZero dstar (τ d ^ n) = τ d ^ (-n) d:n:inst✝:NeZero dstar ({ val := -Complex.exp (Real.pi * Complex.I / d), inv := -Complex.exp (-Real.pi * Complex.I / d), val_inv := , inv_val := } ^ n) = { val := -Complex.exp (Real.pi * Complex.I / d), inv := -Complex.exp (-Real.pi * Complex.I / d), val_inv := , inv_val := } ^ (-n); d:n:inst✝:NeZero d(star ({ val := -Complex.exp (Real.pi * Complex.I / d), inv := -Complex.exp (-Real.pi * Complex.I / d), val_inv := , inv_val := } ^ n)) = ({ val := -Complex.exp (Real.pi * Complex.I / d), inv := -Complex.exp (-Real.pi * Complex.I / d), val_inv := , inv_val := } ^ (-n)); d:n:inst✝:NeZero d(-(starRingEnd ) (Complex.exp (Real.pi * Complex.I / d))) ^ n = ((-Complex.exp (Real.pi * Complex.I / d)) ^ n)⁻¹; d:n:inst✝:NeZero d(-Complex.exp ((starRingEnd ) (Real.pi * Complex.I / d))) ^ n = ((-Complex.exp (Real.pi * Complex.I / d)) ^ n)⁻¹; d:n:inst✝:NeZero d(-Complex.exp (-(Real.pi * Complex.I) / d)) ^ n = ((-Complex.exp (Real.pi * Complex.I / d)) ^ n)⁻¹; d:n:inst✝:NeZero d(-1) ^ n * Complex.exp (-(Real.pi * Complex.I) / d) ^ n = ((-Complex.exp (Real.pi * Complex.I / d)) ^ n)⁻¹; nth_rw 3 [d:n:inst✝:NeZero d(-1) ^ n * Complex.exp (-(Real.pi * Complex.I) / d) ^ n = ((-1 * Complex.exp (Real.pi * Complex.I / d)) ^ n)⁻¹d:n:inst✝:NeZero d(-1) ^ n * Complex.exp (-(Real.pi * Complex.I) / d) ^ n = ((-1 * Complex.exp (Real.pi * Complex.I / d)) ^ n)⁻¹; d:n:inst✝:NeZero d(-1) ^ n * Complex.exp (-(Real.pi * Complex.I) / d) ^ n = ((-1) ^ n * Complex.exp (Real.pi * Complex.I / d) ^ n)⁻¹; d:n:inst✝:NeZero d(-1) ^ n * Complex.exp (-(Real.pi * Complex.I) / d) ^ n = (Complex.exp (Real.pi * Complex.I / d) ^ n)⁻¹ * ((-1) ^ n)⁻¹; d:n:inst✝:NeZero d(-1) ^ n * Complex.exp (n * (-(Real.pi * Complex.I) / d)) = Complex.exp (-(n * (Real.pi * Complex.I / d))) * ((-1) ^ n)⁻¹; d:n:inst✝:NeZero dComplex.exp (n * (-1 * (Real.pi * Complex.I) / d)) * (-1) ^ n = Complex.exp (-(n * (Real.pi * Complex.I / d))) * ((-1) ^ n)⁻¹; nth_rw 3 [d:n:inst✝:NeZero dComplex.exp (n * (-1 * (Real.pi * Complex.I) / d)) * (-1) ^ n = Complex.exp (-1 * (n * (Real.pi * Complex.I / d))) * ((-1) ^ n)⁻¹d:n:inst✝:NeZero dComplex.exp (n * (-1 * (Real.pi * Complex.I) / d)) * (-1) ^ n = Complex.exp (-1 * (n * (Real.pi * Complex.I / d))) * ((-1) ^ n)⁻¹; All goals completed! 🐙 -- rw[Units.inv_pow_eq_pow_inv (-1) n]
Lemma2.11
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Lemma 2.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0
Used by 3
Reverse dependency previews
Preview
Theorem 7.1
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
L∃∀N

τ^2 = ω.

Proof for Lemma 2.11
uses 0

τ^2 = (-\exp(πi/d))^2 = (-1)^2 · (\exp(πi/d))^2 = 1 · \exp(2πi/d) = ω.

Lean code for Lemma2.11@[simp] lemma tau_sq_eq_omega (d : ) [NeZero d] : (τ d)^2 = ω d := d:inst✝:NeZero dτ d ^ 2 = ω d d:inst✝:NeZero d{ val := -Complex.exp (Real.pi * Complex.I / d), inv := -Complex.exp (-Real.pi * Complex.I / d), val_inv := , inv_val := } ^ 2 = { val := Complex.exp (2 * Real.pi * Complex.I / d), inv := Complex.exp (-2 * Real.pi * Complex.I / d), val_inv := , inv_val := }; d:inst✝:NeZero d({ val := -Complex.exp (Real.pi * Complex.I / d), inv := -Complex.exp (-Real.pi * Complex.I / d), val_inv := , inv_val := } ^ 2) = { val := Complex.exp (2 * Real.pi * Complex.I / d), inv := Complex.exp (-2 * Real.pi * Complex.I / d), val_inv := , inv_val := }; d:inst✝:NeZero dComplex.exp (Real.pi * Complex.I / d) ^ 2 = Complex.exp (2 * Real.pi * Complex.I / d); d:inst✝:NeZero dComplex.exp (2 (Real.pi * Complex.I / d)) = Complex.exp (2 * Real.pi * Complex.I / d); d:inst✝:NeZero dComplex.exp (2 * (Real.pi * Complex.I / d)) = Complex.exp (2 * Real.pi * Complex.I / d); All goals completed! 🐙;
Lemma2.12
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Lemma 2.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0used by 1L∃∀N

If d is odd then τ^d = 1.

Proof for Lemma 2.12
uses 0

τ^d = (-\exp(πi/d))^d = (-1)^d · (\exp(πi/d))^d = (-1)^d · \exp(πi) = (-1)^d · (-1) = (-1)^{d+1} = 1 when d is odd.

Lean code for Lemma2.12@[simp] lemma tau_pow_d_eq_one_of_odd (hodd : Odd d) : (τ d)^d = 1 := d:hnezero:NeZero dhodd:Odd dτ d ^ d = 1 d:hnezero:NeZero dhodd:Odd d{ val := -Complex.exp (Real.pi * Complex.I / d), inv := -Complex.exp (-Real.pi * Complex.I / d), val_inv := , inv_val := } ^ d = 1; d:hnezero:NeZero dhodd:Odd d({ val := -Complex.exp (Real.pi * Complex.I / d), inv := -Complex.exp (-Real.pi * Complex.I / d), val_inv := , inv_val := } ^ d) = 1; d:hnezero:NeZero dhodd:Odd d(-Complex.exp (Real.pi * Complex.I / d)) ^ d = 1; d:hnezero:NeZero dhodd:Odd d-1 * Complex.exp (Real.pi * Complex.I / d) ^ d = 1 d:hnezero:NeZero dhodd:Odd d-1 * Complex.exp (d (Real.pi * Complex.I / d)) = 1; d:hnezero:NeZero dhodd:Odd d-Complex.exp (d * (Real.pi * Complex.I / d)) = 1; d:hnezero:NeZero dhodd:Odd d-Complex.exp (Real.pi * Complex.I / d * d) = 1; All goals completed! 🐙 where neg_one_pow_odd : x : , Odd x (((-1) : )) ^ x = (-1) := d:hnezero:NeZero dhodd:Odd d (x : ), Odd x (-1) ^ x = -1 d:hnezero:NeZero dhodd:Odd dx:hoddx:Odd x(-1) ^ x = -1; d:hnezero:NeZero dhodd:Odd dx:hoddx:Odd xOdd xd:hnezero:NeZero dhodd:Odd dx:hoddx:Odd x-1 1; d:hnezero:NeZero dhodd:Odd dx:hoddx:Odd x-1 1; All goals completed! 🐙
Lemma2.13
Group: Roots of unity and their basic properties. (11)
Group member previews
Preview
Lemma 2.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0used by 0L∃∀N

τ^{d^2} = 1.

Proof for Lemma 2.13
uses 0

τ^{d^2} = (-\exp(πi/d))^{d^2} = (-1)^{d^2} · (-1)^d = (-1)^{d(d+1)} = 1 since either d or d+1 is even.

Lean code for Lemma2.13lemma tau_pow_d2_one : (τ d) ^ (d ^ 2) = 1 := d:hnezero:NeZero dτ d ^ d ^ 2 = 1 d:hnezero:NeZero d{ val := -Complex.exp (Real.pi * Complex.I / d), inv := -Complex.exp (-Real.pi * Complex.I / d), val_inv := , inv_val := } ^ d ^ 2 = 1; d:hnezero:NeZero d({ val := -Complex.exp (Real.pi * Complex.I / d), inv := -Complex.exp (-Real.pi * Complex.I / d), val_inv := , inv_val := } ^ d ^ 2) = 1; d:hnezero:NeZero d(-Complex.exp (Real.pi * Complex.I / d)) ^ d ^ 2 = 1 d:hnezero:NeZero d(-1 * Complex.exp (Real.pi * Complex.I / d)) ^ d ^ 2 = 1 d:hnezero:NeZero d(-1 * Complex.exp (Real.pi * Complex.I / d)) ^ (d * d) = 1 d:hnezero:NeZero d(-1) ^ (d * d) * Complex.exp (Real.pi * Complex.I / d) ^ (d * d) = 1; d:hnezero:NeZero d(-1) ^ (d * d) * Complex.exp ((d * d) * (Real.pi * Complex.I / d)) = 1 d:hnezero:NeZero d(-1) ^ (d * d) * Complex.exp (d * d * (Real.pi * Complex.I / d)) = 1 d:hnezero:NeZero d(-1) ^ (d * d) * Complex.exp (d * (d * (Real.pi * Complex.I / d))) = 1 d:hnezero:NeZero d(-1) ^ (d * d) * Complex.exp (d * (Real.pi * Complex.I)) = 1d:hnezero:NeZero dIsUnit d d:hnezero:NeZero d(-1) ^ (d * d) * Complex.exp (Real.pi * Complex.I) ^ d = 1d:hnezero:NeZero dIsUnit d d:hnezero:NeZero d(-1) ^ (d * d) * (-1) ^ d = 1d:hnezero:NeZero dIsUnit d d:hnezero:NeZero d(-1) ^ (d * d + d) = 1d:hnezero:NeZero dIsUnit d d:hnezero:NeZero d(-1) ^ (d * (d + 1)) = 1d:hnezero:NeZero dIsUnit d d:hnezero:NeZero dEven (d * (d + 1))d:hnezero:NeZero d-1 1d:hnezero:NeZero dIsUnit d d:hnezero:NeZero d-1 1d:hnezero:NeZero dIsUnit d d:hnezero:NeZero d-1 1 All goals completed! 🐙 d:hnezero:NeZero dIsUnit d All goals completed! 🐙
Lean codelemma mod_d_nonneg (a : ) : 0 a % d := d:hnezero:NeZero da:0 a % d d:hnezero:NeZero da:d 0 All goals completed! 🐙 theorem tau_pow_n_mod_d_of_d_odd (n d : ) (hodd : Odd d) [NeZero d] : τ d ^ n = τ d ^ (n % d) := pow_eq_pow_mod n (tau_pow_d_eq_one_of_odd d hodd)