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

Commit 74c25a5

Browse files
fpvandoornmergify[bot]
authored andcommitted
feat(*): lemmas needed for two projects (#1294)
* feat(multiplicity|enat): add facts needed for IMO 2019-4 * feat(*): various lemmas needed for the cubing a cube proof * typo * some cleanup * fixes, add choose_two_right * projections for associated.prime and irreducible
1 parent fa68342 commit 74c25a5

19 files changed

+388
-35
lines changed

src/algebra/associated.lean

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -110,22 +110,47 @@ lemma dvd_and_not_dvd_iff [integral_domain α] {x y : α} :
110110
λ ⟨hx0, d, hdu, hdx⟩, ⟨⟨d, hdx⟩, λ ⟨e, he⟩, hdu (is_unit_of_dvd_one _
111111
⟨e, (domain.mul_left_inj hx0).1 $ by conv {to_lhs, rw [he, hdx]};simp [mul_assoc]⟩)⟩⟩
112112

113+
lemma pow_dvd_pow_iff [integral_domain α] {x : α} {n m : ℕ} (h0 : x ≠ 0) (h1 : ¬ is_unit x) :
114+
x ^ n ∣ x ^ m ↔ n ≤ m :=
115+
begin
116+
split,
117+
{ intro h, rw [← not_lt], intro hmn, apply h1,
118+
have : x * x ^ m ∣ 1 * x ^ m,
119+
{ rw [← pow_succ, one_mul], exact dvd_trans (pow_dvd_pow _ (nat.succ_le_of_lt hmn)) h },
120+
rwa [mul_dvd_mul_iff_right, ← is_unit_iff_dvd_one] at this, apply pow_ne_zero m h0 },
121+
{ apply pow_dvd_pow }
122+
end
123+
113124
/-- prime element of a semiring -/
114125
def prime [comm_semiring α] (p : α) : Prop :=
115126
p ≠ 0 ∧ ¬ is_unit p ∧ (∀a b, p ∣ a * b → p ∣ a ∨ p ∣ b)
116127

117-
@[simp] lemma not_prime_zero [integral_domain α] : ¬ prime (0 : α)
118-
| ⟨h, _⟩ := h rfl
128+
namespace prime
129+
130+
lemma ne_zero [comm_semiring α] {p : α} (hp : prime p) : p ≠ 0 :=
131+
hp.1
132+
133+
lemma not_unit [comm_semiring α] {p : α} (hp : prime p) : ¬ is_unit p :=
134+
hp.2.1
135+
136+
lemma div_or_div [comm_semiring α] {p : α} (hp : prime p) {a b : α} (h : p ∣ a * b) :
137+
p ∣ a ∨ p ∣ b :=
138+
hp.2.2 a b h
139+
140+
end prime
141+
142+
@[simp] lemma not_prime_zero [comm_semiring α] : ¬ prime (0 : α) :=
143+
λ h, h.ne_zero rfl
119144

120145
@[simp] lemma not_prime_one [comm_semiring α] : ¬ prime (1 : α) :=
121-
λ h, h.2.1 is_unit_one
146+
λ h, h.not_unit is_unit_one
122147

123148
lemma exists_mem_multiset_dvd_of_prime [comm_semiring α] {s : multiset α} {p : α} (hp : prime p) :
124149
p ∣ s.prod → ∃a∈s, p ∣ a :=
125-
multiset.induction_on s (assume h, (hp.2.1 $ is_unit_of_dvd_one _ h).elim) $
150+
multiset.induction_on s (assume h, (hp.not_unit $ is_unit_of_dvd_one _ h).elim) $
126151
assume a s ih h,
127152
have p ∣ a * s.prod, by simpa using h,
128-
match hp.2.2 a s.prod this with
153+
match hp.div_or_div this with
129154
| or.inl h := ⟨a, multiset.mem_cons_self a s, h⟩
130155
| or.inr h := let ⟨a, has, h⟩ := ih h in ⟨a, multiset.mem_cons_of_mem has, h⟩
131156
end
@@ -138,14 +163,25 @@ monoid allows us to reuse irreducible for associated elements.
138163
@[class] def irreducible [monoid α] (p : α) : Prop :=
139164
¬ is_unit p ∧ ∀a b, p = a * b → is_unit a ∨ is_unit b
140165

166+
namespace irreducible
167+
168+
lemma not_unit [monoid α] {p : α} (hp : irreducible p) : ¬ is_unit p :=
169+
hp.1
170+
171+
lemma is_unit_or_is_unit [monoid α] {p : α} (hp : irreducible p) {a b : α} (h : p = a * b) :
172+
is_unit a ∨ is_unit b :=
173+
hp.2 a b h
174+
175+
end irreducible
176+
141177
@[simp] theorem not_irreducible_one [monoid α] : ¬ irreducible (1 : α) :=
142178
by simp [irreducible]
143179

144180
@[simp] theorem not_irreducible_zero [semiring α] : ¬ irreducible (0 : α)
145181
| ⟨hn0, h⟩ := have is_unit (0:α) ∨ is_unit (0:α), from h 0 0 ((mul_zero 0).symm),
146182
this.elim hn0 hn0
147183

148-
theorem ne_zero_of_irreducible [semiring α] : ∀ {p:α}, irreducible p → p ≠ 0
184+
theorem irreducible.ne_zero [semiring α] : ∀ {p:α}, irreducible p → p ≠ 0
149185
| _ hp rfl := not_irreducible_zero hp
150186

151187
theorem of_irreducible_mul {α} [monoid α] {x y : α} :
@@ -164,8 +200,8 @@ begin
164200
end
165201

166202
lemma irreducible_of_prime [integral_domain α] {p : α} (hp : prime p) : irreducible p :=
167-
⟨hp.2.1, λ a b hab,
168-
(show a * b ∣ a ∨ a * b ∣ b, from hab ▸ hp.2.2 a b (hab ▸ (dvd_refl _))).elim
203+
⟨hp.not_unit, λ a b hab,
204+
(show a * b ∣ a ∨ a * b ∣ b, from hab ▸ hp.div_or_div (hab ▸ (dvd_refl _))).elim
169205
(λ ⟨x, hx⟩, or.inr (is_unit_iff_dvd_one.2
170206
⟨x, (domain.mul_left_inj (show a ≠ 0, from λ h, by simp [*, prime] at *)).1
171207
$ by conv {to_lhs, rw hx}; simp [mul_comm, mul_assoc, mul_left_comm]⟩))
@@ -179,9 +215,9 @@ lemma succ_dvd_or_succ_dvd_of_succ_sum_dvd_mul [integral_domain α] {p : α} (hp
179215
λ ⟨x, hx⟩ ⟨y, hy⟩ ⟨z, hz⟩,
180216
have h : p ^ (k + l) * (x * y) = p ^ (k + l) * (p * z),
181217
by simpa [mul_comm, _root_.pow_add, hx, hy, mul_assoc, mul_left_comm] using hz,
182-
have hp0: p ^ (k + l) ≠ 0, from pow_ne_zero _ hp.1,
218+
have hp0: p ^ (k + l) ≠ 0, from pow_ne_zero _ hp.ne_zero,
183219
have hpd : p ∣ x * y, from ⟨z, by rwa [domain.mul_left_inj hp0] at h⟩,
184-
(hp.2.2 x y hpd).elim
220+
(hp.div_or_div hpd).elim
185221
(λ ⟨d, hd⟩, or.inl ⟨d, by simp [*, _root_.pow_succ, mul_comm, mul_left_comm, mul_assoc]⟩)
186222
(λ ⟨d, hd⟩, or.inr ⟨d, by simp [*, _root_.pow_succ, mul_comm, mul_left_comm, mul_assoc]⟩)
187223

@@ -244,14 +280,14 @@ end
244280

245281
lemma exists_associated_mem_of_dvd_prod [integral_domain α] {p : α}
246282
(hp : prime p) {s : multiset α} : (∀ r ∈ s, prime r) → p ∣ s.prod → ∃ q ∈ s, p ~ᵤ q :=
247-
multiset.induction_on s (by simp [mt is_unit_iff_dvd_one.2 hp.2.1])
283+
multiset.induction_on s (by simp [mt is_unit_iff_dvd_one.2 hp.not_unit])
248284
(λ a s ih hs hps, begin
249285
rw [multiset.prod_cons] at hps,
250-
cases hp.2.2 _ _ hps with h h,
286+
cases hp.div_or_div hps with h h,
251287
{ use [a, by simp],
252288
cases h with u hu,
253289
cases ((irreducible_of_prime (hs a (multiset.mem_cons.2
254-
(or.inl rfl)))).2 p u hu).resolve_left hp.2.1 with v hv,
290+
(or.inl rfl)))).2 p u hu).resolve_left hp.not_unit with v hv,
255291
exact ⟨v, by simp [hu, hv]⟩ },
256292
{ rcases ih (λ r hr, hs _ (multiset.mem_cons.2 (or.inr hr))) h with ⟨q, hq₁, hq₂⟩,
257293
exact ⟨q, multiset.mem_cons.2 (or.inr hq₁), hq₂⟩ }
@@ -275,10 +311,10 @@ lemma ne_zero_iff_of_associated [comm_semiring α] {a b : α} (h : a ~ᵤ b) : a
275311
by haveI := classical.dec; exact not_iff_not.2 (eq_zero_iff_of_associated h)
276312

