-- Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean
theorem dvd_of_isCyclotomicExtension [IsCyclotomicExtension {n} ℚ K] {ζ : K}
    {l : ℕ} (hζ : IsPrimitiveRoot ζ l) (hl : l ≠ 0) : l ∣ 2 * n

Proof state:
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
⊢ l ∣ 2 * ↑n

Tactic:
have hroot := IsCyclotomicExtension.zeta_spec n ℚ K

Result:
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
⊢ l ∣ 2 * ↑n

Proof state:
case intro
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
key : φ (l.lcm ↑n) ≤ φ ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (↑n * r)
⊢ l ∣ 2 * ↑n

Tactic:
rw [← hr] at ineq

Result:
case intro
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
key : φ (l.lcm ↑n) ≤ φ ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
⊢ l ∣ 2 * ↑n

Proof state:
case intro.inr
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = 2 * ↑n
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
rpos : 0 < r
key : r = 2
⊢ l ∣ 2 * ↑n

Tactic:
simpa [← hr] using _root_.dvd_lcm_left _ _

Result:
no goals

Proof state:
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
key : φ r ≤ 1
h : r = 0
hr : l = 0
⊢ False

Tactic:
exact hl.1 hr

Result:
no goals

Proof state:
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl : l ≠ 0
⊢ l ∣ 2 * ↑n

Tactic:
have hl : NeZero l := ⟨hl⟩

Result:
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
⊢ l ∣ 2 * ↑n

Proof state:
case intro
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
rpos : 0 < r
key : r = 1 ∨ r = 2
⊢ l ∣ 2 * ↑n

Tactic:
rcases key with (key | key)

Result:
case intro.inl
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
rpos : 0 < r
key : r = 1
⊢ l ∣ 2 * ↑n

case intro.inr
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
rpos : 0 < r
key : r = 2
⊢ l ∣ 2 * ↑n

Proof state:
case intro.inl
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
rpos : 0 < r
key : r = 1
⊢ l ∣ 2 * GCDMonoid.lcm l ↑n

Tactic:
exact dvd_mul_of_dvd_right (_root_.dvd_lcm_left l ↑n) 2

Result:
no goals

Proof state:
case intro
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
key : φ (l.lcm ↑n) ≤ φ ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
⊢ l ∣ 2 * ↑n

Tactic:
replace key := (mul_le_iff_le_one_right (Nat.totient_pos.2 n.2)).mp (le_trans ineq key)

Result:
case intro
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
key : φ r ≤ 1
⊢ l ∣ 2 * ↑n

Proof state:
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
key : φ r ≤ 1
h : r = 0
⊢ False

Tactic:
simp only [h, mul_zero, _root_.lcm_eq_zero_iff, PNat.ne_zero, or_false] at hr

Result:
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
key : φ r ≤ 1
h : r = 0
hr : l = 0
⊢ False

Proof state:
case intro
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
key : φ (l.lcm ↑n) ≤ φ ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
⊢ l ∣ 2 * ↑n

Tactic:
have ineq := Nat.totient_super_multiplicative n r

Result:
case intro
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
key : φ (l.lcm ↑n) ≤ φ ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (↑n * r)
⊢ l ∣ 2 * ↑n

Proof state:
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
key : φ r ≤ 1
⊢ 0 < r

Tactic:
refine Nat.pos_of_ne_zero (fun h ↦ ?_)

Result:
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
key : φ r ≤ 1
h : r = 0
⊢ False

Proof state:
case intro
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
key : φ r ≤ 1
rpos : 0 < r
⊢ l ∣ 2 * ↑n

Tactic:
replace key := (Nat.dvd_prime Nat.prime_two).1 (Nat.dvd_two_of_totient_le_one rpos key)

Result:
case intro
n : ℕ+
K : Type u
inst✝² : Field K
inst✝¹ : NumberField K
inst✝ : IsCyclotomicExtension {n} ℚ K
ζ : K
l : ℕ
hζ : IsPrimitiveRoot ζ l
hl✝ : l ≠ 0
hl : NeZero l
hroot : IsPrimitiveRoot (zeta n ℚ K) ↑n
r : ℕ
hr : GCDMonoid.lcm l ↑n = ↑n * r
ineq : φ ↑n * φ r ≤ φ (GCDMonoid.lcm l ↑n)
rpos : 0 < r
key : r = 1 ∨ r = 2
⊢ l ∣ 2 * ↑n