Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 3bd2044

Browse files
chore(data/nat/prime): reuse a result from algebra.big_operators.associated (#11143)
1 parent 57a9f8b commit 3bd2044

File tree

3 files changed

+95
-81
lines changed

3 files changed

+95
-81
lines changed

src/algebra/big_operators/associated.lean

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -135,27 +135,4 @@ lemma prime.dvd_finsupp_prod_iff {f: α →₀ M} {g : α → M → ℕ} {p :
135135
p ∣ f.prod g ↔ ∃ a ∈ f.support, p ∣ g a (f a) :=
136136
prime.dvd_finset_prod_iff pp _
137137

138-
/-- Prime `p` divides the product of a list `L` iff it divides some `a ∈ L` -/
139-
lemma prime.dvd_prod_iff {p : M} {L : list M} (pp : prime p) :
140-
p ∣ L.prod ↔ ∃ a ∈ L, p ∣ a :=
141-
begin
142-
split,
143-
{ intros h,
144-
induction L,
145-
{ simp only [list.prod_nil] at h, exact absurd h (prime.not_dvd_one pp) },
146-
{ rw list.prod_cons at h,
147-
cases (prime.dvd_or_dvd pp) h, { use L_hd, simp [h_1] },
148-
{ rcases L_ih h_1 with ⟨x, hx1, hx2⟩, use x, simp [list.mem_cons_iff, hx1, hx2] } } },
149-
{ exact λ ⟨a, ha1, ha2⟩, dvd_trans ha2 (list.dvd_prod ha1) },
150-
end
151-
152138
end comm_monoid_with_zero
153-
154-
lemma nat.prime.dvd_finset_prod_iff {α : Type*} {S : finset α} {p : ℕ}
155-
(pp : prime p) (g : α → ℕ) : p ∣ S.prod g ↔ ∃ a ∈ S, p ∣ g a :=
156-
by apply prime.dvd_finset_prod_iff pp
157-
158-
lemma nat.prime.dvd_finsupp_prod_iff {α M : Type*} [has_zero M] {f: α →₀ M}
159-
{g : α → M → ℕ} {p : ℕ} (pp : prime p) :
160-
p ∣ f.prod g ↔ ∃ a ∈ f.support, p ∣ g a (f a) :=
161-
nat.prime.dvd_finset_prod_iff pp _

src/data/list/prime.lean

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/-
2+
Copyright (c) 2018 Johannes Hölzl. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Johannes Hölzl, Jens Wagemaker, Anne Baanen
5+
-/
6+
7+
import algebra.associated
8+
import data.list.big_operators
9+
import data.list.perm
10+
11+
/-!
12+
# Products of lists of prime elements.
13+
14+
This file contains some theorems relating `prime` and products of `list`s.
15+
16+
-/
17+
18+
open list
19+
20+
section comm_monoid_with_zero
21+
22+
variables {M : Type*} [comm_monoid_with_zero M]
23+
24+
/-- Prime `p` divides the product of a list `L` iff it divides some `a ∈ L` -/
25+
lemma prime.dvd_prod_iff {p : M} {L : list M} (pp : prime p) : p ∣ L.prod ↔ ∃ a ∈ L, p ∣ a :=
26+
begin
27+
split,
28+
{ intros h,
29+
induction L with L_hd L_tl L_ih,
30+
{ rw prod_nil at h, exact absurd h pp.not_dvd_one },
31+
{ rw prod_cons at h,
32+
cases pp.dvd_or_dvd h with hd hd,
33+
{ exact ⟨L_hd, mem_cons_self L_hd L_tl, hd⟩ },
34+
{ obtain ⟨x, hx1, hx2⟩ := L_ih hd,
35+
exact ⟨x, mem_cons_of_mem L_hd hx1, hx2⟩ } } },
36+
{ exact λ ⟨a, ha1, ha2⟩, dvd_trans ha2 (dvd_prod ha1) },
37+
end
38+
39+
lemma prime.not_dvd_prod {p : M} {L : list M} (pp : prime p) (hL : ∀ a ∈ L, ¬ p ∣ a) :
40+
¬ p ∣ L.prod :=
41+
mt (prime.dvd_prod_iff pp).mp $ not_bex.mpr hL
42+
43+
end comm_monoid_with_zero
44+
45+
section cancel_comm_monoid_with_zero
46+
47+
variables {M : Type*} [cancel_comm_monoid_with_zero M] [unique (units M)]
48+
49+
lemma prime_dvd_prime_iff_eq {p q : M} (pp : prime p) (qp : prime q) : p ∣ q ↔ p = q :=
50+
by rw [pp.dvd_prime_iff_associated qp, ←associated_eq_eq]
51+
52+
lemma mem_list_primes_of_dvd_prod {p : M} (hp : prime p) {L : list M} (hL : ∀ q ∈ L, prime q)
53+
(hpL : p ∣ L.prod) : p ∈ L :=
54+
begin
55+
obtain ⟨x, hx1, hx2⟩ := hp.dvd_prod_iff.mp hpL,
56+
rwa (prime_dvd_prime_iff_eq hp (hL x hx1)).mp hx2
57+
end
58+
59+
lemma perm_of_prod_eq_prod : ∀ {l₁ l₂ : list M}, l₁.prod = l₂.prod →
60+
(∀ p ∈ l₁, prime p) → (∀ p ∈ l₂, prime p) → perm l₁ l₂
61+
| [] [] _ _ _ := perm.nil
62+
| [] (a :: l) h₁ h₂ h₃ :=
63+
have ha : a ∣ 1 := @prod_nil M _ ▸ h₁.symm ▸ (@prod_cons _ _ l a).symm ▸ dvd_mul_right _ _,
64+
absurd ha (prime.not_dvd_one (h₃ a (mem_cons_self _ _)))
65+
| (a :: l) [] h₁ h₂ h₃ :=
66+
have ha : a ∣ 1 := @prod_nil M _ ▸ h₁ ▸ (@prod_cons _ _ l a).symm ▸ dvd_mul_right _ _,
67+
absurd ha (prime.not_dvd_one (h₂ a (mem_cons_self _ _)))
68+
| (a :: l₁) (b :: l₂) h hl₁ hl₂ :=
69+
begin
70+
classical,
71+
have hl₁' : ∀ p ∈ l₁, prime p := λ p hp, hl₁ p (mem_cons_of_mem _ hp),
72+
have hl₂' : ∀ p ∈ (b :: l₂).erase a, prime p := λ p hp, hl₂ p (mem_of_mem_erase hp),
73+
have ha : a ∈ (b :: l₂) := mem_list_primes_of_dvd_prod (hl₁ a (mem_cons_self _ _)) hl₂
74+
(h ▸ by rw prod_cons; exact dvd_mul_right _ _),
75+
have hb : b :: l₂ ~ a :: (b :: l₂).erase a := perm_cons_erase ha,
76+
have hl : prod l₁ = prod ((b :: l₂).erase a) :=
77+
((mul_right_inj' (hl₁ a (mem_cons_self _ _)).ne_zero).1 $
78+
by rwa [← prod_cons, ← prod_cons, ← hb.prod_eq]),
79+
exact perm.trans ((perm_of_prod_eq_prod hl hl₁' hl₂').cons _) hb.symm
80+
end
81+
82+
end cancel_comm_monoid_with_zero

src/data/nat/prime.lean

Lines changed: 13 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Copyright (c) 2015 Microsoft Corporation. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Leonardo de Moura, Jeremy Avigad, Mario Carneiro
55
-/
6-
import algebra.associated
6+
import data.list.prime
77
import data.list.sort
88
import data.nat.gcd
99
import data.nat.sqrt
@@ -538,28 +538,6 @@ theorem prime_iff {p : ℕ} : p.prime ↔ _root_.prime p :=
538538
theorem irreducible_iff_prime {p : ℕ} : irreducible p ↔ _root_.prime p :=
539539
by rw [←prime_iff, prime]
540540

541-
/-- Prime `p` divides the product of `L : list ℕ` iff it divides some `a ∈ L` -/
542-
lemma prime.dvd_prod_iff {p : ℕ} {L : list ℕ} (pp : p.prime) :
543-
p ∣ L.prod ↔ ∃ a ∈ L, p ∣ a :=
544-
begin
545-
split,
546-
{ intros h,
547-
induction L,
548-
{ simp only [list.prod_nil] at h, exact absurd h (prime.not_dvd_one pp) },
549-
{ rw list.prod_cons at h,
550-
cases (prime.dvd_mul pp).mp h,
551-
{ use L_hd, simp [h_1] },
552-
{ rcases L_ih h_1 with ⟨x, hx1, hx2⟩, use x, simp [list.mem_cons_iff, hx1, hx2] } } },
553-
{ exact λ ⟨a, ha1, ha2⟩, dvd_trans ha2 (list.dvd_prod ha1) },
554-
end
555-
-- TODO: This proof duplicates a more general proof in `algebra/associated`.
556-
-- The two proofs should be integrated after the merger of `nat.prime` and `prime`
557-
-- that's about to occur. (2021-12-17)
558-
559-
lemma prime.not_dvd_prod {p : ℕ} {L : list ℕ} (pp : prime p) (hL : ∀ a ∈ L, ¬ p ∣ a) :
560-
¬ p ∣ L.prod :=
561-
mt (prime.dvd_prod_iff pp).mp (not_bex.mpr hL)
562-
563541
theorem prime.dvd_of_dvd_pow {p m n : ℕ} (pp : prime p) (h : p ∣ m^n) : p ∣ m :=
564542
begin
565543
induction n with n IH,
@@ -723,17 +701,12 @@ by simpa using not_iff_not.mpr ne_one_iff_exists_prime_dvd
723701
section
724702
open list
725703

726-
lemma mem_list_primes_of_dvd_prod {p : ℕ} (hp : prime p) :
727-
∀ {l : list ℕ}, (∀ p ∈ l, prime p) → p ∣ prod l → p ∈ l :=
728-
begin
729-
intros L hL hpL,
730-
rcases (prime.dvd_prod_iff hp).mp hpL with ⟨x, hx1, hx2⟩,
731-
rwa ((prime_dvd_prime_iff_eq hp (hL x hx1)).mp hx2)
732-
end
733-
734704
lemma mem_factors_iff_dvd {n p : ℕ} (hn : 0 < n) (hp : prime p) : p ∈ factors n ↔ p ∣ n :=
735705
⟨λ h, prod_factors hn ▸ list.dvd_prod h,
736-
λ h, mem_list_primes_of_dvd_prod hp (@prime_of_mem_factors n) ((prod_factors hn).symm ▸ h)⟩
706+
λ h, mem_list_primes_of_dvd_prod
707+
(prime_iff.mp hp)
708+
(λ p h, prime_iff.mp (prime_of_mem_factors h))
709+
((prod_factors hn).symm ▸ h)⟩
737710

738711
lemma dvd_of_mem_factors {n p : ℕ} (h : p ∈ n.factors) : p ∣ n :=
739712
begin
@@ -746,36 +719,18 @@ lemma mem_factors {n p} (hn : 0 < n) : p ∈ factors n ↔ prime p ∧ p ∣ n :
746719
⟨λ h, ⟨prime_of_mem_factors h, (mem_factors_iff_dvd hn $ prime_of_mem_factors h).mp h⟩,
747720
λ ⟨hprime, hdvd⟩, (mem_factors_iff_dvd hn hprime).mpr hdvd⟩
748721

749-
lemma perm_of_prod_eq_prod : ∀ {l₁ l₂ : list ℕ}, prod l₁ = prod l₂ →
750-
(∀ p ∈ l₁, prime p) → (∀ p ∈ l₂, prime p) → l₁ ~ l₂
751-
| [] [] _ _ _ := perm.nil
752-
| [] (a :: l) h₁ h₂ h₃ :=
753-
have ha : a ∣ 1 := @prod_nil ℕ _ ▸ h₁.symm ▸ (@prod_cons _ _ l a).symm ▸ dvd_mul_right _ _,
754-
absurd ha (prime.not_dvd_one (h₃ a (mem_cons_self _ _)))
755-
| (a :: l) [] h₁ h₂ h₃ :=
756-
have ha : a ∣ 1 := @prod_nil ℕ _ ▸ h₁ ▸ (@prod_cons _ _ l a).symm ▸ dvd_mul_right _ _,
757-
absurd ha (prime.not_dvd_one (h₂ a (mem_cons_self _ _)))
758-
| (a :: l₁) (b :: l₂) h hl₁ hl₂ :=
759-
have hl₁' : ∀ p ∈ l₁, prime p := λ p hp, hl₁ p (mem_cons_of_mem _ hp),
760-
have hl₂' : ∀ p ∈ (b :: l₂).erase a, prime p := λ p hp, hl₂ p (mem_of_mem_erase hp),
761-
have ha : a ∈ (b :: l₂) := mem_list_primes_of_dvd_prod (hl₁ a (mem_cons_self _ _)) hl₂
762-
(h ▸ by rw prod_cons; exact dvd_mul_right _ _),
763-
have hb : b :: l₂ ~ a :: (b :: l₂).erase a := perm_cons_erase ha,
764-
have hl : prod l₁ = prod ((b :: l₂).erase a) :=
765-
(nat.mul_right_inj (prime.pos (hl₁ a (mem_cons_self _ _)))).1 $
766-
by rwa [← prod_cons, ← prod_cons, ← hb.prod_eq],
767-
perm.trans ((perm_of_prod_eq_prod hl hl₁' hl₂').cons _) hb.symm
768-
769722
/-- **Fundamental theorem of arithmetic**-/
770723
lemma factors_unique {n : ℕ} {l : list ℕ} (h₁ : prod l = n) (h₂ : ∀ p ∈ l, prime p) :
771724
l ~ factors n :=
772725
begin
773-
refine perm_of_prod_eq_prod _ h₂ (λ p, prime_of_mem_factors),
774-
rw h₁,
775-
refine (prod_factors (nat.pos_of_ne_zero _)).symm,
776-
rintro rfl,
777-
rw prod_eq_zero_iff at h₁,
778-
exact prime.ne_zero (h₂ 0 h₁) rfl,
726+
refine perm_of_prod_eq_prod _ _ _,
727+
{ rw h₁,
728+
refine (prod_factors (nat.pos_of_ne_zero _)).symm,
729+
rintro rfl,
730+
rw prod_eq_zero_iff at h₁,
731+
exact prime.ne_zero (h₂ 0 h₁) rfl },
732+
{ simp_rw ←prime_iff, exact h₂ },
733+
{ simp_rw ←prime_iff, exact (λ p, prime_of_mem_factors) },
779734
end
780735

781736
lemma prime.factors_pow {p : ℕ} (hp : p.prime) (n : ℕ) :

0 commit comments

Comments
 (0)