Skip to content

Commit ca4918b

Browse files
committed
Merge remote-tracking branch 'upstream/master' into bump/v4.22.0
2 parents b470243 + f8aa277 commit ca4918b

File tree

15 files changed

+620
-10
lines changed

15 files changed

+620
-10
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5616,6 +5616,7 @@ import Mathlib.RingTheory.WittVector.Truncated
56165616
import Mathlib.RingTheory.WittVector.Verschiebung
56175617
import Mathlib.RingTheory.WittVector.WittPolynomial
56185618
import Mathlib.RingTheory.ZMod
5619+
import Mathlib.RingTheory.ZMod.UnitsCyclic
56195620
import Mathlib.SetTheory.Cardinal.Aleph
56205621
import Mathlib.SetTheory.Cardinal.Arithmetic
56215622
import Mathlib.SetTheory.Cardinal.Basic

Mathlib/Algebra/Group/Subgroup/Ker.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,12 @@ theorem ker_one : (1 : G →* M).ker = ⊤ :=
292292
theorem ker_id : (MonoidHom.id G).ker = ⊥ :=
293293
rfl
294294

295+
@[to_additive] theorem ker_eq_top_iff {f : G →* M} : f.ker = ⊤ ↔ f = 1 := by
296+
simp_rw [ker, ← top_le_iff, SetLike.le_def, f.ext_iff, Subgroup.mem_top, true_imp_iff]; rfl
297+
298+
@[to_additive] theorem range_eq_bot_iff {f : G →* G'} : f.range = ⊥ ↔ f = 1 := by
299+
rw [← le_bot_iff, f.range_eq_map, map_le_iff_le_comap, top_le_iff, comap_bot, ker_eq_top_iff]
300+
295301
@[to_additive]
296302
theorem ker_eq_bot_iff (f : G →* M) : f.ker = ⊥ ↔ Function.Injective f :=
297303
fun h x y hxy => by rwa [eq_iff, h, mem_bot, inv_mul_eq_one, eq_comm] at hxy, fun h =>

Mathlib/Algebra/Group/Units/Hom.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ variable {M}
107107
@[to_additive (attr := simp)]
108108
theorem coeHom_apply (x : Mˣ) : coeHom M x = ↑x := rfl
109109

110+
@[to_additive]
111+
theorem coeHom_injective : Function.Injective (coeHom M) :=
112+
Units.ext
113+
110114
section DivisionMonoid
111115

112116
variable [DivisionMonoid α]

Mathlib/Algebra/Ring/Parity.lean

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,10 @@ lemma Odd.natCast {R : Type*} [Semiring R] {n : ℕ} (hn : Odd n) : Odd (n : R)
134134
rw [mul_add, add_mul, mul_one, ← add_assoc, one_mul, mul_assoc, ← mul_add, ← mul_add, ← mul_assoc,
135135
← Nat.cast_two, ← Nat.cast_comm]
136136

137-
lemma Odd.pow (ha : Odd a) : ∀ {n : ℕ}, Odd (a ^ n)
138-
| 0 => by
139-
rw [pow_zero]
140-
exact odd_one
141-
| n + 1 => by rw [pow_succ]; exact ha.pow.mul ha
137+
lemma Odd.pow {n : ℕ} (ha : Odd a) : Odd (a ^ n) := by
138+
induction n with
139+
| zero => simp [pow_zero]
140+
| succ n hrec => rw [pow_succ]; exact hrec.mul ha
142141

143142
lemma Odd.pow_add_pow_eq_zero [IsCancelAdd α] (hn : Odd n) (hab : a + b = 0) :
144143
a ^ n + b ^ n = 0 := by
@@ -279,6 +278,11 @@ lemma Odd.of_mul_left (h : Odd (m * n)) : Odd m :=
279278
lemma Odd.of_mul_right (h : Odd (m * n)) : Odd n :=
280279
(odd_mul.mp h).2
281280

281+
lemma odd_pow_iff {e : ℕ} (he : e ≠ 0) : Odd (n ^ e) ↔ Odd n := by
282+
refine ⟨?_, Odd.pow⟩
283+
simp only [← Nat.not_even_iff_odd, not_imp_not, even_pow]
284+
exact fun h ↦ ⟨h, he⟩
285+
282286
lemma even_div : Even (m / n) ↔ m % (2 * n) / n = 0 := by
283287
rw [even_iff_two_dvd, dvd_iff_mod_eq_zero, ← Nat.mod_mul_right_div_self, mul_comm]
284288

Mathlib/Data/Int/Basic.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,7 @@ lemma eq_of_mod_eq_of_natAbs_sub_lt_natAbs {a b c : ℤ} (h1 : a % b = c)
101101
lemma natAbs_le_of_dvd_ne_zero (hmn : m ∣ n) (hn : n ≠ 0) : natAbs m ≤ natAbs n :=
102102
not_lt.mp (mt (eq_zero_of_dvd_of_natAbs_lt_natAbs hmn) hn)
103103

104+
theorem gcd_emod (m n : ℤ) : (m % n).gcd n = m.gcd n := by
105+
conv_rhs => rw [← m.emod_add_ediv n, gcd_add_mul_left_left]
106+
104107
end Int

Mathlib/Data/Int/ModEq.lean

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,30 @@ theorem cancel_left_div_gcd (hm : 0 < m) (h : c * a ≡ c * b [ZMOD m]) : a ≡
190190
theorem of_div (h : a / c ≡ b / c [ZMOD m / c]) (ha : c ∣ a) (ha : c ∣ b) (ha : c ∣ m) :
191191
a ≡ b [ZMOD m] := by convert h.mul_left' <;> rwa [Int.mul_ediv_cancel']
192192