277313
lemma prime_of_associated [comm_semiring α] {p q : α} (h : p ~ᵤ q) (hp : prime p) : prime q :=
278-
⟨(ne_zero_iff_of_associated h).1 hp.1,
314+
⟨(ne_zero_iff_of_associated h).1 hp.ne_zero,
279315
let ⟨u, hu⟩ := h in
280-
⟨λ ⟨v, hv⟩, hp.2.1 ⟨v * u⁻¹, by simp [hv.symm, hu.symm]⟩,
281-
hu ▸ by simp [mul_unit_dvd_iff]; exact hp.2.2⟩⟩
316+
⟨λ ⟨v, hv⟩, hp.not_unit ⟨v * u⁻¹, by simp [hv.symm, hu.symm]⟩,
317+
hu ▸ by { simp [mul_unit_dvd_iff], intros a b, exact hp.div_or_div }⟩⟩
282318

283319
lemma prime_iff_of_associated [comm_semiring α] {p q : α}
284320
(h : p ~ᵤ q) : prime p ↔ prime q :=
@@ -477,13 +513,23 @@ iff.intro dvd_of_mk_le_mk mk_le_mk_of_dvd
477513

478514
def prime (p : associates α) : Prop := p ≠ 0 ∧ p ≠ 1 ∧ (∀a b, p ≤ a * b → p ≤ a ∨ p ≤ b)
479515

