Skip to content

Commit

Permalink
feat(data/nat/basic): split exists_lt_and_lt_iff_not_dvd into if
Browse files Browse the repository at this point in the history
…and `iff` lemmas (#15099)

Pull out from `exists_lt_and_lt_iff_not_dvd` ("`n` is not divisible by `a` iff it is between `a * k` and `a * (k + 1)` for some `k`") a separate lemma proving the forward direction (which doesn't need the `0 < a` assumption) and use this to golf the `iff` lemma.

Also renames the lemma to the more descriptive `not_dvd_{of,iff}_between_consec_multiples`.
  • Loading branch information
stuart-presnell committed Jul 11, 2022
1 parent 67779f7 commit e3e4cc6
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 14 deletions.
28 changes: 16 additions & 12 deletions src/data/nat/basic.lean
Expand Up @@ -1268,24 +1268,28 @@ begin
{ exact nat.div_eq_zero (m.mod_lt n.succ_pos) }
end

/-- `m` is not divisible by `n` iff it is between `n * k` and `n * (k + 1)` for some `k`. -/
lemma exists_lt_and_lt_iff_not_dvd (m : ℕ) {n : ℕ} (hn : 0 < n) :
(∃ k, n * k < m ∧ m < n * (k + 1)) ↔ ¬ nm :=
/-- `n` is not divisible by `a` if it is between `a * k` and `a * (k + 1)` for some `k`. -/
lemma not_dvd_of_between_consec_multiples {n a k : ℕ} (h1 : a * k < n) (h2 : n < a * (k + 1)) :
¬ an :=
begin
split,
{ rintro ⟨k, h1k, h2k⟩ ⟨l, rfl⟩, rw [mul_lt_mul_left hn] at h1k h2k,
rw [lt_succ_iff, ← not_lt] at h2k, exact h2k h1k },
{ intro h, rw [dvd_iff_mod_eq_zero, ← ne.def, ← pos_iff_ne_zero] at h,
simp only [← mod_add_div m n] {single_pass := tt},
refine ⟨m / n, lt_add_of_pos_left _ h, _⟩,
rw [add_comm _ 1, left_distrib, mul_one], exact add_lt_add_right (mod_lt _ hn) _ }
rintro ⟨d, rfl⟩,
exact monotone.ne_of_lt_of_lt_nat (covariant.monotone_of_const a) k h1 h2 d rfl,
end

/-- `n` is not divisible by `a` iff it is between `a * k` and `a * (k + 1)` for some `k`. -/
lemma not_dvd_iff_between_consec_multiples (n : ℕ) {a : ℕ} (ha : 0 < a) :
(∃ k : ℕ, a * k < n ∧ n < a * (k + 1)) ↔ ¬ a ∣ n :=
begin
refine ⟨λ ⟨k, hk1, hk2⟩, not_dvd_of_between_consec_multiples hk1 hk2,
λ han, ⟨n/a, ⟨lt_of_le_of_ne (mul_div_le n a) _, lt_mul_div_succ _ ha⟩⟩⟩,
exact mt (dvd.intro (n/a)) han,
end

/-- Two natural numbers are equal if and only if the have the same multiples. -/
/-- Two natural numbers are equal if and only if they have the same multiples. -/
lemma dvd_right_iff_eq {m n : ℕ} : (∀ a : ℕ, m ∣ a ↔ n ∣ a) ↔ m = n :=
⟨λ h, dvd_antisymm ((h _).mpr dvd_rfl) ((h _).mp dvd_rfl), λ h n, by rw h⟩

/-- Two natural numbers are equal if and only if the have the same divisors. -/
/-- Two natural numbers are equal if and only if they have the same divisors. -/
lemma dvd_left_iff_eq {m n : ℕ} : (∀ a : ℕ, a ∣ m ↔ a ∣ n) ↔ m = n :=
⟨λ h, dvd_antisymm ((h _).mp dvd_rfl) ((h _).mpr dvd_rfl), λ h n, by rw h⟩

Expand Down
5 changes: 3 additions & 2 deletions src/data/nat/multiplicity.lean
Expand Up @@ -120,7 +120,8 @@ begin
revert hm,
have h4 : ∀ m ∈ Ico (p * n + 1) (p * (n + 1)), multiplicity p m = 0,
{ intros m hm, apply multiplicity_eq_zero_of_not_dvd,
rw [← exists_lt_and_lt_iff_not_dvd _ (pos_iff_ne_zero.mpr hp.ne_zero)], rw [mem_Ico] at hm,
rw [← not_dvd_iff_between_consec_multiples _ (pos_iff_ne_zero.mpr hp.ne_zero)],
rw [mem_Ico] at hm,
exact ⟨n, lt_of_succ_le hm.1, hm.2⟩ },
simp_rw [← prod_Ico_id_eq_factorial, multiplicity.finset.prod hp', ← sum_Ico_consecutive _ h1 h3,
add_assoc], intro h,
Expand Down Expand Up @@ -194,7 +195,7 @@ lemma multiplicity_le_multiplicity_choose_add {p : ℕ} (hp : p.prime) : ∀ (n
multiplicity p n ≤ multiplicity p (choose n k) + multiplicity p k
| _ 0 := by simp
| 0 (_+1) := by simp
| (n+1) (k+1) :=
| (n+1) (k+1) :=
begin
rw ← hp.multiplicity_mul,
refine multiplicity_le_multiplicity_of_dvd_right _,
Expand Down

0 comments on commit e3e4cc6

Please sign in to comment.