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

Commit c238aad

Browse files
committed
refactor(data/nat): simplify find_greatest; fix namespace nat.nat.find_greatest -> nat.find_greatest
1 parent 83edcc0 commit c238aad

File tree

1 file changed

+48
-60
lines changed

1 file changed

+48
-60
lines changed

data/nat/basic.lean

Lines changed: 48 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ protected theorem eq_mul_of_div_eq_left {a b c : ℕ} (H1 : b ∣ a) (H2 : a / b
181181
by rw [mul_comm, nat.eq_mul_of_div_eq_right H1 H2]
182182

183183
protected theorem mul_div_cancel_left' {a b : ℕ} (Hd : a ∣ b) : a * (b / a) = b :=
184-
by rw [mul_comm,nat.div_mul_cancel Hd]
184+
by rw [mul_comm,nat.div_mul_cancel Hd]
185185

186186
protected theorem div_mod_unique {n k m d : ℕ} (h : 0 < k) :
187187
n / k = d ∧ n % k = m ↔ m + k * d = n ∧ m < k :=
@@ -388,31 +388,31 @@ theorem pow_dvd_pow_of_dvd {a b : ℕ} (h : a ∣ b) : ∀ n:ℕ, a^n ∣ b^n
388388
| 0 := dvd_refl _
389389
| (n+1) := mul_dvd_mul (pow_dvd_pow_of_dvd n) h
390390

391-
theorem mul_pow (a b n : ℕ) : (a * b) ^ n = a ^ n * b ^ n :=
391+
theorem mul_pow (a b n : ℕ) : (a * b) ^ n = a ^ n * b ^ n :=
392392
by induction n; simp [*, nat.pow_succ, mul_comm, mul_assoc, mul_left_comm]
393393

394394
protected theorem pow_mul (a b n : ℕ) : n ^ (a * b) = (n ^ a) ^ b :=
395395
by induction b; simp [*, nat.succ_eq_add_one, nat.pow_add, mul_add, mul_comm]
396396

397397
theorem pow_pos {p : ℕ} (hp : p > 0) : ∀ n : ℕ, p ^ n > 0
398-
| 0 := by simpa using zero_lt_one
399-
| (k+1) := mul_pos (pow_pos _) hp
398+
| 0 := by simpa using zero_lt_one
399+
| (k+1) := mul_pos (pow_pos _) hp
400400

401401
lemma pow_eq_mul_pow_sub (p : ℕ) {m n : ℕ} (h : m ≤ n) : p ^ m * p ^ (n - m) = p ^ n :=
402-
by rw [←nat.pow_add, nat.add_sub_cancel' h]
402+
by rw [←nat.pow_add, nat.add_sub_cancel' h]
403403

404404
lemma pow_lt_pow_succ {p : ℕ} (h : p > 1) (n : ℕ) : p^n < p^(n+1) :=
405405
suffices p^n*1 < p^n*p, by simpa,
406-
nat.mul_lt_mul_of_pos_left h (nat.pow_pos (lt_of_succ_lt h) n)
406+
nat.mul_lt_mul_of_pos_left h (nat.pow_pos (lt_of_succ_lt h) n)
407407

408408
lemma lt_pow_self {p : ℕ} (h : p > 1) : ∀ n : ℕ, n < p ^ n
409409
| 0 := by simp [zero_lt_one]
410410
| (n+1) := calc
411411
n + 1 < p^n + 1 : nat.add_lt_add_right (lt_pow_self _) _
412-
... ≤ p ^ (n+1) : pow_lt_pow_succ h _
412+
... ≤ p ^ (n+1) : pow_lt_pow_succ h _
413413

414414
lemma not_pos_pow_dvd : ∀ {p k : ℕ} (hp : p > 1) (hk : k > 1), ¬ p^k ∣ p
415-
| (succ p) (succ k) hp hk h :=
415+
| (succ p) (succ k) hp hk h :=
416416
have (succ p)^k * succ p ∣ 1 * succ p, by simpa,
417417
have (succ p) ^ k ∣ 1, from dvd_of_mul_dvd_mul_right (succ_pos _) this,
418418
have he : (succ p) ^ k = 1, from eq_one_of_dvd_one this,
@@ -578,51 +578,39 @@ le_of_dvd (fact_pos _) (fact_dvd_fact h)
578578

579579
section find_greatest
580580

581-
private def nat.find_greatest_core_aux (P : ℕ → Prop) [decidable_pred P] (bound : ℕ) :
582-
Π m : ℕ, (∀ k, m < k ∧ k ≤ bound → ¬ P k) →
583-
psum {n // P n ∧ ∀ k, n < k ∧ k ≤ bound → ¬ P k} (∀ k, k ≤ bound → ¬ P k)
584-
| 0 h := if hp0 : P 0 then psum.inl ⟨0, hp0, h⟩ else psum.inr $
585-
λ k hk, if hk0 : 0 = k then by rwa hk0 at hp0 else h _ ⟨lt_of_le_of_ne (nat.zero_le _) hk0, hk⟩
586-
| (m+1) h :=
587-
if hkp : P (m+1) then psum.inl ⟨m+1, hkp, h⟩
588-
else nat.find_greatest_core_aux m $
589-
λ k ⟨hmk, hkb⟩, if hm1k : m + 1 = k then by rwa hm1k at hkp else
590-
have m + 1 < k, from lt_of_le_of_ne (nat.succ_le_of_lt hmk) hm1k,
591-
h _ ⟨this, hkb⟩
592-
593-
594-
protected def nat.find_greatest_core (P : ℕ → Prop) [decidable_pred P] (bound : ℕ) :
595-
psum {n // P n ∧ ∀ k, n < k ∧ k ≤ bound → ¬ P k} (∀ k, k ≤ bound → ¬ P k) :=
596-
nat.find_greatest_core_aux P bound bound $ λ _ ⟨hlt, hle⟩, false.elim $ not_le_of_gt hlt hle
597-
598-
protected def nat.find_greatest_aux {P : ℕ → Prop} [decidable_pred P] {bound : ℕ} :
599-
psum {n // P n ∧ ∀ k, n < k ∧ k ≤ bound → ¬ P k} (∀ k, k ≤ bound → ¬ P k) → ℕ
600-
| (psum.inl ⟨n, _⟩) := n
601-
| (psum.inr _) := 0
602-
603-
/--
604-
Finds the largest n ≤ bound such that P n holds, or returns 0 if no such n exists
605-
-/
606-
protected def nat.find_greatest (P : ℕ → Prop) [decidable_pred P] (bound : ℕ) : ℕ :=
607-
nat.find_greatest_aux $ nat.find_greatest_core P bound
608-
609-
lemma nat.find_greatest_spec {P : ℕ → Prop} [decidable_pred P] {bound : ℕ}
610-
(hex : ∃ m, m ≤ bound ∧ P m) : P (nat.find_greatest P bound) :=
611-
begin
612-
unfold nat.find_greatest,
613-
rcases nat.find_greatest_core P bound with ⟨n, hn⟩ | h,
614-
{ cases hn; simpa only [nat.find_greatest_aux] },
615-
{ apply absurd hex, simpa }
616-
end
617-
618-
lemma nat.find_greatest_is_greatest {P : ℕ → Prop} [decidable_pred P] {bound : ℕ}
619-
(hex : ∃ m, m ≤ bound ∧ P m) : ∀ k, nat.find_greatest P bound < k ∧ k ≤ bound → ¬ P k :=
620-
begin
621-
unfold nat.find_greatest,
622-
rcases nat.find_greatest_core P bound with ⟨n, hn⟩ | h,
623-
{ cases hn; simpa only [nat.find_greatest_aux] },
624-
{ apply absurd hex, simpa }
625-
end
581+
/-- `find_greatest P b` is the largest `i ≤ bound` such that `P i` holds, or `0` if no such `i`
582+
exists -/
583+
protected def find_greatest (P : ℕ → Prop) [decidable_pred P] : ℕ → ℕ
584+
| 0 := 0
585+
| (n + 1) := if P (n + 1) then n + 1 else find_greatest n
586+
587+
variables {P : ℕ → Prop} [decidable_pred P]
588+
589+
lemma find_greatest_spec_and_le :
590+
∀{b m}, m ≤ b → P m → P (nat.find_greatest P b) ∧ m ≤ nat.find_greatest P b
591+
| 0 m hm hP :=
592+
have m = 0, from le_antisymm hm (nat.zero_le _),
593+
show P 0 ∧ m ≤ 0, from this ▸ ⟨hP, le_refl _⟩
594+
| (b + 1) m hm hP :=
595+
begin
596+
by_cases h : P (b + 1),
597+
{ simp [nat.find_greatest, h, hm] },
598+
{ have : m ≠ b + 1 := assume this, h $ this ▸ hP,
599+
have : m ≤ b := (le_of_not_gt $ assume h : b + 1 ≤ m, this $ le_antisymm hm h),
600+
have : P (nat.find_greatest P b) ∧ m ≤ nat.find_greatest P b :=
601+
find_greatest_spec_and_le this hP,
602+
simp [nat.find_greatest, h, this], }
603+
end
604+
605+
lemma find_greatest_spec {b} : (∃m, m ≤ b ∧ P m) → P (nat.find_greatest P b)
606+
| ⟨m, hmb, hm⟩ := (find_greatest_spec_and_le hmb hm).1
607+
608+
lemma le_find_greatest {b m} (hmb : m ≤ b) (hm : P m) : m ≤ nat.find_greatest P b :=
609+
(find_greatest_spec_and_le hmb hm).2
610+
611+
lemma find_greatest_is_greatest {P : ℕ → Prop} [decidable_pred P] {b} :
612+
(∃ m, m ≤ b ∧ P m) → ∀ k, nat.find_greatest P b < k ∧ k ≤ b → ¬ P k
613+
| ⟨m, hmb, hP⟩ k ⟨hk, hkb⟩ hPk := lt_irrefl k $ lt_of_le_of_lt (le_find_greatest hkb hPk) hk
626614

627615
end find_greatest
628616

@@ -631,7 +619,7 @@ lemma dvd_div_of_mul_dvd {a b c : ℕ} (h : a * b ∣ c) : b ∣ c / a :=
631619
if ha : a = 0 then
632620
by simp [ha]
633621
else
634-
have ha : a > 0, from nat.pos_of_ne_zero ha,
622+
have ha : a > 0, from nat.pos_of_ne_zero ha,
635623
have h1 : ∃ d, c = a * b * d, from h,
636624
let ⟨d, hd⟩ := h1 in
637625
have hac : a ∣ c, from dvd_of_mul_right_dvd h,
@@ -646,28 +634,28 @@ have h3 : b = a * d * c, from
646634
nat.eq_mul_of_div_eq_left hab hd,
647635
show ∃ d, b = c * a * d, from ⟨d, by cc⟩
648636

649-
lemma nat.div_mul_div {a b c d : ℕ} (hab : b ∣ a) (hcd : d ∣ c) :
637+
lemma nat.div_mul_div {a b c d : ℕ} (hab : b ∣ a) (hcd : d ∣ c) :
650638
(a / b) * (c / d) = (a * c) / (b * d) :=
651639
have exi1 : ∃ x, a = b * x, from hab,
652640
have exi2 : ∃ y, c = d * y, from hcd,
653-
if hb : b = 0 then by simp [hb]
641+
if hb : b = 0 then by simp [hb]
654642
else have b > 0, from nat.pos_of_ne_zero hb,
655643
if hd : d = 0 then by simp [hd]
656644
else have d > 0, from nat.pos_of_ne_zero hd,
657-
begin
645+
begin
658646
cases exi1 with x hx, cases exi2 with y hy,
659-
rw [hx, hy, nat.mul_div_cancel_left, nat.mul_div_cancel_left],
647+
rw [hx, hy, nat.mul_div_cancel_left, nat.mul_div_cancel_left],
660648
symmetry,
661649
apply nat.div_eq_of_eq_mul_left,
662650
apply mul_pos,
663651
repeat {assumption},
664652
cc
665-
end
653+
end
666654

667655
lemma pow_div_of_le_of_pow_div {p m n k : ℕ} (hmn : m ≤ n) (hdiv : p ^ n ∣ k) : p ^ m ∣ k :=
668656
have p ^ m ∣ p ^ n, from pow_dvd_pow _ hmn,
669657
dvd_trans this hdiv
670658

671-
end div
659+
end div
672660

673661
end nat

0 commit comments

Comments
 (0)