516+
lemma prime.ne_zero {p : associates α} (hp : prime p) : p ≠ 0 :=
517+
hp.1
518+
519+
lemma prime.ne_one {p : associates α} (hp : prime p) : p ≠ 1 :=
520+
hp.2.1
521+
522+
lemma prime.le_or_le {p : associates α} (hp : prime p) {a b : associates α} (h : p ≤ a * b) :
523+
p ≤ a ∨ p ≤ b :=
524+
hp.2.2 a b h
525+
480526
lemma exists_mem_multiset_le_of_prime {s : multiset (associates α)} {p : associates α}
481527
(hp : prime p) :
482528
p ≤ s.prod → ∃a∈s, p ≤ a :=
483-
multiset.induction_on s (assume ⟨d, eq⟩, (hp.2.1 (mul_eq_one_iff.1 eq).1).elim) $
529+
multiset.induction_on s (assume ⟨d, eq⟩, (hp.ne_one (mul_eq_one_iff.1 eq).1).elim) $
484530
assume a s ih h,
485531
have p ≤ a * s.prod, by simpa using h,
486-
match hp.2.2 a s.prod this with
532+
match hp.le_or_le this with
487533
| or.inl h := ⟨a, multiset.mem_cons_self a s, h⟩
488534
| or.inr h := let ⟨a, has, h⟩ := ih h in ⟨a, multiset.mem_cons_of_mem has, h⟩
489535
end

src/algebra/big_operators.lean

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Authors: Johannes Hölzl
55
66
Some big operators for lists and finite sets.
77
-/
8-
import tactic.tauto data.list.basic data.finset
8+
import tactic.tauto data.list.basic data.finset data.nat.enat
99
import algebra.group algebra.ordered_group algebra.group_power
1010