193+
/-- Cancel left multiplication on both sides of the `≡` and in the modulus.
194+
195+
For cancelling left multiplication in the modulus, see `Int.ModEq.of_mul_left`. -/
196+
protected theorem mul_left_cancel' (hc : c ≠ 0) :
197+
c * a ≡ c * b [ZMOD c * m] → a ≡ b [ZMOD m] := by
198+
simp only [modEq_iff_dvd, Int.natCast_mul, ← Int.mul_sub]
199+
exact Int.dvd_of_mul_dvd_mul_left hc
200+
201+
protected theorem mul_left_cancel_iff' (hc : c ≠ 0) :
202+
c * a ≡ c * b [ZMOD c * m] ↔ a ≡ b [ZMOD m] :=
203+
⟨ModEq.mul_left_cancel' hc, Int.ModEq.mul_left'⟩
204+
205+
/-- Cancel right multiplication on both sides of the `≡` and in the modulus.
206+
207+
For cancelling right multiplication in the modulus, see `Int.ModEq.of_mul_right`. -/
208+
protected theorem mul_right_cancel' (hc : c ≠ 0) :
209+
a * c ≡ b * c [ZMOD m * c] → a ≡ b [ZMOD m] := by
210+
simp only [modEq_iff_dvd, Int.natCast_mul, ← Int.sub_mul]
211+
exact Int.dvd_of_mul_dvd_mul_right hc
212+
213+
protected theorem mul_right_cancel_iff' (hc : c ≠ 0) :
214+
a * c ≡ b * c [ZMOD m * c] ↔ a ≡ b [ZMOD m] :=
215+
⟨ModEq.mul_right_cancel' hc, ModEq.mul_right'⟩
216+
193217
end ModEq
194218

195219
theorem modEq_one : a ≡ b [ZMOD 1] :=

Mathlib/Data/Nat/ModEq.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ theorem mod_modEq (a n) : a % n ≡ a [MOD n] :=
9090

9191
namespace ModEq
9292

93+
theorem self_mul_add : ModEq m (m * a + b) b := by
94+
simp [Nat.ModEq]
95+
9396
lemma of_dvd (d : m ∣ n) (h : a ≡ b [MOD n]) : a ≡ b [MOD m] :=
9497
modEq_of_dvd <| Int.ofNat_dvd.mpr d |>.trans h.dvd
9598

Mathlib/Data/Nat/Totient.lean

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,11 @@ theorem prime_iff_card_units (p : ℕ) [Fintype (ZMod p)ˣ] :
240240
theorem totient_two : φ 2 = 1 :=
241241
(totient_prime prime_two).trans rfl
242242

243+
/-- Euler's totient function is only odd at `1` or `2`. -/
244+
theorem odd_totient_iff {n : ℕ} :
245+
Odd (φ n) ↔ n = 1 ∨ n = 2 := by
246+
rcases n with _ | _ | _ | _ <;> simp [Nat.totient_even]
247+
243248
theorem totient_eq_one_iff : ∀ {n : ℕ}, n.totient = 1 ↔ n = 1 ∨ n = 2
244249
| 0 => by simp
245250
| 1 => by simp
@@ -252,6 +257,21 @@ theorem totient_eq_one_iff : ∀ {n : ℕ}, n.totient = 1 ↔ n = 1 ∨ n = 2
252257
theorem dvd_two_of_totient_le_one {a : ℕ} (han : 0 < a) (ha : a.totient ≤ 1) : a ∣ 2 := by
253258
rcases totient_eq_one_iff.mp <| le_antisymm ha <| totient_pos.2 han with rfl | rfl <;> norm_num
254259

260+
theorem odd_totient_iff_eq_one {n : ℕ} :
261+
Odd (φ n) ↔ φ n = 1 := by
262+
simp [Nat.odd_totient_iff, Nat.totient_eq_one_iff]
263+
264+
/-- `Nat.totient m` and `Nat.totient n` are coprime iff one of them is 1. -/
265+
theorem totient_coprime_totient_iff (m n : ℕ) :
266+
(φ m).Coprime (φ n) ↔ (m = 1 ∨ m = 2) ∨ (n = 1 ∨ n = 2) := by
267+
constructor
268+
· rw [← not_imp_not]
269+
simp_rw [← odd_totient_iff, not_or, not_odd_iff_even, even_iff_two_dvd]
270+
exact fun h ↦ Nat.not_coprime_of_dvd_of_dvd one_lt_two h.1 h.2
271+
· simp_rw [← totient_eq_one_iff]
272+
rintro (h | h) <;> rw [h]
273+
exacts [Nat.coprime_one_left _, Nat.coprime_one_right _]
274+
255275
/-! ### Euler's product formula for the totient function
256276
257277
We prove several different statements of this formula. -/

