@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
4
4
Authors: Stuart Presnell
5
5
-/
6
6
import data.nat.prime
7
- import data.nat.mul_ind
7
+ import data.finsupp.multiset
8
8
import algebra.big_operators.finsupp
9
9
10
10
/-!
@@ -30,6 +30,8 @@ and (where appropriate) choose a uniform canonical way of expressing these ideas
30
30
with a normalization function, and then deduplicated. The basics of this have been started in
31
31
`ring_theory/unique_factorization_domain`.
32
32
33
+ * Extend the inductions to any `normalization_monoid` with unique factorization.
34
+
33
35
-/
34
36
35
37
open nat finset list finsupp
@@ -44,38 +46,38 @@ noncomputable def factorization (n : ℕ) : ℕ →₀ ℕ := (n.factors : multi
44
46
@[simp] lemma factorization_prod_pow_eq_self {n : ℕ} (hn : n ≠ 0 ) : n.factorization.prod pow = n :=
45
47
begin
46
48
simp only [←prod_to_multiset, factorization, multiset.coe_prod, multiset.to_finsupp_to_multiset],
47
- exact prod_factors hn.bot_lt ,
49
+ exact prod_factors hn,
48
50
end
49
51
50
- lemma factorization_eq_count {n p : ℕ} : n.factorization p = n.factors.count p :=
52
+ @[simp] lemma factors_count_eq {n p : ℕ} : n.factors.count p = n.factorization p :=
51
53
by simp [factorization]
52
- -- TODO: As part of the unification mentioned in the TODO above,
53
- -- consider making this a [ simp ] lemma from `n.factors.count` to `n.factorization`
54
+
55
+ lemma eq_of_factorization_eq {a b : ℕ} (ha : a ≠ 0 ) (hb : b ≠ 0 )
56
+ (h : ∀ p : ℕ, a.factorization p = b.factorization p) : a = b :=
57
+ eq_of_perm_factors ha hb (by simpa only [list.perm_iff_count, factors_count_eq] using h)
54
58
55
59
/-- Every nonzero natural number has a unique prime factorization -/
56
60
lemma factorization_inj : set.inj_on factorization { x : ℕ | x ≠ 0 } :=
57
- λ a ha b hb h, eq_of_count_factors_eq
58
- (zero_lt_iff.mpr ha) (zero_lt_iff.mpr hb) (λ p, by simp [←factorization_eq_count, h])
61
+ λ a ha b hb h, eq_of_factorization_eq ha hb (λ p, by simp [h])
59
62
60
- @[simp] lemma factorization_zero : factorization 0 = 0 :=
63
+ @[simp] lemma factorization_zero : factorization 0 = 0 :=
61
64
by simp [factorization]
62
65
63
66
@[simp] lemma factorization_one : factorization 1 = 0 :=
64
67
by simp [factorization]
65
68
66
69
/-- The support of `n.factorization` is exactly `n.factors.to_finset` -/
67
- @[simp] lemma support_factorization {n : ℕ} :
68
- n.factorization.support = n.factors.to_finset :=
70
+ @[simp] lemma support_factorization {n : ℕ} : n.factorization.support = n.factors.to_finset :=
69
71
by simpa [factorization, multiset.to_finsupp_support]
70
72
71
73
lemma factor_iff_mem_factorization {n p : ℕ} : p ∈ n.factorization.support ↔ p ∈ n.factors :=
72
74
by simp only [support_factorization, list.mem_to_finset]
73
75
74
76
lemma prime_of_mem_factorization {n p : ℕ} : p ∈ n.factorization.support → p.prime :=
75
- (@ prime_of_mem_factors n p) ∘ (@factor_iff_mem_factorization n p).mp
77
+ prime_of_mem_factors ∘ (@factor_iff_mem_factorization n p).mp
76
78
77
79
lemma pos_of_mem_factorization {n p : ℕ} : p ∈ n.factorization.support → 0 < p :=
78
- (@ prime.pos p) ∘ (@prime_of_mem_factorization n p)
80
+ prime.pos ∘ (@prime_of_mem_factorization n p)
79
81
80
82
lemma factorization_eq_zero_of_non_prime (n p : ℕ) (hp : ¬p.prime) : n.factorization p = 0 :=
81
83
not_mem_support_iff.1 (mt prime_of_mem_factorization hp)
@@ -87,27 +89,79 @@ by simp [factorization, add_equiv.map_eq_zero_iff, multiset.coe_eq_zero]
87
89
/-- For nonzero `a` and `b`, the power of `p` in `a * b` is the sum of the powers in `a` and `b` -/
88
90
@[simp] lemma factorization_mul {a b : ℕ} (ha : a ≠ 0 ) (hb : b ≠ 0 ) :
89
91
(a * b).factorization = a.factorization + b.factorization :=
90
- by { ext p, simp only [add_apply, factorization_eq_count ,
91
- count_factors_mul_of_pos (zero_lt_iff.mpr ha) (zero_lt_iff.mpr hb)] }
92
+ by { ext p, simp only [add_apply, ←factors_count_eq ,
93
+ perm_iff_count.mp (perm_factors_mul ha hb) p, count_append ] }
92
94
93
95
/-- For any `p`, the power of `p` in `n^k` is `k` times the power in `n` -/
94
- lemma factorization_pow { n k : ℕ} :
96
+ @[simp] lemma factorization_pow ( n k : ℕ) :
95
97
factorization (n^k) = k • n.factorization :=
96
- by { ext p, simp [factorization_eq_count, factors_count_pow] }
98
+ begin
99
+ induction k with k ih,
100
+ { simp },
101
+ rcases n.eq_zero_or_pos with rfl | hn,
102
+ { simp },
103
+ rw [pow_succ, factorization_mul hn.ne' (pow_ne_zero _ hn.ne'), ih, succ_eq_one_add, add_smul,
104
+ one_smul],
105
+ end
106
+
107
+ /-- For coprime `a` and `b`, the power of `p` in `a * b` is the sum of the powers in `a` and `b` -/
108
+ lemma factorization_mul_apply_of_coprime {p a b : ℕ} (hab : coprime a b) :
109
+ (a * b).factorization p = a.factorization p + b.factorization p :=
110
+ by simp only [←factors_count_eq, perm_iff_count.mp (perm_factors_mul_of_coprime hab), count_append]
111
+
112
+ /-- If `p` is a prime factor of `a` then the power of `p` in `a` is the same that in `a * b`,
113
+ for any `b` coprime to `a`. -/
114
+ lemma factorization_eq_of_coprime_left {p a b : ℕ} (hab : coprime a b) (hpa : p ∈ a.factors) :
115
+ (a * b).factorization p = a.factorization p :=
116
+ begin
117
+ rw [factorization_mul_apply_of_coprime hab, ←factors_count_eq, ←factors_count_eq],
118
+ simpa only [count_eq_zero_of_not_mem (coprime_factors_disjoint hab hpa)],
119
+ end
120
+
121
+ /-- If `p` is a prime factor of `b` then the power of `p` in `b` is the same that in `a * b`,
122
+ for any `a` coprime to `b`. -/
123
+ lemma factorization_eq_of_coprime_right {p a b : ℕ} (hab : coprime a b) (hpb : p ∈ b.factors) :
124
+ (a * b).factorization p = b.factorization p :=
125
+ by { rw mul_comm, exact factorization_eq_of_coprime_left (coprime_comm.mp hab) hpb }
126
+
127
+ lemma pow_factorization_dvd (n p : ℕ) : p ^ n.factorization p ∣ n :=
128
+ begin
129
+ rw ←factors_count_eq,
130
+ by_cases hp : p.prime,
131
+ { apply dvd_of_factors_subperm (pow_ne_zero _ hp.ne_zero),
132
+ rw [hp.factors_pow, list.subperm_ext_iff],
133
+ intros q hq,
134
+ simp [list.eq_of_mem_repeat hq] },
135
+ { rw count_eq_zero_of_not_mem (mt prime_of_mem_factors hp),
136
+ simp },
137
+ end
138
+
139
+ lemma pow_succ_factorization_not_dvd {n p : ℕ} (hn : n ≠ 0 ) (hp : p.prime) :
140
+ ¬ p ^ (n.factorization p + 1 ) ∣ n :=
141
+ begin
142
+ intro h,
143
+ have := factors_sublist_of_dvd h hn,
144
+ rw [hp.factors_pow, ←le_count_iff_repeat_sublist, factors_count_eq] at this ,
145
+ linarith
146
+ end
147
+
148
+ lemma prime.factorization_pos_of_dvd {n p : ℕ} (hp : p.prime) (hn : n ≠ 0 ) (h : p ∣ n) :
149
+ 0 < n.factorization p :=
150
+ by rwa [←factors_count_eq, count_pos, mem_factors_iff_dvd hn hp]
97
151
98
152
/-- The only prime factor of prime `p` is `p` itself, with multiplicity `1` -/
99
153
@[simp] lemma prime.factorization {p : ℕ} (hp : prime p) :
100
154
p.factorization = single p 1 :=
101
155
begin
102
156
ext q,
103
- rw [factorization_eq_count , factors_prime hp, single_apply, count_singleton', if_congr eq_comm];
157
+ rw [←factors_count_eq , factors_prime hp, single_apply, count_singleton', if_congr eq_comm];
104
158
refl,
105
159
end
106
160
107
161
/-- For prime `p` the only prime factor of `p^k` is `p` with multiplicity `k` -/
108
- @[simp] lemma prime.factorization_pow {p k : ℕ} (hp : prime p) :
109
- factorization (p^ k) = single p k :=
110
- by simp [factorization_pow, hp.factorization ]
162
+ lemma prime.factorization_pow {p k : ℕ} (hp : prime p) :
163
+ factorization (p ^ k) = single p k :=
164
+ by simp [hp ]
111
165
112
166
/-- For any `p : ℕ` and any function `g : α → ℕ` that's non-zero on `S : finset α`,
113
167
the power of `p` in `S.prod g` equals the sum over `x ∈ S` of the powers of `p` in `g x`.
@@ -169,7 +223,7 @@ lemma factorization_mul_of_coprime {a b : ℕ} (hab : coprime a b) :
169
223
(a * b).factorization = a.factorization + b.factorization :=
170
224
begin
171
225
ext q,
172
- simp only [finsupp.coe_add, add_apply, factorization_eq_count, count_factors_mul_of_coprime hab],
226
+ simp only [finsupp.coe_add, add_apply, ←factors_count_eq, factorization_mul_apply_of_coprime hab],
173
227
end
174
228
175
229
/-- For coprime `a` and `b` the prime factorization `a * b` is the union of those of `a` and `b` -/
@@ -185,9 +239,72 @@ lemma factorization_mul_support {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
185
239
begin
186
240
ext q,
187
241
simp only [finset.mem_union, factor_iff_mem_factorization],
188
- rw mem_factors_mul ha hb,
242
+ exact mem_factors_mul ha hb
189
243
end
190
244
245
+ /-- Given `P 0, P 1` and a way to extend `P a` to `P (p ^ k * a)`,
246
+ you can define `P` for all natural numbers. -/
247
+ @[elab_as_eliminator]
248
+ def rec_on_prime_pow {P : ℕ → Sort *} (h0 : P 0 ) (h1 : P 1 )
249
+ (h : ∀ a p n : ℕ, p.prime → ¬ p ∣ a → P a → P (p ^ n * a)) : ∀ (a : ℕ), P a :=
250
+ λ a, nat.strong_rec_on a $ λ n,
251
+ match n with
252
+ | 0 := λ _, h0
253
+ | 1 := λ _, h1
254
+ | (k+2 ) := λ hk, begin
255
+ let p := (k + 2 ).min_fac,
256
+ have hp : prime p := min_fac_prime (succ_succ_ne_one k),
257
+ -- the awkward `let` stuff here is because `factorization` is noncomputable (finsupp);
258
+ -- we get around this by using the computable `factors.count`, and rewriting when we want
259
+ -- to use the `factorization` API
260
+ let t := (k+2 ).factors.count p,
261
+ have ht : t = (k+2 ).factorization p := factors_count_eq,
262
+ have hpt : p ^ t ∣ k + 2 := by { rw ht, exact pow_factorization_dvd _ _ },
263
+ have htp : 0 < t :=
264
+ by { rw ht,
265
+ exact hp.factorization_pos_of_dvd (nat.succ_ne_zero (k + 1 )) (min_fac_dvd _) },
266
+
267
+ convert h ((k + 2 ) / p ^ t) p t hp _ _,
268
+ { rw nat.mul_div_cancel' hpt },
269
+ { rw [nat.dvd_div_iff hpt, ←pow_succ', ht],
270
+ exact pow_succ_factorization_not_dvd (k + 1 ).succ_ne_zero hp },
271
+
272
+ apply hk _ (nat.div_lt_of_lt_mul _),
273
+ rw [lt_mul_iff_one_lt_left nat.succ_pos', one_lt_pow_iff htp.ne],
274
+ exact hp.one_lt
275
+ end
276
+ end
277
+
278
+ /-- Given `P 0`, `P 1`, and `P (p ^ k)` for positive prime powers, and a way to extend `P a` and
279
+ `P b` to `P (a * b)` when `a, b` are coprime, you can define `P` for all natural numbers. -/
280
+ @[elab_as_eliminator]
281
+ def rec_on_pos_prime_coprime {P : ℕ → Sort *} (hp : ∀ p n : ℕ, prime p → 0 < n → P (p ^ n))
282
+ (h0 : P 0 ) (h1 : P 1 ) (h : ∀ a b, 0 < a → 0 < b → coprime a b → P a → P b → P (a * b)) :
283
+ ∀ a, P a :=
284
+ rec_on_prime_pow h0 h1 $ λ a p n hp' hpa ha,
285
+ (h (p ^ n) a (pow_pos hp'.pos _) (nat.pos_of_ne_zero (λ t, by simpa [t] using hpa))
286
+ (prime.coprime_pow_of_not_dvd hp' hpa).symm
287
+ (if h : n = 0 then eq.rec h1 h.symm else hp p n hp' $ nat.pos_of_ne_zero h) ha)
288
+
289
+ /-- Given `P 0`, `P (p ^ k)` for all prime powers, and a way to extend `P a` and `P b` to
290
+ `P (a * b)` when `a, b` are coprime, you can define `P` for all natural numbers. -/
291
+ @[elab_as_eliminator]
292
+ def rec_on_prime_coprime {P : ℕ → Sort *} (h0 : P 0 ) (hp : ∀ p n : ℕ, prime p → P (p ^ n))
293
+ (h : ∀ a b, 0 < a → 0 < b → coprime a b → P a → P b → P (a * b)) : ∀ a, P a :=
294
+ rec_on_pos_prime_coprime (λ p n h _, hp p n h) h0 (hp 2 0 prime_two) h
295
+
296
+ /-- Given `P 0`, `P 1`, `P p` for all primes, and a proof that you can extend
297
+ `P a` and `P b` to `P (a * b)`, you can define `P` for all natural numbers. -/
298
+ @[elab_as_eliminator]
299
+ def rec_on_mul {P : ℕ → Sort *} (h0 : P 0 ) (h1 : P 1 )
300
+ (hp : ∀ p, prime p → P p) (h : ∀ a b, P a → P b → P (a * b)) : ∀ a, P a :=
301
+ let hp : ∀ p n : ℕ, prime p → P (p ^ n) :=
302
+ λ p n hp', match n with
303
+ | 0 := h1
304
+ | (n+1 ) := by exact h _ _ (hp p hp') (_match _)
305
+ end in
306
+ rec_on_prime_coprime h0 hp $ λ a b _ _ _, h a b
307
+
191
308
/-- For any multiplicative function `f` with `f 1 = 1` and any `n > 0`,
192
309
we can evaluate `f n` by evaluating `f` at `p ^ k` over the factorization of `n` -/
193
310
lemma multiplicative_factorization {β : Type *} [comm_monoid β] (f : ℕ → β)
@@ -233,6 +350,29 @@ begin
233
350
{ rintro ⟨c, rfl⟩, rw factorization_mul hd (right_ne_zero_of_mul hn), simp },
234
351
end
235
352
353
+ lemma dvd_of_mem_factorization {n p : ℕ} (h : p ∈ n.factorization.support) : p ∣ n :=
354
+ begin
355
+ rcases eq_or_ne p 0 with rfl | hp,
356
+ { rw [nat.support_factorization, list.mem_to_finset] at h,
357
+ exact absurd (nat.prime_of_mem_factors h) (nat.not_prime_zero) },
358
+ apply nat.dvd_of_factors_subperm hp,
359
+ rw [nat.factors_prime $ nat.prime_of_mem_factorization h, list.subperm_singleton_iff],
360
+ rwa ←nat.factor_iff_mem_factorization,
361
+ end
362
+
363
+ lemma factorization_le_factorization_mul_left {a b : ℕ} (hb : b ≠ 0 ) :
364
+ a.factorization ≤ (a * b).factorization :=
365
+ begin
366
+ rcases eq_or_ne a 0 with rfl | ha,
367
+ { simp },
368
+ rw [factorization_le_iff_dvd ha $ mul_ne_zero ha hb],
369
+ exact dvd.intro b rfl
370
+ end
371
+
372
+ lemma factorization_le_factorization_mul_right {a b : ℕ} (ha : a ≠ 0 ) :
373
+ b.factorization ≤ (a * b).factorization :=
374
+ by { rw mul_comm, apply factorization_le_factorization_mul_left ha }
375
+
236
376
lemma prime.pow_dvd_iff_le_factorization {p k n : ℕ} (pp : prime p) (hn : n ≠ 0 ) :
237
377
p ^ k ∣ n ↔ k ≤ n.factorization p :=
238
378
by rw [←factorization_le_iff_dvd (pow_pos pp.pos k).ne' hn, pp.factorization_pow, single_le_iff]
@@ -250,51 +390,49 @@ begin
250
390
exact le_of_dvd ha.bot_lt hab,
251
391
end
252
392
253
- @[simp]
254
- lemma div_factorization_eq_tsub_of_dvd {d n : ℕ} (hn : n ≠ 0 ) (h : d ∣ n) :
393
+ @[simp] lemma factorization_div {d n : ℕ} (h : d ∣ n) :
255
394
(n / d).factorization = n.factorization - d.factorization :=
256
395
begin
257
- have hd : d ≠ 0 := ne_zero_of_dvd_ne_zero hn h,
258
- cases dvd_iff_exists_eq_mul_left.mp h with c hc,
259
- have hc_pos : c ≠ 0 , { subst hc, exact left_ne_zero_of_mul hn },
260
- rw [hc, nat.mul_div_cancel c hd.bot_lt, factorization_mul hc_pos hd, add_tsub_cancel_right],
396
+ rcases eq_or_ne d 0 with rfl | hd,
397
+ { rw zero_dvd_iff at h,
398
+ subst h,
399
+ simp },
400
+ rcases eq_or_ne n 0 with rfl | hn,
401
+ { simp },
402
+ apply add_left_injective d.factorization,
403
+ simp only,
404
+ symmetry,
405
+ rw [tsub_add_cancel_of_le $ (nat.factorization_le_iff_dvd hd hn).mpr h],
406
+ nth_rewrite 0 ←nat.div_mul_cancel h,
407
+ exact nat.factorization_mul (nat.div_pos (nat.le_of_dvd hn.bot_lt h) hd.bot_lt).ne' hd,
261
408
end
262
409
263
410
lemma dvd_iff_div_factorization_eq_tsub (d n : ℕ) (hd : d ≠ 0 ) (hdn : d ≤ n) :
264
411
d ∣ n ↔ (n / d).factorization = n.factorization - d.factorization :=
265
412
begin
266
- have hn : n ≠ 0 := (lt_of_lt_of_le hd.bot_lt hdn).ne.symm,
267
- refine ⟨div_factorization_eq_tsub_of_dvd hn, _⟩,
268
- { rcases eq_or_lt_of_le hdn with rfl | hd_lt_n, { simp },
269
- have h1 : n / d ≠ 0 := λ H, nat.lt_asymm hd_lt_n ((nat.div_eq_zero_iff hd.bot_lt).mp H),
270
- intros h,
271
- rw dvd_iff_le_div_mul n d,
272
- by_contra h2,
273
- cases (exists_factorization_lt_of_lt (mul_ne_zero h1 hd) (not_le.mp h2)) with p hp,
274
- rwa [factorization_mul h1 hd, add_apply, ←lt_tsub_iff_right, h, tsub_apply,
275
- lt_self_iff_false] at hp },
276
- end
277
-
278
- lemma pow_factorization_dvd (p d : ℕ) : p ^ d.factorization p ∣ d :=
279
- begin
280
- rcases eq_or_ne d 0 with rfl | hd, { simp },
281
- by_cases pp : prime p,
282
- { rw pp.pow_dvd_iff_le_factorization hd },
283
- { rw factorization_eq_zero_of_non_prime d p pp, simp },
413
+ refine ⟨factorization_div, _⟩,
414
+ rcases eq_or_lt_of_le hdn with rfl | hd_lt_n, { simp },
415
+ have h1 : n / d ≠ 0 := λ H, nat.lt_asymm hd_lt_n ((nat.div_eq_zero_iff hd.bot_lt).mp H),
416
+ intros h,
417
+ rw dvd_iff_le_div_mul n d,
418
+ by_contra h2,
419
+ cases (exists_factorization_lt_of_lt (mul_ne_zero h1 hd) (not_le.mp h2)) with p hp,
420
+ rwa [factorization_mul h1 hd, add_apply, ←lt_tsub_iff_right, h, tsub_apply,
421
+ lt_self_iff_false] at hp
284
422
end
285
423
286
424
lemma dvd_iff_prime_pow_dvd_dvd {n d : ℕ} (hd : d ≠ 0 ) (hn : n ≠ 0 ) :
287
- d ∣ n ↔ ∀ p k : ℕ, prime p → p^ k ∣ d → p^ k ∣ n :=
425
+ d ∣ n ↔ ∀ p k : ℕ, prime p → p ^ k ∣ d → p ^ k ∣ n :=
288
426
begin
289
427
split,
290
428
{ exact λ h p k pp hpkd, dvd_trans hpkd h },
291
429
{ intros h,
292
430
rw [←factorization_le_iff_dvd hd hn, finsupp.le_def],
293
431
intros p,
294
432
by_cases pp : prime p, swap,
295
- { rw factorization_eq_zero_of_non_prime d p pp, exact zero_le' },
433
+ { rw factorization_eq_zero_of_non_prime d p pp, exact nat. zero_le _ },
296
434
rw ←pp.pow_dvd_iff_le_factorization hn,
297
- exact h p _ pp (pow_factorization_dvd p _) },
435
+ exact h p _ pp (pow_factorization_dvd _ _) },
298
436
end
299
437
300
438
end nat
0 commit comments