1111
universes u v w
@@ -354,6 +354,18 @@ lemma sum_nat_cast [add_comm_monoid β] [has_one β] (s : finset α) (f : α →
354354
↑(s.sum f) = s.sum (λa, f a : α → β) :=
355355
(sum_hom _).symm
356356

357+
lemma prod_nat_cast [comm_semiring β] (s : finset α) (f : α → ℕ) :
358+
↑(s.prod f) = s.prod (λa, f a : α → β) :=
359+
(prod_hom _).symm
360+
361+
protected lemma sum_nat_coe_enat [decidable_eq α] (s : finset α) (f : α → ℕ) :
362+
s.sum (λ x, (f x : enat)) = (s.sum f : ℕ) :=
363+
begin
364+
induction s using finset.induction with a s has ih h,
365+
{ simp },
366+
{ simp [has, ih] }
367+
end
368+
357369
lemma le_sum_of_subadditive [add_comm_monoid α] [ordered_comm_monoid β]
358370
(f : α → β) (h_zero : f 0 = 0) (h_add : ∀x y, f (x + y) ≤ f x + f y) (s : finset γ) (g : γ → α) :
359371
f (s.sum g) ≤ s.sum (λc, f (g c)) :=
@@ -520,6 +532,43 @@ calc s₁.sum f = (s₁.filter (λx, f x = 0)).sum f + (s₁.filter (λx, f x
520532

521533
end canonically_ordered_monoid
522534

535+
section linear_ordered_comm_ring
536+
variables [decidable_eq α] [linear_ordered_comm_ring β]
537+
538+
/- this is also true for a ordered commutative multiplicative monoid -/
539+
lemma prod_nonneg {s : finset α} {f : α → β}
540+
(h0 : ∀(x ∈ s), 0 ≤ f x) : 0 ≤ s.prod f :=
541+
begin
542+
induction s using finset.induction with a s has ih h,
543+
{ simp [zero_le_one] },
544+
{ simp [has], apply mul_nonneg, apply h0 a (mem_insert_self a s),
545+
exact ih (λ x H, h0 x (mem_insert_of_mem H)) }
546+
end
547+
548+
/- this is also true for a ordered commutative multiplicative monoid -/
549+
lemma prod_pos {s : finset α} {f : α → β} (h0 : ∀(x ∈ s), 0 < f x) : 0 < s.prod f :=
550+
begin
551+
induction s using finset.induction with a s has ih h,
552+
{ simp [zero_lt_one] },
553+
{ simp [has], apply mul_pos, apply h0 a (mem_insert_self a s),
554+
exact ih (λ x H, h0 x (mem_insert_of_mem H)) }
555+
end
556+
557+
/- this is also true for a ordered commutative multiplicative monoid -/
558+
lemma prod_le_prod {s : finset α} {f g : α → β} (h0 : ∀(x ∈ s), 0 ≤ f x)
559+
(h1 : ∀(x ∈ s), f x ≤ g x) : s.prod f ≤ s.prod g :=
560+
begin
561+
induction s using finset.induction with a s has ih h,
562+
{ simp },
563+
{ simp [has], apply mul_le_mul,
564+
exact h1 a (mem_insert_self a s),
565+
apply ih (λ x H, h0 _ _) (λ x H, h1 _ _); exact (mem_insert_of_mem H),
566+
apply prod_nonneg (λ x H, h0 x (mem_insert_of_mem H)),
567+
apply le_trans (h0 a (mem_insert_self a s)) (h1 a (mem_insert_self a s)) }
568+
end
569+
570+
end linear_ordered_comm_ring
571+
523572
@[simp] lemma card_pi [decidable_eq α] {δ : α → Type*}
524573
(s : finset α) (t : Π a, finset (δ a)) :
525574
(s.pi t).card = s.prod (λ a, card (t a)) :=

src/algebra/order_functions.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ lemma le_iff_le (H : strict_mono f) {a b} :
4545
λ h, (lt_or_eq_of_le h).elim (λ h', le_of_lt (H _ _ h')) (λ h', h' ▸ le_refl _)⟩
4646
end
4747

48+
protected lemma nat {β} [preorder β] {f : ℕ → β} (h : ∀n, f n < f (n+1)) : strict_mono f :=
49+
by { intros n m hnm, induction hnm with m' hnm' ih, apply h, exact lt.trans ih (h _) }
50+
4851
-- `preorder α` isn't strong enough: if the preorder on α is an equivalence relation,
4952
-- then `strict_mono f` is vacuously true.
5053
lemma monotone [partial_order α] [preorder β] {f : α → β} (H : strict_mono f) : monotone f :=

src/algebra/ordered_group.lean

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ instance ordered_cancel_comm_monoid.to_ordered_comm_monoid
401401
{ lt_of_add_lt_add_left := @lt_of_add_lt_add_left _ _, ..H }
402402

403403
section ordered_cancel_comm_monoid
404-
variables [ordered_cancel_comm_monoid α] {a b c : α}
404+
variables [ordered_cancel_comm_monoid α] {a b c x y : α}
405405

406406
@[simp] lemma add_le_add_iff_left (a : α) {b c : α} : a + b ≤ a + c ↔ b ≤ c :=
407407
⟨le_of_add_le_add_left, λ h, add_le_add_left h _⟩
@@ -429,6 +429,18 @@ by rwa add_zero at this
429429
@[simp] lemma lt_add_iff_pos_left (a : α) {b : α} : a < b + a ↔ 0 < b :=
430430
by rw [add_comm, lt_add_iff_pos_right]
431431

432+
@[simp] lemma add_le_iff_nonpos_left : x + y ≤ y ↔ x ≤ 0 :=
433+
by { convert add_le_add_iff_right y, rw [zero_add] }
434+
435+
@[simp] lemma add_le_iff_nonpos_right : x + y ≤ x ↔ y ≤ 0 :=
436+
by { convert add_le_add_iff_left x, rw [add_zero] }
437+
438+
@[simp] lemma add_lt_iff_neg_right : x + y < y ↔ x < 0 :=
439+
by { convert add_lt_add_iff_right y, rw [zero_add] }
440+
441+
@[simp] lemma add_lt_iff_neg_left : x + y < x ↔ y < 0 :=
442+
by { convert add_lt_add_iff_left x, rw [add_zero] }
443+
432444
lemma add_eq_zero_iff_eq_zero_of_nonneg
433445
(ha : 0 ≤ a) (hb : 0 ≤ b) : a + b = 0 ↔ a = 0 ∧ b = 0 :=
434446
⟨λ hab : a + b = 0,

src/data/fin.lean

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,35 @@ rfl
210210
@fin.cases n C H0 Hs i.succ = Hs i :=
211211
by cases i; refl
212212

213+
lemma forall_fin_succ {P : fin (n+1) → Prop} :
214+
(∀ i, P i) ↔ P 0 ∧ (∀ i:fin n, P i.succ) :=
215+
⟨λ H, ⟨H 0, λ i, H _⟩, λ ⟨H0, H1⟩ i, fin.cases H0 H1 i⟩
216+
217+
lemma exists_fin_succ {P : fin (n+1) → Prop} :
218+
(∃ i, P i) ↔ P 0 ∨ (∃i:fin n, P i.succ) :=
219+
⟨λ ⟨i, h⟩, fin.cases or.inl (λ i hi, or.inr ⟨i, hi⟩) i h,
220+
λ h, or.elim h (λ h, ⟨0, h⟩) $ λ⟨i, hi⟩, ⟨i.succ, hi⟩⟩
221+
213222
end rec
214223

224+
section tuple
225+
/- We can think of the type `fin n → α` as `n`-tuples in `α`. Here are some relevant operations. -/
226+
227+
def tail {α} (p : fin (n+1) → α) : fin n → α := λ i, p i.succ
228+
def cons {α} (x : α) (v : fin n → α) : fin (n+1) → α :=
229+
λ j, fin.cases x v j
230+
231+
@[simp] lemma tail_cons {α} (x : α) (p : fin n → α) : tail (cons x p) = p :=
232+
by simp [tail, cons]
233+
234+
@[simp] lemma cons_succ {α} (x : α) (p : fin n → α) (i : fin n) : cons x p i.succ = p i :=
235+
by simp [cons]
236+
237+
@[simp] lemma cons_zero {α} (x : α) (p : fin n → α) : cons x p 0 = x :=
238+
by simp [cons]
239+
240+
end tuple
241+
215242
section find
216243

217244
def find : Π {n : ℕ} (p : fin n → Prop) [decidable_pred p], option (fin n)

src/data/finset.lean

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,16 @@ theorem min_le_of_mem {s : finset α} {a b : α} (h₁ : b ∈ s) (h₂ : a ∈
16161616
by rcases @inf_le (with_top α) _ _ _ _ _ h₁ _ rfl with ⟨b', hb, ab⟩;
16171617
cases h₂.symm.trans hb; assumption
16181618

1619+
lemma exists_min (s : finset β) (f : β → α)
1620+
(h : nonempty ↥(↑s : set β)) : ∃ x ∈ s, ∀ x' ∈ s, f x ≤ f x' :=
1621+
begin
1622+
have : s.image f ≠ ∅,
1623+
rwa [ne, image_eq_empty, ← ne.def, ← nonempty_iff_ne_empty],
1624+
cases min_of_ne_empty this with y hy,
1625+
rcases mem_image.mp (mem_of_min hy) with ⟨x, hx, rfl⟩,
1626+
exact ⟨x, hx, λ x' hx', min_le_of_mem (mem_image_of_mem f hx') hy⟩
1627+
end
1628+
16191629
end max_min
16201630

16211631
section sort

src/data/multiset.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,9 @@ quot.induction_on s $ λ l, mem_map
613613
@[simp] theorem card_map (f : α → β) (s) : card (map f s) = card s :=
614614
quot.induction_on s $ λ l, length_map _ _
615615

616+
@[simp] theorem multiset.map_eq_zero {s : multiset α} {f : α → β} : s.map f = 0 ↔ s = 0 :=
617+
by rw [← multiset.card_eq_zero, multiset.card_map, multiset.card_eq_zero]
618+
616619
theorem mem_map_of_mem (f : α → β) {a : α} {s : multiset α} (h : a ∈ s) : f a ∈ map f s :=
617620
mem_map.2 ⟨_, h, rfl⟩
618621

0 commit comments

Comments
 (0)