data.nat.totient
⟷
Mathlib.Data.Nat.Totient
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -6,7 +6,7 @@ Authors: Chris Hughes
import Algebra.CharP.Two
import Data.Nat.Factorization.Basic
import Data.Nat.Periodic
-import Data.Zmod.Basic
+import Data.ZMod.Basic
#align_import data.nat.totient from "leanprover-community/mathlib"@"31ca6f9cf5f90a6206092cd7f84b359dcb6d52e0"
@@ -242,7 +242,7 @@ theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n +
· rintro hap b _ rfl
exact hap (dvd_mul_left _ _)
· rintro h ⟨b, rfl⟩
- rw [pow_succ] at ha
+ rw [pow_succ'] at ha
exact h b (lt_of_mul_lt_mul_left ha (zero_le _)) (mul_comm _ _)))
_ = _ := by
have h1 : Function.Injective (· * p) := mul_left_injective₀ hp.NeZero
@@ -250,10 +250,10 @@ theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n +
by
simp only [mem_image, mem_range, exists_imp]
rintro b h rfl
- rw [pow_succ']
+ rw [pow_succ]
exact (mul_lt_mul_right hp.pos).2 h
rw [card_sdiff h2, card_image_of_inj_on (h1.inj_on _), card_range, card_range, ←
- one_mul (p ^ n), pow_succ, ← tsub_mul, one_mul, mul_comm]
+ one_mul (p ^ n), pow_succ', ← tsub_mul, one_mul, mul_comm]
#align nat.totient_prime_pow_succ Nat.totient_prime_pow_succ
-/
@@ -361,7 +361,7 @@ theorem totient_mul_prod_primeFactors (n : ℕ) :
simp only [← prod_factorization_eq_prod_factors, ← Finsupp.prod_mul]
refine' Finsupp.prod_congr fun p hp => _
rw [Finsupp.mem_support_iff, ← zero_lt_iff] at hp
- rw [mul_comm, ← mul_assoc, ← pow_succ, Nat.sub_add_cancel hp]
+ rw [mul_comm, ← mul_assoc, ← pow_succ', Nat.sub_add_cancel hp]
#align nat.totient_mul_prod_factors Nat.totient_mul_prod_primeFactors
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -196,7 +196,7 @@ theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
have : d ∣ b := by rw [← hb2]; apply gcd_dvd_right
rcases this with ⟨q, rfl⟩
refine' ⟨q, ⟨⟨(mul_lt_mul_left hd0).1 hb1, _⟩, rfl⟩⟩
- rwa [gcd_mul_left, mul_right_eq_self_iff hd0] at hb2
+ rwa [gcd_mul_left, mul_right_eq_self_iff hd0] at hb2
#align nat.totient_div_of_dvd Nat.totient_div_of_dvd
-/
@@ -242,7 +242,7 @@ theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n +
· rintro hap b _ rfl
exact hap (dvd_mul_left _ _)
· rintro h ⟨b, rfl⟩
- rw [pow_succ] at ha
+ rw [pow_succ] at ha
exact h b (lt_of_mul_lt_mul_left ha (zero_le _)) (mul_comm _ _)))
_ = _ := by
have h1 : Function.Injective (· * p) := mul_left_injective₀ hp.NeZero
@@ -280,10 +280,10 @@ theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Pr
· apply lt_of_le_of_ne
· rwa [succ_le_iff]
· rintro rfl
- rw [totient_one, tsub_self] at h
+ rw [totient_one, tsub_self] at h
exact one_ne_zero h
rw [totient_eq_card_coprime, range_eq_Ico, ← Ico_insert_succ_left hp.le, Finset.filter_insert,
- if_neg (not_coprime_of_dvd_of_dvd hp (dvd_refl p) (dvd_zero p)), ← Nat.card_Ico 1 p] at h
+ if_neg (not_coprime_of_dvd_of_dvd hp (dvd_refl p) (dvd_zero p)), ← Nat.card_Ico 1 p] at h
refine'
p.prime_of_coprime hp fun n hn hnz => Finset.filter_card_eq h n <| finset.mem_Ico.mpr ⟨_, hn⟩
rwa [succ_le_iff, pos_iff_ne_zero]
@@ -360,7 +360,7 @@ theorem totient_mul_prod_primeFactors (n : ℕ) :
nth_rw 3 [← factorization_prod_pow_eq_self hn]
simp only [← prod_factorization_eq_prod_factors, ← Finsupp.prod_mul]
refine' Finsupp.prod_congr fun p hp => _
- rw [Finsupp.mem_support_iff, ← zero_lt_iff] at hp
+ rw [Finsupp.mem_support_iff, ← zero_lt_iff] at hp
rw [mul_comm, ← mul_assoc, ← pow_succ, Nat.sub_add_cancel hp]
#align nat.totient_mul_prod_factors Nat.totient_mul_prod_primeFactors
-/
@@ -448,7 +448,7 @@ theorem totient_mul_of_prime_of_dvd {p n : ℕ} (hp : p.Prime) (h : p ∣ n) :
(p * n).totient = p * n.totient :=
by
have h1 := totient_gcd_mul_totient_mul p n
- rw [gcd_eq_left h, mul_assoc] at h1
+ rw [gcd_eq_left h, mul_assoc] at h1
simpa [(totient_pos hp.pos).ne', mul_comm] using h1
#align nat.totient_mul_of_prime_of_dvd Nat.totient_mul_of_prime_of_dvd
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -158,7 +158,7 @@ theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient :=
haveI : Fact (1 < n) := ⟨one_lt_two.trans hn⟩
haveI : NeZero n := NeZero.of_gt hn
suffices 2 = orderOf (-1 : (ZMod n)ˣ) by
- rw [← ZMod.card_units_eq_totient, even_iff_two_dvd, this]; exact orderOf_dvd_card_univ
+ rw [← ZMod.card_units_eq_totient, even_iff_two_dvd, this]; exact orderOf_dvd_card
rw [← orderOf_units, Units.coe_neg_one, orderOf_neg_one, ringChar.eq (ZMod n) n, if_neg hn.ne']
#align nat.totient_even Nat.totient_even
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -350,9 +350,9 @@ theorem totient_eq_prod_factorization {n : ℕ} (hn : n ≠ 0) :
#align nat.totient_eq_prod_factorization Nat.totient_eq_prod_factorization
-/
-#print Nat.totient_mul_prod_factors /-
+#print Nat.totient_mul_prod_primeFactors /-
/-- Euler's product formula for the totient function. -/
-theorem totient_mul_prod_factors (n : ℕ) :
+theorem totient_mul_prod_primeFactors (n : ℕ) :
φ n * ∏ p in n.factors.toFinset, p = n * ∏ p in n.factors.toFinset, (p - 1) :=
by
by_cases hn : n = 0; · simp [hn]
@@ -362,18 +362,18 @@ theorem totient_mul_prod_factors (n : ℕ) :
refine' Finsupp.prod_congr fun p hp => _
rw [Finsupp.mem_support_iff, ← zero_lt_iff] at hp
rw [mul_comm, ← mul_assoc, ← pow_succ, Nat.sub_add_cancel hp]
-#align nat.totient_mul_prod_factors Nat.totient_mul_prod_factors
+#align nat.totient_mul_prod_factors Nat.totient_mul_prod_primeFactors
-/
-#print Nat.totient_eq_div_factors_mul /-
+#print Nat.totient_eq_div_primeFactors_mul /-
/-- Euler's product formula for the totient function. -/
-theorem totient_eq_div_factors_mul (n : ℕ) :
+theorem totient_eq_div_primeFactors_mul (n : ℕ) :
φ n = (n / ∏ p in n.factors.toFinset, p) * ∏ p in n.factors.toFinset, (p - 1) :=
by
rw [← mul_div_left n.totient, totient_mul_prod_factors, mul_comm,
Nat.mul_div_assoc _ (prod_prime_factors_dvd n), mul_comm]
simpa [prod_factorization_eq_prod_factors] using prod_pos fun p => pos_of_mem_factorization
-#align nat.totient_eq_div_factors_mul Nat.totient_eq_div_factors_mul
+#align nat.totient_eq_div_factors_mul Nat.totient_eq_div_primeFactors_mul
-/
#print Nat.totient_eq_mul_prod_factors /-
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,10 +3,10 @@ Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes
-/
-import Mathbin.Algebra.CharP.Two
-import Mathbin.Data.Nat.Factorization.Basic
-import Mathbin.Data.Nat.Periodic
-import Mathbin.Data.Zmod.Basic
+import Algebra.CharP.Two
+import Data.Nat.Factorization.Basic
+import Data.Nat.Periodic
+import Data.Zmod.Basic
#align_import data.nat.totient from "leanprover-community/mathlib"@"31ca6f9cf5f90a6206092cd7f84b359dcb6d52e0"
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -34,7 +34,7 @@ namespace Nat
/-- Euler's totient function. This counts the number of naturals strictly less than `n` which are
coprime with `n`. -/
def totient (n : ℕ) : ℕ :=
- ((range n).filterₓ n.coprime).card
+ ((range n).filterₓ n.Coprime).card
#align nat.totient Nat.totient
-/
@@ -54,14 +54,14 @@ theorem totient_one : φ 1 = 1 := by simp [totient]
-/
#print Nat.totient_eq_card_coprime /-
-theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filterₓ n.coprime).card :=
+theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filterₓ n.Coprime).card :=
rfl
#align nat.totient_eq_card_coprime Nat.totient_eq_card_coprime
-/
#print Nat.totient_eq_card_lt_and_coprime /-
/-- A characterisation of `nat.totient` that avoids `finset`. -/
-theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card {m | m < n ∧ n.coprime m} :=
+theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card {m | m < n ∧ n.Coprime m} :=
by
let e : {m | m < n ∧ n.coprime m} ≃ Finset.filter n.coprime (Finset.range n) :=
{ toFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using m.property⟩
@@ -94,7 +94,7 @@ theorem totient_pos : ∀ {n : ℕ}, 0 < n → 0 < φ n
#print Nat.filter_coprime_Ico_eq_totient /-
theorem filter_coprime_Ico_eq_totient (a n : ℕ) :
- ((Ico n (n + a)).filterₓ (coprime a)).card = totient a :=
+ ((Ico n (n + a)).filterₓ (Coprime a)).card = totient a :=
by
rw [totient, filter_Ico_card_eq_of_periodic, count_eq_card_filter_range]
exact periodic_coprime a
@@ -103,7 +103,7 @@ theorem filter_coprime_Ico_eq_totient (a n : ℕ) :
#print Nat.Ico_filter_coprime_le /-
theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
- ((Ico k (k + n)).filterₓ (coprime a)).card ≤ totient a * (n / a + 1) :=
+ ((Ico k (k + n)).filterₓ (Coprime a)).card ≤ totient a * (n / a + 1) :=
by
conv_lhs => rw [← Nat.mod_add_div n a]
induction' n / a with i ih
@@ -142,7 +142,7 @@ diamonds. -/
theorem ZMod.card_units_eq_totient (n : ℕ) [NeZero n] [Fintype (ZMod n)ˣ] :
Fintype.card (ZMod n)ˣ = φ n :=
calc
- Fintype.card (ZMod n)ˣ = Fintype.card { x : ZMod n // x.val.coprime n } :=
+ Fintype.card (ZMod n)ˣ = Fintype.card { x : ZMod n // x.val.Coprime n } :=
Fintype.card_congr ZMod.unitsEquivCoprime
_ = φ n := by
obtain ⟨m, rfl⟩ : ∃ m, n = m + 1 := exists_eq_succ_of_ne_zero NeZero.out
@@ -164,7 +164,7 @@ theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient :=
-/
#print Nat.totient_mul /-
-theorem totient_mul {m n : ℕ} (h : m.coprime n) : φ (m * n) = φ m * φ n :=
+theorem totient_mul {m n : ℕ} (h : m.Coprime n) : φ (m * n) = φ m * φ n :=
if hmn0 : m * n = 0 then by
cases' Nat.mul_eq_zero.1 hmn0 with h h <;>
simp only [totient_zero, MulZeroClass.mul_zero, MulZeroClass.zero_mul, h]
@@ -228,7 +228,7 @@ theorem sum_totient' (n : ℕ) : ∑ m in (range n.succ).filterₓ (· ∣ n),
/-- When `p` is prime, then the totient of `p ^ (n + 1)` is `p ^ n * (p - 1)` -/
theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n + 1)) = p ^ n * (p - 1) :=
calc
- φ (p ^ (n + 1)) = ((range (p ^ (n + 1))).filterₓ (coprime (p ^ (n + 1)))).card :=
+ φ (p ^ (n + 1)) = ((range (p ^ (n + 1))).filterₓ (Coprime (p ^ (n + 1)))).card :=
totient_eq_card_coprime _
_ = (range (p ^ (n + 1)) \ (range (p ^ n)).image (· * p)).card :=
(congr_arg card
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,17 +2,14 @@
Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes
-
-! This file was ported from Lean 3 source module data.nat.totient
-! leanprover-community/mathlib commit 31ca6f9cf5f90a6206092cd7f84b359dcb6d52e0
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Algebra.CharP.Two
import Mathbin.Data.Nat.Factorization.Basic
import Mathbin.Data.Nat.Periodic
import Mathbin.Data.Zmod.Basic
+#align_import data.nat.totient from "leanprover-community/mathlib"@"31ca6f9cf5f90a6206092cd7f84b359dcb6d52e0"
+
/-!
# Euler's totient function
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -41,7 +41,6 @@ def totient (n : ℕ) : ℕ :=
#align nat.totient Nat.totient
-/
--- mathport name: nat.totient
scoped notation "φ" => Nat.totient
#print Nat.totient_zero /-
@@ -57,9 +56,11 @@ theorem totient_one : φ 1 = 1 := by simp [totient]
#align nat.totient_one Nat.totient_one
-/
+#print Nat.totient_eq_card_coprime /-
theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filterₓ n.coprime).card :=
rfl
#align nat.totient_eq_card_coprime Nat.totient_eq_card_coprime
+-/
#print Nat.totient_eq_card_lt_and_coprime /-
/-- A characterisation of `nat.totient` that avoids `finset`. -/
@@ -94,13 +95,16 @@ theorem totient_pos : ∀ {n : ℕ}, 0 < n → 0 < φ n
#align nat.totient_pos Nat.totient_pos
-/
+#print Nat.filter_coprime_Ico_eq_totient /-
theorem filter_coprime_Ico_eq_totient (a n : ℕ) :
((Ico n (n + a)).filterₓ (coprime a)).card = totient a :=
by
rw [totient, filter_Ico_card_eq_of_periodic, count_eq_card_filter_range]
exact periodic_coprime a
#align nat.filter_coprime_Ico_eq_totient Nat.filter_coprime_Ico_eq_totient
+-/
+#print Nat.Ico_filter_coprime_le /-
theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
((Ico k (k + n)).filterₓ (coprime a)).card ≤ totient a * (n / a + 1) :=
by
@@ -130,9 +134,11 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
apply card_union_le
_ ≤ a.totient * i + a.totient + a.totient := add_le_add_right ih (totient a)
#align nat.Ico_filter_coprime_le Nat.Ico_filter_coprime_le
+-/
open ZMod
+#print ZMod.card_units_eq_totient /-
/-- Note this takes an explicit `fintype ((zmod n)ˣ)` argument to avoid trouble with instance
diamonds. -/
@[simp]
@@ -147,6 +153,7 @@ theorem ZMod.card_units_eq_totient (n : ℕ) [NeZero n] [Fintype (ZMod n)ˣ] :
Fin.sum_univ_eq_sum_range, @Nat.coprime_comm (m + 1)]
rfl
#align zmod.card_units_eq_totient ZMod.card_units_eq_totient
+-/
#print Nat.totient_even /-
theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient :=
@@ -174,6 +181,7 @@ theorem totient_mul {m n : ℕ} (h : m.coprime n) : φ (m * n) = φ m * φ n :=
#align nat.totient_mul Nat.totient_mul
-/
+#print Nat.totient_div_of_dvd /-
/-- For `d ∣ n`, the totient of `n/d` equals the number of values `k < n` such that `gcd n k = d` -/
theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
φ (n / d) = (filter (fun k : ℕ => n.gcd k = d) (range n)).card :=
@@ -193,6 +201,7 @@ theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
refine' ⟨q, ⟨⟨(mul_lt_mul_left hd0).1 hb1, _⟩, rfl⟩⟩
rwa [gcd_mul_left, mul_right_eq_self_iff hd0] at hb2
#align nat.totient_div_of_dvd Nat.totient_div_of_dvd
+-/
#print Nat.sum_totient /-
theorem sum_totient (n : ℕ) : n.divisors.Sum φ = n :=
@@ -209,12 +218,14 @@ theorem sum_totient (n : ℕ) : n.divisors.Sum φ = n :=
#align nat.sum_totient Nat.sum_totient
-/
+#print Nat.sum_totient' /-
theorem sum_totient' (n : ℕ) : ∑ m in (range n.succ).filterₓ (· ∣ n), φ m = n :=
by
convert sum_totient _ using 1
simp only [Nat.divisors, sum_filter, range_eq_Ico]
rw [sum_eq_sum_Ico_succ_bot] <;> simp
#align nat.sum_totient' Nat.sum_totient'
+-/
#print Nat.totient_prime_pow_succ /-
/-- When `p` is prime, then the totient of `p ^ (n + 1)` is `p ^ n * (p - 1)` -/
@@ -282,6 +293,7 @@ theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Pr
#align nat.totient_eq_iff_prime Nat.totient_eq_iff_prime
-/
+#print Nat.card_units_zmod_lt_sub_one /-
theorem card_units_zmod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
Fintype.card (ZMod p)ˣ ≤ p - 1 :=
by
@@ -289,7 +301,9 @@ theorem card_units_zmod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
rw [ZMod.card_units_eq_totient p]
exact Nat.le_pred_of_lt (Nat.totient_lt p hp)
#align nat.card_units_zmod_lt_sub_one Nat.card_units_zmod_lt_sub_one
+-/
+#print Nat.prime_iff_card_units /-
theorem prime_iff_card_units (p : ℕ) [Fintype (ZMod p)ˣ] :
p.Prime ↔ Fintype.card (ZMod p)ˣ = p - 1 :=
by
@@ -301,6 +315,7 @@ theorem prime_iff_card_units (p : ℕ) [Fintype (ZMod p)ˣ] :
simp
rw [ZMod.card_units_eq_totient, Nat.totient_eq_iff_prime <| NeZero.pos p]
#align nat.prime_iff_card_units Nat.prime_iff_card_units
+-/
#print Nat.totient_two /-
@[simp]
@@ -338,6 +353,7 @@ theorem totient_eq_prod_factorization {n : ℕ} (hn : n ≠ 0) :
#align nat.totient_eq_prod_factorization Nat.totient_eq_prod_factorization
-/
+#print Nat.totient_mul_prod_factors /-
/-- Euler's product formula for the totient function. -/
theorem totient_mul_prod_factors (n : ℕ) :
φ n * ∏ p in n.factors.toFinset, p = n * ∏ p in n.factors.toFinset, (p - 1) :=
@@ -350,7 +366,9 @@ theorem totient_mul_prod_factors (n : ℕ) :
rw [Finsupp.mem_support_iff, ← zero_lt_iff] at hp
rw [mul_comm, ← mul_assoc, ← pow_succ, Nat.sub_add_cancel hp]
#align nat.totient_mul_prod_factors Nat.totient_mul_prod_factors
+-/
+#print Nat.totient_eq_div_factors_mul /-
/-- Euler's product formula for the totient function. -/
theorem totient_eq_div_factors_mul (n : ℕ) :
φ n = (n / ∏ p in n.factors.toFinset, p) * ∏ p in n.factors.toFinset, (p - 1) :=
@@ -359,7 +377,9 @@ theorem totient_eq_div_factors_mul (n : ℕ) :
Nat.mul_div_assoc _ (prod_prime_factors_dvd n), mul_comm]
simpa [prod_factorization_eq_prod_factors] using prod_pos fun p => pos_of_mem_factorization
#align nat.totient_eq_div_factors_mul Nat.totient_eq_div_factors_mul
+-/
+#print Nat.totient_eq_mul_prod_factors /-
/-- Euler's product formula for the totient function. -/
theorem totient_eq_mul_prod_factors (n : ℕ) :
(φ n : ℚ) = n * ∏ p in n.factors.toFinset, (1 - p⁻¹) :=
@@ -377,6 +397,7 @@ theorem totient_eq_mul_prod_factors (n : ℕ) :
have hp' : (p : ℚ) ≠ 0 := cast_ne_zero.mpr hp.ne.symm
rw [sub_mul, one_mul, mul_comm, mul_inv_cancel hp', cast_pred hp]
#align nat.totient_eq_mul_prod_factors Nat.totient_eq_mul_prod_factors
+-/
#print Nat.totient_gcd_mul_totient_mul /-
theorem totient_gcd_mul_totient_mul (a b : ℕ) : φ (a.gcd b) * φ (a * b) = φ a * φ b * a.gcd b :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -209,7 +209,7 @@ theorem sum_totient (n : ℕ) : n.divisors.Sum φ = n :=
#align nat.sum_totient Nat.sum_totient
-/
-theorem sum_totient' (n : ℕ) : (∑ m in (range n.succ).filterₓ (· ∣ n), φ m) = n :=
+theorem sum_totient' (n : ℕ) : ∑ m in (range n.succ).filterₓ (· ∣ n), φ m = n :=
by
convert sum_totient _ using 1
simp only [Nat.divisors, sum_filter, range_eq_Ico]
@@ -340,7 +340,7 @@ theorem totient_eq_prod_factorization {n : ℕ} (hn : n ≠ 0) :
/-- Euler's product formula for the totient function. -/
theorem totient_mul_prod_factors (n : ℕ) :
- (φ n * ∏ p in n.factors.toFinset, p) = n * ∏ p in n.factors.toFinset, p - 1 :=
+ φ n * ∏ p in n.factors.toFinset, p = n * ∏ p in n.factors.toFinset, (p - 1) :=
by
by_cases hn : n = 0; · simp [hn]
rw [totient_eq_prod_factorization hn]
@@ -353,7 +353,7 @@ theorem totient_mul_prod_factors (n : ℕ) :
/-- Euler's product formula for the totient function. -/
theorem totient_eq_div_factors_mul (n : ℕ) :
- φ n = (n / ∏ p in n.factors.toFinset, p) * ∏ p in n.factors.toFinset, p - 1 :=
+ φ n = (n / ∏ p in n.factors.toFinset, p) * ∏ p in n.factors.toFinset, (p - 1) :=
by
rw [← mul_div_left n.totient, totient_mul_prod_factors, mul_comm,
Nat.mul_div_assoc _ (prod_prime_factors_dvd n), mul_comm]
@@ -361,11 +361,12 @@ theorem totient_eq_div_factors_mul (n : ℕ) :
#align nat.totient_eq_div_factors_mul Nat.totient_eq_div_factors_mul
/-- Euler's product formula for the totient function. -/
-theorem totient_eq_mul_prod_factors (n : ℕ) : (φ n : ℚ) = n * ∏ p in n.factors.toFinset, 1 - p⁻¹ :=
+theorem totient_eq_mul_prod_factors (n : ℕ) :
+ (φ n : ℚ) = n * ∏ p in n.factors.toFinset, (1 - p⁻¹) :=
by
by_cases hn : n = 0; · simp [hn]
have hn' : (n : ℚ) ≠ 0 := by simp [hn]
- have hpQ : (∏ p in n.factors.to_finset, (p : ℚ)) ≠ 0 :=
+ have hpQ : ∏ p in n.factors.to_finset, (p : ℚ) ≠ 0 :=
by
rw [← cast_prod, cast_ne_zero, ← zero_lt_iff, ← prod_factorization_eq_prod_factors]
exact prod_pos fun p hp => pos_of_mem_factorization hp
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -129,7 +129,6 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
rw [filter_union, ← filter_coprime_Ico_eq_totient a (k + n % a + a * i)]
apply card_union_le
_ ≤ a.totient * i + a.totient + a.totient := add_le_add_right ih (totient a)
-
#align nat.Ico_filter_coprime_le Nat.Ico_filter_coprime_le
open ZMod
@@ -147,7 +146,6 @@ theorem ZMod.card_units_eq_totient (n : ℕ) [NeZero n] [Fintype (ZMod n)ˣ] :
simp only [totient, Finset.card_eq_sum_ones, Fintype.card_subtype, Finset.sum_filter, ←
Fin.sum_univ_eq_sum_range, @Nat.coprime_comm (m + 1)]
rfl
-
#align zmod.card_units_eq_totient ZMod.card_units_eq_totient
#print Nat.totient_even /-
@@ -248,7 +246,6 @@ theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n +
exact (mul_lt_mul_right hp.pos).2 h
rw [card_sdiff h2, card_image_of_inj_on (h1.inj_on _), card_range, card_range, ←
one_mul (p ^ n), pow_succ, ← tsub_mul, one_mul, mul_comm]
-
#align nat.totient_prime_pow_succ Nat.totient_prime_pow_succ
-/
@@ -391,7 +388,6 @@ theorem totient_gcd_mul_totient_mul (a b : ℕ) : φ (a.gcd b) * φ (a * b) = φ
calc
a1 / b1 * c1 * (a2 / b2 * c2) = a1 / b1 * (a2 / b2) * (c1 * c2) := by apply mul_mul_mul_comm
_ = a1 * a2 / (b1 * b2) * (c1 * c2) := by congr 1; exact div_mul_div_comm h1 h2
-
simp only [totient_eq_div_factors_mul]
rw [shuffle, shuffle]
rotate_left; repeat' apply prod_prime_factors_dvd
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -63,9 +63,9 @@ theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filterₓ n.coprim
#print Nat.totient_eq_card_lt_and_coprime /-
/-- A characterisation of `nat.totient` that avoids `finset`. -/
-theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card { m | m < n ∧ n.coprime m } :=
+theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card {m | m < n ∧ n.coprime m} :=
by
- let e : { m | m < n ∧ n.coprime m } ≃ Finset.filter n.coprime (Finset.range n) :=
+ let e : {m | m < n ∧ n.coprime m} ≃ Finset.filter n.coprime (Finset.range n) :=
{ toFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using m.property⟩
invFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using m.property⟩
left_inv := fun m => by simp only [Subtype.coe_mk, Subtype.coe_eta]
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -113,7 +113,7 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
simp only [Finset.le_eq_subset]
exact Ico_subset_Ico rfl.le (add_le_add_left (le_of_lt (mod_lt n a_pos)) k)
simp only [mul_succ]
- simp_rw [← add_assoc] at ih⊢
+ simp_rw [← add_assoc] at ih ⊢
calc
(Filter a.coprime (Ico k (k + n % a + a * i + a))).card =
(Filter a.coprime
@@ -193,7 +193,7 @@ theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
have : d ∣ b := by rw [← hb2]; apply gcd_dvd_right
rcases this with ⟨q, rfl⟩
refine' ⟨q, ⟨⟨(mul_lt_mul_left hd0).1 hb1, _⟩, rfl⟩⟩
- rwa [gcd_mul_left, mul_right_eq_self_iff hd0] at hb2
+ rwa [gcd_mul_left, mul_right_eq_self_iff hd0] at hb2
#align nat.totient_div_of_dvd Nat.totient_div_of_dvd
#print Nat.sum_totient /-
@@ -236,7 +236,7 @@ theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n +
· rintro hap b _ rfl
exact hap (dvd_mul_left _ _)
· rintro h ⟨b, rfl⟩
- rw [pow_succ] at ha
+ rw [pow_succ] at ha
exact h b (lt_of_mul_lt_mul_left ha (zero_le _)) (mul_comm _ _)))
_ = _ := by
have h1 : Function.Injective (· * p) := mul_left_injective₀ hp.NeZero
@@ -275,10 +275,10 @@ theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Pr
· apply lt_of_le_of_ne
· rwa [succ_le_iff]
· rintro rfl
- rw [totient_one, tsub_self] at h
+ rw [totient_one, tsub_self] at h
exact one_ne_zero h
rw [totient_eq_card_coprime, range_eq_Ico, ← Ico_insert_succ_left hp.le, Finset.filter_insert,
- if_neg (not_coprime_of_dvd_of_dvd hp (dvd_refl p) (dvd_zero p)), ← Nat.card_Ico 1 p] at h
+ if_neg (not_coprime_of_dvd_of_dvd hp (dvd_refl p) (dvd_zero p)), ← Nat.card_Ico 1 p] at h
refine'
p.prime_of_coprime hp fun n hn hnz => Finset.filter_card_eq h n <| finset.mem_Ico.mpr ⟨_, hn⟩
rwa [succ_le_iff, pos_iff_ne_zero]
@@ -350,7 +350,7 @@ theorem totient_mul_prod_factors (n : ℕ) :
nth_rw 3 [← factorization_prod_pow_eq_self hn]
simp only [← prod_factorization_eq_prod_factors, ← Finsupp.prod_mul]
refine' Finsupp.prod_congr fun p hp => _
- rw [Finsupp.mem_support_iff, ← zero_lt_iff] at hp
+ rw [Finsupp.mem_support_iff, ← zero_lt_iff] at hp
rw [mul_comm, ← mul_assoc, ← pow_succ, Nat.sub_add_cancel hp]
#align nat.totient_mul_prod_factors Nat.totient_mul_prod_factors
@@ -433,7 +433,7 @@ theorem totient_mul_of_prime_of_dvd {p n : ℕ} (hp : p.Prime) (h : p ∣ n) :
(p * n).totient = p * n.totient :=
by
have h1 := totient_gcd_mul_totient_mul p n
- rw [gcd_eq_left h, mul_assoc] at h1
+ rw [gcd_eq_left h, mul_assoc] at h1
simpa [(totient_pos hp.pos).ne', mul_comm] using h1
#align nat.totient_mul_of_prime_of_dvd Nat.totient_mul_of_prime_of_dvd
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -29,7 +29,7 @@ We prove the divisor sum formula, namely that `n` equals `φ` summed over the di
open Finset
-open BigOperators
+open scoped BigOperators
namespace Nat
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -57,12 +57,6 @@ theorem totient_one : φ 1 = 1 := by simp [totient]
#align nat.totient_one Nat.totient_one
-/
-/- warning: nat.totient_eq_card_coprime -> Nat.totient_eq_card_coprime is a dubious translation:
-lean 3 declaration is
- forall (n : Nat), Eq.{1} Nat (Nat.totient n) (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime n) (fun (a : Nat) => Nat.coprime.decidable n a) (Finset.range n)))
-but is expected to have type
- forall (n : Nat), Eq.{1} Nat (Nat.totient n) (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime n) (fun (a : Nat) => Nat.instDecidableCoprime_1 n a) (Finset.range n)))
-Case conversion may be inaccurate. Consider using '#align nat.totient_eq_card_coprime Nat.totient_eq_card_coprimeₓ'. -/
theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filterₓ n.coprime).card :=
rfl
#align nat.totient_eq_card_coprime Nat.totient_eq_card_coprime
@@ -100,12 +94,6 @@ theorem totient_pos : ∀ {n : ℕ}, 0 < n → 0 < φ n
#align nat.totient_pos Nat.totient_pos
-/
-/- warning: nat.filter_coprime_Ico_eq_totient -> Nat.filter_coprime_Ico_eq_totient is a dubious translation:
-lean 3 declaration is
- forall (a : Nat) (n : Nat), Eq.{1} Nat (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime a) (fun (a_1 : Nat) => Nat.coprime.decidable a a_1) (Finset.Ico.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) Nat.locallyFiniteOrder n (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n a)))) (Nat.totient a)
-but is expected to have type
- forall (a : Nat) (n : Nat), Eq.{1} Nat (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime a) (fun (a_1 : Nat) => Nat.instDecidableCoprime_1 a a_1) (Finset.Ico.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) instLocallyFiniteOrderNatToPreorderToPartialOrderStrictOrderedSemiring n (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n a)))) (Nat.totient a)
-Case conversion may be inaccurate. Consider using '#align nat.filter_coprime_Ico_eq_totient Nat.filter_coprime_Ico_eq_totientₓ'. -/
theorem filter_coprime_Ico_eq_totient (a n : ℕ) :
((Ico n (n + a)).filterₓ (coprime a)).card = totient a :=
by
@@ -113,12 +101,6 @@ theorem filter_coprime_Ico_eq_totient (a n : ℕ) :
exact periodic_coprime a
#align nat.filter_coprime_Ico_eq_totient Nat.filter_coprime_Ico_eq_totient
-/- warning: nat.Ico_filter_coprime_le -> Nat.Ico_filter_coprime_le is a dubious translation:
-lean 3 declaration is
- forall {a : Nat} (k : Nat) (n : Nat), (LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) a) -> (LE.le.{0} Nat Nat.hasLe (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime a) (fun (a_1 : Nat) => Nat.coprime.decidable a a_1) (Finset.Ico.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) Nat.locallyFiniteOrder k (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) k n)))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Nat.totient a) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.hasDiv) n a) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))))
-but is expected to have type
- forall {a : Nat} (k : Nat) (n : Nat), (LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) a) -> (LE.le.{0} Nat instLENat (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime a) (fun (a_1 : Nat) => Nat.instDecidableCoprime_1 a a_1) (Finset.Ico.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) instLocallyFiniteOrderNatToPreorderToPartialOrderStrictOrderedSemiring k (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) k n)))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Nat.totient a) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.instDivNat) n a) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))
-Case conversion may be inaccurate. Consider using '#align nat.Ico_filter_coprime_le Nat.Ico_filter_coprime_leₓ'. -/
theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
((Ico k (k + n)).filterₓ (coprime a)).card ≤ totient a * (n / a + 1) :=
by
@@ -152,12 +134,6 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
open ZMod
-/- warning: zmod.card_units_eq_totient -> ZMod.card_units_eq_totient is a dubious translation:
-lean 3 declaration is
- forall (n : Nat) [_inst_1 : NeZero.{0} Nat Nat.hasZero n] [_inst_2 : Fintype.{0} (Units.{0} (ZMod n) (Ring.toMonoid.{0} (ZMod n) (CommRing.toRing.{0} (ZMod n) (ZMod.commRing n))))], Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod n) (Ring.toMonoid.{0} (ZMod n) (CommRing.toRing.{0} (ZMod n) (ZMod.commRing n)))) _inst_2) (Nat.totient n)
-but is expected to have type
- forall (n : Nat) [_inst_1 : NeZero.{0} Nat (LinearOrderedCommMonoidWithZero.toZero.{0} Nat Nat.linearOrderedCommMonoidWithZero) n] [_inst_2 : Fintype.{0} (Units.{0} (ZMod n) (MonoidWithZero.toMonoid.{0} (ZMod n) (Semiring.toMonoidWithZero.{0} (ZMod n) (CommSemiring.toSemiring.{0} (ZMod n) (CommRing.toCommSemiring.{0} (ZMod n) (ZMod.commRing n))))))], Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod n) (MonoidWithZero.toMonoid.{0} (ZMod n) (Semiring.toMonoidWithZero.{0} (ZMod n) (CommSemiring.toSemiring.{0} (ZMod n) (CommRing.toCommSemiring.{0} (ZMod n) (ZMod.commRing n)))))) _inst_2) (Nat.totient n)
-Case conversion may be inaccurate. Consider using '#align zmod.card_units_eq_totient ZMod.card_units_eq_totientₓ'. -/
/-- Note this takes an explicit `fintype ((zmod n)ˣ)` argument to avoid trouble with instance
diamonds. -/
@[simp]
@@ -200,12 +176,6 @@ theorem totient_mul {m n : ℕ} (h : m.coprime n) : φ (m * n) = φ m * φ n :=
#align nat.totient_mul Nat.totient_mul
-/
-/- warning: nat.totient_div_of_dvd -> Nat.totient_div_of_dvd is a dubious translation:
-lean 3 declaration is
- forall {n : Nat} {d : Nat}, (Dvd.Dvd.{0} Nat Nat.hasDvd d n) -> (Eq.{1} Nat (Nat.totient (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.hasDiv) n d)) (Finset.card.{0} Nat (Finset.filter.{0} Nat (fun (k : Nat) => Eq.{1} Nat (Nat.gcd n k) d) (fun (a : Nat) => Nat.decidableEq (Nat.gcd n a) d) (Finset.range n))))
-but is expected to have type
- forall {n : Nat} {d : Nat}, (Dvd.dvd.{0} Nat Nat.instDvdNat d n) -> (Eq.{1} Nat (Nat.totient (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.instDivNat) n d)) (Finset.card.{0} Nat (Finset.filter.{0} Nat (fun (k : Nat) => Eq.{1} Nat (Nat.gcd n k) d) (fun (a : Nat) => instDecidableEqNat (Nat.gcd n a) d) (Finset.range n))))
-Case conversion may be inaccurate. Consider using '#align nat.totient_div_of_dvd Nat.totient_div_of_dvdₓ'. -/
/-- For `d ∣ n`, the totient of `n/d` equals the number of values `k < n` such that `gcd n k = d` -/
theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
φ (n / d) = (filter (fun k : ℕ => n.gcd k = d) (range n)).card :=
@@ -241,12 +211,6 @@ theorem sum_totient (n : ℕ) : n.divisors.Sum φ = n :=
#align nat.sum_totient Nat.sum_totient
-/
-/- warning: nat.sum_totient' -> Nat.sum_totient' is a dubious translation:
-lean 3 declaration is
- forall (n : Nat), Eq.{1} Nat (Finset.sum.{0, 0} Nat Nat Nat.addCommMonoid (Finset.filter.{0} Nat (fun (_x : Nat) => Dvd.Dvd.{0} Nat Nat.hasDvd _x n) (fun (a : Nat) => Nat.decidableDvd a n) (Finset.range (Nat.succ n))) (fun (m : Nat) => Nat.totient m)) n
-but is expected to have type
- forall (n : Nat), Eq.{1} Nat (Finset.sum.{0, 0} Nat Nat Nat.addCommMonoid (Finset.filter.{0} Nat (fun (_x : Nat) => Dvd.dvd.{0} Nat Nat.instDvdNat _x n) (fun (a : Nat) => Nat.decidable_dvd a n) (Finset.range (Nat.succ n))) (fun (m : Nat) => Nat.totient m)) n
-Case conversion may be inaccurate. Consider using '#align nat.sum_totient' Nat.sum_totient'ₓ'. -/
theorem sum_totient' (n : ℕ) : (∑ m in (range n.succ).filterₓ (· ∣ n), φ m) = n :=
by
convert sum_totient _ using 1
@@ -321,12 +285,6 @@ theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Pr
#align nat.totient_eq_iff_prime Nat.totient_eq_iff_prime
-/
-/- warning: nat.card_units_zmod_lt_sub_one -> Nat.card_units_zmod_lt_sub_one is a dubious translation:
-lean 3 declaration is
- forall {p : Nat}, (LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))) p) -> (forall [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))], LE.le.{0} Nat Nat.hasLe (Fintype.card.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) p (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))))
-but is expected to have type
- forall {p : Nat}, (LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)) p) -> (forall [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (CommSemiring.toSemiring.{0} (ZMod p) (CommRing.toCommSemiring.{0} (ZMod p) (ZMod.commRing p))))))], LE.le.{0} Nat instLENat (Fintype.card.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (CommSemiring.toSemiring.{0} (ZMod p) (CommRing.toCommSemiring.{0} (ZMod p) (ZMod.commRing p)))))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
-Case conversion may be inaccurate. Consider using '#align nat.card_units_zmod_lt_sub_one Nat.card_units_zmod_lt_sub_oneₓ'. -/
theorem card_units_zmod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
Fintype.card (ZMod p)ˣ ≤ p - 1 :=
by
@@ -335,12 +293,6 @@ theorem card_units_zmod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
exact Nat.le_pred_of_lt (Nat.totient_lt p hp)
#align nat.card_units_zmod_lt_sub_one Nat.card_units_zmod_lt_sub_one
-/- warning: nat.prime_iff_card_units -> Nat.prime_iff_card_units is a dubious translation:
-lean 3 declaration is
- forall (p : Nat) [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))], Iff (Nat.Prime p) (Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) p (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))))
-but is expected to have type
- forall (p : Nat) [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (CommSemiring.toSemiring.{0} (ZMod p) (CommRing.toCommSemiring.{0} (ZMod p) (ZMod.commRing p))))))], Iff (Nat.Prime p) (Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (CommSemiring.toSemiring.{0} (ZMod p) (CommRing.toCommSemiring.{0} (ZMod p) (ZMod.commRing p)))))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
-Case conversion may be inaccurate. Consider using '#align nat.prime_iff_card_units Nat.prime_iff_card_unitsₓ'. -/
theorem prime_iff_card_units (p : ℕ) [Fintype (ZMod p)ˣ] :
p.Prime ↔ Fintype.card (ZMod p)ˣ = p - 1 :=
by
@@ -389,12 +341,6 @@ theorem totient_eq_prod_factorization {n : ℕ} (hn : n ≠ 0) :
#align nat.totient_eq_prod_factorization Nat.totient_eq_prod_factorization
-/
-/- warning: nat.totient_mul_prod_factors -> Nat.totient_mul_prod_factors is a dubious translation:
-lean 3 declaration is
- forall (n : Nat), Eq.{1} Nat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Nat.totient n) (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => Nat.decidableEq a b) (Nat.factors n)) (fun (p : Nat) => p))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) n (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => Nat.decidableEq a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) p (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))))
-but is expected to have type
- forall (n : Nat), Eq.{1} Nat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Nat.totient n) (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => p))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) n (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))
-Case conversion may be inaccurate. Consider using '#align nat.totient_mul_prod_factors Nat.totient_mul_prod_factorsₓ'. -/
/-- Euler's product formula for the totient function. -/
theorem totient_mul_prod_factors (n : ℕ) :
(φ n * ∏ p in n.factors.toFinset, p) = n * ∏ p in n.factors.toFinset, p - 1 :=
@@ -408,12 +354,6 @@ theorem totient_mul_prod_factors (n : ℕ) :
rw [mul_comm, ← mul_assoc, ← pow_succ, Nat.sub_add_cancel hp]
#align nat.totient_mul_prod_factors Nat.totient_mul_prod_factors
-/- warning: nat.totient_eq_div_factors_mul -> Nat.totient_eq_div_factors_mul is a dubious translation:
-lean 3 declaration is
- forall (n : Nat), Eq.{1} Nat (Nat.totient n) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.hasDiv) n (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => Nat.decidableEq a b) (Nat.factors n)) (fun (p : Nat) => p))) (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => Nat.decidableEq a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) p (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))))
-but is expected to have type
- forall (n : Nat), Eq.{1} Nat (Nat.totient n) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.instDivNat) n (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => p))) (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))
-Case conversion may be inaccurate. Consider using '#align nat.totient_eq_div_factors_mul Nat.totient_eq_div_factors_mulₓ'. -/
/-- Euler's product formula for the totient function. -/
theorem totient_eq_div_factors_mul (n : ℕ) :
φ n = (n / ∏ p in n.factors.toFinset, p) * ∏ p in n.factors.toFinset, p - 1 :=
@@ -423,12 +363,6 @@ theorem totient_eq_div_factors_mul (n : ℕ) :
simpa [prod_factorization_eq_prod_factors] using prod_pos fun p => pos_of_mem_factorization
#align nat.totient_eq_div_factors_mul Nat.totient_eq_div_factors_mul
-/- warning: nat.totient_eq_mul_prod_factors -> Nat.totient_eq_mul_prod_factors is a dubious translation:
-lean 3 declaration is
- forall (n : Nat), Eq.{1} Rat ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.totient n)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.hasMul) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) n) (Finset.prod.{0, 0} Rat Nat Rat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => Nat.decidableEq a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Rat Rat Rat (instHSub.{0} Rat (SubNegMonoid.toHasSub.{0} Rat (AddGroup.toSubNegMonoid.{0} Rat Rat.addGroup))) (OfNat.ofNat.{0} Rat 1 (OfNat.mk.{0} Rat 1 (One.one.{0} Rat Rat.hasOne))) (Inv.inv.{0} Rat Rat.hasInv ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) p)))))
-but is expected to have type
- forall (n : Nat), Eq.{1} Rat (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.totient n)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) n) (Finset.prod.{0, 0} Rat Nat Rat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Rat Rat Rat (instHSub.{0} Rat Rat.instSubRat) (OfNat.ofNat.{0} Rat 1 (Rat.instOfNatRat 1)) (Inv.inv.{0} Rat Rat.instInvRat (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) p)))))
-Case conversion may be inaccurate. Consider using '#align nat.totient_eq_mul_prod_factors Nat.totient_eq_mul_prod_factorsₓ'. -/
/-- Euler's product formula for the totient function. -/
theorem totient_eq_mul_prod_factors (n : ℕ) : (φ n : ℚ) = n * ∏ p in n.factors.toFinset, 1 - p⁻¹ :=
by
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -179,10 +179,8 @@ theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient :=
by
haveI : Fact (1 < n) := ⟨one_lt_two.trans hn⟩
haveI : NeZero n := NeZero.of_gt hn
- suffices 2 = orderOf (-1 : (ZMod n)ˣ)
- by
- rw [← ZMod.card_units_eq_totient, even_iff_two_dvd, this]
- exact orderOf_dvd_card_univ
+ suffices 2 = orderOf (-1 : (ZMod n)ˣ) by
+ rw [← ZMod.card_units_eq_totient, even_iff_two_dvd, this]; exact orderOf_dvd_card_univ
rw [← orderOf_units, Units.coe_neg_one, orderOf_neg_one, ringChar.eq (ZMod n) n, if_neg hn.ne']
#align nat.totient_even Nat.totient_even
-/
@@ -222,9 +220,7 @@ theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
· simp [hd0.ne']
· simp only [mem_filter, mem_range, exists_prop, and_imp]
refine' fun b hb1 hb2 => _
- have : d ∣ b := by
- rw [← hb2]
- apply gcd_dvd_right
+ have : d ∣ b := by rw [← hb2]; apply gcd_dvd_right
rcases this with ⟨q, rfl⟩
refine' ⟨q, ⟨⟨(mul_lt_mul_left hd0).1 hb1, _⟩, rfl⟩⟩
rwa [gcd_mul_left, mul_right_eq_self_iff hd0] at hb2
@@ -233,8 +229,7 @@ theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
#print Nat.sum_totient /-
theorem sum_totient (n : ℕ) : n.divisors.Sum φ = n :=
by
- rcases n.eq_zero_or_pos with (rfl | hn)
- · simp
+ rcases n.eq_zero_or_pos with (rfl | hn); · simp
rw [← sum_div_divisors n φ]
have : n = ∑ d : ℕ in n.divisors, (Filter (fun k : ℕ => n.gcd k = d) (range n)).card :=
by
@@ -437,8 +432,7 @@ Case conversion may be inaccurate. Consider using '#align nat.totient_eq_mul_pro
/-- Euler's product formula for the totient function. -/
theorem totient_eq_mul_prod_factors (n : ℕ) : (φ n : ℚ) = n * ∏ p in n.factors.toFinset, 1 - p⁻¹ :=
by
- by_cases hn : n = 0
- · simp [hn]
+ by_cases hn : n = 0; · simp [hn]
have hn' : (n : ℚ) ≠ 0 := by simp [hn]
have hpQ : (∏ p in n.factors.to_finset, (p : ℚ)) ≠ 0 :=
by
@@ -462,14 +456,11 @@ theorem totient_gcd_mul_totient_mul (a b : ℕ) : φ (a.gcd b) * φ (a * b) = φ
intro a1 a2 b1 b2 c1 c2 h1 h2
calc
a1 / b1 * c1 * (a2 / b2 * c2) = a1 / b1 * (a2 / b2) * (c1 * c2) := by apply mul_mul_mul_comm
- _ = a1 * a2 / (b1 * b2) * (c1 * c2) := by
- congr 1
- exact div_mul_div_comm h1 h2
+ _ = a1 * a2 / (b1 * b2) * (c1 * c2) := by congr 1; exact div_mul_div_comm h1 h2
simp only [totient_eq_div_factors_mul]
rw [shuffle, shuffle]
- rotate_left
- repeat' apply prod_prime_factors_dvd
+ rotate_left; repeat' apply prod_prime_factors_dvd
· simp only [prod_factors_gcd_mul_prod_factors_mul]
rw [eq_comm, mul_comm, ← mul_assoc, ← Nat.mul_div_assoc]
exact mul_dvd_mul (prod_prime_factors_dvd a) (prod_prime_factors_dvd b)
@@ -480,8 +471,7 @@ theorem totient_gcd_mul_totient_mul (a b : ℕ) : φ (a.gcd b) * φ (a * b) = φ
theorem totient_super_multiplicative (a b : ℕ) : φ a * φ b ≤ φ (a * b) :=
by
let d := a.gcd b
- rcases(zero_le a).eq_or_lt with (rfl | ha0)
- · simp
+ rcases(zero_le a).eq_or_lt with (rfl | ha0); · simp
have hd0 : 0 < d := Nat.gcd_pos_of_pos_left _ ha0
rw [← mul_le_mul_right hd0, ← totient_gcd_mul_totient_mul a b, mul_comm]
apply mul_le_mul_left' (Nat.totient_le d)
@@ -491,10 +481,8 @@ theorem totient_super_multiplicative (a b : ℕ) : φ a * φ b ≤ φ (a * b) :=
#print Nat.totient_dvd_of_dvd /-
theorem totient_dvd_of_dvd {a b : ℕ} (h : a ∣ b) : φ a ∣ φ b :=
by
- rcases eq_or_ne a 0 with (rfl | ha0)
- · simp [zero_dvd_iff.1 h]
- rcases eq_or_ne b 0 with (rfl | hb0)
- · simp
+ rcases eq_or_ne a 0 with (rfl | ha0); · simp [zero_dvd_iff.1 h]
+ rcases eq_or_ne b 0 with (rfl | hb0); · simp
have hab' : a.factorization.support ⊆ b.factorization.support :=
by
intro p
mathlib commit https://github.com/leanprover-community/mathlib/commit/08e1d8d4d989df3a6df86f385e9053ec8a372cc1
@@ -156,7 +156,7 @@ open ZMod
lean 3 declaration is
forall (n : Nat) [_inst_1 : NeZero.{0} Nat Nat.hasZero n] [_inst_2 : Fintype.{0} (Units.{0} (ZMod n) (Ring.toMonoid.{0} (ZMod n) (CommRing.toRing.{0} (ZMod n) (ZMod.commRing n))))], Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod n) (Ring.toMonoid.{0} (ZMod n) (CommRing.toRing.{0} (ZMod n) (ZMod.commRing n)))) _inst_2) (Nat.totient n)
but is expected to have type
- forall (n : Nat) [_inst_1 : NeZero.{0} Nat (LinearOrderedCommMonoidWithZero.toZero.{0} Nat Nat.linearOrderedCommMonoidWithZero) n] [_inst_2 : Fintype.{0} (Units.{0} (ZMod n) (MonoidWithZero.toMonoid.{0} (ZMod n) (Semiring.toMonoidWithZero.{0} (ZMod n) (Ring.toSemiring.{0} (ZMod n) (CommRing.toRing.{0} (ZMod n) (ZMod.commRing n))))))], Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod n) (MonoidWithZero.toMonoid.{0} (ZMod n) (Semiring.toMonoidWithZero.{0} (ZMod n) (Ring.toSemiring.{0} (ZMod n) (CommRing.toRing.{0} (ZMod n) (ZMod.commRing n)))))) _inst_2) (Nat.totient n)
+ forall (n : Nat) [_inst_1 : NeZero.{0} Nat (LinearOrderedCommMonoidWithZero.toZero.{0} Nat Nat.linearOrderedCommMonoidWithZero) n] [_inst_2 : Fintype.{0} (Units.{0} (ZMod n) (MonoidWithZero.toMonoid.{0} (ZMod n) (Semiring.toMonoidWithZero.{0} (ZMod n) (CommSemiring.toSemiring.{0} (ZMod n) (CommRing.toCommSemiring.{0} (ZMod n) (ZMod.commRing n))))))], Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod n) (MonoidWithZero.toMonoid.{0} (ZMod n) (Semiring.toMonoidWithZero.{0} (ZMod n) (CommSemiring.toSemiring.{0} (ZMod n) (CommRing.toCommSemiring.{0} (ZMod n) (ZMod.commRing n)))))) _inst_2) (Nat.totient n)
Case conversion may be inaccurate. Consider using '#align zmod.card_units_eq_totient ZMod.card_units_eq_totientₓ'. -/
/-- Note this takes an explicit `fintype ((zmod n)ˣ)` argument to avoid trouble with instance
diamonds. -/
@@ -330,7 +330,7 @@ theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Pr
lean 3 declaration is
forall {p : Nat}, (LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))) p) -> (forall [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))], LE.le.{0} Nat Nat.hasLe (Fintype.card.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) p (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))))
but is expected to have type
- forall {p : Nat}, (LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)) p) -> (forall [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (Ring.toSemiring.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))))], LE.le.{0} Nat instLENat (Fintype.card.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (Ring.toSemiring.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
+ forall {p : Nat}, (LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)) p) -> (forall [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (CommSemiring.toSemiring.{0} (ZMod p) (CommRing.toCommSemiring.{0} (ZMod p) (ZMod.commRing p))))))], LE.le.{0} Nat instLENat (Fintype.card.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (CommSemiring.toSemiring.{0} (ZMod p) (CommRing.toCommSemiring.{0} (ZMod p) (ZMod.commRing p)))))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
Case conversion may be inaccurate. Consider using '#align nat.card_units_zmod_lt_sub_one Nat.card_units_zmod_lt_sub_oneₓ'. -/
theorem card_units_zmod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
Fintype.card (ZMod p)ˣ ≤ p - 1 :=
@@ -344,7 +344,7 @@ theorem card_units_zmod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
lean 3 declaration is
forall (p : Nat) [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))], Iff (Nat.Prime p) (Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) p (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))))
but is expected to have type
- forall (p : Nat) [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (Ring.toSemiring.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))))], Iff (Nat.Prime p) (Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (Ring.toSemiring.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
+ forall (p : Nat) [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (CommSemiring.toSemiring.{0} (ZMod p) (CommRing.toCommSemiring.{0} (ZMod p) (ZMod.commRing p))))))], Iff (Nat.Prime p) (Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (CommSemiring.toSemiring.{0} (ZMod p) (CommRing.toCommSemiring.{0} (ZMod p) (ZMod.commRing p)))))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
Case conversion may be inaccurate. Consider using '#align nat.prime_iff_card_units Nat.prime_iff_card_unitsₓ'. -/
theorem prime_iff_card_units (p : ℕ) [Fintype (ZMod p)ˣ] :
p.Prime ↔ Fintype.card (ZMod p)ˣ = p - 1 :=
@@ -432,7 +432,7 @@ theorem totient_eq_div_factors_mul (n : ℕ) :
lean 3 declaration is
forall (n : Nat), Eq.{1} Rat ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.totient n)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.hasMul) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) n) (Finset.prod.{0, 0} Rat Nat Rat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => Nat.decidableEq a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Rat Rat Rat (instHSub.{0} Rat (SubNegMonoid.toHasSub.{0} Rat (AddGroup.toSubNegMonoid.{0} Rat Rat.addGroup))) (OfNat.ofNat.{0} Rat 1 (OfNat.mk.{0} Rat 1 (One.one.{0} Rat Rat.hasOne))) (Inv.inv.{0} Rat Rat.hasInv ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) p)))))
but is expected to have type
- forall (n : Nat), Eq.{1} Rat (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.totient n)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) n) (Finset.prod.{0, 0} Rat Nat Rat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Rat Rat Rat (instHSub.{0} Rat Rat.instSubRat) (OfNat.ofNat.{0} Rat 1 (Rat.instOfNatRat 1)) (Inv.inv.{0} Rat Rat.instInvRat (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) p)))))
+ forall (n : Nat), Eq.{1} Rat (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.totient n)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) n) (Finset.prod.{0, 0} Rat Nat Rat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Rat Rat Rat (instHSub.{0} Rat Rat.instSubRat) (OfNat.ofNat.{0} Rat 1 (Rat.instOfNatRat 1)) (Inv.inv.{0} Rat Rat.instInvRat (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) p)))))
Case conversion may be inaccurate. Consider using '#align nat.totient_eq_mul_prod_factors Nat.totient_eq_mul_prod_factorsₓ'. -/
/-- Euler's product formula for the totient function. -/
theorem totient_eq_mul_prod_factors (n : ℕ) : (φ n : ℚ) = n * ∏ p in n.factors.toFinset, 1 - p⁻¹ :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/3cacc945118c8c637d89950af01da78307f59325
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes
! This file was ported from Lean 3 source module data.nat.totient
-! leanprover-community/mathlib commit 5cc2dfdd3e92f340411acea4427d701dc7ed26f8
+! leanprover-community/mathlib commit 31ca6f9cf5f90a6206092cd7f84b359dcb6d52e0
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -16,6 +16,9 @@ import Mathbin.Data.Zmod.Basic
/-!
# Euler's totient function
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
This file defines [Euler's totient function](https://en.wikipedia.org/wiki/Euler's_totient_function)
`nat.totient n` which counts the number of naturals less than `n` that are coprime with `n`.
We prove the divisor sum formula, namely that `n` equals `φ` summed over the divisors of `n`. See
mathlib commit https://github.com/leanprover-community/mathlib/commit/d95bef0d215ea58c0fd7bbc4b151bf3fe952c095
@@ -323,19 +323,19 @@ theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Pr
#align nat.totient_eq_iff_prime Nat.totient_eq_iff_prime
-/
-/- warning: nat.card_units_zmod_lt_sub_one -> Nat.card_units_zMod_lt_sub_one is a dubious translation:
+/- warning: nat.card_units_zmod_lt_sub_one -> Nat.card_units_zmod_lt_sub_one is a dubious translation:
lean 3 declaration is
forall {p : Nat}, (LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))) p) -> (forall [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))], LE.le.{0} Nat Nat.hasLe (Fintype.card.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) p (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))))
but is expected to have type
forall {p : Nat}, (LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)) p) -> (forall [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (Ring.toSemiring.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))))], LE.le.{0} Nat instLENat (Fintype.card.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (Ring.toSemiring.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
-Case conversion may be inaccurate. Consider using '#align nat.card_units_zmod_lt_sub_one Nat.card_units_zMod_lt_sub_oneₓ'. -/
-theorem card_units_zMod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
+Case conversion may be inaccurate. Consider using '#align nat.card_units_zmod_lt_sub_one Nat.card_units_zmod_lt_sub_oneₓ'. -/
+theorem card_units_zmod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
Fintype.card (ZMod p)ˣ ≤ p - 1 :=
by
haveI : NeZero p := ⟨(pos_of_gt hp).ne'⟩
rw [ZMod.card_units_eq_totient p]
exact Nat.le_pred_of_lt (Nat.totient_lt p hp)
-#align nat.card_units_zmod_lt_sub_one Nat.card_units_zMod_lt_sub_one
+#align nat.card_units_zmod_lt_sub_one Nat.card_units_zmod_lt_sub_one
/- warning: nat.prime_iff_card_units -> Nat.prime_iff_card_units is a dubious translation:
lean 3 declaration is
mathlib commit https://github.com/leanprover-community/mathlib/commit/0148d455199ed64bf8eb2f493a1e7eb9211ce170
@@ -30,28 +30,41 @@ open BigOperators
namespace Nat
+#print Nat.totient /-
/-- Euler's totient function. This counts the number of naturals strictly less than `n` which are
coprime with `n`. -/
def totient (n : ℕ) : ℕ :=
((range n).filterₓ n.coprime).card
#align nat.totient Nat.totient
+-/
-- mathport name: nat.totient
scoped notation "φ" => Nat.totient
+#print Nat.totient_zero /-
@[simp]
theorem totient_zero : φ 0 = 0 :=
rfl
#align nat.totient_zero Nat.totient_zero
+-/
+#print Nat.totient_one /-
@[simp]
theorem totient_one : φ 1 = 1 := by simp [totient]
#align nat.totient_one Nat.totient_one
+-/
+/- warning: nat.totient_eq_card_coprime -> Nat.totient_eq_card_coprime is a dubious translation:
+lean 3 declaration is
+ forall (n : Nat), Eq.{1} Nat (Nat.totient n) (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime n) (fun (a : Nat) => Nat.coprime.decidable n a) (Finset.range n)))
+but is expected to have type
+ forall (n : Nat), Eq.{1} Nat (Nat.totient n) (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime n) (fun (a : Nat) => Nat.instDecidableCoprime_1 n a) (Finset.range n)))
+Case conversion may be inaccurate. Consider using '#align nat.totient_eq_card_coprime Nat.totient_eq_card_coprimeₓ'. -/
theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filterₓ n.coprime).card :=
rfl
#align nat.totient_eq_card_coprime Nat.totient_eq_card_coprime
+#print Nat.totient_eq_card_lt_and_coprime /-
/-- A characterisation of `nat.totient` that avoids `finset`. -/
theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card { m | m < n ∧ n.coprime m } :=
by
@@ -62,21 +75,34 @@ theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card { m | m < n
right_inv := fun m => by simp only [Subtype.coe_mk, Subtype.coe_eta] }
rw [totient_eq_card_coprime, card_congr e, card_eq_fintype_card, Fintype.card_coe]
#align nat.totient_eq_card_lt_and_coprime Nat.totient_eq_card_lt_and_coprime
+-/
+#print Nat.totient_le /-
theorem totient_le (n : ℕ) : φ n ≤ n :=
((range n).card_filter_le _).trans_eq (card_range n)
#align nat.totient_le Nat.totient_le
+-/
+#print Nat.totient_lt /-
theorem totient_lt (n : ℕ) (hn : 1 < n) : φ n < n :=
(card_lt_card (filter_ssubset.2 ⟨0, by simp [hn.ne', pos_of_gt hn]⟩)).trans_eq (card_range n)
#align nat.totient_lt Nat.totient_lt
+-/
+#print Nat.totient_pos /-
theorem totient_pos : ∀ {n : ℕ}, 0 < n → 0 < φ n
| 0 => by decide
| 1 => by simp [totient]
| n + 2 => fun h => card_pos.2 ⟨1, mem_filter.2 ⟨mem_range.2 (by decide), coprime_one_right _⟩⟩
#align nat.totient_pos Nat.totient_pos
+-/
+/- warning: nat.filter_coprime_Ico_eq_totient -> Nat.filter_coprime_Ico_eq_totient is a dubious translation:
+lean 3 declaration is
+ forall (a : Nat) (n : Nat), Eq.{1} Nat (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime a) (fun (a_1 : Nat) => Nat.coprime.decidable a a_1) (Finset.Ico.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) Nat.locallyFiniteOrder n (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n a)))) (Nat.totient a)
+but is expected to have type
+ forall (a : Nat) (n : Nat), Eq.{1} Nat (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime a) (fun (a_1 : Nat) => Nat.instDecidableCoprime_1 a a_1) (Finset.Ico.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) instLocallyFiniteOrderNatToPreorderToPartialOrderStrictOrderedSemiring n (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n a)))) (Nat.totient a)
+Case conversion may be inaccurate. Consider using '#align nat.filter_coprime_Ico_eq_totient Nat.filter_coprime_Ico_eq_totientₓ'. -/
theorem filter_coprime_Ico_eq_totient (a n : ℕ) :
((Ico n (n + a)).filterₓ (coprime a)).card = totient a :=
by
@@ -84,6 +110,12 @@ theorem filter_coprime_Ico_eq_totient (a n : ℕ) :
exact periodic_coprime a
#align nat.filter_coprime_Ico_eq_totient Nat.filter_coprime_Ico_eq_totient
+/- warning: nat.Ico_filter_coprime_le -> Nat.Ico_filter_coprime_le is a dubious translation:
+lean 3 declaration is
+ forall {a : Nat} (k : Nat) (n : Nat), (LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) a) -> (LE.le.{0} Nat Nat.hasLe (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime a) (fun (a_1 : Nat) => Nat.coprime.decidable a a_1) (Finset.Ico.{0} Nat (PartialOrder.toPreorder.{0} Nat (OrderedCancelAddCommMonoid.toPartialOrder.{0} Nat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} Nat Nat.strictOrderedSemiring))) Nat.locallyFiniteOrder k (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) k n)))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Nat.totient a) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.hasDiv) n a) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))))
+but is expected to have type
+ forall {a : Nat} (k : Nat) (n : Nat), (LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) a) -> (LE.le.{0} Nat instLENat (Finset.card.{0} Nat (Finset.filter.{0} Nat (Nat.coprime a) (fun (a_1 : Nat) => Nat.instDecidableCoprime_1 a a_1) (Finset.Ico.{0} Nat (PartialOrder.toPreorder.{0} Nat (StrictOrderedSemiring.toPartialOrder.{0} Nat Nat.strictOrderedSemiring)) instLocallyFiniteOrderNatToPreorderToPartialOrderStrictOrderedSemiring k (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) k n)))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Nat.totient a) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.instDivNat) n a) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))
+Case conversion may be inaccurate. Consider using '#align nat.Ico_filter_coprime_le Nat.Ico_filter_coprime_leₓ'. -/
theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
((Ico k (k + n)).filterₓ (coprime a)).card ≤ totient a * (n / a + 1) :=
by
@@ -117,6 +149,12 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
open ZMod
+/- warning: zmod.card_units_eq_totient -> ZMod.card_units_eq_totient is a dubious translation:
+lean 3 declaration is
+ forall (n : Nat) [_inst_1 : NeZero.{0} Nat Nat.hasZero n] [_inst_2 : Fintype.{0} (Units.{0} (ZMod n) (Ring.toMonoid.{0} (ZMod n) (CommRing.toRing.{0} (ZMod n) (ZMod.commRing n))))], Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod n) (Ring.toMonoid.{0} (ZMod n) (CommRing.toRing.{0} (ZMod n) (ZMod.commRing n)))) _inst_2) (Nat.totient n)
+but is expected to have type
+ forall (n : Nat) [_inst_1 : NeZero.{0} Nat (LinearOrderedCommMonoidWithZero.toZero.{0} Nat Nat.linearOrderedCommMonoidWithZero) n] [_inst_2 : Fintype.{0} (Units.{0} (ZMod n) (MonoidWithZero.toMonoid.{0} (ZMod n) (Semiring.toMonoidWithZero.{0} (ZMod n) (Ring.toSemiring.{0} (ZMod n) (CommRing.toRing.{0} (ZMod n) (ZMod.commRing n))))))], Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod n) (MonoidWithZero.toMonoid.{0} (ZMod n) (Semiring.toMonoidWithZero.{0} (ZMod n) (Ring.toSemiring.{0} (ZMod n) (CommRing.toRing.{0} (ZMod n) (ZMod.commRing n)))))) _inst_2) (Nat.totient n)
+Case conversion may be inaccurate. Consider using '#align zmod.card_units_eq_totient ZMod.card_units_eq_totientₓ'. -/
/-- Note this takes an explicit `fintype ((zmod n)ˣ)` argument to avoid trouble with instance
diamonds. -/
@[simp]
@@ -133,6 +171,7 @@ theorem ZMod.card_units_eq_totient (n : ℕ) [NeZero n] [Fintype (ZMod n)ˣ] :
#align zmod.card_units_eq_totient ZMod.card_units_eq_totient
+#print Nat.totient_even /-
theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient :=
by
haveI : Fact (1 < n) := ⟨one_lt_two.trans hn⟩
@@ -143,7 +182,9 @@ theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient :=
exact orderOf_dvd_card_univ
rw [← orderOf_units, Units.coe_neg_one, orderOf_neg_one, ringChar.eq (ZMod n) n, if_neg hn.ne']
#align nat.totient_even Nat.totient_even
+-/
+#print Nat.totient_mul /-
theorem totient_mul {m n : ℕ} (h : m.coprime n) : φ (m * n) = φ m * φ n :=
if hmn0 : m * n = 0 then by
cases' Nat.mul_eq_zero.1 hmn0 with h h <;>
@@ -156,7 +197,14 @@ theorem totient_mul {m n : ℕ} (h : m.coprime n) : φ (m * n) = φ m * φ n :=
rw [Fintype.card_congr (Units.mapEquiv (ZMod.chineseRemainder h).toMulEquiv).toEquiv,
Fintype.card_congr (@MulEquiv.prodUnits (ZMod m) (ZMod n) _ _).toEquiv, Fintype.card_prod]
#align nat.totient_mul Nat.totient_mul
+-/
+/- warning: nat.totient_div_of_dvd -> Nat.totient_div_of_dvd is a dubious translation:
+lean 3 declaration is
+ forall {n : Nat} {d : Nat}, (Dvd.Dvd.{0} Nat Nat.hasDvd d n) -> (Eq.{1} Nat (Nat.totient (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.hasDiv) n d)) (Finset.card.{0} Nat (Finset.filter.{0} Nat (fun (k : Nat) => Eq.{1} Nat (Nat.gcd n k) d) (fun (a : Nat) => Nat.decidableEq (Nat.gcd n a) d) (Finset.range n))))
+but is expected to have type
+ forall {n : Nat} {d : Nat}, (Dvd.dvd.{0} Nat Nat.instDvdNat d n) -> (Eq.{1} Nat (Nat.totient (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.instDivNat) n d)) (Finset.card.{0} Nat (Finset.filter.{0} Nat (fun (k : Nat) => Eq.{1} Nat (Nat.gcd n k) d) (fun (a : Nat) => instDecidableEqNat (Nat.gcd n a) d) (Finset.range n))))
+Case conversion may be inaccurate. Consider using '#align nat.totient_div_of_dvd Nat.totient_div_of_dvdₓ'. -/
/-- For `d ∣ n`, the totient of `n/d` equals the number of values `k < n` such that `gcd n k = d` -/
theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
φ (n / d) = (filter (fun k : ℕ => n.gcd k = d) (range n)).card :=
@@ -179,6 +227,7 @@ theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
rwa [gcd_mul_left, mul_right_eq_self_iff hd0] at hb2
#align nat.totient_div_of_dvd Nat.totient_div_of_dvd
+#print Nat.sum_totient /-
theorem sum_totient (n : ℕ) : n.divisors.Sum φ = n :=
by
rcases n.eq_zero_or_pos with (rfl | hn)
@@ -192,7 +241,14 @@ theorem sum_totient (n : ℕ) : n.divisors.Sum φ = n :=
nth_rw_rhs 1 [this]
exact sum_congr rfl fun x hx => totient_div_of_dvd (dvd_of_mem_divisors hx)
#align nat.sum_totient Nat.sum_totient
+-/
+/- warning: nat.sum_totient' -> Nat.sum_totient' is a dubious translation:
+lean 3 declaration is
+ forall (n : Nat), Eq.{1} Nat (Finset.sum.{0, 0} Nat Nat Nat.addCommMonoid (Finset.filter.{0} Nat (fun (_x : Nat) => Dvd.Dvd.{0} Nat Nat.hasDvd _x n) (fun (a : Nat) => Nat.decidableDvd a n) (Finset.range (Nat.succ n))) (fun (m : Nat) => Nat.totient m)) n
+but is expected to have type
+ forall (n : Nat), Eq.{1} Nat (Finset.sum.{0, 0} Nat Nat Nat.addCommMonoid (Finset.filter.{0} Nat (fun (_x : Nat) => Dvd.dvd.{0} Nat Nat.instDvdNat _x n) (fun (a : Nat) => Nat.decidable_dvd a n) (Finset.range (Nat.succ n))) (fun (m : Nat) => Nat.totient m)) n
+Case conversion may be inaccurate. Consider using '#align nat.sum_totient' Nat.sum_totient'ₓ'. -/
theorem sum_totient' (n : ℕ) : (∑ m in (range n.succ).filterₓ (· ∣ n), φ m) = n :=
by
convert sum_totient _ using 1
@@ -200,6 +256,7 @@ theorem sum_totient' (n : ℕ) : (∑ m in (range n.succ).filterₓ (· ∣ n),
rw [sum_eq_sum_Ico_succ_bot] <;> simp
#align nat.sum_totient' Nat.sum_totient'
+#print Nat.totient_prime_pow_succ /-
/-- When `p` is prime, then the totient of `p ^ (n + 1)` is `p ^ n * (p - 1)` -/
theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n + 1)) = p ^ n * (p - 1) :=
calc
@@ -231,18 +288,24 @@ theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n +
one_mul (p ^ n), pow_succ, ← tsub_mul, one_mul, mul_comm]
#align nat.totient_prime_pow_succ Nat.totient_prime_pow_succ
+-/
+#print Nat.totient_prime_pow /-
/-- When `p` is prime, then the totient of `p ^ n` is `p ^ (n - 1) * (p - 1)` -/
theorem totient_prime_pow {p : ℕ} (hp : p.Prime) {n : ℕ} (hn : 0 < n) :
φ (p ^ n) = p ^ (n - 1) * (p - 1) := by
rcases exists_eq_succ_of_ne_zero (pos_iff_ne_zero.1 hn) with ⟨m, rfl⟩ <;>
exact totient_prime_pow_succ hp _
#align nat.totient_prime_pow Nat.totient_prime_pow
+-/
+#print Nat.totient_prime /-
theorem totient_prime {p : ℕ} (hp : p.Prime) : φ p = p - 1 := by
rw [← pow_one p, totient_prime_pow hp] <;> simp
#align nat.totient_prime Nat.totient_prime
+-/
+#print Nat.totient_eq_iff_prime /-
theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Prime :=
by
refine' ⟨fun h => _, totient_prime⟩
@@ -258,7 +321,14 @@ theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Pr
p.prime_of_coprime hp fun n hn hnz => Finset.filter_card_eq h n <| finset.mem_Ico.mpr ⟨_, hn⟩
rwa [succ_le_iff, pos_iff_ne_zero]
#align nat.totient_eq_iff_prime Nat.totient_eq_iff_prime
+-/
+/- warning: nat.card_units_zmod_lt_sub_one -> Nat.card_units_zMod_lt_sub_one is a dubious translation:
+lean 3 declaration is
+ forall {p : Nat}, (LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))) p) -> (forall [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))], LE.le.{0} Nat Nat.hasLe (Fintype.card.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) p (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))))
+but is expected to have type
+ forall {p : Nat}, (LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)) p) -> (forall [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (Ring.toSemiring.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))))], LE.le.{0} Nat instLENat (Fintype.card.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (Ring.toSemiring.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
+Case conversion may be inaccurate. Consider using '#align nat.card_units_zmod_lt_sub_one Nat.card_units_zMod_lt_sub_oneₓ'. -/
theorem card_units_zMod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
Fintype.card (ZMod p)ˣ ≤ p - 1 :=
by
@@ -267,6 +337,12 @@ theorem card_units_zMod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
exact Nat.le_pred_of_lt (Nat.totient_lt p hp)
#align nat.card_units_zmod_lt_sub_one Nat.card_units_zMod_lt_sub_one
+/- warning: nat.prime_iff_card_units -> Nat.prime_iff_card_units is a dubious translation:
+lean 3 declaration is
+ forall (p : Nat) [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))], Iff (Nat.Prime p) (Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod p) (Ring.toMonoid.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) p (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))))
+but is expected to have type
+ forall (p : Nat) [_inst_1 : Fintype.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (Ring.toSemiring.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p))))))], Iff (Nat.Prime p) (Eq.{1} Nat (Fintype.card.{0} (Units.{0} (ZMod p) (MonoidWithZero.toMonoid.{0} (ZMod p) (Semiring.toMonoidWithZero.{0} (ZMod p) (Ring.toSemiring.{0} (ZMod p) (CommRing.toRing.{0} (ZMod p) (ZMod.commRing p)))))) _inst_1) (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
+Case conversion may be inaccurate. Consider using '#align nat.prime_iff_card_units Nat.prime_iff_card_unitsₓ'. -/
theorem prime_iff_card_units (p : ℕ) [Fintype (ZMod p)ˣ] :
p.Prime ↔ Fintype.card (ZMod p)ˣ = p - 1 :=
by
@@ -279,11 +355,14 @@ theorem prime_iff_card_units (p : ℕ) [Fintype (ZMod p)ˣ] :
rw [ZMod.card_units_eq_totient, Nat.totient_eq_iff_prime <| NeZero.pos p]
#align nat.prime_iff_card_units Nat.prime_iff_card_units
+#print Nat.totient_two /-
@[simp]
theorem totient_two : φ 2 = 1 :=
(totient_prime prime_two).trans rfl
#align nat.totient_two Nat.totient_two
+-/
+#print Nat.totient_eq_one_iff /-
theorem totient_eq_one_iff : ∀ {n : ℕ}, n.totient = 1 ↔ n = 1 ∨ n = 2
| 0 => by simp
| 1 => by simp
@@ -293,12 +372,14 @@ theorem totient_eq_one_iff : ∀ {n : ℕ}, n.totient = 1 ↔ n = 1 ∨ n = 2
simp only [succ_succ_ne_one, false_or_iff]
exact ⟨fun h => not_even_one.elim <| h ▸ totient_even this, by rintro ⟨⟩⟩
#align nat.totient_eq_one_iff Nat.totient_eq_one_iff
+-/
/-! ### Euler's product formula for the totient function
We prove several different statements of this formula. -/
+#print Nat.totient_eq_prod_factorization /-
/-- Euler's product formula for the totient function. -/
theorem totient_eq_prod_factorization {n : ℕ} (hn : n ≠ 0) :
φ n = n.factorization.Prod fun p k => p ^ (k - 1) * (p - 1) :=
@@ -308,7 +389,14 @@ theorem totient_eq_prod_factorization {n : ℕ} (hn : n ≠ 0) :
have h := zero_lt_iff.mpr (finsupp.mem_support_iff.mp hp)
rw [totient_prime_pow (prime_of_mem_factorization hp) h]
#align nat.totient_eq_prod_factorization Nat.totient_eq_prod_factorization
+-/
+/- warning: nat.totient_mul_prod_factors -> Nat.totient_mul_prod_factors is a dubious translation:
+lean 3 declaration is
+ forall (n : Nat), Eq.{1} Nat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Nat.totient n) (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => Nat.decidableEq a b) (Nat.factors n)) (fun (p : Nat) => p))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) n (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => Nat.decidableEq a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) p (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))))
+but is expected to have type
+ forall (n : Nat), Eq.{1} Nat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Nat.totient n) (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => p))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) n (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))
+Case conversion may be inaccurate. Consider using '#align nat.totient_mul_prod_factors Nat.totient_mul_prod_factorsₓ'. -/
/-- Euler's product formula for the totient function. -/
theorem totient_mul_prod_factors (n : ℕ) :
(φ n * ∏ p in n.factors.toFinset, p) = n * ∏ p in n.factors.toFinset, p - 1 :=
@@ -322,6 +410,12 @@ theorem totient_mul_prod_factors (n : ℕ) :
rw [mul_comm, ← mul_assoc, ← pow_succ, Nat.sub_add_cancel hp]
#align nat.totient_mul_prod_factors Nat.totient_mul_prod_factors
+/- warning: nat.totient_eq_div_factors_mul -> Nat.totient_eq_div_factors_mul is a dubious translation:
+lean 3 declaration is
+ forall (n : Nat), Eq.{1} Nat (Nat.totient n) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.hasDiv) n (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => Nat.decidableEq a b) (Nat.factors n)) (fun (p : Nat) => p))) (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => Nat.decidableEq a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) p (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))))
+but is expected to have type
+ forall (n : Nat), Eq.{1} Nat (Nat.totient n) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.instDivNat) n (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => p))) (Finset.prod.{0, 0} Nat Nat Nat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) p (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))
+Case conversion may be inaccurate. Consider using '#align nat.totient_eq_div_factors_mul Nat.totient_eq_div_factors_mulₓ'. -/
/-- Euler's product formula for the totient function. -/
theorem totient_eq_div_factors_mul (n : ℕ) :
φ n = (n / ∏ p in n.factors.toFinset, p) * ∏ p in n.factors.toFinset, p - 1 :=
@@ -331,6 +425,12 @@ theorem totient_eq_div_factors_mul (n : ℕ) :
simpa [prod_factorization_eq_prod_factors] using prod_pos fun p => pos_of_mem_factorization
#align nat.totient_eq_div_factors_mul Nat.totient_eq_div_factors_mul
+/- warning: nat.totient_eq_mul_prod_factors -> Nat.totient_eq_mul_prod_factors is a dubious translation:
+lean 3 declaration is
+ forall (n : Nat), Eq.{1} Rat ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.totient n)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.hasMul) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) n) (Finset.prod.{0, 0} Rat Nat Rat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => Nat.decidableEq a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Rat Rat Rat (instHSub.{0} Rat (SubNegMonoid.toHasSub.{0} Rat (AddGroup.toSubNegMonoid.{0} Rat Rat.addGroup))) (OfNat.ofNat.{0} Rat 1 (OfNat.mk.{0} Rat 1 (One.one.{0} Rat Rat.hasOne))) (Inv.inv.{0} Rat Rat.hasInv ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) p)))))
+but is expected to have type
+ forall (n : Nat), Eq.{1} Rat (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.totient n)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) n) (Finset.prod.{0, 0} Rat Nat Rat.commMonoid (List.toFinset.{0} Nat (fun (a : Nat) (b : Nat) => instDecidableEqNat a b) (Nat.factors n)) (fun (p : Nat) => HSub.hSub.{0, 0, 0} Rat Rat Rat (instHSub.{0} Rat Rat.instSubRat) (OfNat.ofNat.{0} Rat 1 (Rat.instOfNatRat 1)) (Inv.inv.{0} Rat Rat.instInvRat (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) p)))))
+Case conversion may be inaccurate. Consider using '#align nat.totient_eq_mul_prod_factors Nat.totient_eq_mul_prod_factorsₓ'. -/
/-- Euler's product formula for the totient function. -/
theorem totient_eq_mul_prod_factors (n : ℕ) : (φ n : ℚ) = n * ∏ p in n.factors.toFinset, 1 - p⁻¹ :=
by
@@ -349,6 +449,7 @@ theorem totient_eq_mul_prod_factors (n : ℕ) : (φ n : ℚ) = n * ∏ p in n.fa
rw [sub_mul, one_mul, mul_comm, mul_inv_cancel hp', cast_pred hp]
#align nat.totient_eq_mul_prod_factors Nat.totient_eq_mul_prod_factors
+#print Nat.totient_gcd_mul_totient_mul /-
theorem totient_gcd_mul_totient_mul (a b : ℕ) : φ (a.gcd b) * φ (a * b) = φ a * φ b * a.gcd b :=
by
have shuffle :
@@ -370,7 +471,9 @@ theorem totient_gcd_mul_totient_mul (a b : ℕ) : φ (a.gcd b) * φ (a * b) = φ
rw [eq_comm, mul_comm, ← mul_assoc, ← Nat.mul_div_assoc]
exact mul_dvd_mul (prod_prime_factors_dvd a) (prod_prime_factors_dvd b)
#align nat.totient_gcd_mul_totient_mul Nat.totient_gcd_mul_totient_mul
+-/
+#print Nat.totient_super_multiplicative /-
theorem totient_super_multiplicative (a b : ℕ) : φ a * φ b ≤ φ (a * b) :=
by
let d := a.gcd b
@@ -380,7 +483,9 @@ theorem totient_super_multiplicative (a b : ℕ) : φ a * φ b ≤ φ (a * b) :=
rw [← mul_le_mul_right hd0, ← totient_gcd_mul_totient_mul a b, mul_comm]
apply mul_le_mul_left' (Nat.totient_le d)
#align nat.totient_super_multiplicative Nat.totient_super_multiplicative
+-/
+#print Nat.totient_dvd_of_dvd /-
theorem totient_dvd_of_dvd {a b : ℕ} (h : a ∣ b) : φ a ∣ φ b :=
by
rcases eq_or_ne a 0 with (rfl | ha0)
@@ -396,7 +501,9 @@ theorem totient_dvd_of_dvd {a b : ℕ} (h : a ∣ b) : φ a ∣ φ b :=
refine' Finsupp.prod_dvd_prod_of_subset_of_dvd hab' fun p hp => mul_dvd_mul _ dvd_rfl
exact pow_dvd_pow p (tsub_le_tsub_right ((factorization_le_iff_dvd ha0 hb0).2 h p) 1)
#align nat.totient_dvd_of_dvd Nat.totient_dvd_of_dvd
+-/
+#print Nat.totient_mul_of_prime_of_dvd /-
theorem totient_mul_of_prime_of_dvd {p n : ℕ} (hp : p.Prime) (h : p ∣ n) :
(p * n).totient = p * n.totient :=
by
@@ -404,13 +511,16 @@ theorem totient_mul_of_prime_of_dvd {p n : ℕ} (hp : p.Prime) (h : p ∣ n) :
rw [gcd_eq_left h, mul_assoc] at h1
simpa [(totient_pos hp.pos).ne', mul_comm] using h1
#align nat.totient_mul_of_prime_of_dvd Nat.totient_mul_of_prime_of_dvd
+-/
+#print Nat.totient_mul_of_prime_of_not_dvd /-
theorem totient_mul_of_prime_of_not_dvd {p n : ℕ} (hp : p.Prime) (h : ¬p ∣ n) :
(p * n).totient = (p - 1) * n.totient :=
by
rw [totient_mul _, totient_prime hp]
simpa [h] using coprime_or_dvd_of_prime hp n
#align nat.totient_mul_of_prime_of_not_dvd Nat.totient_mul_of_prime_of_not_dvd
+-/
end Nat
mathlib commit https://github.com/leanprover-community/mathlib/commit/3180fab693e2cee3bff62675571264cb8778b212
@@ -90,7 +90,7 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
conv_lhs => rw [← Nat.mod_add_div n a]
induction' n / a with i ih
· rw [← filter_coprime_Ico_eq_totient a k]
- simp only [add_zero, mul_one, mul_zero, le_of_lt (mod_lt n a_pos)]
+ simp only [add_zero, mul_one, MulZeroClass.mul_zero, le_of_lt (mod_lt n a_pos)]
mono
refine' monotone_filter_left a.coprime _
simp only [Finset.le_eq_subset]
@@ -146,7 +146,8 @@ theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient :=
theorem totient_mul {m n : ℕ} (h : m.coprime n) : φ (m * n) = φ m * φ n :=
if hmn0 : m * n = 0 then by
- cases' Nat.mul_eq_zero.1 hmn0 with h h <;> simp only [totient_zero, mul_zero, zero_mul, h]
+ cases' Nat.mul_eq_zero.1 hmn0 with h h <;>
+ simp only [totient_zero, MulZeroClass.mul_zero, MulZeroClass.zero_mul, h]
else by
haveI : NeZero (m * n) := ⟨hmn0⟩
haveI : NeZero m := ⟨left_ne_zero_of_mul hmn0⟩
mathlib commit https://github.com/leanprover-community/mathlib/commit/4c586d291f189eecb9d00581aeb3dd998ac34442
@@ -205,7 +205,7 @@ theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n +
φ (p ^ (n + 1)) = ((range (p ^ (n + 1))).filterₓ (coprime (p ^ (n + 1)))).card :=
totient_eq_card_coprime _
_ = (range (p ^ (n + 1)) \ (range (p ^ n)).image (· * p)).card :=
- congr_arg card
+ (congr_arg card
(by
rw [sdiff_eq_filter]
apply filter_congr
@@ -217,7 +217,7 @@ theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n +
exact hap (dvd_mul_left _ _)
· rintro h ⟨b, rfl⟩
rw [pow_succ] at ha
- exact h b (lt_of_mul_lt_mul_left ha (zero_le _)) (mul_comm _ _))
+ exact h b (lt_of_mul_lt_mul_left ha (zero_le _)) (mul_comm _ _)))
_ = _ := by
have h1 : Function.Injective (· * p) := mul_left_injective₀ hp.NeZero
have h2 : (range (p ^ n)).image (· * p) ⊆ range (p ^ (n + 1)) := fun a =>
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
@@ -100,8 +100,8 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
(Ico k (k + n % a + a * i) ∪ Ico (k + n % a + a * i) (k + n % a + a * i + a))).card := by
congr
rw [Ico_union_Ico_eq_Ico]
- rw [add_assoc]
- exact le_self_add
+ · rw [add_assoc]
+ exact le_self_add
exact le_self_add
_ ≤ (filter a.Coprime (Ico k (k + n % a + a * i))).card + a.totient := by
rw [filter_union, ← filter_coprime_Ico_eq_totient a (k + n % a + a * i)]
We add IsPrimitiveRoot.exists_pow_or_neg_mul_pow_of_isOfFinOrder
: If x
is a root of unity (spelled as IsOfFinOrder x
) in an n
-th cyclotomic extension of ℚ
, where n
is odd, and ζ
is a primitive n
-th root of unity, then there exists r < n
such that x = ζ^r
or x = -ζ^r
.
From flt-regular
@@ -276,6 +276,9 @@ theorem totient_eq_one_iff : ∀ {n : ℕ}, n.totient = 1 ↔ n = 1 ∨ n = 2
exact ⟨fun h => not_even_one.elim <| h ▸ totient_even this, by rintro ⟨⟩⟩
#align nat.totient_eq_one_iff Nat.totient_eq_one_iff
+theorem dvd_two_of_totient_le_one {a : ℕ} (han : 0 < a) (ha : a.totient ≤ 1) : a ∣ 2 := by
+ rcases totient_eq_one_iff.mp <| le_antisymm ha <| totient_pos han with rfl | rfl <;> norm_num
+
/-! ### Euler's product formula for the totient function
We prove several different statements of this formula. -/
This is a very large PR, but it has been reviewed piecemeal already in PRs to the bump/v4.7.0
branch as we update to intermediate nightlies.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Kyle Miller <kmill31415@gmail.com> Co-authored-by: damiano <adomani@gmail.com>
@@ -211,7 +211,7 @@ theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n +
have h2 : (range (p ^ n)).image (· * p) ⊆ range (p ^ (n + 1)) := fun a => by
simp only [mem_image, mem_range, exists_imp]
rintro b ⟨h, rfl⟩
- rw [pow_succ]
+ rw [Nat.pow_succ]
exact (mul_lt_mul_right hp.pos).2 h
rw [card_sdiff h2, Finset.card_image_of_injective _ h1, card_range, card_range, ←
one_mul (p ^ n), pow_succ', ← tsub_mul, one_mul, mul_comm]
Homogenises porting notes via capitalisation and addition of whitespace.
It makes the following changes:
@@ -88,7 +88,7 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
· rw [← filter_coprime_Ico_eq_totient a k]
simp only [add_zero, mul_one, mul_zero, le_of_lt (mod_lt n a_pos),
Nat.zero_eq, zero_add]
- --Porting note: below line was `mono`
+ -- Porting note: below line was `mono`
refine Finset.card_mono ?_
refine' monotone_filter_left a.Coprime _
simp only [Finset.le_eq_subset]
have
, replace
and suffices
(#10640)
No changes to tactic file, it's just boring fixes throughout the library.
This follows on from #6964.
Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
@@ -230,8 +230,8 @@ theorem totient_prime {p : ℕ} (hp : p.Prime) : φ p = p - 1 := by
theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Prime := by
refine' ⟨fun h => _, totient_prime⟩
- replace hp : 1 < p
- · apply lt_of_le_of_ne
+ replace hp : 1 < p := by
+ apply lt_of_le_of_ne
· rwa [succ_le_iff]
· rintro rfl
rw [totient_one, tsub_self] at h
@@ -213,7 +213,7 @@ theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n +
rintro b ⟨h, rfl⟩
rw [pow_succ]
exact (mul_lt_mul_right hp.pos).2 h
- rw [card_sdiff h2, card_image_of_injOn (h1.injOn _), card_range, card_range, ←
+ rw [card_sdiff h2, Finset.card_image_of_injective _ h1, card_range, card_range, ←
one_mul (p ^ n), pow_succ', ← tsub_mul, one_mul, mul_comm]
#align nat.totient_prime_pow_succ Nat.totient_prime_pow_succ
The cardinality of a subgroup is greater than the order of any of its elements.
Rename
order_eq_card_zpowers
→ Fintype.card_zpowers
order_eq_card_zpowers'
→ Nat.card_zpowers
(and turn it around to match Nat.card_subgroupPowers
)Submonoid.powers_subset
→ Submonoid.powers_le
orderOf_dvd_card_univ
→ orderOf_dvd_card
orderOf_subgroup
→ Subgroup.orderOf
Subgroup.nonempty
→ Subgroup.coe_nonempty
@@ -131,7 +131,7 @@ theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient := by
haveI : NeZero n := NeZero.of_gt hn
suffices 2 = orderOf (-1 : (ZMod n)ˣ) by
rw [← ZMod.card_units_eq_totient, even_iff_two_dvd, this]
- exact orderOf_dvd_card_univ
+ exact orderOf_dvd_card
rw [← orderOf_units, Units.coe_neg_one, orderOf_neg_one, ringChar.eq (ZMod n) n, if_neg hn.ne']
#align nat.totient_even Nat.totient_even
Nat.card
is zero (#8202)
and lemmas about injectivity/surjectivity of PLift.map
/ULift.map
.
@@ -70,7 +70,9 @@ theorem totient_lt (n : ℕ) (hn : 1 < n) : φ n < n :=
theorem totient_pos : ∀ {n : ℕ}, 0 < n → 0 < φ n
| 0 => by decide
| 1 => by simp [totient]
- | n + 2 => fun _ => card_pos.2 ⟨1, mem_filter.2 ⟨mem_range.2 (by simp), coprime_one_right _⟩⟩
+ | n + 2 => fun _ =>
+ -- Must qualify `Finset.card_pos` because of leanprover/lean4#2849
+ Finset.card_pos.2 ⟨1, mem_filter.2 ⟨mem_range.2 (by simp), coprime_one_right _⟩⟩
#align nat.totient_pos Nat.totient_pos
theorem filter_coprime_Ico_eq_totient (a n : ℕ) :
mathlib can't make up its mind on whether to spell "the prime factors of n
" as n.factors.toFinset
or n.factorization.support
, even though those two are defeq. This PR proposes to unify everything to a new definition Nat.primeFactors
, and streamline the existing scattered API about n.factors.toFinset
and n.factorization.support
to Nat.primeFactors
. We also get to write a bit more API that didn't make sense before, eg primeFactors_mono
.
@@ -286,40 +286,39 @@ theorem totient_eq_prod_factorization {n : ℕ} (hn : n ≠ 0) :
apply Finsupp.prod_congr _
intro p hp
have h := zero_lt_iff.mpr (Finsupp.mem_support_iff.mp hp)
- rw [totient_prime_pow (prime_of_mem_factorization hp) h]
+ rw [totient_prime_pow (prime_of_mem_primeFactors hp) h]
#align nat.totient_eq_prod_factorization Nat.totient_eq_prod_factorization
/-- Euler's product formula for the totient function. -/
-theorem totient_mul_prod_factors (n : ℕ) :
- (φ n * ∏ p in n.factors.toFinset, p) = n * ∏ p in n.factors.toFinset, (p - 1) := by
+theorem totient_mul_prod_primeFactors (n : ℕ) :
+ (φ n * ∏ p in n.primeFactors, p) = n * ∏ p in n.primeFactors, (p - 1) := by
by_cases hn : n = 0; · simp [hn]
rw [totient_eq_prod_factorization hn]
nth_rw 3 [← factorization_prod_pow_eq_self hn]
- simp only [← prod_factorization_eq_prod_factors, ← Finsupp.prod_mul]
+ simp only [prod_primeFactors_prod_factorization, ← Finsupp.prod_mul]
refine' Finsupp.prod_congr (M := ℕ) (N := ℕ) fun p hp => _
rw [Finsupp.mem_support_iff, ← zero_lt_iff] at hp
rw [mul_comm, ← mul_assoc, ← pow_succ', Nat.sub_one, Nat.succ_pred_eq_of_pos hp]
-#align nat.totient_mul_prod_factors Nat.totient_mul_prod_factors
+#align nat.totient_mul_prod_factors Nat.totient_mul_prod_primeFactors
/-- Euler's product formula for the totient function. -/
-theorem totient_eq_div_factors_mul (n : ℕ) :
- φ n = (n / ∏ p in n.factors.toFinset, p) * ∏ p in n.factors.toFinset, (p - 1) := by
- rw [← mul_div_left n.totient, totient_mul_prod_factors, mul_comm,
- Nat.mul_div_assoc _ (prod_prime_factors_dvd n), mul_comm]
- have := prod_pos (fun p => pos_of_mem_factorization (n := n))
- simpa [prod_factorization_eq_prod_factors] using this
-#align nat.totient_eq_div_factors_mul Nat.totient_eq_div_factors_mul
+theorem totient_eq_div_primeFactors_mul (n : ℕ) :
+ φ n = (n / ∏ p in n.primeFactors, p) * ∏ p in n.primeFactors, (p - 1) := by
+ rw [← mul_div_left n.totient, totient_mul_prod_primeFactors, mul_comm,
+ Nat.mul_div_assoc _ (prod_primeFactors_dvd n), mul_comm]
+ exact prod_pos (fun p => pos_of_mem_primeFactors)
+#align nat.totient_eq_div_factors_mul Nat.totient_eq_div_primeFactors_mul
/-- Euler's product formula for the totient function. -/
theorem totient_eq_mul_prod_factors (n : ℕ) :
- (φ n : ℚ) = n * ∏ p in n.factors.toFinset, (1 - (p : ℚ)⁻¹) := by
+ (φ n : ℚ) = n * ∏ p in n.primeFactors, (1 - (p : ℚ)⁻¹) := by
by_cases hn : n = 0
· simp [hn]
have hn' : (n : ℚ) ≠ 0 := by simp [hn]
- have hpQ : (∏ p in n.factors.toFinset, (p : ℚ)) ≠ 0 := by
- rw [← cast_prod, cast_ne_zero, ← zero_lt_iff, ← prod_factorization_eq_prod_factors]
- exact prod_pos fun p hp => pos_of_mem_factorization hp
- simp only [totient_eq_div_factors_mul n, prod_prime_factors_dvd n, cast_mul, cast_prod,
+ have hpQ : (∏ p in n.primeFactors, (p : ℚ)) ≠ 0 := by
+ rw [← cast_prod, cast_ne_zero, ← zero_lt_iff, prod_primeFactors_prod_factorization]
+ exact prod_pos fun p hp => pos_of_mem_primeFactors hp
+ simp only [totient_eq_div_primeFactors_mul n, prod_primeFactors_dvd n, cast_mul, cast_prod,
cast_div_charZero, mul_comm_div, mul_right_inj' hn', div_eq_iff hpQ, ← prod_mul_distrib]
refine' prod_congr rfl fun p hp => _
have hp := pos_of_mem_factors (List.mem_toFinset.mp hp)
@@ -337,13 +336,13 @@ theorem totient_gcd_mul_totient_mul (a b : ℕ) : φ (a.gcd b) * φ (a * b) = φ
_ = a1 * a2 / (b1 * b2) * (c1 * c2) := by
congr 1
exact div_mul_div_comm h1 h2
- simp only [totient_eq_div_factors_mul]
+ simp only [totient_eq_div_primeFactors_mul]
rw [shuffle, shuffle]
rotate_left
- repeat' apply prod_prime_factors_dvd
- · simp only [prod_factors_gcd_mul_prod_factors_mul]
+ repeat' apply prod_primeFactors_dvd
+ · simp only [prod_primeFactors_gcd_mul_prod_primeFactors_mul]
rw [eq_comm, mul_comm, ← mul_assoc, ← Nat.mul_div_assoc]
- exact mul_dvd_mul (prod_prime_factors_dvd a) (prod_prime_factors_dvd b)
+ exact mul_dvd_mul (prod_primeFactors_dvd a) (prod_primeFactors_dvd b)
#align nat.totient_gcd_mul_totient_mul Nat.totient_gcd_mul_totient_mul
theorem totient_super_multiplicative (a b : ℕ) : φ a * φ b ≤ φ (a * b) := by
@@ -361,10 +360,7 @@ theorem totient_dvd_of_dvd {a b : ℕ} (h : a ∣ b) : φ a ∣ φ b := by
· simp [zero_dvd_iff.1 h]
rcases eq_or_ne b 0 with (rfl | hb0)
· simp
- have hab' : a.factorization.support ⊆ b.factorization.support := by
- intro p
- simp only [support_factorization, List.mem_toFinset]
- apply factors_subset_of_dvd h hb0
+ have hab' := primeFactors_mono h hb0
rw [totient_eq_prod_factorization ha0, totient_eq_prod_factorization hb0]
refine' Finsupp.prod_dvd_prod_of_subset_of_dvd hab' fun p _ => mul_dvd_mul _ dvd_rfl
exact pow_dvd_pow p (tsub_le_tsub_right ((factorization_le_iff_dvd ha0 hb0).2 h p) 1)
@@ -245,7 +245,7 @@ theorem card_units_zmod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
Fintype.card (ZMod p)ˣ ≤ p - 1 := by
haveI : NeZero p := ⟨(pos_of_gt hp).ne'⟩
rw [ZMod.card_units_eq_totient p]
- exact Nat.le_pred_of_lt (Nat.totient_lt p hp)
+ exact Nat.le_sub_one_of_lt (Nat.totient_lt p hp)
#align nat.card_units_zmod_lt_sub_one Nat.card_units_zmod_lt_sub_one
theorem prime_iff_card_units (p : ℕ) [Fintype (ZMod p)ˣ] :
rcases
, convert
and congrm
(#7725)
Replace rcases(
with rcases (
. Same thing for convert(
and congrm(
. No other change.
@@ -348,7 +348,7 @@ theorem totient_gcd_mul_totient_mul (a b : ℕ) : φ (a.gcd b) * φ (a * b) = φ
theorem totient_super_multiplicative (a b : ℕ) : φ a * φ b ≤ φ (a * b) := by
let d := a.gcd b
- rcases(zero_le a).eq_or_lt with (rfl | ha0)
+ rcases (zero_le a).eq_or_lt with (rfl | ha0)
· simp
have hd0 : 0 < d := Nat.gcd_pos_of_pos_left _ ha0
apply le_of_mul_le_mul_right _ hd0
@@ -30,7 +30,7 @@ namespace Nat
/-- Euler's totient function. This counts the number of naturals strictly less than `n` which are
coprime with `n`. -/
def totient (n : ℕ) : ℕ :=
- ((range n).filter n.coprime).card
+ ((range n).filter n.Coprime).card
#align nat.totient Nat.totient
@[inherit_doc]
@@ -45,13 +45,13 @@ theorem totient_zero : φ 0 = 0 :=
theorem totient_one : φ 1 = 1 := by simp [totient]
#align nat.totient_one Nat.totient_one
-theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filter n.coprime).card :=
+theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filter n.Coprime).card :=
rfl
#align nat.totient_eq_card_coprime Nat.totient_eq_card_coprime
/-- A characterisation of `Nat.totient` that avoids `Finset`. -/
-theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card { m | m < n ∧ n.coprime m } := by
- let e : { m | m < n ∧ n.coprime m } ≃ Finset.filter n.coprime (Finset.range n) :=
+theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card { m | m < n ∧ n.Coprime m } := by
+ let e : { m | m < n ∧ n.Coprime m } ≃ Finset.filter n.Coprime (Finset.range n) :=
{ toFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using m.property⟩
invFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using m.property⟩
left_inv := fun m => by simp only [Subtype.coe_mk, Subtype.coe_eta]
@@ -74,13 +74,13 @@ theorem totient_pos : ∀ {n : ℕ}, 0 < n → 0 < φ n
#align nat.totient_pos Nat.totient_pos
theorem filter_coprime_Ico_eq_totient (a n : ℕ) :
- ((Ico n (n + a)).filter (coprime a)).card = totient a := by
+ ((Ico n (n + a)).filter (Coprime a)).card = totient a := by
rw [totient, filter_Ico_card_eq_of_periodic, count_eq_card_filter_range]
exact periodic_coprime a
#align nat.filter_coprime_Ico_eq_totient Nat.filter_coprime_Ico_eq_totient
theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
- ((Ico k (k + n)).filter (coprime a)).card ≤ totient a * (n / a + 1) := by
+ ((Ico k (k + n)).filter (Coprime a)).card ≤ totient a * (n / a + 1) := by
conv_lhs => rw [← Nat.mod_add_div n a]
induction' n / a with i ih
· rw [← filter_coprime_Ico_eq_totient a k]
@@ -88,20 +88,20 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
Nat.zero_eq, zero_add]
--Porting note: below line was `mono`
refine Finset.card_mono ?_
- refine' monotone_filter_left a.coprime _
+ refine' monotone_filter_left a.Coprime _
simp only [Finset.le_eq_subset]
exact Ico_subset_Ico rfl.le (add_le_add_left (le_of_lt (mod_lt n a_pos)) k)
simp only [mul_succ]
simp_rw [← add_assoc] at ih ⊢
calc
- (filter a.coprime (Ico k (k + n % a + a * i + a))).card = (filter a.coprime
+ (filter a.Coprime (Ico k (k + n % a + a * i + a))).card = (filter a.Coprime
(Ico k (k + n % a + a * i) ∪ Ico (k + n % a + a * i) (k + n % a + a * i + a))).card := by
congr
rw [Ico_union_Ico_eq_Ico]
rw [add_assoc]
exact le_self_add
exact le_self_add
- _ ≤ (filter a.coprime (Ico k (k + n % a + a * i))).card + a.totient := by
+ _ ≤ (filter a.Coprime (Ico k (k + n % a + a * i))).card + a.totient := by
rw [filter_union, ← filter_coprime_Ico_eq_totient a (k + n % a + a * i)]
apply card_union_le
_ ≤ a.totient * i + a.totient + a.totient := add_le_add_right ih (totient a)
@@ -115,7 +115,7 @@ diamonds. -/
theorem _root_.ZMod.card_units_eq_totient (n : ℕ) [NeZero n] [Fintype (ZMod n)ˣ] :
Fintype.card (ZMod n)ˣ = φ n :=
calc
- Fintype.card (ZMod n)ˣ = Fintype.card { x : ZMod n // x.val.coprime n } :=
+ Fintype.card (ZMod n)ˣ = Fintype.card { x : ZMod n // x.val.Coprime n } :=
Fintype.card_congr ZMod.unitsEquivCoprime
_ = φ n := by
obtain ⟨m, rfl⟩ : ∃ m, n = m + 1 := exists_eq_succ_of_ne_zero NeZero.out
@@ -133,7 +133,7 @@ theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient := by
rw [← orderOf_units, Units.coe_neg_one, orderOf_neg_one, ringChar.eq (ZMod n) n, if_neg hn.ne']
#align nat.totient_even Nat.totient_even
-theorem totient_mul {m n : ℕ} (h : m.coprime n) : φ (m * n) = φ m * φ n :=
+theorem totient_mul {m n : ℕ} (h : m.Coprime n) : φ (m * n) = φ m * φ n :=
if hmn0 : m * n = 0 then by
cases' Nat.mul_eq_zero.1 hmn0 with h h <;>
simp only [totient_zero, mul_zero, zero_mul, h]
@@ -153,7 +153,7 @@ theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
rcases hnd with ⟨x, rfl⟩
rw [Nat.mul_div_cancel_left x hd0]
apply Finset.card_congr fun k _ => d * k
- · simp only [mem_filter, mem_range, and_imp, coprime]
+ · simp only [mem_filter, mem_range, and_imp, Coprime]
refine' fun a ha1 ha2 => ⟨(mul_lt_mul_left hd0).2 ha1, _⟩
rw [gcd_mul_left, ha2, mul_one]
· simp [hd0.ne']
@@ -188,7 +188,7 @@ theorem sum_totient' (n : ℕ) : (∑ m in (range n.succ).filter (· ∣ n), φ
/-- When `p` is prime, then the totient of `p ^ (n + 1)` is `p ^ n * (p - 1)` -/
theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n + 1)) = p ^ n * (p - 1) :=
calc
- φ (p ^ (n + 1)) = ((range (p ^ (n + 1))).filter (coprime (p ^ (n + 1)))).card :=
+ φ (p ^ (n + 1)) = ((range (p ^ (n + 1))).filter (Coprime (p ^ (n + 1)))).card :=
totient_eq_card_coprime _
_ = (range (p ^ (n + 1)) \ (range (p ^ n)).image (· * p)).card :=
(congr_arg card
@@ -30,7 +30,7 @@ namespace Nat
/-- Euler's totient function. This counts the number of naturals strictly less than `n` which are
coprime with `n`. -/
def totient (n : ℕ) : ℕ :=
- ((range n).filter n.Coprime).card
+ ((range n).filter n.coprime).card
#align nat.totient Nat.totient
@[inherit_doc]
@@ -45,13 +45,13 @@ theorem totient_zero : φ 0 = 0 :=
theorem totient_one : φ 1 = 1 := by simp [totient]
#align nat.totient_one Nat.totient_one
-theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filter n.Coprime).card :=
+theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filter n.coprime).card :=
rfl
#align nat.totient_eq_card_coprime Nat.totient_eq_card_coprime
/-- A characterisation of `Nat.totient` that avoids `Finset`. -/
-theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card { m | m < n ∧ n.Coprime m } := by
- let e : { m | m < n ∧ n.Coprime m } ≃ Finset.filter n.Coprime (Finset.range n) :=
+theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card { m | m < n ∧ n.coprime m } := by
+ let e : { m | m < n ∧ n.coprime m } ≃ Finset.filter n.coprime (Finset.range n) :=
{ toFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using m.property⟩
invFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using m.property⟩
left_inv := fun m => by simp only [Subtype.coe_mk, Subtype.coe_eta]
@@ -74,13 +74,13 @@ theorem totient_pos : ∀ {n : ℕ}, 0 < n → 0 < φ n
#align nat.totient_pos Nat.totient_pos
theorem filter_coprime_Ico_eq_totient (a n : ℕ) :
- ((Ico n (n + a)).filter (Coprime a)).card = totient a := by
+ ((Ico n (n + a)).filter (coprime a)).card = totient a := by
rw [totient, filter_Ico_card_eq_of_periodic, count_eq_card_filter_range]
exact periodic_coprime a
#align nat.filter_coprime_Ico_eq_totient Nat.filter_coprime_Ico_eq_totient
theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
- ((Ico k (k + n)).filter (Coprime a)).card ≤ totient a * (n / a + 1) := by
+ ((Ico k (k + n)).filter (coprime a)).card ≤ totient a * (n / a + 1) := by
conv_lhs => rw [← Nat.mod_add_div n a]
induction' n / a with i ih
· rw [← filter_coprime_Ico_eq_totient a k]
@@ -88,20 +88,20 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
Nat.zero_eq, zero_add]
--Porting note: below line was `mono`
refine Finset.card_mono ?_
- refine' monotone_filter_left a.Coprime _
+ refine' monotone_filter_left a.coprime _
simp only [Finset.le_eq_subset]
exact Ico_subset_Ico rfl.le (add_le_add_left (le_of_lt (mod_lt n a_pos)) k)
simp only [mul_succ]
simp_rw [← add_assoc] at ih ⊢
calc
- (filter a.Coprime (Ico k (k + n % a + a * i + a))).card = (filter a.Coprime
+ (filter a.coprime (Ico k (k + n % a + a * i + a))).card = (filter a.coprime
(Ico k (k + n % a + a * i) ∪ Ico (k + n % a + a * i) (k + n % a + a * i + a))).card := by
congr
rw [Ico_union_Ico_eq_Ico]
rw [add_assoc]
exact le_self_add
exact le_self_add
- _ ≤ (filter a.Coprime (Ico k (k + n % a + a * i))).card + a.totient := by
+ _ ≤ (filter a.coprime (Ico k (k + n % a + a * i))).card + a.totient := by
rw [filter_union, ← filter_coprime_Ico_eq_totient a (k + n % a + a * i)]
apply card_union_le
_ ≤ a.totient * i + a.totient + a.totient := add_le_add_right ih (totient a)
@@ -115,7 +115,7 @@ diamonds. -/
theorem _root_.ZMod.card_units_eq_totient (n : ℕ) [NeZero n] [Fintype (ZMod n)ˣ] :
Fintype.card (ZMod n)ˣ = φ n :=
calc
- Fintype.card (ZMod n)ˣ = Fintype.card { x : ZMod n // x.val.Coprime n } :=
+ Fintype.card (ZMod n)ˣ = Fintype.card { x : ZMod n // x.val.coprime n } :=
Fintype.card_congr ZMod.unitsEquivCoprime
_ = φ n := by
obtain ⟨m, rfl⟩ : ∃ m, n = m + 1 := exists_eq_succ_of_ne_zero NeZero.out
@@ -133,7 +133,7 @@ theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient := by
rw [← orderOf_units, Units.coe_neg_one, orderOf_neg_one, ringChar.eq (ZMod n) n, if_neg hn.ne']
#align nat.totient_even Nat.totient_even
-theorem totient_mul {m n : ℕ} (h : m.Coprime n) : φ (m * n) = φ m * φ n :=
+theorem totient_mul {m n : ℕ} (h : m.coprime n) : φ (m * n) = φ m * φ n :=
if hmn0 : m * n = 0 then by
cases' Nat.mul_eq_zero.1 hmn0 with h h <;>
simp only [totient_zero, mul_zero, zero_mul, h]
@@ -153,7 +153,7 @@ theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
rcases hnd with ⟨x, rfl⟩
rw [Nat.mul_div_cancel_left x hd0]
apply Finset.card_congr fun k _ => d * k
- · simp only [mem_filter, mem_range, and_imp, Coprime]
+ · simp only [mem_filter, mem_range, and_imp, coprime]
refine' fun a ha1 ha2 => ⟨(mul_lt_mul_left hd0).2 ha1, _⟩
rw [gcd_mul_left, ha2, mul_one]
· simp [hd0.ne']
@@ -188,7 +188,7 @@ theorem sum_totient' (n : ℕ) : (∑ m in (range n.succ).filter (· ∣ n), φ
/-- When `p` is prime, then the totient of `p ^ (n + 1)` is `p ^ n * (p - 1)` -/
theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n + 1)) = p ^ n * (p - 1) :=
calc
- φ (p ^ (n + 1)) = ((range (p ^ (n + 1))).filter (Coprime (p ^ (n + 1)))).card :=
+ φ (p ^ (n + 1)) = ((range (p ^ (n + 1))).filter (coprime (p ^ (n + 1)))).card :=
totient_eq_card_coprime _
_ = (range (p ^ (n + 1)) \ (range (p ^ n)).image (· * p)).card :=
(congr_arg card
Some changes have already been review and delegated in #6910 and #7148.
The diff that needs looking at is https://github.com/leanprover-community/mathlib4/pull/7174/commits/64d6d07ee18163627c8f517eb31455411921c5ac
The std bump PR was insta-merged already!
Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -30,7 +30,7 @@ namespace Nat
/-- Euler's totient function. This counts the number of naturals strictly less than `n` which are
coprime with `n`. -/
def totient (n : ℕ) : ℕ :=
- ((range n).filter n.coprime).card
+ ((range n).filter n.Coprime).card
#align nat.totient Nat.totient
@[inherit_doc]
@@ -45,13 +45,13 @@ theorem totient_zero : φ 0 = 0 :=
theorem totient_one : φ 1 = 1 := by simp [totient]
#align nat.totient_one Nat.totient_one
-theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filter n.coprime).card :=
+theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filter n.Coprime).card :=
rfl
#align nat.totient_eq_card_coprime Nat.totient_eq_card_coprime
/-- A characterisation of `Nat.totient` that avoids `Finset`. -/
-theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card { m | m < n ∧ n.coprime m } := by
- let e : { m | m < n ∧ n.coprime m } ≃ Finset.filter n.coprime (Finset.range n) :=
+theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card { m | m < n ∧ n.Coprime m } := by
+ let e : { m | m < n ∧ n.Coprime m } ≃ Finset.filter n.Coprime (Finset.range n) :=
{ toFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using m.property⟩
invFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using m.property⟩
left_inv := fun m => by simp only [Subtype.coe_mk, Subtype.coe_eta]
@@ -74,13 +74,13 @@ theorem totient_pos : ∀ {n : ℕ}, 0 < n → 0 < φ n
#align nat.totient_pos Nat.totient_pos
theorem filter_coprime_Ico_eq_totient (a n : ℕ) :
- ((Ico n (n + a)).filter (coprime a)).card = totient a := by
+ ((Ico n (n + a)).filter (Coprime a)).card = totient a := by
rw [totient, filter_Ico_card_eq_of_periodic, count_eq_card_filter_range]
exact periodic_coprime a
#align nat.filter_coprime_Ico_eq_totient Nat.filter_coprime_Ico_eq_totient
theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
- ((Ico k (k + n)).filter (coprime a)).card ≤ totient a * (n / a + 1) := by
+ ((Ico k (k + n)).filter (Coprime a)).card ≤ totient a * (n / a + 1) := by
conv_lhs => rw [← Nat.mod_add_div n a]
induction' n / a with i ih
· rw [← filter_coprime_Ico_eq_totient a k]
@@ -88,20 +88,20 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
Nat.zero_eq, zero_add]
--Porting note: below line was `mono`
refine Finset.card_mono ?_
- refine' monotone_filter_left a.coprime _
+ refine' monotone_filter_left a.Coprime _
simp only [Finset.le_eq_subset]
exact Ico_subset_Ico rfl.le (add_le_add_left (le_of_lt (mod_lt n a_pos)) k)
simp only [mul_succ]
simp_rw [← add_assoc] at ih ⊢
calc
- (filter a.coprime (Ico k (k + n % a + a * i + a))).card = (filter a.coprime
+ (filter a.Coprime (Ico k (k + n % a + a * i + a))).card = (filter a.Coprime
(Ico k (k + n % a + a * i) ∪ Ico (k + n % a + a * i) (k + n % a + a * i + a))).card := by
congr
rw [Ico_union_Ico_eq_Ico]
rw [add_assoc]
exact le_self_add
exact le_self_add
- _ ≤ (filter a.coprime (Ico k (k + n % a + a * i))).card + a.totient := by
+ _ ≤ (filter a.Coprime (Ico k (k + n % a + a * i))).card + a.totient := by
rw [filter_union, ← filter_coprime_Ico_eq_totient a (k + n % a + a * i)]
apply card_union_le
_ ≤ a.totient * i + a.totient + a.totient := add_le_add_right ih (totient a)
@@ -115,7 +115,7 @@ diamonds. -/
theorem _root_.ZMod.card_units_eq_totient (n : ℕ) [NeZero n] [Fintype (ZMod n)ˣ] :
Fintype.card (ZMod n)ˣ = φ n :=
calc
- Fintype.card (ZMod n)ˣ = Fintype.card { x : ZMod n // x.val.coprime n } :=
+ Fintype.card (ZMod n)ˣ = Fintype.card { x : ZMod n // x.val.Coprime n } :=
Fintype.card_congr ZMod.unitsEquivCoprime
_ = φ n := by
obtain ⟨m, rfl⟩ : ∃ m, n = m + 1 := exists_eq_succ_of_ne_zero NeZero.out
@@ -133,7 +133,7 @@ theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient := by
rw [← orderOf_units, Units.coe_neg_one, orderOf_neg_one, ringChar.eq (ZMod n) n, if_neg hn.ne']
#align nat.totient_even Nat.totient_even
-theorem totient_mul {m n : ℕ} (h : m.coprime n) : φ (m * n) = φ m * φ n :=
+theorem totient_mul {m n : ℕ} (h : m.Coprime n) : φ (m * n) = φ m * φ n :=
if hmn0 : m * n = 0 then by
cases' Nat.mul_eq_zero.1 hmn0 with h h <;>
simp only [totient_zero, mul_zero, zero_mul, h]
@@ -153,7 +153,7 @@ theorem totient_div_of_dvd {n d : ℕ} (hnd : d ∣ n) :
rcases hnd with ⟨x, rfl⟩
rw [Nat.mul_div_cancel_left x hd0]
apply Finset.card_congr fun k _ => d * k
- · simp only [mem_filter, mem_range, and_imp, coprime]
+ · simp only [mem_filter, mem_range, and_imp, Coprime]
refine' fun a ha1 ha2 => ⟨(mul_lt_mul_left hd0).2 ha1, _⟩
rw [gcd_mul_left, ha2, mul_one]
· simp [hd0.ne']
@@ -188,7 +188,7 @@ theorem sum_totient' (n : ℕ) : (∑ m in (range n.succ).filter (· ∣ n), φ
/-- When `p` is prime, then the totient of `p ^ (n + 1)` is `p ^ n * (p - 1)` -/
theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n + 1)) = p ^ n * (p - 1) :=
calc
- φ (p ^ (n + 1)) = ((range (p ^ (n + 1))).filter (coprime (p ^ (n + 1)))).card :=
+ φ (p ^ (n + 1)) = ((range (p ^ (n + 1))).filter (Coprime (p ^ (n + 1)))).card :=
totient_eq_card_coprime _
_ = (range (p ^ (n + 1)) \ (range (p ^ n)).image (· * p)).card :=
(congr_arg card
MulZeroClass.
in mul_zero
/zero_mul
(#6682)
Search&replace MulZeroClass.mul_zero
-> mul_zero
, MulZeroClass.zero_mul
-> zero_mul
.
These were introduced by Mathport, as the full name of mul_zero
is actually MulZeroClass.mul_zero
(it's exported with the short name).
@@ -84,7 +84,7 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
conv_lhs => rw [← Nat.mod_add_div n a]
induction' n / a with i ih
· rw [← filter_coprime_Ico_eq_totient a k]
- simp only [add_zero, mul_one, MulZeroClass.mul_zero, le_of_lt (mod_lt n a_pos),
+ simp only [add_zero, mul_one, mul_zero, le_of_lt (mod_lt n a_pos),
Nat.zero_eq, zero_add]
--Porting note: below line was `mono`
refine Finset.card_mono ?_
@@ -136,7 +136,7 @@ theorem totient_even {n : ℕ} (hn : 2 < n) : Even n.totient := by
theorem totient_mul {m n : ℕ} (h : m.coprime n) : φ (m * n) = φ m * φ n :=
if hmn0 : m * n = 0 then by
cases' Nat.mul_eq_zero.1 hmn0 with h h <;>
- simp only [totient_zero, MulZeroClass.mul_zero, MulZeroClass.zero_mul, h]
+ simp only [totient_zero, mul_zero, zero_mul, h]
else by
haveI : NeZero (m * n) := ⟨hmn0⟩
haveI : NeZero m := ⟨left_ne_zero_of_mul hmn0⟩
@@ -2,11 +2,6 @@
Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes
-
-! This file was ported from Lean 3 source module data.nat.totient
-! leanprover-community/mathlib commit 5cc2dfdd3e92f340411acea4427d701dc7ed26f8
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Algebra.CharP.Two
import Mathlib.Data.Nat.Factorization.Basic
@@ -14,6 +9,8 @@ import Mathlib.Data.Nat.Periodic
import Mathlib.Data.ZMod.Basic
import Mathlib.Tactic.Monotonicity
+#align_import data.nat.totient from "leanprover-community/mathlib"@"5cc2dfdd3e92f340411acea4427d701dc7ed26f8"
+
/-!
# Euler's totient function
@@ -286,7 +286,7 @@ We prove several different statements of this formula. -/
theorem totient_eq_prod_factorization {n : ℕ} (hn : n ≠ 0) :
φ n = n.factorization.prod fun p k => p ^ (k - 1) * (p - 1) := by
rw [multiplicative_factorization φ (@totient_mul) totient_one hn]
- apply Finsupp.prod_congr _
+ apply Finsupp.prod_congr _
intro p hp
have h := zero_lt_iff.mpr (Finsupp.mem_support_iff.mp hp)
rw [totient_prime_pow (prime_of_mem_factorization hp) h]
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com> Co-authored-by: Floris van Doorn <fpvdoorn@gmail.com> Co-authored-by: Jeremy Tan Jie Rui <reddeloostw@gmail.com> Co-authored-by: Alex J Best <alex.j.best@gmail.com>
@@ -256,7 +256,7 @@ theorem prime_iff_card_units (p : ℕ) [Fintype (ZMod p)ˣ] :
cases' eq_zero_or_neZero p with hp hp
· subst hp
simp only [ZMod, not_prime_zero, false_iff_iff, zero_tsub]
- -- the subst created an non-defeq but subsingleton instance diamond; resolve it
+ -- the subst created a non-defeq but subsingleton instance diamond; resolve it
suffices Fintype.card ℤˣ ≠ 0 by convert this
simp
rw [ZMod.card_units_eq_totient, Nat.totient_eq_iff_prime <| NeZero.pos p]
by
s! (#3825)
This PR puts, with one exception, every single remaining by
that lies all by itself on its own line to the previous line, thus matching the current behaviour of start-port.sh
. The exception is when the by
begins the second or later argument to a tuple or anonymous constructor; see https://github.com/leanprover-community/mathlib4/pull/3825#discussion_r1186702599.
Essentially this is s/\n *by$/ by/g
, but with manual editing to satisfy the linter's max-100-char-line requirement. The Python style linter is also modified to catch these "isolated by
s".
@@ -97,10 +97,8 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
simp only [mul_succ]
simp_rw [← add_assoc] at ih ⊢
calc
- (filter a.coprime (Ico k (k + n % a + a * i + a))).card =
- (filter a.coprime
- (Ico k (k + n % a + a * i) ∪ Ico (k + n % a + a * i) (k + n % a + a * i + a))).card :=
- by
+ (filter a.coprime (Ico k (k + n % a + a * i + a))).card = (filter a.coprime
+ (Ico k (k + n % a + a * i) ∪ Ico (k + n % a + a * i) (k + n % a + a * i + a))).card := by
congr
rw [Ico_union_Ico_eq_Ico]
rw [add_assoc]
This PR fixes two things:
align
statements for definitions and theorems and instances that are separated by two newlines from the relevant declaration (s/\n\n#align/\n#align
). This is often seen in the mathport output after ending calc
blocks.#align
statements. (This was needed for a script I wrote for #3630.)@@ -110,7 +110,6 @@ theorem Ico_filter_coprime_le {a : ℕ} (k n : ℕ) (a_pos : 0 < a) :
rw [filter_union, ← filter_coprime_Ico_eq_totient a (k + n % a + a * i)]
apply card_union_le
_ ≤ a.totient * i + a.totient + a.totient := add_le_add_right ih (totient a)
-
#align nat.Ico_filter_coprime_le Nat.Ico_filter_coprime_le
open ZMod
@@ -219,7 +218,6 @@ theorem totient_prime_pow_succ {p : ℕ} (hp : p.Prime) (n : ℕ) : φ (p ^ (n +
exact (mul_lt_mul_right hp.pos).2 h
rw [card_sdiff h2, card_image_of_injOn (h1.injOn _), card_range, card_range, ←
one_mul (p ^ n), pow_succ', ← tsub_mul, one_mul, mul_comm]
-
#align nat.totient_prime_pow_succ Nat.totient_prime_pow_succ
/-- When `p` is prime, then the totient of `p ^ n` is `p ^ (n - 1) * (p - 1)` -/
@@ -52,7 +52,7 @@ theorem totient_eq_card_coprime (n : ℕ) : φ n = ((range n).filter n.coprime).
rfl
#align nat.totient_eq_card_coprime Nat.totient_eq_card_coprime
-/-- A characterisation of `nat.totient` that avoids `finset`. -/
+/-- A characterisation of `Nat.totient` that avoids `Finset`. -/
theorem totient_eq_card_lt_and_coprime (n : ℕ) : φ n = Nat.card { m | m < n ∧ n.coprime m } := by
let e : { m | m < n ∧ n.coprime m } ≃ Finset.filter n.coprime (Finset.range n) :=
{ toFun := fun m => ⟨m, by simpa only [Finset.mem_filter, Finset.mem_range] using m.property⟩
@@ -248,19 +248,19 @@ theorem totient_eq_iff_prime {p : ℕ} (hp : 0 < p) : p.totient = p - 1 ↔ p.Pr
rwa [succ_le_iff, pos_iff_ne_zero]
#align nat.totient_eq_iff_prime Nat.totient_eq_iff_prime
-theorem card_units_zMod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
+theorem card_units_zmod_lt_sub_one {p : ℕ} (hp : 1 < p) [Fintype (ZMod p)ˣ] :
Fintype.card (ZMod p)ˣ ≤ p - 1 := by
haveI : NeZero p := ⟨(pos_of_gt hp).ne'⟩
rw [ZMod.card_units_eq_totient p]
exact Nat.le_pred_of_lt (Nat.totient_lt p hp)
-#align nat.card_units_zmod_lt_sub_one Nat.card_units_zMod_lt_sub_one
+#align nat.card_units_zmod_lt_sub_one Nat.card_units_zmod_lt_sub_one
theorem prime_iff_card_units (p : ℕ) [Fintype (ZMod p)ˣ] :
p.Prime ↔ Fintype.card (ZMod p)ˣ = p - 1 := by
cases' eq_zero_or_neZero p with hp hp
· subst hp
simp only [ZMod, not_prime_zero, false_iff_iff, zero_tsub]
- -- the substI created an non-defeq but subsingleton instance diamond; resolve it
+ -- the subst created an non-defeq but subsingleton instance diamond; resolve it
suffices Fintype.card ℤˣ ≠ 0 by convert this
simp
rw [ZMod.card_units_eq_totient, Nat.totient_eq_iff_prime <| NeZero.pos p]
The unported dependencies are