Skip to content

Commit

Permalink
feat(data/nat,data/int): add some modular arithmetic lemmas (#2460)
Browse files Browse the repository at this point in the history
These lemmas (a) were found useful in formalising solutions to some
olympiad problems, see
<https://leanprover.zulipchat.com/#narrow/stream/113489-new-members/topic/Some.20olympiad.20formalisations>;
(b) seem more generally relevant than to just those particular
problems; (c) do not show up through library_search as being already
present.
  • Loading branch information
jsm28 committed Apr 20, 2020
1 parent d1ba87a commit 8adfafd
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/data/int/basic.lean
Expand Up @@ -527,6 +527,14 @@ theorem mod_eq_zero_of_dvd : ∀ {a b : ℤ}, a ∣ b → b % a = 0
theorem dvd_iff_mod_eq_zero (a b : ℤ) : a ∣ b ↔ b % a = 0 :=
⟨mod_eq_zero_of_dvd, dvd_of_mod_eq_zero⟩

/-- If `a % b = c` then `b` divides `a - c`. -/
lemma dvd_sub_of_mod_eq {a b c : ℤ} (h : a % b = c) : b ∣ a - c :=
begin
have hx : a % b % b = c % b, { rw h },
rw [mod_mod, ←mod_sub_cancel_right c, sub_self, zero_mod] at hx,
exact dvd_of_mod_eq_zero hx
end

theorem nat_abs_dvd {a b : ℤ} : (a.nat_abs : ℤ) ∣ b ↔ a ∣ b :=
(nat_abs_eq a).elim (λ e, by rw ← e) (λ e, by rw [← neg_dvd_iff_dvd, ← e])

Expand Down Expand Up @@ -734,6 +742,23 @@ begin
repeat {assumption}
end

/-- If an integer with larger absolute value divides an integer, it is
zero. -/
lemma eq_zero_of_dvd_of_nat_abs_lt_nat_abs {a b : ℤ} (w : a ∣ b) (h : nat_abs b < nat_abs a) :
b = 0 :=
begin
rw [←nat_abs_dvd, ←dvd_nat_abs, coe_nat_dvd] at w,
rw ←nat_abs_eq_zero,
exact eq_zero_of_dvd_of_lt w h
end

/-- If two integers are congruent to a sufficiently large modulus,
they are equal. -/
lemma eq_of_mod_eq_of_nat_abs_sub_lt_nat_abs {a b c : ℤ} (h1 : a % b = c)
(h2 : nat_abs (a - c) < nat_abs b) :
a = c :=
eq_of_sub_eq_zero (eq_zero_of_dvd_of_nat_abs_lt_nat_abs (dvd_sub_of_mod_eq h1) h2)

theorem of_nat_add_neg_succ_of_nat_of_lt {m n : ℕ}
(h : m < n.succ) : of_nat m + -[1+n] = -[1+ n - m] :=
begin
Expand Down
11 changes: 11 additions & 0 deletions src/data/nat/basic.lean
Expand Up @@ -597,6 +597,11 @@ end
(λ n0, by simp [n0])
(λ npos, mod_eq_of_lt (mod_lt _ npos))

/-- If `a` and `b` are equal mod `c`, `a - b` is zero mod `c`. -/
lemma sub_mod_eq_zero_of_mod_eq {a b c : ℕ} (h : a % c = b % c) : (a - b) % c = 0 :=
by rw [←nat.mod_add_div a c, ←nat.mod_add_div b c, ←h, ←nat.sub_sub, nat.add_sub_cancel_left,
←nat.mul_sub_left_distrib, nat.mul_mod_right]

theorem add_pos_left {m : ℕ} (h : 0 < m) (n : ℕ) : 0 < m + n :=
calc
m + n > 0 + n : nat.add_lt_add_right h n
Expand Down Expand Up @@ -1361,6 +1366,12 @@ by rw [←nat.div_mul_cancel w, h, one_mul]
lemma eq_zero_of_dvd_of_div_eq_zero {a b : ℕ} (w : a ∣ b) (h : b / a = 0) : b = 0 :=
by rw [←nat.div_mul_cancel w, h, zero_mul]

/-- If a small natural number is divisible by a larger natural number,
the small number is zero. -/
lemma eq_zero_of_dvd_of_lt {a b : ℕ} (w : a ∣ b) (h : b < a) : b = 0 :=
nat.eq_zero_of_dvd_of_div_eq_zero w
((nat.div_eq_zero_iff (lt_of_le_of_lt (zero_le b) h)).elim_right h)

lemma div_le_div_left {a b c : ℕ} (h₁ : c ≤ b) (h₂ : 0 < c) : a / b ≤ a / c :=
(nat.le_div_iff_mul_le _ _ h₂).2 $
le_trans (mul_le_mul_left _ h₁) (div_mul_le_self _ _)
Expand Down

0 comments on commit 8adfafd

Please sign in to comment.