Mathlib/Data/ZMod/Basic.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ open Function ZMod
3636

3737
namespace ZMod
3838

39+
instance : IsDomain (ZMod 0) := inferInstanceAs (IsDomain ℤ)
40+
3941
/-- For non-zero `n : ℕ`, the ring `Fin n` is equivalent to `ZMod n`. -/
4042
def finEquiv : ∀ (n : ℕ) [NeZero n], Fin n ≃+* ZMod n
4143
| 0, h => (h.ne _ rfl).elim
@@ -141,6 +143,12 @@ theorem natCast_self (n : ℕ) : (n : ZMod n) = 0 :=
141143
theorem natCast_self' (n : ℕ) : (n + 1 : ZMod (n + 1)) = 0 := by
142144
rw [← Nat.cast_add_one, natCast_self (n + 1)]
143145

146+
lemma natCast_pow_eq_zero_of_le (p : ℕ) {m n : ℕ} (h : n ≤ m) :
147+
(p ^ m : ZMod (p ^ n)) = 0 := by
148+
obtain ⟨q, rfl⟩ := Nat.exists_eq_add_of_le h
149+
rw [pow_add, ← Nat.cast_pow]
150+
simp
151+
144152
section UniversalProperty
145153

146154
variable {n : ℕ} {R : Type*}
@@ -340,6 +348,9 @@ theorem cast_natCast (h : m ∣ n) (k : ℕ) : (cast (k : ZMod n) : R) = k :=
340348
theorem cast_intCast (h : m ∣ n) (k : ℤ) : (cast (k : ZMod n) : R) = k :=
341349
map_intCast (castHom h R) k
342350

351+
theorem castHom_surjective (h : m ∣ n) : Function.Surjective (castHom h (ZMod m)) :=
352+
fun a ↦ by obtain ⟨a, rfl⟩ := intCast_surjective a; exact ⟨a, map_intCast ..⟩
353+
343354
end CharDvd
344355

345356
section CharEq
@@ -812,6 +823,10 @@ theorem inv_mul_of_unit {n : ℕ} (a : ZMod n) (h : IsUnit a) : a⁻¹ * a = 1 :
812823
protected theorem inv_eq_of_mul_eq_one (n : ℕ) (a b : ZMod n) (h : a * b = 1) : a⁻¹ = b :=
813824
left_inv_eq_right_inv (inv_mul_of_unit a ⟨⟨a, b, h, mul_comm a b ▸ h⟩, rfl⟩) h
814825

826+
@[simp]
827+
theorem inv_neg_one (n : ℕ) : (-1 : ZMod n)⁻¹ = -1 :=
828+
ZMod.inv_eq_of_mul_eq_one n (-1) (-1) (by simp)
829+
815830
lemma inv_mul_eq_one_of_isUnit {n : ℕ} {a : ZMod n} (ha : IsUnit a) (b : ZMod n) :
816831
a⁻¹ * b = 1 ↔ a = b := by
817832
-- ideally, this would be `ha.inv_mul_eq_one`, but `ZMod n` is not a `DivisionMonoid`...

Mathlib/Data/ZMod/Coprime.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors: Michael Stoll
66
import Mathlib.Algebra.EuclideanDomain.Int
77
import Mathlib.Data.Nat.Prime.Int
88
import Mathlib.Data.ZMod.Basic
9+
import Mathlib.RingTheory.Int.Basic
910
import Mathlib.RingTheory.PrincipalIdealDomain
1011

1112
/-!
@@ -19,6 +20,11 @@ assert_not_exists TwoSidedIdeal
1920

2021
namespace ZMod
2122

23+
theorem coe_int_isUnit_iff_isCoprime (n : ℤ) (m : ℕ) :
24+
IsUnit (n : ZMod m) ↔ IsCoprime (m : ℤ) n := by
25+
rw [Int.isCoprime_iff_nat_coprime, Nat.coprime_comm, ← isUnit_iff_coprime, Associated.isUnit_iff]
26+
simpa only [eq_intCast, Int.cast_natCast] using (Int.associated_natAbs _).map (Int.castRingHom _)
27+
2228
/-- If `p` is a prime and `a` is an integer, then `a : ZMod p` is zero if and only if
2329
`gcd a p ≠ 1`. -/
2430
theorem eq_zero_iff_gcd_ne_one {a : ℤ} {p : ℕ} [pp : Fact p.Prime] :

0 commit comments

Comments
 (0)