data.nat.basic
⟷
Mathlib.Data.Nat.Defs
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
div
/mod
as an equivalence on nat
/int
(#18359)
The motivation here is to be able to use this to change a sum/product/supr/infi/tsum/etc to be indexed by a product, such that every n
th term can be collected into an inner / outer sum. We already have the API in most places for equiv
s and prod
s to do this, all that's missing is the equivalences in this PR.
Note that we use [ne_zero n]
instead of hn : n ≠ 0
as this is required by fin.of_nat'
for the coercion.
Co-authored-by: Junyan Xu <junyanxumath@gmail.com>
@@ -543,6 +543,7 @@ by { rw mul_comm, exact mod_add_div _ _ }
lemma div_add_mod' (m k : ℕ) : (m / k) * k + m % k = m :=
by { rw mul_comm, exact div_add_mod _ _ }
+/-- See also `nat.div_mod_equiv` for a similar statement as an `equiv`. -/
protected theorem div_mod_unique {n k m d : ℕ} (h : 0 < k) :
n / k = d ∧ n % k = m ↔ m + k * d = n ∧ m < k :=
⟨λ ⟨e₁, e₂⟩, e₁ ▸ e₂ ▸ ⟨mod_add_div _ _, mod_lt _ h⟩,
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
n ≠ 0
instead of 0 < n
or 1 ≤ n
.1 < n
instead of 2 ≤ n
.nat.exists_eq_add_of_le'
(forward-ported in leanprover-community/mathlib4#1662).@@ -210,18 +210,14 @@ by { rw ←not_iff_not, push_neg, exact forall_lt_succ }
@[simp] theorem add_def {a b : ℕ} : nat.add a b = a + b := rfl
@[simp] theorem mul_def {a b : ℕ} : nat.mul a b = a * b := rfl
-lemma exists_eq_add_of_le : ∀ {m n : ℕ}, m ≤ n → ∃ k : ℕ, n = m + k
-| 0 0 h := ⟨0, by simp⟩
-| 0 (n+1) h := ⟨n+1, by simp⟩
-| (m+1) (n+1) h :=
- let ⟨k, hk⟩ := exists_eq_add_of_le (nat.le_of_succ_le_succ h) in
- ⟨k, by simp [hk, add_comm, add_left_comm]⟩
-
-lemma exists_eq_add_of_lt : ∀ {m n : ℕ}, m < n → ∃ k : ℕ, n = m + k + 1
-| 0 0 h := false.elim $ lt_irrefl _ h
-| 0 (n+1) h := ⟨n, by simp⟩
-| (m+1) (n+1) h := let ⟨k, hk⟩ := exists_eq_add_of_le (nat.le_of_succ_le_succ h) in
- ⟨k, by simp [hk]⟩
+lemma exists_eq_add_of_le (h : m ≤ n) : ∃ k : ℕ, n = m + k :=
+⟨n - m, (nat.add_sub_of_le h).symm⟩
+
+lemma exists_eq_add_of_le' (h : m ≤ n) : ∃ k : ℕ, n = k + m :=
+⟨n - m, (nat.sub_add_cancel h).symm⟩
+
+lemma exists_eq_add_of_lt (h : m < n) : ∃ k : ℕ, n = m + k + 1 :=
+⟨n - (m + 1), by rw [add_right_comm, nat.add_sub_of_le h]⟩
/-! ### `pred` -/
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
@@ -79,15 +79,10 @@ instance : semiring ℕ := infer_instance
protected lemma nat.nsmul_eq_mul (m n : ℕ) : m • n = m * n := rfl
-theorem nat.eq_of_mul_eq_mul_right {n m k : ℕ} (Hm : 0 < m) (H : n * m = k * m) : n = k :=
-by rw [mul_comm n m, mul_comm k m] at H; exact nat.eq_of_mul_eq_mul_left Hm H
-
instance nat.cancel_comm_monoid_with_zero : cancel_comm_monoid_with_zero ℕ :=
{ mul_left_cancel_of_ne_zero :=
λ _ _ _ h1 h2, nat.eq_of_mul_eq_mul_left (nat.pos_of_ne_zero h1) h2,
- mul_right_cancel_of_ne_zero :=
- λ _ _ _ h1 h2, nat.eq_of_mul_eq_mul_right (nat.pos_of_ne_zero h1) h2,
- .. (infer_instance : comm_monoid_with_zero ℕ) }
+ .. nat.comm_semiring }
attribute [simp] nat.not_lt_zero nat.succ_ne_zero nat.succ_ne_self
nat.zero_ne_one nat.one_ne_zero
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(first ported)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -105,12 +105,12 @@ protected theorem Nat.nsmul_eq_mul (m n : ℕ) : m • n = m * n :=
#align nat.nsmul_eq_mul Nat.nsmul_eq_mul
-/
-#print Nat.cancelCommMonoidWithZero /-
-instance Nat.cancelCommMonoidWithZero : CancelCommMonoidWithZero ℕ :=
+#print Nat.instCancelCommMonoidWithZero /-
+instance Nat.instCancelCommMonoidWithZero : CancelCommMonoidWithZero ℕ :=
{ Nat.commSemiring with
hMul_left_cancel_of_ne_zero := fun _ _ _ h1 h2 =>
Nat.eq_of_mul_eq_mul_left (Nat.pos_of_ne_zero h1) h2 }
-#align nat.cancel_comm_monoid_with_zero Nat.cancelCommMonoidWithZero
+#align nat.cancel_comm_monoid_with_zero Nat.instCancelCommMonoidWithZero
-/
attribute [simp] Nat.not_lt_zero Nat.succ_ne_zero Nat.succ_ne_self Nat.zero_ne_one Nat.one_ne_zero
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -222,7 +222,7 @@ theorem succ_max_succ {m n : ℕ} : max (succ m) (succ n) = succ (max m n) :=
by
by_cases h1 : m ≤ n
rw [max_eq_right h1, max_eq_right (succ_le_succ h1)]
- · rw [not_le] at h1 ; have h2 := le_of_lt h1
+ · rw [not_le] at h1; have h2 := le_of_lt h1
rw [max_eq_left h2, max_eq_left (succ_le_succ h2)]
#align nat.max_succ_succ Nat.succ_max_succ
-/
@@ -440,7 +440,7 @@ theorem mul_ne_mul_right {a b c : ℕ} (ha : 0 < a) : a * b ≠ a * c ↔ b ≠
#print Nat.mul_right_eq_self_iff /-
theorem mul_right_eq_self_iff {a b : ℕ} (ha : 0 < a) : a * b = a ↔ b = 1 :=
- suffices a * b = a * 1 ↔ b = 1 by rwa [mul_one] at this
+ suffices a * b = a * 1 ↔ b = 1 by rwa [mul_one] at this
mul_right_inj' ha.ne'
#align nat.mul_right_eq_self_iff Nat.mul_right_eq_self_iff
-/
@@ -538,8 +538,8 @@ theorem leRecOn_succ_left {C : ℕ → Sort u} {n m} (h1 : n ≤ m) (h2 : n + 1
theorem leRecOn_injective {C : ℕ → Sort u} {n m} (hnm : n ≤ m) (next : ∀ n, C n → C (n + 1))
(Hnext : ∀ n, Function.Injective (next n)) : Function.Injective (leRecOn hnm next) :=
by
- induction' hnm with m hnm ih; · intro x y H; rwa [le_rec_on_self, le_rec_on_self] at H
- intro x y H; rw [le_rec_on_succ hnm, le_rec_on_succ hnm] at H ; exact ih (Hnext _ H)
+ induction' hnm with m hnm ih; · intro x y H; rwa [le_rec_on_self, le_rec_on_self] at H
+ intro x y H; rw [le_rec_on_succ hnm, le_rec_on_succ hnm] at H; exact ih (Hnext _ H)
#align nat.le_rec_on_injective Nat.leRecOn_injective
-/
@@ -925,7 +925,7 @@ theorem mod_mod (a n : ℕ) : a % n % n = a % n :=
@[simp]
theorem mod_add_mod (m n k : ℕ) : (m % n + k) % n = (m + k) % n := by
have := (add_mul_mod_self_left (m % n + k) n (m / n)).symm <;>
- rwa [add_right_comm, mod_add_div] at this
+ rwa [add_right_comm, mod_add_div] at this
#align nat.mod_add_mod Nat.mod_add_mod
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -1183,12 +1183,12 @@ instance decidableForallFin {n : ℕ} (P : Fin n → Prop) [H : DecidablePred P]
#align nat.decidable_forall_fin Nat.decidableForallFin
-/
-#print Nat.decidableBallLe /-
-instance decidableBallLe (n : ℕ) (P : ∀ k ≤ n, Prop) [H : ∀ n h, Decidable (P n h)] :
+#print Nat.decidableBallLE /-
+instance decidableBallLE (n : ℕ) (P : ∀ k ≤ n, Prop) [H : ∀ n h, Decidable (P n h)] :
Decidable (∀ n h, P n h) :=
decidable_of_iff (∀ (k) (h : k < succ n), P k (le_of_lt_succ h))
⟨fun a k h => a k (lt_succ_of_le h), fun a k h => a k _⟩
-#align nat.decidable_ball_le Nat.decidableBallLe
+#align nat.decidable_ball_le Nat.decidableBallLE
-/
#print Nat.decidableExistsLT /-
@@ -1201,11 +1201,11 @@ instance decidableExistsLT {P : ℕ → Prop} [h : DecidablePred P] :
#align nat.decidable_exists_lt Nat.decidableExistsLT
-/
-#print Nat.decidableExistsLe /-
-instance decidableExistsLe {P : ℕ → Prop} [h : DecidablePred P] :
+#print Nat.decidableExistsLE /-
+instance decidableExistsLE {P : ℕ → Prop} [h : DecidablePred P] :
DecidablePred fun n => ∃ m : ℕ, m ≤ n ∧ P m := fun n =>
decidable_of_iff (∃ m, m < n + 1 ∧ P m) (exists_congr fun x => and_congr_left' lt_succ_iff)
-#align nat.decidable_exists_le Nat.decidableExistsLe
+#align nat.decidable_exists_le Nat.decidableExistsLE
-/
end Nat
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -180,10 +180,10 @@ theorem succ_pos' {n : ℕ} : 0 < succ n :=
#align nat.succ_pos' Nat.succ_pos'
-/
-#print Nat.succ_inj' /-
-theorem succ_inj' {n m : ℕ} : succ n = succ m ↔ n = m :=
+#print Nat.succ_inj /-
+theorem succ_inj {n m : ℕ} : succ n = succ m ↔ n = m :=
⟨succ.inj, congr_arg _⟩
-#align nat.succ_inj' Nat.succ_inj'
+#align nat.succ_inj' Nat.succ_inj
-/
#print Nat.succ_injective /-
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -1013,14 +1013,14 @@ theorem lt_mul_div_succ (m : ℕ) {n : ℕ} (n0 : 0 < n) : m < n * (m / n + 1) :
#align nat.lt_mul_div_succ Nat.lt_mul_div_succ
-/
-#print Nat.mul_add_mod /-
-theorem mul_add_mod (a b c : ℕ) : (a * b + c) % b = c % b := by simp [Nat.add_mod]
-#align nat.mul_add_mod Nat.mul_add_mod
+#print Nat.mul_add_mod' /-
+theorem mul_add_mod' (a b c : ℕ) : (a * b + c) % b = c % b := by simp [Nat.add_mod]
+#align nat.mul_add_mod Nat.mul_add_mod'
-/
#print Nat.mul_add_mod_of_lt /-
theorem mul_add_mod_of_lt {a b c : ℕ} (h : c < b) : (a * b + c) % b = c := by
- rw [Nat.mul_add_mod, Nat.mod_eq_of_lt h]
+ rw [Nat.mul_add_mod', Nat.mod_eq_of_lt h]
#align nat.mul_add_mod_of_lt Nat.mul_add_mod_of_lt
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -217,14 +217,14 @@ theorem succ_le_succ_iff {m n : ℕ} : succ m ≤ succ n ↔ m ≤ n :=
#align nat.succ_le_succ_iff Nat.succ_le_succ_iff
-/
-#print Nat.max_succ_succ /-
-theorem max_succ_succ {m n : ℕ} : max (succ m) (succ n) = succ (max m n) :=
+#print Nat.succ_max_succ /-
+theorem succ_max_succ {m n : ℕ} : max (succ m) (succ n) = succ (max m n) :=
by
by_cases h1 : m ≤ n
rw [max_eq_right h1, max_eq_right (succ_le_succ h1)]
· rw [not_le] at h1 ; have h2 := le_of_lt h1
rw [max_eq_left h2, max_eq_left (succ_le_succ h2)]
-#align nat.max_succ_succ Nat.max_succ_succ
+#align nat.max_succ_succ Nat.succ_max_succ
-/
#print Nat.not_succ_lt_self /-
mathlib commit https://github.com/leanprover-community/mathlib/commit/b1abe23ae96fef89ad30d9f4362c307f72a55010
@@ -802,11 +802,13 @@ protected theorem mul_div_cancel_left' {a b : ℕ} (Hd : a ∣ b) : a * (b / a)
#align nat.mul_div_cancel_left' Nat.mul_div_cancel_left'
-/
+/- warning: nat.mul_div_mul_left clashes with nat.mul_div_mul -> Nat.mul_div_mul_left
+Case conversion may be inaccurate. Consider using '#align nat.mul_div_mul_left Nat.mul_div_mul_leftₓ'. -/
#print Nat.mul_div_mul_left /-
--TODO: Update `nat.mul_div_mul` in the core?
/-- Alias of `nat.mul_div_mul` -/
protected theorem mul_div_mul_left (a b : ℕ) {c : ℕ} (hc : 0 < c) : c * a / (c * b) = a / b :=
- Nat.mul_div_mul a b hc
+ Nat.mul_div_mul_left a b hc
#align nat.mul_div_mul_left Nat.mul_div_mul_left
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,9 +3,9 @@ Copyright (c) 2014 Floris van Doorn (c) 2016 Microsoft Corporation. All rights r
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
-/
-import Mathbin.Order.Basic
-import Mathbin.Algebra.GroupWithZero.Basic
-import Mathbin.Algebra.Ring.Defs
+import Order.Basic
+import Algebra.GroupWithZero.Basic
+import Algebra.Ring.Defs
#align_import data.nat.basic from "leanprover-community/mathlib"@"bd835ef554f37ef9b804f0903089211f89cb370b"
mathlib commit https://github.com/leanprover-community/mathlib/commit/32a7e535287f9c73f2e4d2aef306a39190f0b504
@@ -108,7 +108,7 @@ protected theorem Nat.nsmul_eq_mul (m n : ℕ) : m • n = m * n :=
#print Nat.cancelCommMonoidWithZero /-
instance Nat.cancelCommMonoidWithZero : CancelCommMonoidWithZero ℕ :=
{ Nat.commSemiring with
- mul_left_cancel_of_ne_zero := fun _ _ _ h1 h2 =>
+ hMul_left_cancel_of_ne_zero := fun _ _ _ h1 h2 =>
Nat.eq_of_mul_eq_mul_left (Nat.pos_of_ne_zero h1) h2 }
#align nat.cancel_comm_monoid_with_zero Nat.cancelCommMonoidWithZero
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,16 +2,13 @@
Copyright (c) 2014 Floris van Doorn (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
-
-! This file was ported from Lean 3 source module data.nat.basic
-! leanprover-community/mathlib commit bd835ef554f37ef9b804f0903089211f89cb370b
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Order.Basic
import Mathbin.Algebra.GroupWithZero.Basic
import Mathbin.Algebra.Ring.Defs
+#align_import data.nat.basic from "leanprover-community/mathlib"@"bd835ef554f37ef9b804f0903089211f89cb370b"
+
/-!
# Basic operations on the natural numbers
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -220,6 +220,7 @@ theorem succ_le_succ_iff {m n : ℕ} : succ m ≤ succ n ↔ m ≤ n :=
#align nat.succ_le_succ_iff Nat.succ_le_succ_iff
-/
+#print Nat.max_succ_succ /-
theorem max_succ_succ {m n : ℕ} : max (succ m) (succ n) = succ (max m n) :=
by
by_cases h1 : m ≤ n
@@ -227,6 +228,7 @@ theorem max_succ_succ {m n : ℕ} : max (succ m) (succ n) = succ (max m n) :=
· rw [not_le] at h1 ; have h2 := le_of_lt h1
rw [max_eq_left h2, max_eq_left (succ_le_succ h2)]
#align nat.max_succ_succ Nat.max_succ_succ
+-/
#print Nat.not_succ_lt_self /-
theorem not_succ_lt_self {n : ℕ} : ¬succ n < n :=
@@ -313,9 +315,11 @@ theorem forall_lt_succ {P : ℕ → Prop} {n : ℕ} : (∀ m < n + 1, P m) ↔ (
#align nat.forall_lt_succ Nat.forall_lt_succ
-/
+#print Nat.exists_lt_succ /-
theorem exists_lt_succ {P : ℕ → Prop} {n : ℕ} : (∃ m < n + 1, P m) ↔ (∃ m < n, P m) ∨ P n := by
rw [← not_iff_not]; push_neg; exact forall_lt_succ
#align nat.exists_lt_succ Nat.exists_lt_succ
+-/
/-! ### `add` -/
@@ -394,9 +398,11 @@ theorem pred_sub (n m : ℕ) : pred n - m = pred (n - m) := by
#align nat.pred_sub Nat.pred_sub
-/
+#print Nat.le_pred_of_lt /-
theorem le_pred_of_lt {n m : ℕ} (h : m < n) : m ≤ n - 1 :=
Nat.sub_le_sub_right h 1
#align nat.le_pred_of_lt Nat.le_pred_of_lt
+-/
#print Nat.le_of_pred_lt /-
theorem le_of_pred_lt {m n : ℕ} : pred m < n → m ≤ n :=
@@ -572,11 +578,13 @@ theorem strongRecOn'_beta {P : ℕ → Sort _} {h} {n : ℕ} :
#align nat.strong_rec_on_beta' Nat.strongRecOn'_beta
-/
+#print Nat.le_induction /-
/-- Induction principle starting at a non-zero number. For maps to a `Sort*` see `le_rec_on`. -/
@[elab_as_elim]
theorem le_induction {P : Nat → Prop} {m} (h0 : P m) (h1 : ∀ n, m ≤ n → P n → P (n + 1)) :
∀ n, m ≤ n → P n := by apply Nat.le.ndrec h0 <;> exact h1
#align nat.le_induction Nat.le_induction
+-/
#print Nat.decreasingInduction /-
/-- Decreasing induction: if `P (k+1)` implies `P k`, then `P n` implies `P m` for all `m ≤ n`.
@@ -797,15 +805,19 @@ protected theorem mul_div_cancel_left' {a b : ℕ} (Hd : a ∣ b) : a * (b / a)
#align nat.mul_div_cancel_left' Nat.mul_div_cancel_left'
-/
+#print Nat.mul_div_mul_left /-
--TODO: Update `nat.mul_div_mul` in the core?
/-- Alias of `nat.mul_div_mul` -/
protected theorem mul_div_mul_left (a b : ℕ) {c : ℕ} (hc : 0 < c) : c * a / (c * b) = a / b :=
Nat.mul_div_mul a b hc
#align nat.mul_div_mul_left Nat.mul_div_mul_left
+-/
+#print Nat.mul_div_mul_right /-
protected theorem mul_div_mul_right (a b : ℕ) {c : ℕ} (hc : 0 < c) : a * c / (b * c) = a / b := by
rw [mul_comm, mul_comm b, a.mul_div_mul_left b hc]
#align nat.mul_div_mul_right Nat.mul_div_mul_right
+-/
#print Nat.lt_div_mul_add /-
theorem lt_div_mul_add {a b : ℕ} (hb : 0 < b) : a < a / b * b + b :=
@@ -1036,16 +1048,20 @@ theorem find_eq_iff (h : ∃ n : ℕ, p n) : Nat.find h = m ↔ p m ∧ ∀ n <
#align nat.find_eq_iff Nat.find_eq_iff
-/
+#print Nat.find_lt_iff /-
@[simp]
theorem find_lt_iff (h : ∃ n : ℕ, p n) (n : ℕ) : Nat.find h < n ↔ ∃ m < n, p m :=
⟨fun h2 => ⟨Nat.find h, h2, Nat.find_spec h⟩, fun ⟨m, hmn, hm⟩ =>
(Nat.find_min' h hm).trans_lt hmn⟩
#align nat.find_lt_iff Nat.find_lt_iff
+-/
+#print Nat.find_le_iff /-
@[simp]
theorem find_le_iff (h : ∃ n : ℕ, p n) (n : ℕ) : Nat.find h ≤ n ↔ ∃ m ≤ n, p m := by
simp only [exists_prop, ← lt_succ_iff, find_lt_iff]
#align nat.find_le_iff Nat.find_le_iff
+-/
#print Nat.le_find_iff /-
@[simp]
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -747,8 +747,7 @@ protected theorem div_pos {a b : ℕ} (hba : b ≤ a) (hb : 0 < b) : 0 < a / b :
(calc
a = a % b := by simpa [h] using (mod_add_div a b).symm
_ < b := (Nat.mod_lt a hb)
- _ ≤ a := hba
- )
+ _ ≤ a := hba)
#align nat.div_pos Nat.div_pos
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -116,8 +116,9 @@ instance Nat.cancelCommMonoidWithZero : CancelCommMonoidWithZero ℕ :=
#align nat.cancel_comm_monoid_with_zero Nat.cancelCommMonoidWithZero
-/
-attribute [simp]
- Nat.not_lt_zero Nat.succ_ne_zero Nat.succ_ne_self Nat.zero_ne_one Nat.one_ne_zero Nat.zero_ne_bit1 Nat.bit1_ne_zero Nat.bit0_ne_one Nat.one_ne_bit0 Nat.bit0_ne_bit1 Nat.bit1_ne_bit0
+attribute [simp] Nat.not_lt_zero Nat.succ_ne_zero Nat.succ_ne_self Nat.zero_ne_one Nat.one_ne_zero
+ Nat.zero_ne_bit1 Nat.bit1_ne_zero Nat.bit0_ne_one Nat.one_ne_bit0 Nat.bit0_ne_bit1
+ Nat.bit1_ne_bit0
variable {m n k : ℕ}
@@ -139,7 +140,7 @@ theorem and_forall_succ {p : ℕ → Prop} : (p 0 ∧ ∀ n, p (n + 1)) ↔ ∀
@[simp]
theorem or_exists_succ {p : ℕ → Prop} : (p 0 ∨ ∃ n, p (n + 1)) ↔ ∃ n, p n :=
⟨fun h => h.elim (fun h0 => ⟨0, h0⟩) fun ⟨n, hn⟩ => ⟨n + 1, hn⟩, by rintro ⟨_ | n, hn⟩;
- exacts[Or.inl hn, Or.inr ⟨n, hn⟩]⟩
+ exacts [Or.inl hn, Or.inr ⟨n, hn⟩]⟩
#align nat.or_exists_succ Nat.or_exists_succ
-/
@@ -223,7 +224,7 @@ theorem max_succ_succ {m n : ℕ} : max (succ m) (succ n) = succ (max m n) :=
by
by_cases h1 : m ≤ n
rw [max_eq_right h1, max_eq_right (succ_le_succ h1)]
- · rw [not_le] at h1; have h2 := le_of_lt h1
+ · rw [not_le] at h1 ; have h2 := le_of_lt h1
rw [max_eq_left h2, max_eq_left (succ_le_succ h2)]
#align nat.max_succ_succ Nat.max_succ_succ
@@ -436,7 +437,7 @@ theorem mul_ne_mul_right {a b c : ℕ} (ha : 0 < a) : a * b ≠ a * c ↔ b ≠
#print Nat.mul_right_eq_self_iff /-
theorem mul_right_eq_self_iff {a b : ℕ} (ha : 0 < a) : a * b = a ↔ b = 1 :=
- suffices a * b = a * 1 ↔ b = 1 by rwa [mul_one] at this
+ suffices a * b = a * 1 ↔ b = 1 by rwa [mul_one] at this
mul_right_inj' ha.ne'
#align nat.mul_right_eq_self_iff Nat.mul_right_eq_self_iff
-/
@@ -534,8 +535,8 @@ theorem leRecOn_succ_left {C : ℕ → Sort u} {n m} (h1 : n ≤ m) (h2 : n + 1
theorem leRecOn_injective {C : ℕ → Sort u} {n m} (hnm : n ≤ m) (next : ∀ n, C n → C (n + 1))
(Hnext : ∀ n, Function.Injective (next n)) : Function.Injective (leRecOn hnm next) :=
by
- induction' hnm with m hnm ih; · intro x y H; rwa [le_rec_on_self, le_rec_on_self] at H
- intro x y H; rw [le_rec_on_succ hnm, le_rec_on_succ hnm] at H; exact ih (Hnext _ H)
+ induction' hnm with m hnm ih; · intro x y H; rwa [le_rec_on_self, le_rec_on_self] at H
+ intro x y H; rw [le_rec_on_succ hnm, le_rec_on_succ hnm] at H ; exact ih (Hnext _ H)
#align nat.le_rec_on_injective Nat.leRecOn_injective
-/
@@ -914,7 +915,7 @@ theorem mod_mod (a n : ℕ) : a % n % n = a % n :=
@[simp]
theorem mod_add_mod (m n k : ℕ) : (m % n + k) % n = (m + k) % n := by
have := (add_mul_mod_self_left (m % n + k) n (m / n)).symm <;>
- rwa [add_right_comm, mod_add_div] at this
+ rwa [add_right_comm, mod_add_div] at this
#align nat.mod_add_mod Nat.mod_add_mod
-/
@@ -1086,7 +1087,7 @@ theorem find_comp_succ (h₁ : ∃ n, p n) (h₂ : ∃ n, p (n + 1)) (h0 : ¬p 0
by
refine' (find_eq_iff _).2 ⟨Nat.find_spec h₂, fun n hn => _⟩
cases' n with n
- exacts[h0, @Nat.find_min (fun n => p (n + 1)) _ h₂ _ (succ_lt_succ_iff.1 hn)]
+ exacts [h0, @Nat.find_min (fun n => p (n + 1)) _ h₂ _ (succ_lt_succ_iff.1 hn)]
#align nat.find_comp_succ Nat.find_comp_succ
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -219,12 +219,6 @@ theorem succ_le_succ_iff {m n : ℕ} : succ m ≤ succ n ↔ m ≤ n :=
#align nat.succ_le_succ_iff Nat.succ_le_succ_iff
-/
-/- warning: nat.max_succ_succ -> Nat.max_succ_succ is a dubious translation:
-lean 3 declaration is
- forall {m : Nat} {n : Nat}, Eq.{1} Nat (LinearOrder.max.{0} Nat Nat.linearOrder (Nat.succ m) (Nat.succ n)) (Nat.succ (LinearOrder.max.{0} Nat Nat.linearOrder m n))
-but is expected to have type
- forall {m : Nat} {n : Nat}, Eq.{1} Nat (Max.max.{0} Nat Nat.instMaxNat (Nat.succ m) (Nat.succ n)) (Nat.succ (Max.max.{0} Nat Nat.instMaxNat m n))
-Case conversion may be inaccurate. Consider using '#align nat.max_succ_succ Nat.max_succ_succₓ'. -/
theorem max_succ_succ {m n : ℕ} : max (succ m) (succ n) = succ (max m n) :=
by
by_cases h1 : m ≤ n
@@ -318,12 +312,6 @@ theorem forall_lt_succ {P : ℕ → Prop} {n : ℕ} : (∀ m < n + 1, P m) ↔ (
#align nat.forall_lt_succ Nat.forall_lt_succ
-/
-/- warning: nat.exists_lt_succ -> Nat.exists_lt_succ is a dubious translation:
-lean 3 declaration is
- forall {P : Nat -> Prop} {n : Nat}, Iff (Exists.{1} Nat (fun (m : Nat) => Exists.{0} (LT.lt.{0} Nat Nat.hasLt m (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) (fun (H : LT.lt.{0} Nat Nat.hasLt m (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) => P m))) (Or (Exists.{1} Nat (fun (m : Nat) => Exists.{0} (LT.lt.{0} Nat Nat.hasLt m n) (fun (H : LT.lt.{0} Nat Nat.hasLt m n) => P m))) (P n))
-but is expected to have type
- forall {P : Nat -> Prop} {n : Nat}, Iff (Exists.{1} Nat (fun (m : Nat) => And (LT.lt.{0} Nat instLTNat m (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (P m))) (Or (Exists.{1} Nat (fun (m : Nat) => And (LT.lt.{0} Nat instLTNat m n) (P m))) (P n))
-Case conversion may be inaccurate. Consider using '#align nat.exists_lt_succ Nat.exists_lt_succₓ'. -/
theorem exists_lt_succ {P : ℕ → Prop} {n : ℕ} : (∃ m < n + 1, P m) ↔ (∃ m < n, P m) ∨ P n := by
rw [← not_iff_not]; push_neg; exact forall_lt_succ
#align nat.exists_lt_succ Nat.exists_lt_succ
@@ -405,12 +393,6 @@ theorem pred_sub (n m : ℕ) : pred n - m = pred (n - m) := by
#align nat.pred_sub Nat.pred_sub
-/
-/- warning: nat.le_pred_of_lt -> Nat.le_pred_of_lt is a dubious translation:
-lean 3 declaration is
- forall {n : Nat} {m : Nat}, (LT.lt.{0} Nat Nat.hasLt m n) -> (LE.le.{0} Nat Nat.hasLe m (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))))
-but is expected to have type
- forall {n : Nat} {m : Nat}, (LT.lt.{0} Nat instLTNat n m) -> (LE.le.{0} Nat instLENat n (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) m (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
-Case conversion may be inaccurate. Consider using '#align nat.le_pred_of_lt Nat.le_pred_of_ltₓ'. -/
theorem le_pred_of_lt {n m : ℕ} (h : m < n) : m ≤ n - 1 :=
Nat.sub_le_sub_right h 1
#align nat.le_pred_of_lt Nat.le_pred_of_lt
@@ -589,12 +571,6 @@ theorem strongRecOn'_beta {P : ℕ → Sort _} {h} {n : ℕ} :
#align nat.strong_rec_on_beta' Nat.strongRecOn'_beta
-/
-/- warning: nat.le_induction -> Nat.le_induction is a dubious translation:
-lean 3 declaration is
- forall {P : Nat -> Prop} {m : Nat}, (P m) -> (forall (n : Nat), (LE.le.{0} Nat Nat.hasLe m n) -> (P n) -> (P (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) n (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))))) -> (forall (n : Nat), (LE.le.{0} Nat Nat.hasLe m n) -> (P n))
-but is expected to have type
- forall {P : Nat} {m : forall (n : Nat), (LE.le.{0} Nat instLENat P n) -> Prop}, (m P (le_rfl.{0} Nat (PartialOrder.toPreorder.{0} Nat (LinearOrder.toPartialOrder.{0} Nat Nat.linearOrder)) P)) -> (forall (n : Nat) (ᾰ : LE.le.{0} Nat instLENat P n), (m n ᾰ) -> (m (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) (LE.le.trans.{0} Nat (PartialOrder.toPreorder.{0} Nat (LinearOrder.toPartialOrder.{0} Nat Nat.linearOrder)) P n (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) ᾰ (Nat.le_succ n)))) -> (forall (n : Nat) (ᾰ : LE.le.{0} Nat instLENat P n), m n ᾰ)
-Case conversion may be inaccurate. Consider using '#align nat.le_induction Nat.le_inductionₓ'. -/
/-- Induction principle starting at a non-zero number. For maps to a `Sort*` see `le_rec_on`. -/
@[elab_as_elim]
theorem le_induction {P : Nat → Prop} {m} (h0 : P m) (h1 : ∀ n, m ≤ n → P n → P (n + 1)) :
@@ -821,24 +797,12 @@ protected theorem mul_div_cancel_left' {a b : ℕ} (Hd : a ∣ b) : a * (b / a)
#align nat.mul_div_cancel_left' Nat.mul_div_cancel_left'
-/
-/- warning: nat.mul_div_mul_left -> Nat.mul_div_mul_left is a dubious translation:
-lean 3 declaration is
- forall (a : Nat) (b : Nat) {c : Nat}, (LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) c) -> (Eq.{1} Nat (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.hasDiv) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) c a) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) c b)) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.hasDiv) a b))
-but is expected to have type
- forall {a : Nat} (b : Nat) (c : Nat), (LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) a) -> (Eq.{1} Nat (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.instDivNat) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) a b) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) a c)) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.instDivNat) b c))
-Case conversion may be inaccurate. Consider using '#align nat.mul_div_mul_left Nat.mul_div_mul_leftₓ'. -/
--TODO: Update `nat.mul_div_mul` in the core?
/-- Alias of `nat.mul_div_mul` -/
protected theorem mul_div_mul_left (a b : ℕ) {c : ℕ} (hc : 0 < c) : c * a / (c * b) = a / b :=
Nat.mul_div_mul a b hc
#align nat.mul_div_mul_left Nat.mul_div_mul_left
-/- warning: nat.mul_div_mul_right -> Nat.mul_div_mul_right is a dubious translation:
-lean 3 declaration is
- forall (a : Nat) (b : Nat) {c : Nat}, (LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) c) -> (Eq.{1} Nat (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.hasDiv) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) a c) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) b c)) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.hasDiv) a b))
-but is expected to have type
- forall {a : Nat} (b : Nat) (c : Nat), (LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) a) -> (Eq.{1} Nat (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.instDivNat) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) b a) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) c a)) (HDiv.hDiv.{0, 0, 0} Nat Nat Nat (instHDiv.{0} Nat Nat.instDivNat) b c))
-Case conversion may be inaccurate. Consider using '#align nat.mul_div_mul_right Nat.mul_div_mul_rightₓ'. -/
protected theorem mul_div_mul_right (a b : ℕ) {c : ℕ} (hc : 0 < c) : a * c / (b * c) = a / b := by
rw [mul_comm, mul_comm b, a.mul_div_mul_left b hc]
#align nat.mul_div_mul_right Nat.mul_div_mul_right
@@ -1072,24 +1036,12 @@ theorem find_eq_iff (h : ∃ n : ℕ, p n) : Nat.find h = m ↔ p m ∧ ∀ n <
#align nat.find_eq_iff Nat.find_eq_iff
-/
-/- warning: nat.find_lt_iff -> Nat.find_lt_iff is a dubious translation:
-lean 3 declaration is
- forall {p : Nat -> Prop} [_inst_1 : DecidablePred.{1} Nat p] (h : Exists.{1} Nat (fun (n : Nat) => p n)) (n : Nat), Iff (LT.lt.{0} Nat Nat.hasLt (Nat.find (fun (n : Nat) => p n) (fun (a : Nat) => _inst_1 a) h) n) (Exists.{1} Nat (fun (m : Nat) => Exists.{0} (LT.lt.{0} Nat Nat.hasLt m n) (fun (H : LT.lt.{0} Nat Nat.hasLt m n) => p m)))
-but is expected to have type
- forall {p : Nat -> Prop} [_inst_1 : DecidablePred.{1} Nat p] (h : Exists.{1} Nat (fun (n : Nat) => p n)) (n : Nat), Iff (LT.lt.{0} Nat instLTNat (Nat.find (fun (n : Nat) => p n) (fun (a : Nat) => _inst_1 a) h) n) (Exists.{1} Nat (fun (m : Nat) => And (LT.lt.{0} Nat instLTNat m n) (p m)))
-Case conversion may be inaccurate. Consider using '#align nat.find_lt_iff Nat.find_lt_iffₓ'. -/
@[simp]
theorem find_lt_iff (h : ∃ n : ℕ, p n) (n : ℕ) : Nat.find h < n ↔ ∃ m < n, p m :=
⟨fun h2 => ⟨Nat.find h, h2, Nat.find_spec h⟩, fun ⟨m, hmn, hm⟩ =>
(Nat.find_min' h hm).trans_lt hmn⟩
#align nat.find_lt_iff Nat.find_lt_iff
-/- warning: nat.find_le_iff -> Nat.find_le_iff is a dubious translation:
-lean 3 declaration is
- forall {p : Nat -> Prop} [_inst_1 : DecidablePred.{1} Nat p] (h : Exists.{1} Nat (fun (n : Nat) => p n)) (n : Nat), Iff (LE.le.{0} Nat Nat.hasLe (Nat.find (fun (n : Nat) => p n) (fun (a : Nat) => _inst_1 a) h) n) (Exists.{1} Nat (fun (m : Nat) => Exists.{0} (LE.le.{0} Nat Nat.hasLe m n) (fun (H : LE.le.{0} Nat Nat.hasLe m n) => p m)))
-but is expected to have type
- forall {p : Nat -> Prop} [_inst_1 : DecidablePred.{1} Nat p] (h : Exists.{1} Nat (fun (n : Nat) => p n)) (n : Nat), Iff (LE.le.{0} Nat instLENat (Nat.find (fun (n : Nat) => p n) (fun (a : Nat) => _inst_1 a) h) n) (Exists.{1} Nat (fun (m : Nat) => And (LE.le.{0} Nat instLENat m n) (p m)))
-Case conversion may be inaccurate. Consider using '#align nat.find_le_iff Nat.find_le_iffₓ'. -/
@[simp]
theorem find_le_iff (h : ∃ n : ℕ, p n) (n : ℕ) : Nat.find h ≤ n ↔ ∃ m ≤ n, p m := by
simp only [exists_prop, ← lt_succ_iff, find_lt_iff]
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -138,9 +138,7 @@ theorem and_forall_succ {p : ℕ → Prop} : (p 0 ∧ ∀ n, p (n + 1)) ↔ ∀
#print Nat.or_exists_succ /-
@[simp]
theorem or_exists_succ {p : ℕ → Prop} : (p 0 ∨ ∃ n, p (n + 1)) ↔ ∃ n, p n :=
- ⟨fun h => h.elim (fun h0 => ⟨0, h0⟩) fun ⟨n, hn⟩ => ⟨n + 1, hn⟩,
- by
- rintro ⟨_ | n, hn⟩
+ ⟨fun h => h.elim (fun h0 => ⟨0, h0⟩) fun ⟨n, hn⟩ => ⟨n + 1, hn⟩, by rintro ⟨_ | n, hn⟩;
exacts[Or.inl hn, Or.inr ⟨n, hn⟩]⟩
#align nat.or_exists_succ Nat.or_exists_succ
-/
@@ -231,8 +229,7 @@ theorem max_succ_succ {m n : ℕ} : max (succ m) (succ n) = succ (max m n) :=
by
by_cases h1 : m ≤ n
rw [max_eq_right h1, max_eq_right (succ_le_succ h1)]
- · rw [not_le] at h1
- have h2 := le_of_lt h1
+ · rw [not_le] at h1; have h2 := le_of_lt h1
rw [max_eq_left h2, max_eq_left (succ_le_succ h2)]
#align nat.max_succ_succ Nat.max_succ_succ
@@ -327,11 +324,8 @@ lean 3 declaration is
but is expected to have type
forall {P : Nat -> Prop} {n : Nat}, Iff (Exists.{1} Nat (fun (m : Nat) => And (LT.lt.{0} Nat instLTNat m (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (P m))) (Or (Exists.{1} Nat (fun (m : Nat) => And (LT.lt.{0} Nat instLTNat m n) (P m))) (P n))
Case conversion may be inaccurate. Consider using '#align nat.exists_lt_succ Nat.exists_lt_succₓ'. -/
-theorem exists_lt_succ {P : ℕ → Prop} {n : ℕ} : (∃ m < n + 1, P m) ↔ (∃ m < n, P m) ∨ P n :=
- by
- rw [← not_iff_not]
- push_neg
- exact forall_lt_succ
+theorem exists_lt_succ {P : ℕ → Prop} {n : ℕ} : (∃ m < n + 1, P m) ↔ (∃ m < n, P m) ∨ P n := by
+ rw [← not_iff_not]; push_neg; exact forall_lt_succ
#align nat.exists_lt_succ Nat.exists_lt_succ
/-! ### `add` -/
@@ -558,9 +552,7 @@ theorem leRecOn_succ_left {C : ℕ → Sort u} {n m} (h1 : n ≤ m) (h2 : n + 1
theorem leRecOn_injective {C : ℕ → Sort u} {n m} (hnm : n ≤ m) (next : ∀ n, C n → C (n + 1))
(Hnext : ∀ n, Function.Injective (next n)) : Function.Injective (leRecOn hnm next) :=
by
- induction' hnm with m hnm ih;
- · intro x y H
- rwa [le_rec_on_self, le_rec_on_self] at H
+ induction' hnm with m hnm ih; · intro x y H; rwa [le_rec_on_self, le_rec_on_self] at H
intro x y H; rw [le_rec_on_succ hnm, le_rec_on_succ hnm] at H; exact ih (Hnext _ H)
#align nat.le_rec_on_injective Nat.leRecOn_injective
-/
@@ -569,10 +561,7 @@ theorem leRecOn_injective {C : ℕ → Sort u} {n m} (hnm : n ≤ m) (next : ∀
theorem leRecOn_surjective {C : ℕ → Sort u} {n m} (hnm : n ≤ m) (next : ∀ n, C n → C (n + 1))
(Hnext : ∀ n, Function.Surjective (next n)) : Function.Surjective (leRecOn hnm next) :=
by
- induction' hnm with m hnm ih;
- · intro x
- use x
- rw [le_rec_on_self]
+ induction' hnm with m hnm ih; · intro x; use x; rw [le_rec_on_self]
intro x; rcases Hnext _ x with ⟨w, rfl⟩; rcases ih w with ⟨x, rfl⟩; use x; rw [le_rec_on_succ]
#align nat.le_rec_on_surjective Nat.leRecOn_surjective
-/
@@ -595,10 +584,8 @@ def strongRecOn' {P : ℕ → Sort _} (n : ℕ) (h : ∀ n, (∀ m, m < n → P
#print Nat.strongRecOn'_beta /-
theorem strongRecOn'_beta {P : ℕ → Sort _} {h} {n : ℕ} :
- (strongRecOn' n h : P n) = h n fun m hmn => (strongRecOn' m h : P m) :=
- by
- simp only [strong_rec_on']
- rw [Nat.strongRec']
+ (strongRecOn' n h : P n) = h n fun m hmn => (strongRecOn' m h : P m) := by
+ simp only [strong_rec_on']; rw [Nat.strongRec']
#align nat.strong_rec_on_beta' Nat.strongRecOn'_beta
-/
@@ -628,9 +615,7 @@ def decreasingInduction {P : ℕ → Sort _} (h : ∀ n, P (n + 1) → P n) {m n
#print Nat.decreasingInduction_self /-
@[simp]
theorem decreasingInduction_self {P : ℕ → Sort _} (h : ∀ n, P (n + 1) → P n) {n : ℕ} (nn : n ≤ n)
- (hP : P n) : (decreasingInduction h nn hP : P n) = hP :=
- by
- dsimp only [decreasing_induction]
+ (hP : P n) : (decreasingInduction h nn hP : P n) = hP := by dsimp only [decreasing_induction];
rw [le_rec_on_self]
#align nat.decreasing_induction_self Nat.decreasingInduction_self
-/
@@ -638,20 +623,16 @@ theorem decreasingInduction_self {P : ℕ → Sort _} (h : ∀ n, P (n + 1) →
#print Nat.decreasingInduction_succ /-
theorem decreasingInduction_succ {P : ℕ → Sort _} (h : ∀ n, P (n + 1) → P n) {m n : ℕ} (mn : m ≤ n)
(msn : m ≤ n + 1) (hP : P (n + 1)) :
- (decreasingInduction h msn hP : P m) = decreasingInduction h mn (h n hP) :=
- by
- dsimp only [decreasing_induction]
- rw [le_rec_on_succ]
+ (decreasingInduction h msn hP : P m) = decreasingInduction h mn (h n hP) := by
+ dsimp only [decreasing_induction]; rw [le_rec_on_succ]
#align nat.decreasing_induction_succ Nat.decreasingInduction_succ
-/
#print Nat.decreasingInduction_succ' /-
@[simp]
theorem decreasingInduction_succ' {P : ℕ → Sort _} (h : ∀ n, P (n + 1) → P n) {m : ℕ}
- (msm : m ≤ m + 1) (hP : P (m + 1)) : (decreasingInduction h msm hP : P m) = h m hP :=
- by
- dsimp only [decreasing_induction]
- rw [le_rec_on_succ']
+ (msm : m ≤ m + 1) (hP : P (m + 1)) : (decreasingInduction h msm hP : P m) = h m hP := by
+ dsimp only [decreasing_induction]; rw [le_rec_on_succ']
#align nat.decreasing_induction_succ' Nat.decreasingInduction_succ'
-/
@@ -661,8 +642,7 @@ theorem decreasingInduction_trans {P : ℕ → Sort _} (h : ∀ n, P (n + 1) →
(decreasingInduction h (le_trans mn nk) hP : P m) =
decreasingInduction h mn (decreasingInduction h nk hP) :=
by
- induction' nk with k nk ih
- rw [decreasing_induction_self]
+ induction' nk with k nk ih; rw [decreasing_induction_self]
rw [decreasing_induction_succ h (le_trans mn nk), ih, decreasing_induction_succ]
#align nat.decreasing_induction_trans Nat.decreasingInduction_trans
-/
@@ -730,8 +710,7 @@ def decreasingInduction' {P : ℕ → Sort _} {m n : ℕ} (h : ∀ k < n, m ≤
apply ih
· exact fun k hk => h k hk.step
· exact h n (lt_succ_self n) mn hP
- · intro h hP
- exact hP
+ · intro h hP; exact hP
#align nat.decreasing_induction' Nat.decreasingInduction'
-/
@@ -906,18 +885,12 @@ theorem div_add_mod (m k : ℕ) : k * (m / k) + m % k = m :=
-/
#print Nat.mod_add_div' /-
-theorem mod_add_div' (m k : ℕ) : m % k + m / k * k = m :=
- by
- rw [mul_comm]
- exact mod_add_div _ _
+theorem mod_add_div' (m k : ℕ) : m % k + m / k * k = m := by rw [mul_comm]; exact mod_add_div _ _
#align nat.mod_add_div' Nat.mod_add_div'
-/
#print Nat.div_add_mod' /-
-theorem div_add_mod' (m k : ℕ) : m / k * k + m % k = m :=
- by
- rw [mul_comm]
- exact div_add_mod _ _
+theorem div_add_mod' (m k : ℕ) : m / k * k + m % k = m := by rw [mul_comm]; exact div_add_mod _ _
#align nat.div_add_mod' Nat.div_add_mod'
-/
@@ -1052,8 +1025,7 @@ theorem lt_iff_le_pred : ∀ {m n : ℕ}, 0 < n → (m < n ↔ m ≤ n - 1)
theorem mul_div_le (m n : ℕ) : n * (m / n) ≤ m :=
by
cases' Nat.eq_zero_or_pos n with n0 h
- · rw [n0, MulZeroClass.zero_mul]
- exact m.zero_le
+ · rw [n0, MulZeroClass.zero_mul]; exact m.zero_le
· rw [mul_comm, ← Nat.le_div_iff_mul_le' h]
#align nat.mul_div_le Nat.mul_div_le
-/
@@ -1094,8 +1066,7 @@ variable {p q : ℕ → Prop} [DecidablePred p] [DecidablePred q]
theorem find_eq_iff (h : ∃ n : ℕ, p n) : Nat.find h = m ↔ p m ∧ ∀ n < m, ¬p n :=
by
constructor
- · rintro rfl
- exact ⟨Nat.find_spec h, fun _ => Nat.find_min h⟩
+ · rintro rfl; exact ⟨Nat.find_spec h, fun _ => Nat.find_min h⟩
· rintro ⟨hm, hlt⟩
exact le_antisymm (Nat.find_min' h hm) (not_lt.1 <| imp_not_comm.1 (hlt _) <| Nat.find_spec h)
#align nat.find_eq_iff Nat.find_eq_iff
@@ -1226,9 +1197,7 @@ instance decidableBallLT (n : Nat) (P : ∀ k < n, Prop) :
induction' n with n IH <;> intro <;> skip
· exact is_true fun n => by decide
cases' IH fun k h => P k (lt_succ_of_lt h) with h
- · refine' is_false (mt _ h)
- intro hn k h
- apply hn
+ · refine' is_false (mt _ h); intro hn k h; apply hn
by_cases p : P n (lt_succ_self n)
·
exact
mathlib commit https://github.com/leanprover-community/mathlib/commit/3180fab693e2cee3bff62675571264cb8778b212
@@ -1032,7 +1032,7 @@ theorem eq_of_dvd_of_div_eq_one {a b : ℕ} (w : a ∣ b) (h : b / a = 1) : a =
#print Nat.eq_zero_of_dvd_of_div_eq_zero /-
theorem 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]
+ rw [← Nat.div_mul_cancel w, h, MulZeroClass.zero_mul]
#align nat.eq_zero_of_dvd_of_div_eq_zero Nat.eq_zero_of_dvd_of_div_eq_zero
-/
@@ -1052,7 +1052,7 @@ theorem lt_iff_le_pred : ∀ {m n : ℕ}, 0 < n → (m < n ↔ m ≤ n - 1)
theorem mul_div_le (m n : ℕ) : n * (m / n) ≤ m :=
by
cases' Nat.eq_zero_or_pos n with n0 h
- · rw [n0, zero_mul]
+ · rw [n0, MulZeroClass.zero_mul]
exact m.zero_le
· rw [mul_comm, ← Nat.le_div_iff_mul_le' h]
#align nat.mul_div_le Nat.mul_div_le
mathlib commit https://github.com/leanprover-community/mathlib/commit/4c586d291f189eecb9d00581aeb3dd998ac34442
@@ -790,7 +790,7 @@ protected theorem div_pos {a b : ℕ} (hba : b ≤ a) (hb : 0 < b) : 0 < a / b :
lt_irrefl a
(calc
a = a % b := by simpa [h] using (mod_add_div a b).symm
- _ < b := Nat.mod_lt a hb
+ _ < b := (Nat.mod_lt a hb)
_ ≤ a := hba
)
#align nat.div_pos Nat.div_pos
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
@@ -1197,7 +1197,8 @@ lemma dvd_sub_mod (k : ℕ) : n ∣ k - k % n :=
lemma add_mod_eq_ite :
(m + n) % k = if k ≤ m % k + n % k then m % k + n % k - k else m % k + n % k := by
- cases k; simp only [zero_eq, mod_zero, zero_le, ↓reduceIte, Nat.sub_zero]
+ cases k
+ · simp
rw [Nat.add_mod]
split_ifs with h
· rw [Nat.mod_eq_sub_mod h, Nat.mod_eq_of_lt]
@@ -1292,9 +1293,9 @@ set_option linter.deprecated false in
protected theorem not_two_dvd_bit1 (n : ℕ) : ¬2 ∣ bit1 n := by
rw [bit1, Nat.dvd_add_right, Nat.dvd_one]
-- Porting note: was `cc`
- decide
- rw [bit0, ← Nat.two_mul]
- exact Nat.dvd_mul_right _ _
+ · decide
+ · rw [bit0, ← Nat.two_mul]
+ exact Nat.dvd_mul_right _ _
#align nat.not_two_dvd_bit1 Nat.not_two_dvd_bit1
/-- A natural number `m` divides the sum `m + n` if and only if `m` divides `n`.-/
b ≠ 0 → a * b / b = a
(#12424)
This lets us unify a few lemmas between GroupWithZero
and EuclideanDomain
and two lemmas that were previously proved separately for Nat
, Int
, Polynomial
.
@@ -40,6 +40,9 @@ instance instCancelCommMonoidWithZero : CancelCommMonoidWithZero ℕ where
mul_left_cancel_of_ne_zero h := Nat.eq_of_mul_eq_mul_left (Nat.pos_of_ne_zero h)
#align nat.cancel_comm_monoid_with_zero Nat.instCancelCommMonoidWithZero
+instance instMulDivCancelClass : MulDivCancelClass ℕ where
+ mul_div_cancel _ _b hb := Nat.mul_div_cancel _ (Nat.pos_iff_ne_zero.2 hb)
+
/-!
### Extra instances to short-circuit type class resolution
Int
and Rat
instances (#12235)
Fix a few names and deduplicate the AddCommGroup ℤ
instance
@@ -64,7 +64,7 @@ open Function
namespace Nat
variable {a b c d m n k : ℕ} {p q : ℕ → Prop}
-instance nontrivial : Nontrivial ℕ := ⟨⟨0, 1, Nat.zero_ne_one⟩⟩
+instance instNontrivial : Nontrivial ℕ := ⟨⟨0, 1, Nat.zero_ne_one⟩⟩
attribute [gcongr] Nat.succ_le_succ
attribute [simp] Nat.not_lt_zero Nat.succ_ne_zero Nat.succ_ne_self Nat.zero_ne_one Nat.one_ne_zero
Int
and Rat
instances (#12235)
Fix a few names and deduplicate the AddCommGroup ℤ
instance
@@ -22,8 +22,8 @@ namespace Nat
/-! ### Instances -/
-instance commSemiring : CommSemiring ℕ where
- __ := commMonoid
+instance instCommSemiring : CommSemiring ℕ where
+ __ := instCommMonoid
left_distrib := Nat.left_distrib
right_distrib := Nat.right_distrib
zero_mul := Nat.zero_mul
@@ -35,10 +35,10 @@ instance commSemiring : CommSemiring ℕ where
natCast_zero := rfl
natCast_succ _ := rfl
-instance cancelCommMonoidWithZero : CancelCommMonoidWithZero ℕ where
+instance instCancelCommMonoidWithZero : CancelCommMonoidWithZero ℕ where
__ : CommMonoidWithZero ℕ := by infer_instance
mul_left_cancel_of_ne_zero h := Nat.eq_of_mul_eq_mul_left (Nat.pos_of_ne_zero h)
-#align nat.cancel_comm_monoid_with_zero Nat.cancelCommMonoidWithZero
+#align nat.cancel_comm_monoid_with_zero Nat.instCancelCommMonoidWithZero
/-!
### Extra instances to short-circuit type class resolution
@@ -46,8 +46,8 @@ instance cancelCommMonoidWithZero : CancelCommMonoidWithZero ℕ where
These also prevent non-computable instances being used to construct these instances non-computably.
-/
-instance addCommMonoidWithOne : AddCommMonoidWithOne ℕ := by infer_instance
-instance distrib : Distrib ℕ := by infer_instance
-instance semiring : Semiring ℕ := by infer_instance
+instance instAddCommMonoidWithOne : AddCommMonoidWithOne ℕ := by infer_instance
+instance instDistrib : Distrib ℕ := by infer_instance
+instance instSemiring : Semiring ℕ := by infer_instance
end Nat
Int
and Rat
instances (#12235)
Fix a few names and deduplicate the AddCommGroup ℤ
instance
@@ -23,7 +23,7 @@ namespace Nat
/-! ### Instances -/
-instance addCommMonoid : AddCommMonoid ℕ where
+instance instAddCommMonoid : AddCommMonoid ℕ where
add := Nat.add
add_assoc := Nat.add_assoc
zero := Nat.zero
@@ -34,7 +34,7 @@ instance addCommMonoid : AddCommMonoid ℕ where
nsmul_zero := Nat.zero_mul
nsmul_succ := succ_mul
-instance commMonoid : CommMonoid ℕ where
+instance instCommMonoid : CommMonoid ℕ where
mul := Nat.mul
mul_assoc := Nat.mul_assoc
one := Nat.succ Nat.zero
@@ -51,12 +51,12 @@ instance commMonoid : CommMonoid ℕ where
These also prevent non-computable instances being used to construct these instances non-computably.
-/
-instance addMonoid : AddMonoid ℕ := by infer_instance
-instance monoid : Monoid ℕ := by infer_instance
-instance commSemigroup : CommSemigroup ℕ := by infer_instance
-instance semigroup : Semigroup ℕ := by infer_instance
-instance addCommSemigroup : AddCommSemigroup ℕ := by infer_instance
-instance addSemigroup : AddSemigroup ℕ := by infer_instance
+instance instAddMonoid : AddMonoid ℕ := by infer_instance
+instance instMonoid : Monoid ℕ := by infer_instance
+instance instCommSemigroup : CommSemigroup ℕ := by infer_instance
+instance instSemigroup : Semigroup ℕ := by infer_instance
+instance instAddCommSemigroup : AddCommSemigroup ℕ := by infer_instance
+instance instAddSemigroup : AddSemigroup ℕ := by infer_instance
/-! ### Miscellaneous lemmas -/
@@ -1377,6 +1377,17 @@ lemma dvd_div_of_mul_dvd (h : a * b ∣ c) : b ∣ c / a :=
⟨fun h => mul_dvd_of_dvd_div hbc h, fun h => dvd_div_of_mul_dvd h⟩
#align nat.dvd_div_iff Nat.dvd_div_iff
+lemma dvd_mul_of_div_dvd (h : b ∣ a) (hdiv : a / b ∣ c) : a ∣ b * c := by
+ obtain ⟨e, rfl⟩ := hdiv
+ rw [← Nat.mul_assoc, Nat.mul_comm _ (a / b), Nat.div_mul_cancel h]
+ exact Nat.dvd_mul_right a e
+
+@[simp] lemma div_dvd_iff_dvd_mul (h : b ∣ a) (hb : b ≠ 0) : a / b ∣ c ↔ a ∣ b * c :=
+ exists_congr <| fun d => by
+ have := Nat.dvd_trans (Nat.dvd_mul_left _ d) (Nat.mul_dvd_mul_left d h)
+ rw [eq_comm, Nat.mul_comm, ← Nat.mul_div_assoc d h,
+ Nat.div_eq_iff_eq_mul_right (Nat.pos_of_ne_zero hb) this, Nat.mul_comm, eq_comm]
+
@[simp] lemma div_div_div_eq_div (dvd : b ∣ a) (dvd2 : a ∣ c) : c / (a / b) / b = c / a :=
match a, b, c with
| 0, _, _ => by simp
Nat.sqrt
material (#11866)
Move the content of Data.Nat.ForSqrt
and Data.Nat.Sqrt
to Data.Nat.Defs
by using Nat
-specific Std lemmas rather than the mathlib general ones. This makes it ready to move to Std if wanted.
@@ -12,6 +12,7 @@ import Mathlib.Tactic.PushNeg
import Mathlib.Util.AssertExists
#align_import data.nat.basic from "leanprover-community/mathlib"@"bd835ef554f37ef9b804f0903089211f89cb370b"
+#align_import data.nat.sqrt from "leanprover-community/mathlib"@"ba2245edf0c8bb155f1569fd9b9492a9b384cde6"
/-!
# Basic operations on the natural numbers
@@ -678,6 +679,22 @@ protected lemma eq_div_of_mul_eq_left (hc : c ≠ 0) (h : a * c = b) : a = b / c
protected lemma eq_div_of_mul_eq_right (hc : c ≠ 0) (h : c * a = b) : a = b / c := by
rw [← h, Nat.mul_div_cancel_left _ (Nat.pos_iff_ne_zero.2 hc)]
+protected lemma mul_le_of_le_div (k x y : ℕ) (h : x ≤ y / k) : x * k ≤ y := by
+ if hk : k = 0 then
+ rw [hk, Nat.mul_zero]; exact zero_le _
+ else
+ rwa [← le_div_iff_mul_le (Nat.pos_iff_ne_zero.2 hk)]
+
+protected lemma div_mul_div_le (a b c d : ℕ) :
+ (a / b) * (c / d) ≤ (a * c) / (b * d) := by
+ if hb : b = 0 then simp [hb] else
+ if hd : d = 0 then simp [hd] else
+ have hbd : b * d ≠ 0 := Nat.mul_ne_zero hb hd
+ rw [le_div_iff_mul_le (Nat.pos_of_ne_zero hbd)]
+ transitivity ((a / b) * b) * ((c / d) * d)
+ · apply Nat.le_of_eq; simp only [Nat.mul_assoc, Nat.mul_left_comm]
+ · apply Nat.mul_le_mul <;> apply div_mul_le_self
+
/-!
### `pow`
@@ -1419,6 +1436,235 @@ lemma div_lt_div_of_lt_of_dvd {a b d : ℕ} (hdb : d ∣ b) (h : a < b) : a / d
exact lt_of_le_of_lt (mul_div_le a d) h
#align nat.div_lt_div_of_lt_of_dvd Nat.div_lt_div_of_lt_of_dvd
+/-!
+### `sqrt`
+
+See [Wikipedia, *Methods of computing square roots*]
+(https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)).
+-/
+
+private lemma iter_fp_bound (n k : ℕ) :
+ let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
+ sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
+ intro iter_next
+ unfold sqrt.iter
+ if h : (k + n / k) / 2 < k then
+ simpa [if_pos h] using iter_fp_bound _ _
+ else
+ simpa [if_neg h] using Nat.le_of_not_lt h
+
+private lemma AM_GM : {a b : ℕ} → (4 * a * b ≤ (a + b) * (a + b))
+ | 0, _ => by rw [Nat.mul_zero, Nat.zero_mul]; exact zero_le _
+ | _, 0 => by rw [Nat.mul_zero]; exact zero_le _
+ | a + 1, b + 1 => by
+ simpa only [Nat.mul_add, Nat.add_mul, show (4 : ℕ) = 1 + 1 + 1 + 1 from rfl, Nat.one_mul,
+ Nat.mul_one, Nat.add_assoc, Nat.add_left_comm, Nat.add_le_add_iff_left]
+ using Nat.add_le_add_right (@AM_GM a b) 4
+
+-- These two lemmas seem like they belong to `Std.Data.Nat.Basic`.
+
+lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
+ unfold sqrt.iter
+ let next := (guess + n / guess) / 2
+ if h : next < guess then
+ simpa only [dif_pos h] using sqrt.iter_sq_le n next
+ else
+ simp only [dif_neg h]
+ apply Nat.mul_le_of_le_div
+ apply Nat.le_of_add_le_add_left (a := guess)
+ rw [← Nat.mul_two, ← le_div_iff_mul_le]
+ · exact Nat.le_of_not_lt h
+ · exact Nat.zero_lt_two
+
+lemma sqrt.lt_iter_succ_sq (n guess : ℕ) (hn : n < (guess + 1) * (guess + 1)) :
+ n < (sqrt.iter n guess + 1) * (sqrt.iter n guess + 1) := by
+ unfold sqrt.iter
+ -- m was `next`
+ let m := (guess + n / guess) / 2
+ dsimp
+ split_ifs with h
+ · suffices n < (m + 1) * (m + 1) by
+ simpa only [dif_pos h] using sqrt.lt_iter_succ_sq n m this
+ refine Nat.lt_of_mul_lt_mul_left ?_ (a := 4 * (guess * guess))
+ apply Nat.lt_of_le_of_lt AM_GM
+ rw [show (4 : ℕ) = 2 * 2 from rfl]
+ rw [Nat.mul_mul_mul_comm 2, Nat.mul_mul_mul_comm (2 * guess)]
+ refine Nat.mul_self_lt_mul_self (?_ : _ < _ * succ (_ / 2))
+ rw [← add_div_right _ (by decide), Nat.mul_comm 2, Nat.mul_assoc,
+ show guess + n / guess + 2 = (guess + n / guess + 1) + 1 from rfl]
+ have aux_lemma {a : ℕ} : a ≤ 2 * ((a + 1) / 2) := by omega
+ refine lt_of_lt_of_le ?_ (Nat.mul_le_mul_left _ aux_lemma)
+ rw [Nat.add_assoc, Nat.mul_add]
+ exact Nat.add_lt_add_left (lt_mul_div_succ _ (lt_of_le_of_lt (Nat.zero_le m) h)) _
+ · simpa only [dif_neg h] using hn
+
+#align nat.sqrt Nat.sqrt
+-- Porting note: the implementation òf `Nat.sqrt` in `Std` no longer needs `sqrt_aux`.
+#noalign nat.sqrt_aux_dec
+#noalign nat.sqrt_aux
+#noalign nat.sqrt_aux_0
+#noalign nat.sqrt_aux_1
+#noalign nat.sqrt_aux_2
+private def IsSqrt (n q : ℕ) : Prop :=
+ q * q ≤ n ∧ n < (q + 1) * (q + 1)
+-- Porting note: as the definition of square root has changed,
+-- the proof of `sqrt_isSqrt` is attempted from scratch.
+/-
+Sketch of proof:
+Up to rounding, in terms of the definition of `sqrt.iter`,
+
+* By AM-GM inequality, `next² ≥ n` giving one of the bounds.
+* When we terminated, we have `guess ≥ next` from which we deduce the other bound `n ≥ next²`.
+
+To turn this into a lean proof we need to manipulate, use properties of natural number division etc.
+-/
+private lemma sqrt_isSqrt (n : ℕ) : IsSqrt n (sqrt n) := by
+ match n with
+ | 0 => simp [IsSqrt, sqrt]
+ | 1 => simp [IsSqrt, sqrt]
+ | n + 2 =>
+ have h : ¬ (n + 2) ≤ 1 := by simp
+ simp only [IsSqrt, sqrt, h, ite_false]
+ refine ⟨sqrt.iter_sq_le _ _, sqrt.lt_iter_succ_sq _ _ ?_⟩
+ simp only [Nat.mul_add, Nat.add_mul, Nat.one_mul, Nat.mul_one, ← Nat.add_assoc]
+ rw [lt_add_one_iff, Nat.add_assoc, ← Nat.mul_two]
+ refine le_trans (Nat.le_of_eq (div_add_mod' (n + 2) 2).symm) ?_
+ rw [Nat.add_comm, Nat.add_le_add_iff_right, add_mod_right]
+ simp only [Nat.zero_lt_two, add_div_right, succ_mul_succ]
+ refine le_trans (b := 1) ?_ ?_
+ · exact (lt_succ.1 <| mod_lt n Nat.zero_lt_two)
+ · exact Nat.le_add_left _ _
+
+lemma sqrt_le (n : ℕ) : sqrt n * sqrt n ≤ n := (sqrt_isSqrt n).left
+#align nat.sqrt_le Nat.sqrt_le
+
+lemma sqrt_le' (n : ℕ) : sqrt n ^ 2 ≤ n := by simpa [Nat.pow_two] using sqrt_le n
+#align nat.sqrt_le' Nat.sqrt_le'
+
+lemma lt_succ_sqrt (n : ℕ) : n < succ (sqrt n) * succ (sqrt n) := (sqrt_isSqrt n).right
+#align nat.lt_succ_sqrt Nat.lt_succ_sqrt
+
+lemma lt_succ_sqrt' (n : ℕ) : n < succ (sqrt n) ^ 2 := by simpa [Nat.pow_two] using lt_succ_sqrt n
+#align nat.lt_succ_sqrt' Nat.lt_succ_sqrt'
+
+lemma sqrt_le_add (n : ℕ) : n ≤ sqrt n * sqrt n + sqrt n + sqrt n := by
+ rw [← succ_mul]; exact le_of_lt_succ (lt_succ_sqrt n)
+#align nat.sqrt_le_add Nat.sqrt_le_add
+
+lemma le_sqrt : m ≤ sqrt n ↔ m * m ≤ n :=
+ ⟨fun h ↦ le_trans (mul_self_le_mul_self h) (sqrt_le n),
+ fun h ↦ le_of_lt_succ <| Nat.mul_self_lt_mul_self_iff.1 <| lt_of_le_of_lt h (lt_succ_sqrt n)⟩
+#align nat.le_sqrt Nat.le_sqrt
+
+lemma le_sqrt' : m ≤ sqrt n ↔ m ^ 2 ≤ n := by simpa only [Nat.pow_two] using le_sqrt
+#align nat.le_sqrt' Nat.le_sqrt'
+
+lemma sqrt_lt : sqrt m < n ↔ m < n * n := by simp only [← not_le, le_sqrt]
+#align nat.sqrt_lt Nat.sqrt_lt
+
+lemma sqrt_lt' : sqrt m < n ↔ m < n ^ 2 := by simp only [← not_le, le_sqrt']
+#align nat.sqrt_lt' Nat.sqrt_lt'
+
+lemma sqrt_le_self (n : ℕ) : sqrt n ≤ n := le_trans (le_mul_self _) (sqrt_le n)
+#align nat.sqrt_le_self Nat.sqrt_le_self
+
+lemma sqrt_le_sqrt (h : m ≤ n) : sqrt m ≤ sqrt n := le_sqrt.2 (le_trans (sqrt_le _) h)
+#align nat.sqrt_le_sqrt Nat.sqrt_le_sqrt
+
+@[simp] lemma sqrt_zero : sqrt 0 = 0 := rfl
+#align nat.sqrt_zero Nat.sqrt_zero
+
+@[simp] lemma sqrt_one : sqrt 1 = 1 := rfl
+#align nat.sqrt_one Nat.sqrt_one
+
+lemma sqrt_eq_zero : sqrt n = 0 ↔ n = 0 :=
+ ⟨fun h ↦
+ Nat.eq_zero_of_le_zero <| le_of_lt_succ <| (@sqrt_lt n 1).1 <| by rw [h]; decide,
+ by rintro rfl; simp⟩
+#align nat.sqrt_eq_zero Nat.sqrt_eq_zero
+
+lemma eq_sqrt : a = sqrt n ↔ a * a ≤ n ∧ n < (a + 1) * (a + 1) :=
+ ⟨fun e ↦ e.symm ▸ sqrt_isSqrt n,
+ fun ⟨h₁, h₂⟩ ↦ le_antisymm (le_sqrt.2 h₁) (le_of_lt_succ <| sqrt_lt.2 h₂)⟩
+#align nat.eq_sqrt Nat.eq_sqrt
+
+lemma eq_sqrt' : a = sqrt n ↔ a ^ 2 ≤ n ∧ n < (a + 1) ^ 2 := by
+ simpa only [Nat.pow_two] using eq_sqrt
+#align nat.eq_sqrt' Nat.eq_sqrt'
+
+lemma le_three_of_sqrt_eq_one (h : sqrt n = 1) : n ≤ 3 :=
+ le_of_lt_succ <| (@sqrt_lt n 2).1 <| by rw [h]; decide
+#align nat.le_three_of_sqrt_eq_one Nat.le_three_of_sqrt_eq_one
+
+lemma sqrt_lt_self (h : 1 < n) : sqrt n < n :=
+ sqrt_lt.2 <| by have := Nat.mul_lt_mul_of_pos_left h (lt_of_succ_lt h); rwa [Nat.mul_one] at this
+#align nat.sqrt_lt_self Nat.sqrt_lt_self
+
+lemma sqrt_pos : 0 < sqrt n ↔ 0 < n :=
+ le_sqrt
+#align nat.sqrt_pos Nat.sqrt_pos
+
+lemma sqrt_add_eq (n : ℕ) (h : a ≤ n + n) : sqrt (n * n + a) = n :=
+ le_antisymm
+ (le_of_lt_succ <|
+ sqrt_lt.2 <| by
+ rw [succ_mul, mul_succ, add_succ, Nat.add_assoc];
+ exact lt_succ_of_le (Nat.add_le_add_left h _))
+ (le_sqrt.2 <| Nat.le_add_right _ _)
+#align nat.sqrt_add_eq Nat.sqrt_add_eq
+
+lemma sqrt_add_eq' (n : ℕ) (h : a ≤ n + n) : sqrt (n ^ 2 + a) = n := by
+ simpa [Nat.pow_two] using sqrt_add_eq n h
+#align nat.sqrt_add_eq' Nat.sqrt_add_eq'
+
+lemma sqrt_eq (n : ℕ) : sqrt (n * n) = n := sqrt_add_eq n (zero_le _)
+#align nat.sqrt_eq Nat.sqrt_eq
+
+lemma sqrt_eq' (n : ℕ) : sqrt (n ^ 2) = n := sqrt_add_eq' n (zero_le _)
+#align nat.sqrt_eq' Nat.sqrt_eq'
+
+lemma sqrt_succ_le_succ_sqrt (n : ℕ) : sqrt n.succ ≤ n.sqrt.succ :=
+ le_of_lt_succ <| sqrt_lt.2 <| lt_succ_of_le <|
+ succ_le_succ <| le_trans (sqrt_le_add n) <| Nat.add_le_add_right
+ (by refine' add_le_add (Nat.mul_le_mul_right _ _) _ <;> exact Nat.le_add_right _ 2) _
+#align nat.sqrt_succ_le_succ_sqrt Nat.sqrt_succ_le_succ_sqrt
+
+lemma exists_mul_self (x : ℕ) : (∃ n, n * n = x) ↔ sqrt x * sqrt x = x :=
+ ⟨fun ⟨n, hn⟩ ↦ by rw [← hn, sqrt_eq], fun h ↦ ⟨sqrt x, h⟩⟩
+#align nat.exists_mul_self Nat.exists_mul_self
+
+lemma exists_mul_self' (x : ℕ) : (∃ n, n ^ 2 = x) ↔ sqrt x ^ 2 = x := by
+ simpa only [Nat.pow_two] using exists_mul_self x
+#align nat.exists_mul_self' Nat.exists_mul_self'
+
+lemma sqrt_mul_sqrt_lt_succ (n : ℕ) : sqrt n * sqrt n < n + 1 :=
+ Nat.lt_succ_iff.mpr (sqrt_le _)
+#align nat.sqrt_mul_sqrt_lt_succ Nat.sqrt_mul_sqrt_lt_succ
+
+lemma sqrt_mul_sqrt_lt_succ' (n : ℕ) : sqrt n ^ 2 < n + 1 :=
+ Nat.lt_succ_iff.mpr (sqrt_le' _)
+#align nat.sqrt_mul_sqrt_lt_succ' Nat.sqrt_mul_sqrt_lt_succ'
+
+lemma succ_le_succ_sqrt (n : ℕ) : n + 1 ≤ (sqrt n + 1) * (sqrt n + 1) :=
+ le_of_pred_lt (lt_succ_sqrt _)
+#align nat.succ_le_succ_sqrt Nat.succ_le_succ_sqrt
+
+lemma succ_le_succ_sqrt' (n : ℕ) : n + 1 ≤ (sqrt n + 1) ^ 2 :=
+ le_of_pred_lt (lt_succ_sqrt' _)
+#align nat.succ_le_succ_sqrt' Nat.succ_le_succ_sqrt'
+
+/-- There are no perfect squares strictly between m² and (m+1)² -/
+lemma not_exists_sq (hl : m * m < n) (hr : n < (m + 1) * (m + 1)) : ¬∃ t, t * t = n := by
+ rintro ⟨t, rfl⟩
+ have h1 : m < t := Nat.mul_self_lt_mul_self_iff.1 hl
+ have h2 : t < m + 1 := Nat.mul_self_lt_mul_self_iff.1 hr
+ exact (not_lt_of_ge <| le_of_lt_succ h2) h1
+#align nat.not_exists_sq Nat.not_exists_sq
+
+lemma not_exists_sq' : m ^ 2 < n → n < (m + 1) ^ 2 → ¬∃ t, t ^ 2 = n := by
+ simpa only [Nat.pow_two] using not_exists_sq
+#align nat.not_exists_sq' Nat.not_exists_sq'
+
/-! ### `find` -/
section Find
Data.{Nat,Int}{.Order}.Basic
in group vs ring instances (#11924)
Scatter the content of Data.Nat.Basic
across:
Data.Nat.Defs
for the lemmas having no dependenciesAlgebra.Group.Nat
for the monoid instances and the few miscellaneous lemmas needing them.Algebra.Ring.Nat
for the semiring instance and the few miscellaneous lemmas following it.Similarly, scatter
Data.Int.Basic
across Data.Int.Defs
, Algebra.Group.Int
, Algebra.Ring.Int
Data.Nat.Order.Basic
across Data.Nat.Defs
, Algebra.Order.Group.Nat
, Algebra.Order.Ring.Nat
Data.Int.Order.Basic
across Data.Int.Defs
, Algebra.Order.Group.Int
, Algebra.Order.Ring.Int
Also move a few lemmas from Data.Nat.Order.Lemmas
to Data.Nat.Defs
.
Before
After
@@ -25,21 +25,34 @@ This file contains:
* `strong_rec'`: recursion based on strong inequalities
* decidability instances on predicates about the natural numbers
-## Implementation note
-
-Std has a home-baked development of the algebraic and order theoretic theory of `ℕ` which, in
-particular, is not typeclass-mediated. This is useful to set up the algebra and finiteness libraries
-in mathlib (naturals show up as indices in lists, cardinality in finsets, powers in groups, ...).
-This home-baked development is pursued in this file.
-
-Less basic uses of `ℕ` should however use the typeclass-mediated development. `Data.Nat.Basic` gives
-access to the algebraic instances. `Data.Nat.Order.Basic` is the one giving access to the algebraic
-order instances.
+See note [foundational algebra order theory].
## TODO
-The names of this file, `Data.Nat.Basic` and `Data.Nat.Order.Basic` are archaic and don't match up
-with reality anymore. Rename them.
+Split this file into:
+* `Data.Nat.Init` (or maybe `Data.Nat.Std`?) for lemmas that could go to Std
+* `Data.Nat.Basic` for the lemmas that require mathlib definitions
+-/
+
+library_note "foundational algebra order theory"/--
+Std has a home-baked development of the algebraic and order theoretic theory of `ℕ` and `ℤ` which,
+in particular, is not typeclass-mediated. This is useful to set up the algebra and finiteness
+libraries in mathlib (naturals and integers show up as indices/offsets in lists, cardinality in
+finsets, powers in groups, ...).
+
+Less basic uses of `ℕ` and `ℤ` should however use the typeclass-mediated development.
+
+The relevant files are:
+* `Data.Nat.Defs` for the continuation of the home-baked development on `ℕ`
+* `Data.Int.Defs` for the continuation of the home-baked development on `ℤ`
+* `Algebra.Group.Nat` for the monoid instances on `ℕ`
+* `Algebra.Group.Int` for the group instance on `ℤ`
+* `Algebra.Ring.Nat` for the semiring instance on `ℕ`
+* `Algebra.Ring.Int` for the ring instance on `ℤ`
+* `Algebra.Order.Group.Nat` for the ordered monoid instance on `ℕ`
+* `Algebra.Order.Group.Int` for the ordered group instance on `ℤ`
+* `Algebra.Order.Ring.Nat` for the ordered semiring instance on `ℕ`
+* `Algebra.Order.Ring.Int` for the ordered ring instance on `ℤ`
-/
/- We don't want to import the algebraic hierarchy in this file. -/
@@ -54,6 +67,7 @@ instance nontrivial : Nontrivial ℕ := ⟨⟨0, 1, Nat.zero_ne_one⟩⟩
attribute [gcongr] Nat.succ_le_succ
attribute [simp] Nat.not_lt_zero Nat.succ_ne_zero Nat.succ_ne_self Nat.zero_ne_one Nat.one_ne_zero
+ Nat.min_eq_left Nat.min_eq_right Nat.max_eq_left Nat.max_eq_right
-- Nat.zero_ne_bit1 Nat.bit1_ne_zero Nat.bit0_ne_one Nat.one_ne_bit0 Nat.bit0_ne_bit1
-- Nat.bit1_ne_bit0
@@ -262,9 +276,14 @@ attribute [simp] le_add_left le_add_right Nat.lt_add_left_iff_pos Nat.lt_add_rig
-- Sometimes a bare `Nat.add` or similar appears as a consequence of unfolding during pattern
-- matching. These lemmas package them back up as typeclass mediated operations.
+-- TODO: This is a duplicate of `Nat.add_eq`
@[simp] lemma add_def : Nat.add m n = m + n := rfl
#align nat.add_def Nat.add_def
+-- We want to use these two lemmas earlier than the lemmas simp can prove them with
+@[simp, nolint simpNF] protected lemma add_eq_left : a + b = a ↔ b = 0 := by omega
+@[simp, nolint simpNF] protected lemma add_eq_right : a + b = b ↔ a = 0 := by omega
+
lemma two_le_iff : ∀ n, 2 ≤ n ↔ n ≠ 0 ∧ n ≠ 1
| 0 => by simp
| 1 => by simp
@@ -480,6 +499,7 @@ protected lemma add_le_mul {a : ℕ} (ha : 2 ≤ a) : ∀ {b : ℕ} (_ : 2 ≤ b
#align nat.pow_div Nat.pow_div
#align nat.div_lt_of_lt_mul Nat.div_lt_of_lt_mul
+#align nat.div_eq_zero Nat.div_eq_of_lt
attribute [simp] Nat.div_self
@@ -966,7 +986,7 @@ def pincerRecursion {P : ℕ → ℕ → Sort*} (Ha0 : ∀ m : ℕ, P m 0) (H0b
/-- Decreasing induction: if `P (k+1)` implies `P k` for all `m ≤ k < n`, then `P n` implies `P m`.
Also works for functions to `Sort*`. Weakens the assumptions of `decreasing_induction`. -/
@[elab_as_elim]
-def decreasingInduction' {P : ℕ → Sort*} {m n : ℕ} (h : ∀ k < n, m ≤ k → P (k + 1) → P k)
+def decreasingInduction' {P : ℕ → Sort*} (h : ∀ k < n, m ≤ k → P (k + 1) → P k)
(mn : m ≤ n) (hP : P n) : P m := by
revert h hP
refine' leRecOn' mn _ _
@@ -1021,9 +1041,45 @@ lemma set_induction {S : Set ℕ} (hb : 0 ∈ S) (h_ind : ∀ k : ℕ, k ∈ S
#align nat.pow_dvd_pow_iff_le_right' Nat.pow_dvd_pow_iff_le_right'
#align nat.mod_mul_right_div_self Nat.mod_mul_right_div_self
#align nat.mod_mul_left_div_self Nat.mod_mul_left_div_self
+#align nat.mod_div_self Nat.mod_div_self
attribute [simp] Nat.dvd_zero
+protected lemma lt_div_iff_mul_lt (hdn : d ∣ n) (a : ℕ) : a < n / d ↔ d * a < n := by
+ obtain rfl | hd := d.eq_zero_or_pos
+ · simp [Nat.zero_dvd.1 hdn]
+ · rw [← Nat.mul_lt_mul_left hd, ← Nat.eq_mul_of_div_eq_right hdn rfl]
+#align nat.lt_div_iff_mul_lt Nat.lt_div_iff_mul_lt
+
+lemma mul_div_eq_iff_dvd {n d : ℕ} : d * (n / d) = n ↔ d ∣ n :=
+ calc
+ d * (n / d) = n ↔ d * (n / d) = d * (n / d) + (n % d) := by rw [div_add_mod]
+ _ ↔ d ∣ n := by rw [eq_comm, Nat.add_eq_left, dvd_iff_mod_eq_zero]
+
+lemma mul_div_lt_iff_not_dvd : d * (n / d) < n ↔ ¬ d ∣ n := by
+ simp [Nat.lt_iff_le_and_ne, mul_div_eq_iff_dvd, mul_div_le]
+
+lemma div_eq_iff_eq_of_dvd_dvd (hn : n ≠ 0) (ha : a ∣ n) (hb : b ∣ n) : n / a = n / b ↔ a = b := by
+ constructor <;> intro h
+ · rw [← Nat.mul_right_inj hn]
+ apply Nat.eq_mul_of_div_eq_left (Nat.dvd_trans hb (Nat.dvd_mul_right _ _))
+ rw [eq_comm, Nat.mul_comm, Nat.mul_div_assoc _ hb]
+ exact Nat.eq_mul_of_div_eq_right ha h
+ · rw [h]
+#align nat.div_eq_iff_eq_of_dvd_dvd Nat.div_eq_iff_eq_of_dvd_dvd
+
+protected lemma div_eq_zero_iff (hb : 0 < b) : a / b = 0 ↔ a < b where
+ mp h := by rw [← mod_add_div a b, h, Nat.mul_zero, Nat.add_zero]; exact mod_lt _ hb
+ mpr h := by rw [← Nat.mul_right_inj (Nat.ne_of_gt hb), ← Nat.add_left_cancel_iff, mod_add_div,
+ mod_eq_of_lt h, Nat.mul_zero, Nat.add_zero]
+#align nat.div_eq_zero_iff Nat.div_eq_zero_iff
+
+protected lemma div_ne_zero_iff (hb : b ≠ 0) : a / b ≠ 0 ↔ b ≤ a := by
+ rw [ne_eq, Nat.div_eq_zero_iff (Nat.pos_of_ne_zero hb), not_lt]
+
+protected lemma div_pos_iff (hb : b ≠ 0) : 0 < a / b ↔ b ≤ a := by
+ rw [Nat.pos_iff_ne_zero, Nat.div_ne_zero_iff hb]
+
lemma mul_div_mul_comm_of_dvd_dvd (hba : b ∣ a) (hdc : d ∣ c) :
a * c / (b * d) = a / b * (c / d) := by
obtain rfl | hb := b.eq_zero_or_pos; · simp
@@ -1214,6 +1270,155 @@ lemma mul_add_mod_of_lt (h : c < b) : (a * b + c) % b = c := by
rw [Nat.mul_add_mod', Nat.mod_eq_of_lt h]
#align nat.mul_add_mod_of_lt Nat.mul_add_mod_of_lt
+set_option linter.deprecated false in
+@[simp]
+protected theorem not_two_dvd_bit1 (n : ℕ) : ¬2 ∣ bit1 n := by
+ rw [bit1, Nat.dvd_add_right, Nat.dvd_one]
+ -- Porting note: was `cc`
+ decide
+ rw [bit0, ← Nat.two_mul]
+ exact Nat.dvd_mul_right _ _
+#align nat.not_two_dvd_bit1 Nat.not_two_dvd_bit1
+
+/-- A natural number `m` divides the sum `m + n` if and only if `m` divides `n`.-/
+@[simp] protected lemma dvd_add_self_left : m ∣ m + n ↔ m ∣ n := Nat.dvd_add_right (Nat.dvd_refl m)
+#align nat.dvd_add_self_left Nat.dvd_add_self_left
+
+/-- A natural number `m` divides the sum `n + m` if and only if `m` divides `n`.-/
+@[simp] protected lemma dvd_add_self_right : m ∣ n + m ↔ m ∣ n := Nat.dvd_add_left (Nat.dvd_refl m)
+#align nat.dvd_add_self_right Nat.dvd_add_self_right
+
+-- TODO: update `Nat.dvd_sub` in core
+lemma dvd_sub' (h₁ : k ∣ m) (h₂ : k ∣ n) : k ∣ m - n := by
+ rcases le_total n m with H | H
+ · exact dvd_sub H h₁ h₂
+ · rw [Nat.sub_eq_zero_iff_le.mpr H]
+ exact Nat.dvd_zero k
+#align nat.dvd_sub' Nat.dvd_sub'
+
+lemma succ_div : ∀ a b : ℕ, (a + 1) / b = a / b + if b ∣ a + 1 then 1 else 0
+ | a, 0 => by simp
+ | 0, 1 => by simp
+ | 0, b + 2 => by
+ have hb2 : b + 2 > 1 := by simp
+ simp [ne_of_gt hb2, div_eq_of_lt hb2]
+ | a + 1, b + 1 => by
+ rw [Nat.div_eq]
+ conv_rhs => rw [Nat.div_eq]
+ by_cases hb_eq_a : b = a + 1
+ · simp [hb_eq_a, Nat.le_refl, Nat.not_succ_le_self, Nat.dvd_refl]
+ by_cases hb_le_a1 : b ≤ a + 1
+ · have hb_le_a : b ≤ a := le_of_lt_succ (lt_of_le_of_ne hb_le_a1 hb_eq_a)
+ have h₁ : 0 < b + 1 ∧ b + 1 ≤ a + 1 + 1 := ⟨succ_pos _, Nat.add_le_add_iff_right.2 hb_le_a1⟩
+ have h₂ : 0 < b + 1 ∧ b + 1 ≤ a + 1 := ⟨succ_pos _, Nat.add_le_add_iff_right.2 hb_le_a⟩
+ have dvd_iff : b + 1 ∣ a - b + 1 ↔ b + 1 ∣ a + 1 + 1 := by
+ rw [Nat.dvd_add_iff_left (Nat.dvd_refl (b + 1)), ← Nat.add_sub_add_right a 1 b,
+ Nat.add_comm (_ - _), Nat.add_assoc, Nat.sub_add_cancel (succ_le_succ hb_le_a),
+ Nat.add_comm 1]
+ have wf : a - b < a + 1 := lt_succ_of_le (Nat.sub_le _ _)
+ rw [if_pos h₁, if_pos h₂, Nat.add_sub_add_right, Nat.add_sub_add_right, Nat.add_comm a,
+ Nat.add_sub_assoc hb_le_a, Nat.add_comm 1,
+ have := wf
+ succ_div (a - b)]
+ simp [dvd_iff, succ_eq_add_one, Nat.add_comm 1, Nat.add_assoc]
+ · have hba : ¬b ≤ a := not_le_of_gt (lt_trans (lt_succ_self a) (lt_of_not_ge hb_le_a1))
+ have hb_dvd_a : ¬b + 1 ∣ a + 2 := fun h =>
+ hb_le_a1 (le_of_succ_le_succ (le_of_dvd (succ_pos _) h))
+ simp [hba, hb_le_a1, hb_dvd_a]
+#align nat.succ_div Nat.succ_div
+
+lemma succ_div_of_dvd (hba : b ∣ a + 1) : (a + 1) / b = a / b + 1 := by rw [succ_div, if_pos hba]
+#align nat.succ_div_of_dvd Nat.succ_div_of_dvd
+
+lemma succ_div_of_not_dvd (hba : ¬b ∣ a + 1) : (a + 1) / b = a / b := by
+ rw [succ_div, if_neg hba, Nat.add_zero]
+#align nat.succ_div_of_not_dvd Nat.succ_div_of_not_dvd
+
+lemma dvd_iff_div_mul_eq (n d : ℕ) : d ∣ n ↔ n / d * d = n :=
+ ⟨fun h => Nat.div_mul_cancel h, fun h => by rw [← h]; exact Nat.dvd_mul_left _ _⟩
+#align nat.dvd_iff_div_mul_eq Nat.dvd_iff_div_mul_eq
+
+lemma dvd_iff_le_div_mul (n d : ℕ) : d ∣ n ↔ n ≤ n / d * d :=
+ ((dvd_iff_div_mul_eq _ _).trans le_antisymm_iff).trans (and_iff_right (div_mul_le_self n d))
+#align nat.dvd_iff_le_div_mul Nat.dvd_iff_le_div_mul
+
+lemma dvd_iff_dvd_dvd (n d : ℕ) : d ∣ n ↔ ∀ k : ℕ, k ∣ d → k ∣ n :=
+ ⟨fun h _ hkd => Nat.dvd_trans hkd h, fun h => h _ (Nat.dvd_refl _)⟩
+#align nat.dvd_iff_dvd_dvd Nat.dvd_iff_dvd_dvd
+
+lemma dvd_div_of_mul_dvd (h : a * b ∣ c) : b ∣ c / a :=
+ if ha : a = 0 then by simp [ha]
+ else
+ have ha : 0 < a := Nat.pos_of_ne_zero ha
+ have h1 : ∃ d, c = a * b * d := h
+ let ⟨d, hd⟩ := h1
+ have h2 : c / a = b * d := Nat.div_eq_of_eq_mul_right ha (by simpa [Nat.mul_assoc] using hd)
+ show ∃ d, c / a = b * d from ⟨d, h2⟩
+#align nat.dvd_div_of_mul_dvd Nat.dvd_div_of_mul_dvd
+
+@[simp] lemma dvd_div_iff (hbc : c ∣ b) : a ∣ b / c ↔ c * a ∣ b :=
+ ⟨fun h => mul_dvd_of_dvd_div hbc h, fun h => dvd_div_of_mul_dvd h⟩
+#align nat.dvd_div_iff Nat.dvd_div_iff
+
+@[simp] lemma div_div_div_eq_div (dvd : b ∣ a) (dvd2 : a ∣ c) : c / (a / b) / b = c / a :=
+ match a, b, c with
+ | 0, _, _ => by simp
+ | a + 1, 0, _ => by simp at dvd
+ | a + 1, c + 1, _ => by
+ have a_split : a + 1 ≠ 0 := succ_ne_zero a
+ have c_split : c + 1 ≠ 0 := succ_ne_zero c
+ rcases dvd2 with ⟨k, rfl⟩
+ rcases dvd with ⟨k2, pr⟩
+ have k2_nonzero : k2 ≠ 0 := fun k2_zero => by simp [k2_zero] at pr
+ rw [Nat.mul_div_cancel_left k (Nat.pos_of_ne_zero a_split), pr,
+ Nat.mul_div_cancel_left k2 (Nat.pos_of_ne_zero c_split), Nat.mul_comm ((c + 1) * k2) k, ←
+ Nat.mul_assoc k (c + 1) k2, Nat.mul_div_cancel _ (Nat.pos_of_ne_zero k2_nonzero),
+ Nat.mul_div_cancel _ (Nat.pos_of_ne_zero c_split)]
+#align nat.div_div_div_eq_div Nat.div_div_div_eq_div
+
+/-- If a small natural number is divisible by a larger natural number,
+the small number is zero. -/
+lemma eq_zero_of_dvd_of_lt (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)).mpr h)
+#align nat.eq_zero_of_dvd_of_lt Nat.eq_zero_of_dvd_of_lt
+
+lemma le_of_lt_add_of_dvd (h : a < b + n) : n ∣ a → n ∣ b → a ≤ b := by
+ rintro ⟨a, rfl⟩ ⟨b, rfl⟩
+ rw [← mul_succ] at h
+ exact Nat.mul_le_mul_left _ (Nat.lt_succ_iff.1 <| Nat.lt_of_mul_lt_mul_left h)
+#align nat.le_of_lt_add_of_dvd Nat.le_of_lt_add_of_dvd
+
+/-- `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 := by
+ refine'
+ ⟨fun ⟨k, hk1, hk2⟩ => not_dvd_of_between_consec_multiples hk1 hk2, fun han =>
+ ⟨n / a, ⟨lt_of_le_of_ne (mul_div_le n a) _, lt_mul_div_succ _ ha⟩⟩⟩
+ exact mt (⟨n / a, Eq.symm ·⟩) han
+#align nat.not_dvd_iff_between_consec_multiples Nat.not_dvd_iff_between_consec_multiples
+
+/-- Two natural numbers are equal if and only if they have the same multiples. -/
+lemma dvd_right_iff_eq : (∀ a : ℕ, m ∣ a ↔ n ∣ a) ↔ m = n :=
+ ⟨fun h => Nat.dvd_antisymm ((h _).mpr (Nat.dvd_refl _)) ((h _).mp (Nat.dvd_refl _)),
+ fun h n => by rw [h]⟩
+#align nat.dvd_right_iff_eq Nat.dvd_right_iff_eq
+
+/-- Two natural numbers are equal if and only if they have the same divisors. -/
+lemma dvd_left_iff_eq : (∀ a : ℕ, a ∣ m ↔ a ∣ n) ↔ m = n :=
+ ⟨fun h => Nat.dvd_antisymm ((h _).mp (Nat.dvd_refl _)) ((h _).mpr (Nat.dvd_refl _)),
+ fun h n => by rw [h]⟩
+#align nat.dvd_left_iff_eq Nat.dvd_left_iff_eq
+
+/-- `dvd` is injective in the left argument -/
+lemma dvd_left_injective : Function.Injective ((· ∣ ·) : ℕ → ℕ → Prop) := fun _ _ h =>
+ dvd_right_iff_eq.mp fun a => iff_of_eq (congr_fun h a)
+#align nat.dvd_left_injective Nat.dvd_left_injective
+
+lemma div_lt_div_of_lt_of_dvd {a b d : ℕ} (hdb : d ∣ b) (h : a < b) : a / d < b / d := by
+ rw [Nat.lt_div_iff_mul_lt hdb]
+ exact lt_of_le_of_lt (mul_div_le a d) h
+#align nat.div_lt_div_of_lt_of_dvd Nat.div_lt_div_of_lt_of_dvd
+
/-! ### `find` -/
section Find
Data.{Nat,Int}{.Order}.Basic
in group vs ring instances (#11924)
Scatter the content of Data.Nat.Basic
across:
Data.Nat.Defs
for the lemmas having no dependenciesAlgebra.Group.Nat
for the monoid instances and the few miscellaneous lemmas needing them.Algebra.Ring.Nat
for the semiring instance and the few miscellaneous lemmas following it.Similarly, scatter
Data.Int.Basic
across Data.Int.Defs
, Algebra.Group.Int
, Algebra.Ring.Int
Data.Nat.Order.Basic
across Data.Nat.Defs
, Algebra.Order.Group.Nat
, Algebra.Order.Ring.Nat
Data.Int.Order.Basic
across Data.Int.Defs
, Algebra.Order.Group.Int
, Algebra.Order.Ring.Int
Also move a few lemmas from Data.Nat.Order.Lemmas
to Data.Nat.Defs
.
Before
After
Data.{Nat,Int}{.Order}.Basic
in group vs ring instances (#11924)
Scatter the content of Data.Nat.Basic
across:
Data.Nat.Defs
for the lemmas having no dependenciesAlgebra.Group.Nat
for the monoid instances and the few miscellaneous lemmas needing them.Algebra.Ring.Nat
for the semiring instance and the few miscellaneous lemmas following it.Similarly, scatter
Data.Int.Basic
across Data.Int.Defs
, Algebra.Group.Int
, Algebra.Ring.Int
Data.Nat.Order.Basic
across Data.Nat.Defs
, Algebra.Order.Group.Nat
, Algebra.Order.Ring.Nat
Data.Int.Order.Basic
across Data.Int.Defs
, Algebra.Order.Group.Int
, Algebra.Order.Ring.Int
Also move a few lemmas from Data.Nat.Order.Lemmas
to Data.Nat.Defs
.
Before
After
Remove dependencies on algebra in the Data.List
folder except for:
Data.List.EditDistance
: Actually relies on algebra. Maybe should be moved?Data.List.Card
: Completely unused and redundant.Data.List.Cycle
: Relies on Fintype
, which shouldn't rely on algebra but it's hard to fix right now. Maybe should be moved?Data.List.Func
: Completely unused and redundant.Data.List.Lex
: That's order theory. Could be moved.Data.List.Prime
. That's algebra. Should definitely be moved.Data.List.Sym
: Relies on Multiset
, which shouldn't rely on algebra but it's hard to fix right now. Maybe should be moved?Data.List.ToFinsupp
: That's algebra. Should definitely be moved.As a consequence, move the big operators lemmas that were in there to Algebra.BigOperators.List.Basic
. For the lemmas that were Nat
-specific and not about auxiliary definitions, keep a version of them in the original file but stated using Nat.sum
.
Before
After
@@ -323,10 +323,16 @@ theorem le_or_le_of_add_eq_add_pred (h : a + c = b + d - 1) : b ≤ a ∨ d ≤
/-! ### `sub` -/
+attribute [simp] Nat.sub_eq_zero_of_le Nat.sub_le_iff_le_add
+
/-- A version of `Nat.sub_succ` in the form `_ - 1` instead of `Nat.pred _`. -/
lemma sub_succ' (m n : ℕ) : m - n.succ = m - n - 1 := rfl
#align nat.sub_succ' Nat.sub_succ'
+protected lemma sub_eq_of_eq_add' (h : a = b + c) : a - b = c := by rw [h, Nat.add_sub_cancel_left]
+protected lemma eq_sub_of_add_eq (h : c + b = a) : c = a - b := (Nat.sub_eq_of_eq_add h.symm).symm
+protected lemma eq_sub_of_add_eq' (h : b + c = a) : c = a - b := (Nat.sub_eq_of_eq_add' h.symm).symm
+
protected lemma lt_sub_iff_add_lt : a < c - b ↔ a + b < c := ⟨add_lt_of_lt_sub, lt_sub_of_add_lt⟩
protected lemma lt_sub_iff_add_lt' : a < c - b ↔ b + a < c := by omega
protected lemma sub_lt_iff_lt_add (hba : b ≤ a) : a - b < c ↔ a < b + c := by omega
Algebra.BigOperators.List.Basic
, Data.List.Chain
not depend on Data.Nat.Order.Basic
by using Nat
-specific Std lemmas rather than general mathlib ones. I leave the Data.Nat.Basic
import since Algebra.BigOperators.List.Basic
is algebra territory.Algebra.BigOperators.List.Basic
not depend on Algebra.Divisibility.Basic
. I'm not too sure about that one since they already are algebra. My motivation is that they involve ring-like objects while big operators are about group-like objects, but this is in some sense a second order refactor.MonoidWithZero
lemmas from Algebra.BigOperators.List.Basic
to Algebra.BigOperators.List.Lemmas
.Algebra.BigOperators.List.Defs
to Algebra.BigOperators.List.Basic
since no file imported the former without the latter and their imports are becoming very close after this PR.Data.List.Count
, Data.List.Dedup
, Data.List.ProdSigma
, Data.List.Zip
not depend on Algebra.BigOperators.List.Basic
.Algebra.BigOperators.List.Basic
. For the lemmas that were Nat
-specific, keep a version of them stated using Nat.sum
.Nat.sum_eq_listSum (l : List Nat) : Nat.sum l = l.sum
.@@ -57,6 +57,8 @@ attribute [simp] Nat.not_lt_zero Nat.succ_ne_zero Nat.succ_ne_self Nat.zero_ne_o
-- Nat.zero_ne_bit1 Nat.bit1_ne_zero Nat.bit0_ne_one Nat.one_ne_bit0 Nat.bit0_ne_bit1
-- Nat.bit1_ne_bit0
+attribute [simp] Nat.min_eq_left Nat.min_eq_right
+
/-! ### `succ`, `pred` -/
lemma succ_pos' : 0 < succ n := succ_pos n
It seems that most of this file belongs in Std. This changes some proofs to avoid dependencies on mathlib, notably on the typeclass-mediated order lemmas.
@@ -9,7 +9,6 @@ import Mathlib.Logic.Nontrivial.Defs
import Mathlib.Tactic.Cases
import Mathlib.Tactic.GCongr.Core
import Mathlib.Tactic.PushNeg
-import Mathlib.Tactic.Use
import Mathlib.Util.AssertExists
#align_import data.nat.basic from "leanprover-community/mathlib"@"bd835ef554f37ef9b804f0903089211f89cb370b"
@@ -88,7 +87,7 @@ lemma succ_succ_ne_one (n : ℕ) : n.succ.succ ≠ 1 := by simp
alias _root_.LT.lt.nat_succ_le := succ_le_of_lt
#align has_lt.lt.nat_succ_le LT.lt.nat_succ_le
-lemma not_succ_lt_self : ¬ succ n < n := not_lt_of_ge n.le_succ
+lemma not_succ_lt_self : ¬ succ n < n := Nat.not_lt_of_ge n.le_succ
#align nat.not_succ_lt_self Nat.not_succ_lt_self
#align nat.lt_succ_iff Nat.lt_succ_iff
@@ -97,10 +96,10 @@ lemma succ_le_iff : succ m ≤ n ↔ m < n := ⟨lt_of_succ_le, succ_le_of_lt⟩
#align nat.succ_le_iff Nat.succ_le_iff
lemma le_succ_iff : m ≤ n.succ ↔ m ≤ n ∨ m = n.succ := by
- refine ⟨fun hmn ↦ (lt_or_eq_of_le hmn).imp_left le_of_lt_succ, ?_⟩
+ refine ⟨fun hmn ↦ (Nat.lt_or_eq_of_le hmn).imp_left le_of_lt_succ, ?_⟩
rintro (hmn | rfl)
· exact le_succ_of_le hmn
- · rfl
+ · exact Nat.le_refl _
alias ⟨of_le_succ, _⟩ := le_succ_iff
#align nat.of_le_succ Nat.of_le_succ
@@ -113,7 +112,7 @@ lemma lt_iff_le_pred : ∀ {n}, 0 < n → (m < n ↔ m ≤ n - 1) | _ + 1, _ =>
#align nat.lt_iff_le_pred Nat.lt_iff_le_pred
lemma le_of_pred_lt : ∀ {m}, pred m < n → m ≤ n
- | 0 => le_of_lt
+ | 0 => Nat.le_of_lt
| _ + 1 => id
#align nat.le_of_pred_lt Nat.le_of_pred_lt
@@ -150,7 +149,7 @@ lemma le_one_iff_eq_zero_or_eq_one : ∀ {n : ℕ}, n ≤ 1 ↔ n = 0 ∨ n = 1
@[simp] lemma lt_one_iff : n < 1 ↔ n = 0 := Nat.lt_succ_iff.trans $ by rw [le_zero_eq]
#align nat.lt_one_iff Nat.lt_one_iff
-lemma one_le_of_lt (h : a < b) : 1 ≤ b := lt_of_le_of_lt (Nat.zero_le _) h
+lemma one_le_of_lt (h : a < b) : 1 ≤ b := Nat.lt_of_le_of_lt (Nat.zero_le _) h
#align nat.one_le_of_lt Nat.one_le_of_lt
@[simp] lemma min_eq_zero_iff : min m n = 0 ↔ m = 0 ∨ n = 0 := by omega
@@ -295,11 +294,11 @@ lemma add_eq_three_iff :
#align nat.add_eq_three_iff Nat.add_eq_three_iff
lemma le_add_one_iff : m ≤ n + 1 ↔ m ≤ n ∨ m = n + 1 := by
- rw [le_iff_lt_or_eq, lt_add_one_iff]
+ rw [Nat.le_iff_lt_or_eq, lt_add_one_iff]
#align nat.le_add_one_iff Nat.le_add_one_iff
lemma le_and_le_add_one_iff : n ≤ m ∧ m ≤ n + 1 ↔ m = n ∨ m = n + 1 := by
- rw [le_add_one_iff, and_or_left, ← le_antisymm_iff, eq_comm, and_iff_right_of_imp]
+ rw [le_add_one_iff, and_or_left, ← Nat.le_antisymm_iff, eq_comm, and_iff_right_of_imp]
rintro rfl
exact n.le_succ
#align nat.le_and_le_add_one_iff Nat.le_and_le_add_one_iff
@@ -356,7 +355,7 @@ protected lemma zero_eq_mul : 0 = m * n ↔ m = 0 ∨ n = 0 := by rw [eq_comm, N
#align nat.zero_eq_mul Nat.zero_eq_mul
lemma two_mul_ne_two_mul_add_one : 2 * n ≠ 2 * m + 1 :=
- mt (congr_arg (· % 2))
+ mt (congrArg (· % 2))
(by rw [Nat.add_comm, add_mul_mod_self_left, mul_mod_right, mod_eq_of_lt] <;> simp)
#align nat.two_mul_ne_two_mul_add_one Nat.two_mul_ne_two_mul_add_one
@@ -368,10 +367,12 @@ protected lemma mul_left_inj (ha : a ≠ 0) : b * a = c * a ↔ b = c :=
protected lemma mul_right_inj (ha : a ≠ 0) : a * b = a * c ↔ b = c :=
Nat.mul_left_cancel_iff (Nat.pos_iff_ne_zero.2 ha) _ _
-protected lemma mul_ne_mul_left (ha : a ≠ 0) : b * a ≠ c * a ↔ b ≠ c := (Nat.mul_left_inj ha).not
+protected lemma mul_ne_mul_left (ha : a ≠ 0) : b * a ≠ c * a ↔ b ≠ c :=
+ not_congr (Nat.mul_left_inj ha)
#align nat.mul_ne_mul_left Nat.mul_ne_mul_left
-protected lemma mul_ne_mul_right (ha : a ≠ 0) : a * b ≠ a * c ↔ b ≠ c := (Nat.mul_right_inj ha).not
+protected lemma mul_ne_mul_right (ha : a ≠ 0) : a * b ≠ a * c ↔ b ≠ c :=
+ not_congr (Nat.mul_right_inj ha)
#align nat.mul_ne_mul_right Nat.mul_ne_mul_right
lemma mul_eq_left (ha : a ≠ 0) : a * b = a ↔ b = 1 := by simpa using Nat.mul_right_inj ha (c := 1)
@@ -418,7 +419,7 @@ lemma eq_zero_of_double_le (h : 2 * n ≤ n) : n = 0 := by omega
#align nat.eq_zero_of_double_le Nat.eq_zero_of_double_le
lemma eq_zero_of_mul_le (hb : 2 ≤ n) (h : n * m ≤ m) : m = 0 :=
- eq_zero_of_double_le <| le_trans (Nat.mul_le_mul_right _ hb) h
+ eq_zero_of_double_le <| Nat.le_trans (Nat.mul_le_mul_right _ hb) h
#align nat.eq_zero_of_mul_le Nat.eq_zero_of_mul_le
lemma succ_mul_pos (m : ℕ) (hn : 0 < n) : 0 < succ m * n := Nat.mul_pos m.succ_pos hn
@@ -428,25 +429,27 @@ lemma mul_self_le_mul_self (h : m ≤ n) : m * m ≤ n * n := Nat.mul_le_mul h h
#align nat.mul_self_le_mul_self Nat.mul_self_le_mul_self
lemma mul_lt_mul'' (hac : a < c) (hbd : b < d) : a * b < c * d :=
- Nat.mul_lt_mul_of_lt_of_le hac (le_of_lt hbd) $ by omega
+ Nat.mul_lt_mul_of_lt_of_le hac (Nat.le_of_lt hbd) $ by omega
lemma mul_self_lt_mul_self (h : m < n) : m * m < n * n := mul_lt_mul'' h h
#align nat.mul_self_lt_mul_self Nat.mul_self_lt_mul_self
lemma mul_self_le_mul_self_iff : m * m ≤ n * n ↔ m ≤ n :=
- ⟨le_imp_le_of_lt_imp_lt mul_self_lt_mul_self, mul_self_le_mul_self⟩
+ ⟨fun h => Nat.le_of_not_lt fun h' => Nat.not_le_of_gt (mul_self_lt_mul_self h') h,
+ mul_self_le_mul_self⟩
#align nat.mul_self_le_mul_self_iff Nat.mul_self_le_mul_self_iff
lemma mul_self_lt_mul_self_iff : m * m < n * n ↔ m < n := by
- simp only [← not_le, mul_self_le_mul_self_iff]
+ simp only [← Nat.not_le, mul_self_le_mul_self_iff]
#align nat.mul_self_lt_mul_self_iff Nat.mul_self_lt_mul_self_iff
lemma le_mul_self : ∀ n : ℕ, n ≤ n * n
- | 0 => le_refl _
+ | 0 => Nat.le_refl _
| n + 1 => by simp [Nat.mul_add]
#align nat.le_mul_self Nat.le_mul_self
-lemma mul_self_inj : m * m = n * n ↔ m = n := by simp [le_antisymm_iff, mul_self_le_mul_self_iff]
+lemma mul_self_inj : m * m = n * n ↔ m = n := by
+ simp [Nat.le_antisymm_iff, mul_self_le_mul_self_iff]
#align nat.mul_self_inj Nat.mul_self_inj
@[simp] lemma lt_mul_self_iff : ∀ {n : ℕ}, n < n * n ↔ 1 < n
@@ -486,19 +489,20 @@ lemma le_div_iff_mul_le' (hb : 0 < b) : a ≤ c / b ↔ a * b ≤ c := le_div_if
#align nat.le_div_iff_mul_le' Nat.le_div_iff_mul_le'
lemma div_lt_iff_lt_mul' (hb : 0 < b) : a / b < c ↔ a < c * b := by
- simp only [← not_le, le_div_iff_mul_le' hb]
+ simp only [← Nat.not_le, le_div_iff_mul_le' hb]
#align nat.div_lt_iff_lt_mul' Nat.div_lt_iff_lt_mul'
lemma one_le_div_iff (hb : 0 < b) : 1 ≤ a / b ↔ b ≤ a := by rw [le_div_iff_mul_le hb, Nat.one_mul]
#align nat.one_le_div_iff Nat.one_le_div_iff
-lemma div_lt_one_iff (hb : 0 < b) : a / b < 1 ↔ a < b := by simp only [← not_le, one_le_div_iff hb]
+lemma div_lt_one_iff (hb : 0 < b) : a / b < 1 ↔ a < b := by
+ simp only [← Nat.not_le, one_le_div_iff hb]
#align nat.div_lt_one_iff Nat.div_lt_one_iff
@[gcongr]
protected lemma div_le_div_right (h : a ≤ b) : a / c ≤ b / c :=
(c.eq_zero_or_pos.elim fun hc ↦ by simp [hc]) fun hc ↦
- (le_div_iff_mul_le' hc).2 <| le_trans (Nat.div_mul_le_self _ _) h
+ (le_div_iff_mul_le' hc).2 <| Nat.le_trans (Nat.div_mul_le_self _ _) h
#align nat.div_le_div_right Nat.div_le_div_right
lemma lt_of_div_lt_div (h : a / c < b / c) : a < b :=
@@ -506,7 +510,7 @@ lemma lt_of_div_lt_div (h : a / c < b / c) : a < b :=
#align nat.lt_of_div_lt_div Nat.lt_of_div_lt_div
protected lemma div_pos (hba : b ≤ a) (hb : 0 < b) : 0 < a / b :=
- Nat.pos_of_ne_zero fun h ↦ lt_irrefl a $
+ Nat.pos_of_ne_zero fun h ↦ Nat.lt_irrefl a $
calc
a = a % b := by simpa [h] using (mod_add_div a b).symm
_ < b := mod_lt a hb
@@ -514,7 +518,7 @@ protected lemma div_pos (hba : b ≤ a) (hb : 0 < b) : 0 < a / b :=
#align nat.div_pos Nat.div_pos
lemma lt_mul_of_div_lt (h : a / c < b) (hc : 0 < c) : a < b * c :=
- lt_of_not_ge <| not_le_of_gt h ∘ (Nat.le_div_iff_mul_le hc).2
+ Nat.lt_of_not_ge <| Nat.not_le_of_gt h ∘ (Nat.le_div_iff_mul_le hc).2
#align nat.lt_mul_of_div_lt Nat.lt_mul_of_div_lt
lemma mul_div_le_mul_div_assoc (a b c : ℕ) : a * (b / c) ≤ a * b / c :=
@@ -544,7 +548,7 @@ lemma lt_div_mul_add (hb : 0 < b) : a < a / b * b + b := by
@[simp]
protected lemma div_left_inj (hda : d ∣ a) (hdb : d ∣ b) : a / d = b / d ↔ a = b := by
- refine ⟨fun h ↦ ?_, congr_arg fun b ↦ b / d⟩
+ refine ⟨fun h ↦ ?_, congrArg fun b ↦ b / d⟩
rw [← Nat.mul_div_cancel' hda, ← Nat.mul_div_cancel' hdb, h]
#align nat.div_left_inj Nat.div_left_inj
@@ -560,27 +564,27 @@ lemma div_mul_div_comm : b ∣ a → d ∣ c → (a / b) * (c / d) = (a * c) / (
lemma eq_zero_of_le_div (hn : 2 ≤ n) (h : m ≤ m / n) : m = 0 :=
eq_zero_of_mul_le hn <| by
- rw [Nat.mul_comm]; exact (Nat.le_div_iff_mul_le' (lt_of_lt_of_le (by decide) hn)).1 h
+ rw [Nat.mul_comm]; exact (Nat.le_div_iff_mul_le' (Nat.lt_of_lt_of_le (by decide) hn)).1 h
#align nat.eq_zero_of_le_div Nat.eq_zero_of_le_div
lemma div_mul_div_le_div (a b c : ℕ) : a / c * b / a ≤ b / c := by
- obtain rfl | ha := eq_or_ne a 0
+ obtain rfl | ha := Nat.eq_zero_or_pos a
· simp
· calc
a / c * b / a ≤ b * a / c / a :=
Nat.div_le_div_right (by rw [Nat.mul_comm]; exact mul_div_le_mul_div_assoc _ _ _)
_ = b / c := by rw [Nat.div_div_eq_div_mul, Nat.mul_comm b, Nat.mul_comm c,
- Nat.mul_div_mul_left _ _ (Nat.pos_of_ne_zero ha)]
+ Nat.mul_div_mul_left _ _ ha]
#align nat.div_mul_div_le_div Nat.div_mul_div_le_div
-lemma eq_zero_of_le_half (h : n ≤ n / 2) : n = 0 := eq_zero_of_le_div (le_refl _) h
+lemma eq_zero_of_le_half (h : n ≤ n / 2) : n = 0 := eq_zero_of_le_div (Nat.le_refl _) h
#align nat.eq_zero_of_le_half Nat.eq_zero_of_le_half
lemma le_half_of_half_lt_sub (h : a / 2 < a - b) : b ≤ a / 2 := by
rw [Nat.le_div_iff_mul_le Nat.two_pos]
rw [Nat.div_lt_iff_lt_mul Nat.two_pos, Nat.mul_sub_right_distrib, Nat.lt_sub_iff_add_lt,
Nat.mul_two a] at h
- exact le_of_lt (Nat.lt_of_add_lt_add_left h)
+ exact Nat.le_of_lt (Nat.lt_of_add_lt_add_left h)
#align nat.le_half_of_half_lt_sub Nat.le_half_of_half_lt_sub
lemma half_le_of_sub_le_half (h : a - b ≤ a / 2) : a / 2 ≤ b := by
@@ -615,7 +619,7 @@ lemma two_mul_odd_div_two (hn : n % 2 = 1) : 2 * (n / 2) = n - 1 := by
@[gcongr]
lemma div_le_div_left (hcb : c ≤ b) (hc : 0 < c) : a / b ≤ a / c :=
- (Nat.le_div_iff_mul_le hc).2 <| le_trans (Nat.mul_le_mul_left _ hcb) (div_mul_le_self _ _)
+ (Nat.le_div_iff_mul_le hc).2 <| Nat.le_trans (Nat.mul_le_mul_left _ hcb) (div_mul_le_self _ _)
#align nat.div_le_div_left Nat.div_le_div_left
lemma div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
@@ -671,7 +675,7 @@ protected lemma pow_lt_pow_right (ha : 1 < a) (h : m < n) : a ^ m < a ^ n :=
(Nat.pow_lt_pow_iff_right ha).2 h
protected lemma pow_le_pow_iff_left {n : ℕ} (hn : n ≠ 0) : a ^ n ≤ b ^ n ↔ a ≤ b where
- mp := by simpa only [← Nat.not_le, not_imp_not] using (Nat.pow_lt_pow_left · hn)
+ mp := by simpa only [← Nat.not_le, Decidable.not_imp_not] using (Nat.pow_lt_pow_left · hn)
mpr h := Nat.pow_le_pow_left h _
#align nat.pow_le_iff_le_left Nat.pow_le_pow_iff_left
@@ -738,7 +742,7 @@ lemma one_lt_two_pow' (n : ℕ) : 1 < 2 ^ (n + 1) := one_lt_pow n.succ_ne_zero (
#align nat.one_lt_two_pow' Nat.one_lt_two_pow'
lemma mul_lt_mul_pow_succ (ha : 0 < a) (hb : 1 < b) : n * b < a * b ^ (n + 1) := by
- rw [Nat.pow_succ, ← Nat.mul_assoc, Nat.mul_lt_mul_right (lt_trans Nat.zero_lt_one hb)]
+ rw [Nat.pow_succ, ← Nat.mul_assoc, Nat.mul_lt_mul_right (Nat.lt_trans Nat.zero_lt_one hb)]
exact Nat.lt_of_le_of_lt (Nat.le_mul_of_pos_left _ ha)
((Nat.mul_lt_mul_left ha).2 $ Nat.lt_pow_self hb _)
#align nat.mul_lt_mul_pow_succ Nat.mul_lt_mul_pow_succ
@@ -811,39 +815,45 @@ lemma leRecOn_succ' {C : ℕ → Sort*} {n} {h : n ≤ n + 1} {next : ∀ {k}, C
#align nat.le_rec_on_succ' Nat.leRecOn_succ'
lemma leRecOn_trans {C : ℕ → Sort*} {n m k} (hnm : n ≤ m) (hmk : m ≤ k) {next} (x : C n) :
- (leRecOn (le_trans hnm hmk) (@next) x : C k) = leRecOn hmk (@next) (leRecOn hnm (@next) x) := by
- induction' hmk with k hmk ih
- · rw [leRecOn_self]
- · rw [leRecOn_succ (le_trans hnm hmk), ih, leRecOn_succ]
+ (leRecOn (Nat.le_trans hnm hmk) (@next) x : C k) =
+ leRecOn hmk (@next) (leRecOn hnm (@next) x) := by
+ induction hmk with
+ | refl => rw [leRecOn_self]
+ | step hmk ih => rw [leRecOn_succ (Nat.le_trans hnm hmk), ih, leRecOn_succ]
#align nat.le_rec_on_trans Nat.leRecOn_trans
lemma leRecOn_succ_left {C : ℕ → Sort*} {n m} (h1 : n ≤ m) (h2 : n + 1 ≤ m)
{next : ∀ {k}, C k → C (k + 1)} (x : C n) :
(leRecOn h2 next (next x) : C m) = (leRecOn h1 next x : C m) := by
- rw [Subsingleton.elim h1 (le_trans (le_succ n) h2), leRecOn_trans (le_succ n) h2, leRecOn_succ']
+ rw [Subsingleton.elim h1 (Nat.le_trans (le_succ n) h2), leRecOn_trans (le_succ n) h2,
+ leRecOn_succ']
#align nat.le_rec_on_succ_left Nat.leRecOn_succ_left
lemma leRecOn_injective {C : ℕ → Sort*} {n m} (hnm : n ≤ m) (next : ∀ {k}, C k → C (k + 1))
(Hnext : ∀ n, Injective (@next n)) : Injective (@leRecOn C n m hnm next) := by
- induction' hnm with m hnm ih
- · intro x y H
+ induction hnm with
+ | refl =>
+ intro x y H
rwa [leRecOn_self, leRecOn_self] at H
- intro x y H
- rw [leRecOn_succ hnm, leRecOn_succ hnm] at H
- exact ih (Hnext _ H)
+ | step hnm ih =>
+ intro x y H
+ rw [leRecOn_succ hnm, leRecOn_succ hnm] at H
+ exact ih (Hnext _ H)
#align nat.le_rec_on_injective Nat.leRecOn_injective
lemma leRecOn_surjective {C : ℕ → Sort*} {n m} (hnm : n ≤ m) (next : ∀ {k}, C k → C (k + 1))
(Hnext : ∀ n, Surjective (@next n)) : Surjective (@leRecOn C n m hnm next) := by
- induction' hnm with m hnm ih
- · intro x
- use x
+ induction hnm with
+ | refl =>
+ intro x
+ refine ⟨x, ?_⟩
rw [leRecOn_self]
- intro x
- obtain ⟨w, rfl⟩ := Hnext _ x
- obtain ⟨x, rfl⟩ := ih w
- use x
- rw [leRecOn_succ]
+ | step hnm ih =>
+ intro x
+ obtain ⟨w, rfl⟩ := Hnext _ x
+ obtain ⟨x, rfl⟩ := ih w
+ refine ⟨x, ?_⟩
+ rw [leRecOn_succ]
#align nat.le_rec_on_surjective Nat.leRecOn_surjective
/-- Recursion principle based on `<`. -/
@@ -905,17 +915,18 @@ lemma decreasingInduction_succ' {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P
lemma decreasingInduction_trans {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n)
(hmn : m ≤ n) (hnk : n ≤ k) (hP : P k) :
- (decreasingInduction h (le_trans hmn hnk) hP : P m) =
+ (decreasingInduction h (Nat.le_trans hmn hnk) hP : P m) =
decreasingInduction h hmn (decreasingInduction h hnk hP) := by
- induction' hnk with k hnk ih
- · rw [decreasingInduction_self]
- · rw [decreasingInduction_succ h (le_trans hmn hnk), ih, decreasingInduction_succ]
+ induction hnk with
+ | refl => rw [decreasingInduction_self]
+ | step hnk ih =>
+ rw [decreasingInduction_succ h (Nat.le_trans hmn hnk), ih, decreasingInduction_succ]
#align nat.decreasing_induction_trans Nat.decreasingInduction_trans
lemma decreasingInduction_succ_left {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n)
(smn : m + 1 ≤ n) (mn : m ≤ n) (hP : P n) :
decreasingInduction h mn hP = h m (decreasingInduction h smn hP) := by
- rw [Subsingleton.elim mn (le_trans (le_succ m) smn), decreasingInduction_trans,
+ rw [Subsingleton.elim mn (Nat.le_trans (le_succ m) smn), decreasingInduction_trans,
decreasingInduction_succ']
apply Nat.le_succ
#align nat.decreasing_induction_succ_left Nat.decreasingInduction_succ_left
@@ -975,7 +986,7 @@ theorem diag_induction (P : ℕ → ℕ → Prop) (ha : ∀ a, P (a + 1) (a + 1)
apply diag_induction P ha hb hd (a + 1) b h
have _ : a + (b + 1) < (a + 1) + (b + 1) := by simp
apply diag_induction P ha hb hd a (b + 1)
- apply lt_of_le_of_lt (Nat.le_succ _) h
+ apply Nat.lt_of_le_of_lt (Nat.le_succ _) h
termination_by a b _c => a + b
decreasing_by all_goals assumption
#align nat.diag_induction Nat.diag_induction
@@ -1022,7 +1033,9 @@ lemma mul_div_mul_comm_of_dvd_dvd (hba : b ∣ a) (hdc : d ∣ c) :
rw [mul_mod, mod_mod, ← mul_mod]
lemma pow_mod (a b n : ℕ) : a ^ b % n = (a % n) ^ b % n := by
- induction' b with b ih; rfl; simp [Nat.pow_succ, Nat.mul_mod, ih]
+ induction b with
+ | zero => rfl
+ | succ b ih => simp [Nat.pow_succ, Nat.mul_mod, ih]
#align nat.pow_mod Nat.pow_mod
lemma not_pos_pow_dvd : ∀ {a n : ℕ} (_ : 1 < a) (_ : 1 < n), ¬ a ^ n ∣ a
@@ -1039,7 +1052,7 @@ lemma not_pos_pow_dvd : ∀ {a n : ℕ} (_ : 1 < a) (_ : 1 < n), ¬ a ^ n ∣ a
lemma lt_of_pow_dvd_right (hb : b ≠ 0) (ha : 2 ≤ a) (h : a ^ n ∣ b) : n < b := by
rw [← Nat.pow_lt_pow_iff_right (succ_le_iff.1 ha)]
- exact lt_of_le_of_lt (le_of_dvd (Nat.pos_iff_ne_zero.2 hb) h) (lt_pow_self ha _)
+ exact Nat.lt_of_le_of_lt (le_of_dvd (Nat.pos_iff_ne_zero.2 hb) h) (lt_pow_self ha _)
#align nat.lt_of_pow_dvd_right Nat.lt_of_pow_dvd_right
lemma div_dvd_of_dvd (h : n ∣ m) : m / n ∣ m := ⟨n, (Nat.div_mul_cancel h).symm⟩
@@ -1054,8 +1067,8 @@ protected lemma div_div_self (h : n ∣ m) (hm : m ≠ 0) : m / (m / n) = n := b
lemma not_dvd_of_pos_of_lt (h1 : 0 < n) (h2 : n < m) : ¬m ∣ n := by
rintro ⟨k, rfl⟩
rcases Nat.eq_zero_or_pos k with (rfl | hk)
- · exact lt_irrefl 0 h1
- · exact not_lt.2 (Nat.le_mul_of_pos_right _ hk) h2
+ · exact Nat.lt_irrefl 0 h1
+ · exact Nat.not_lt.2 (Nat.le_mul_of_pos_right _ hk) h2
#align nat.not_dvd_of_pos_of_lt Nat.not_dvd_of_pos_of_lt
lemma mod_eq_iff_lt (hn : n ≠ 0) : m % n = m ↔ m < n :=
@@ -1109,7 +1122,7 @@ lemma add_mod_eq_ite :
· rw [Nat.mod_eq_sub_mod h, Nat.mod_eq_of_lt]
exact (Nat.sub_lt_iff_lt_add h).mpr (Nat.add_lt_add (m.mod_lt (zero_lt_succ _))
(n.mod_lt (zero_lt_succ _)))
- · exact Nat.mod_eq_of_lt (lt_of_not_ge h)
+ · exact Nat.mod_eq_of_lt (Nat.lt_of_not_ge h)
#align nat.add_mod_eq_ite Nat.add_mod_eq_ite
/-- `m` is not divisible by `n` if it is between `n * k` and `n * (k + 1)` for some `k`. -/
@@ -1396,7 +1409,7 @@ instance decidableLoHi (lo hi : ℕ) (P : ℕ → Prop) [H : DecidablePred P] :
instance decidableLoHiLe (lo hi : ℕ) (P : ℕ → Prop) [DecidablePred P] :
Decidable (∀ x, lo ≤ x → x ≤ hi → P x) :=
decidable_of_iff (∀ x, lo ≤ x → x < hi + 1 → P x) <|
- ball_congr fun _ _ => imp_congr Nat.lt_succ_iff Iff.rfl
+ forall₂_congr fun _ _ ↦ imp_congr Nat.lt_succ_iff Iff.rfl
#align nat.decidable_lo_hi_le Nat.decidableLoHiLe
end Nat
@@ -10,6 +10,7 @@ import Mathlib.Tactic.Cases
import Mathlib.Tactic.GCongr.Core
import Mathlib.Tactic.PushNeg
import Mathlib.Tactic.Use
+import Mathlib.Util.AssertExists
#align_import data.nat.basic from "leanprover-community/mathlib"@"bd835ef554f37ef9b804f0903089211f89cb370b"
@@ -42,6 +43,9 @@ The names of this file, `Data.Nat.Basic` and `Data.Nat.Order.Basic` are archaic
with reality anymore. Rename them.
-/
+/- We don't want to import the algebraic hierarchy in this file. -/
+assert_not_exists Monoid
+
open Function
namespace Nat
@@ -1123,10 +1127,14 @@ protected lemma dvd_add_left (h : a ∣ c) : a ∣ b + c ↔ a ∣ b := (Nat.dvd
protected lemma dvd_add_right (h : a ∣ b) : a ∣ b + c ↔ a ∣ c := (Nat.dvd_add_iff_right h).symm
#align nat.dvd_add_right Nat.dvd_add_right
+/-- special case of `mul_dvd_mul_iff_left` for `ℕ`.
+Duplicated here to keep simple imports for this file. -/
protected lemma mul_dvd_mul_iff_left (ha : 0 < a) : a * b ∣ a * c ↔ b ∣ c :=
exists_congr fun d ↦ by rw [Nat.mul_assoc, Nat.mul_right_inj $ ne_of_gt ha]
#align nat.mul_dvd_mul_iff_left Nat.mul_dvd_mul_iff_left
+/-- special case of `mul_dvd_mul_iff_right` for `ℕ`.
+Duplicated here to keep simple imports for this file. -/
protected lemma mul_dvd_mul_iff_right (hc : 0 < c) : a * c ∣ b * c ↔ a ∣ b :=
exists_congr fun d ↦ by rw [Nat.mul_right_comm, Nat.mul_left_inj $ ne_of_gt hc]
#align nat.mul_dvd_mul_iff_right Nat.mul_dvd_mul_iff_right
@@ -1315,7 +1315,7 @@ lemma findGreatest_eq_zero_iff : Nat.findGreatest P k = 0 ↔ ∀ ⦃n⦄, 0 < n
#align nat.find_greatest_eq_zero_iff Nat.findGreatest_eq_zero_iff
@[simp] lemma findGreatest_pos : 0 < Nat.findGreatest P k ↔ ∃ n, 0 < n ∧ n ≤ k ∧ P n := by
- rw [Nat.pos_iff_ne_zero, Ne.def, findGreatest_eq_zero_iff]; push_neg; rfl
+ rw [Nat.pos_iff_ne_zero, Ne, findGreatest_eq_zero_iff]; push_neg; rfl
lemma findGreatest_spec (hmb : m ≤ n) (hm : P m) : P (Nat.findGreatest P n) := by
by_cases h : Nat.findGreatest P n = 0
We change the following field in the definition of an additive commutative monoid:
nsmul_succ : ∀ (n : ℕ) (x : G),
- AddMonoid.nsmul (n + 1) x = x + AddMonoid.nsmul n x
+ AddMonoid.nsmul (n + 1) x = AddMonoid.nsmul n x + x
where the latter is more natural
We adjust the definitions of ^
in monoids, groups, etc.
Originally there was a warning comment about why this natural order was preferred
use
x * npowRec n x
and notnpowRec n x * x
in the definition to make sure that definitional unfolding ofnpowRec
is blocked, to avoid deep recursion issues.
but it seems to no longer apply.
Remarks on the PR :
pow_succ
and pow_succ'
have switched their meanings.Ideal.IsPrime.mul_mem_pow
which is defined in [Mathlib/RingTheory/DedekindDomain/Ideal.lean]. Changing the order of operation forced me to add the symmetric lemma Ideal.IsPrime.mem_pow_mul
.@@ -56,13 +56,13 @@ instance commSemiring : CommSemiring ℕ where
mul_comm := Nat.mul_comm
natCast n := n
natCast_zero := rfl
- natCast_succ n := rfl
+ natCast_succ _ := rfl
nsmul m n := m * n
nsmul_zero := Nat.zero_mul
- nsmul_succ _ _ := by dsimp only; rw [Nat.add_comm, Nat.right_distrib, Nat.one_mul]
+ nsmul_succ := succ_mul
npow m n := n ^ m
npow_zero := Nat.pow_zero
- npow_succ _ _ := Nat.pow_succ'
+ npow_succ _ _ := rfl
/-! Extra instances to short-circuit type class resolution and ensure computability -/
Make use of Nat
-specific lemmas from Std rather than the general ones provided by mathlib. Also reverse the dependency between Multiset.Nodup
/Multiset.dedup
and Multiset.sum
since only the latter needs algebra. Also rename Algebra.BigOperators.Multiset.Abs
to Algebra.BigOperators.Multiset.Order
and move some lemmas from Algebra.BigOperators.Multiset.Basic
to it.
The ultimate goal here is to carve out Data
, Algebra
and Order
sublibraries.
@@ -999,6 +999,8 @@ lemma set_induction {S : Set ℕ} (hb : 0 ∈ S) (h_ind : ∀ k : ℕ, k ∈ S
#align nat.mod_mul_right_div_self Nat.mod_mul_right_div_self
#align nat.mod_mul_left_div_self Nat.mod_mul_left_div_self
+attribute [simp] Nat.dvd_zero
+
lemma mul_div_mul_comm_of_dvd_dvd (hba : b ∣ a) (hdc : d ∣ c) :
a * c / (b * d) = a / b * (c / d) := by
obtain rfl | hb := b.eq_zero_or_pos; · simp
Make use of Nat
-specific lemmas from Std rather than the general ones provided by mathlib.
The ultimate goal here is to carve out Data
, Algebra
and Order
sublibraries.
@@ -636,6 +636,12 @@ lemma div_eq_sub_mod_div : m / n = (m - m % n) / n := by
rw [this, mul_div_right _ hn]
#align nat.div_eq_sub_mod_div Nat.div_eq_sub_mod_div
+protected lemma eq_div_of_mul_eq_left (hc : c ≠ 0) (h : a * c = b) : a = b / c := by
+ rw [← h, Nat.mul_div_cancel _ (Nat.pos_iff_ne_zero.2 hc)]
+
+protected lemma eq_div_of_mul_eq_right (hc : c ≠ 0) (h : c * a = b) : a = b / c := by
+ rw [← h, Nat.mul_div_cancel_left _ (Nat.pos_iff_ne_zero.2 hc)]
+
/-!
### `pow`
Move basic Nat
lemmas from Data.Nat.Order.Basic
and Data.Nat.Pow
to Data.Nat.Defs
. Most proofs need adapting, but that's easily solved by replacing the general mathlib lemmas by the new Std Nat
-specific lemmas and using omega
.
Data.Nat.Pow
to Algebra.GroupPower.Order
Data.Nat.Pow
to Algebra.GroupPower.Order
bit
/bit0
/bit1
lemmas from Data.Nat.Order.Basic
to Data.Nat.Bits
Data.Nat.Order.Basic
anymoreNat
-specific lemmas to help fix the fallout (look for nolint simpNF
)Nat.mul_self_le_mul_self_iff
and Nat.mul_self_lt_mul_self_iff
around (they were misnamed)Nat.one_lt_pow
implicit@@ -25,10 +25,21 @@ This file contains:
* `strong_rec'`: recursion based on strong inequalities
* decidability instances on predicates about the natural numbers
-Many theorems that used to live in this file have been moved to `Data.Nat.Order`, so that
-this file requires fewer imports. For each section here there is a corresponding section in
-that file with additional results. It may be possible to move some of these results here,
-by tweaking their proofs.
+## Implementation note
+
+Std has a home-baked development of the algebraic and order theoretic theory of `ℕ` which, in
+particular, is not typeclass-mediated. This is useful to set up the algebra and finiteness libraries
+in mathlib (naturals show up as indices in lists, cardinality in finsets, powers in groups, ...).
+This home-baked development is pursued in this file.
+
+Less basic uses of `ℕ` should however use the typeclass-mediated development. `Data.Nat.Basic` gives
+access to the algebraic instances. `Data.Nat.Order.Basic` is the one giving access to the algebraic
+order instances.
+
+## TODO
+
+The names of this file, `Data.Nat.Basic` and `Data.Nat.Order.Basic` are archaic and don't match up
+with reality anymore. Rename them.
-/
open Function
@@ -132,9 +143,21 @@ lemma one_lt_iff_ne_zero_and_ne_one : ∀ {n : ℕ}, 1 < n ↔ n ≠ 0 ∧ n ≠
lemma le_one_iff_eq_zero_or_eq_one : ∀ {n : ℕ}, n ≤ 1 ↔ n = 0 ∨ n = 1 := by simp [le_succ_iff]
+@[simp] lemma lt_one_iff : n < 1 ↔ n = 0 := Nat.lt_succ_iff.trans $ by rw [le_zero_eq]
+#align nat.lt_one_iff Nat.lt_one_iff
+
+lemma one_le_of_lt (h : a < b) : 1 ≤ b := lt_of_le_of_lt (Nat.zero_le _) h
+#align nat.one_le_of_lt Nat.one_le_of_lt
+
+@[simp] lemma min_eq_zero_iff : min m n = 0 ↔ m = 0 ∨ n = 0 := by omega
+@[simp] lemma max_eq_zero_iff : max m n = 0 ↔ m = 0 ∧ n = 0 := by omega
+#align nat.min_eq_zero_iff Nat.min_eq_zero_iff
+#align nat.max_eq_zero_iff Nat.max_eq_zero_iff
+
-- Moved to Std
#align nat.succ_eq_one_add Nat.succ_eq_one_add
#align nat.one_add Nat.one_add
+#align nat.zero_max Nat.zero_max
lemma pred_eq_sub_one (n : ℕ) : pred n = n - 1 := rfl
#align nat.pred_eq_sub_one Nat.pred_eq_sub_one
@@ -206,24 +229,127 @@ lemma sub_one_add_self (n : ℕ) : (n - 1) + n = 2 * n - 1 := Nat.add_comm _ n
lemma self_add_pred (n : ℕ) : n + pred n = (2 * n).pred := self_add_sub_one n
lemma pred_add_self (n : ℕ) : pred n + n = (2 * n).pred := sub_one_add_self n
+lemma pred_le_iff : pred m ≤ n ↔ m ≤ succ n :=
+ ⟨le_succ_of_pred_le, by cases m; exacts [fun _ ↦ zero_le n, le_of_succ_le_succ]⟩
+#align nat.pred_le_iff Nat.pred_le_iff
+
+lemma lt_of_lt_pred (h : m < n - 1) : m < n := by omega
+#align nat.lt_of_lt_pred Nat.lt_of_lt_pred
+
+lemma le_add_pred_of_pos (a : ℕ) (hb : b ≠ 0) : a ≤ b + (a - 1) := by omega
+#align nat.le_add_pred_of_pos Nat.le_add_pred_of_pos
+
/-! ### `add` -/
+#align nat.add_pos_left Nat.add_pos_left
+#align nat.add_pos_right Nat.add_pos_right
+#align nat.exists_eq_add_of_le Nat.exists_eq_add_of_le
+#align nat.exists_eq_add_of_le' Nat.exists_eq_add_of_le'
+#align nat.exists_eq_add_of_lt Nat.exists_eq_add_of_lt
+
+attribute [simp] le_add_left le_add_right Nat.lt_add_left_iff_pos Nat.lt_add_right_iff_pos
+ Nat.add_le_add_iff_left Nat.add_le_add_iff_right Nat.add_lt_add_iff_left Nat.add_lt_add_iff_right
+ not_lt_zero
+
+-- We want to use these two lemmas earlier than the lemmas simp can prove them with
+@[simp, nolint simpNF] protected alias add_left_inj := Nat.add_right_cancel_iff
+@[simp, nolint simpNF] protected alias add_right_inj := Nat.add_left_cancel_iff
+
-- Sometimes a bare `Nat.add` or similar appears as a consequence of unfolding during pattern
-- matching. These lemmas package them back up as typeclass mediated operations.
@[simp] lemma add_def : Nat.add m n = m + n := rfl
#align nat.add_def Nat.add_def
-#align nat.exists_eq_add_of_le Nat.exists_eq_add_of_le
-#align nat.exists_eq_add_of_le' Nat.exists_eq_add_of_le'
-#align nat.exists_eq_add_of_lt Nat.exists_eq_add_of_lt
+lemma two_le_iff : ∀ n, 2 ≤ n ↔ n ≠ 0 ∧ n ≠ 1
+ | 0 => by simp
+ | 1 => by simp
+ | n + 2 => by simp
+#align nat.two_le_iff Nat.two_le_iff
+
+lemma add_eq_max_iff : m + n = max m n ↔ m = 0 ∨ n = 0 := by omega
+lemma add_eq_min_iff : m + n = min m n ↔ m = 0 ∧ n = 0 := by omega
+#align nat.add_eq_max_iff Nat.add_eq_max_iff
+#align nat.add_eq_min_iff Nat.add_eq_min_iff
+
+-- We want to use this lemma earlier than the lemma simp can prove it with
+@[simp, nolint simpNF] protected lemma add_eq_zero : m + n = 0 ↔ m = 0 ∧ n = 0 := by omega
+
+lemma add_pos_iff_pos_or_pos : 0 < m + n ↔ 0 < m ∨ 0 < n := by omega
+#align nat.add_pos_iff_pos_or_pos Nat.add_pos_iff_pos_or_pos
+
+lemma add_eq_one_iff : m + n = 1 ↔ m = 0 ∧ n = 1 ∨ m = 1 ∧ n = 0 := by
+ cases n <;> simp [succ_eq_add_one, ← Nat.add_assoc, succ_inj']
+#align nat.add_eq_one_iff Nat.add_eq_one_iff
+
+lemma add_eq_two_iff : m + n = 2 ↔ m = 0 ∧ n = 2 ∨ m = 1 ∧ n = 1 ∨ m = 2 ∧ n = 0 := by
+ omega
+#align nat.add_eq_two_iff Nat.add_eq_two_iff
+
+lemma add_eq_three_iff :
+ m + n = 3 ↔ m = 0 ∧ n = 3 ∨ m = 1 ∧ n = 2 ∨ m = 2 ∧ n = 1 ∨ m = 3 ∧ n = 0 := by
+ omega
+#align nat.add_eq_three_iff Nat.add_eq_three_iff
+
+lemma le_add_one_iff : m ≤ n + 1 ↔ m ≤ n ∨ m = n + 1 := by
+ rw [le_iff_lt_or_eq, lt_add_one_iff]
+#align nat.le_add_one_iff Nat.le_add_one_iff
+
+lemma le_and_le_add_one_iff : n ≤ m ∧ m ≤ n + 1 ↔ m = n ∨ m = n + 1 := by
+ rw [le_add_one_iff, and_or_left, ← le_antisymm_iff, eq_comm, and_iff_right_of_imp]
+ rintro rfl
+ exact n.le_succ
+#align nat.le_and_le_add_one_iff Nat.le_and_le_add_one_iff
+
+lemma add_succ_lt_add (hab : a < b) (hcd : c < d) : a + c + 1 < b + d := by
+ rw [Nat.add_assoc]; exact Nat.add_lt_add_of_lt_of_le hab (Nat.succ_le_iff.2 hcd)
+#align nat.add_succ_lt_add Nat.add_succ_lt_add
+
+theorem le_or_le_of_add_eq_add_pred (h : a + c = b + d - 1) : b ≤ a ∨ d ≤ c := by
+ rcases le_or_lt b a with h' | h' <;> [left; right]
+ · exact h'
+ · replace h' := Nat.add_lt_add_right h' c
+ rw [h] at h'
+ rcases d.eq_zero_or_pos with hn | hn
+ · rw [hn]
+ exact zero_le c
+ rw [d.add_sub_assoc (Nat.succ_le_of_lt hn), Nat.add_lt_add_iff_left] at h'
+ exact Nat.le_of_pred_lt h'
+#align nat.le_or_le_of_add_eq_add_pred Nat.le_or_le_of_add_eq_add_pred
+
+/-! ### `sub` -/
+
+/-- A version of `Nat.sub_succ` in the form `_ - 1` instead of `Nat.pred _`. -/
+lemma sub_succ' (m n : ℕ) : m - n.succ = m - n - 1 := rfl
+#align nat.sub_succ' Nat.sub_succ'
+
+protected lemma lt_sub_iff_add_lt : a < c - b ↔ a + b < c := ⟨add_lt_of_lt_sub, lt_sub_of_add_lt⟩
+protected lemma lt_sub_iff_add_lt' : a < c - b ↔ b + a < c := by omega
+protected lemma sub_lt_iff_lt_add (hba : b ≤ a) : a - b < c ↔ a < b + c := by omega
+protected lemma sub_lt_iff_lt_add' (hba : b ≤ a) : a - b < c ↔ a < c + b := by omega
+
+protected lemma sub_sub_sub_cancel_right (h : c ≤ b) : a - c - (b - c) = a - b := by omega
+protected lemma add_sub_sub_cancel (h : c ≤ a) : a + b - (a - c) = b + c := by omega
+protected lemma sub_add_sub_cancel (hab : b ≤ a) (hcb : c ≤ b) : a - b + (b - c) = a - c := by omega
+
+lemma lt_pred_iff : a < pred b ↔ succ a < b := Nat.lt_sub_iff_add_lt (b := 1)
+#align nat.lt_pred_iff Nat.lt_pred_iff
+
+protected lemma sub_lt_sub_iff_right (h : c ≤ a) : a - c < b - c ↔ a < b := by omega
/-! ### `mul` -/
+#align nat.mul_ne_zero Nat.mul_ne_zero
+#align nat.mul_eq_zero Nat.mul_eq_zero
+#align nat.eq_of_mul_eq_mul_right Nat.eq_of_mul_eq_mul_right
+#align nat.le_mul_of_pos_left Nat.le_mul_of_pos_left
+#align nat.le_mul_of_pos_right Nat.le_mul_of_pos_right
+
@[simp] lemma mul_def : Nat.mul m n = m * n := rfl
#align nat.mul_def Nat.mul_def
--- Moved to core
-#align nat.eq_of_mul_eq_mul_right Nat.eq_of_mul_eq_mul_right
+-- Porting note: removing `simp` attribute
+protected lemma zero_eq_mul : 0 = m * n ↔ m = 0 ∨ n = 0 := by rw [eq_comm, Nat.mul_eq_zero]
+#align nat.zero_eq_mul Nat.zero_eq_mul
lemma two_mul_ne_two_mul_add_one : 2 * n ≠ 2 * m + 1 :=
mt (congr_arg (· % 2))
@@ -254,6 +380,9 @@ lemma mul_right_eq_self_iff (ha : 0 < a) : a * b = a ↔ b = 1 := mul_eq_left $
lemma mul_left_eq_self_iff (hb : 0 < b) : a * b = b ↔ a = 1 := mul_eq_right $ ne_of_gt hb
#align nat.mul_left_eq_self_iff Nat.mul_left_eq_self_iff
+protected lemma le_of_mul_le_mul_right (h : a * c ≤ b * c) (hc : 0 < c) : a ≤ b :=
+ Nat.le_of_mul_le_mul_left (by simpa [Nat.mul_comm]) hc
+
set_option push_neg.use_distrib true in
/-- The product of two natural numbers is greater than 1 if and only if
at least one of them is greater than 1 and both are positive. -/
@@ -268,8 +397,75 @@ lemma one_lt_mul_iff : 1 < m * n ↔ 0 < m ∧ 0 < n ∧ (1 < m ∨ 1 < n) := by
· exact Nat.mul_lt_mul_of_lt_of_le' hm h.2.1 Nat.zero_lt_one
· exact Nat.mul_lt_mul_of_le_of_lt h.1 hn h.1
+lemma eq_one_of_mul_eq_one_right (H : m * n = 1) : m = 1 := eq_one_of_dvd_one ⟨n, H.symm⟩
+#align nat.eq_one_of_mul_eq_one_right Nat.eq_one_of_mul_eq_one_right
+
+lemma eq_one_of_mul_eq_one_left (H : m * n = 1) : n = 1 :=
+ eq_one_of_mul_eq_one_right (by rwa [Nat.mul_comm])
+#align nat.eq_one_of_mul_eq_one_left Nat.eq_one_of_mul_eq_one_left
+
+@[simp] protected lemma lt_mul_iff_one_lt_left (hb : 0 < b) : b < a * b ↔ 1 < a := by
+ simpa using Nat.mul_lt_mul_right (b := 1) hb
+
+@[simp] protected lemma lt_mul_iff_one_lt_right (ha : 0 < a) : a < a * b ↔ 1 < b := by
+ simpa using Nat.mul_lt_mul_left (b := 1) ha
+
+lemma eq_zero_of_double_le (h : 2 * n ≤ n) : n = 0 := by omega
+#align nat.eq_zero_of_double_le Nat.eq_zero_of_double_le
+
+lemma eq_zero_of_mul_le (hb : 2 ≤ n) (h : n * m ≤ m) : m = 0 :=
+ eq_zero_of_double_le <| le_trans (Nat.mul_le_mul_right _ hb) h
+#align nat.eq_zero_of_mul_le Nat.eq_zero_of_mul_le
+
+lemma succ_mul_pos (m : ℕ) (hn : 0 < n) : 0 < succ m * n := Nat.mul_pos m.succ_pos hn
+#align nat.succ_mul_pos Nat.succ_mul_pos
+
+lemma mul_self_le_mul_self (h : m ≤ n) : m * m ≤ n * n := Nat.mul_le_mul h h
+#align nat.mul_self_le_mul_self Nat.mul_self_le_mul_self
+
+lemma mul_lt_mul'' (hac : a < c) (hbd : b < d) : a * b < c * d :=
+ Nat.mul_lt_mul_of_lt_of_le hac (le_of_lt hbd) $ by omega
+
+lemma mul_self_lt_mul_self (h : m < n) : m * m < n * n := mul_lt_mul'' h h
+#align nat.mul_self_lt_mul_self Nat.mul_self_lt_mul_self
+
+lemma mul_self_le_mul_self_iff : m * m ≤ n * n ↔ m ≤ n :=
+ ⟨le_imp_le_of_lt_imp_lt mul_self_lt_mul_self, mul_self_le_mul_self⟩
+#align nat.mul_self_le_mul_self_iff Nat.mul_self_le_mul_self_iff
+
+lemma mul_self_lt_mul_self_iff : m * m < n * n ↔ m < n := by
+ simp only [← not_le, mul_self_le_mul_self_iff]
+#align nat.mul_self_lt_mul_self_iff Nat.mul_self_lt_mul_self_iff
+
+lemma le_mul_self : ∀ n : ℕ, n ≤ n * n
+ | 0 => le_refl _
+ | n + 1 => by simp [Nat.mul_add]
+#align nat.le_mul_self Nat.le_mul_self
+
+lemma mul_self_inj : m * m = n * n ↔ m = n := by simp [le_antisymm_iff, mul_self_le_mul_self_iff]
+#align nat.mul_self_inj Nat.mul_self_inj
+
+@[simp] lemma lt_mul_self_iff : ∀ {n : ℕ}, n < n * n ↔ 1 < n
+ | 0 => by simp
+ | n + 1 => Nat.lt_mul_iff_one_lt_left n.succ_pos
+#align nat.lt_mul_self_iff Nat.lt_mul_self_iff
+
+lemma add_sub_one_le_mul (ha : a ≠ 0) (hb : b ≠ 0) : a + b - 1 ≤ a * b := by
+ cases a
+ · cases ha rfl
+ · rw [succ_add, Nat.add_one_sub_one, succ_mul]
+ exact Nat.add_le_add_right (Nat.le_mul_of_pos_right _ $ Nat.pos_iff_ne_zero.2 hb) _
+#align nat.add_sub_one_le_mul Nat.add_sub_one_le_mul
+
+protected lemma add_le_mul {a : ℕ} (ha : 2 ≤ a) : ∀ {b : ℕ} (_ : 2 ≤ b), a + b ≤ a * b
+ | 2, _ => by omega
+ | b + 3, _ => by have := Nat.add_le_mul ha (Nat.le_add_left _ b); rw [mul_succ]; omega
+
/-! ### `div` -/
+#align nat.pow_div Nat.pow_div
+#align nat.div_lt_of_lt_mul Nat.div_lt_of_lt_mul
+
attribute [simp] Nat.div_self
lemma div_le_iff_le_mul_add_pred (hb : 0 < b) : a / b ≤ c ↔ a ≤ b * c + (b - 1) := by
@@ -358,6 +554,192 @@ lemma div_mul_div_comm : b ∣ a → d ∣ c → (a / b) * (c / d) = (a * c) / (
Nat.mul_left_comm x, ← Nat.mul_assoc b, Nat.mul_div_cancel_left _ (Nat.mul_pos hb hd)]
#align nat.div_mul_div_comm Nat.div_mul_div_comm
+lemma eq_zero_of_le_div (hn : 2 ≤ n) (h : m ≤ m / n) : m = 0 :=
+ eq_zero_of_mul_le hn <| by
+ rw [Nat.mul_comm]; exact (Nat.le_div_iff_mul_le' (lt_of_lt_of_le (by decide) hn)).1 h
+#align nat.eq_zero_of_le_div Nat.eq_zero_of_le_div
+
+lemma div_mul_div_le_div (a b c : ℕ) : a / c * b / a ≤ b / c := by
+ obtain rfl | ha := eq_or_ne a 0
+ · simp
+ · calc
+ a / c * b / a ≤ b * a / c / a :=
+ Nat.div_le_div_right (by rw [Nat.mul_comm]; exact mul_div_le_mul_div_assoc _ _ _)
+ _ = b / c := by rw [Nat.div_div_eq_div_mul, Nat.mul_comm b, Nat.mul_comm c,
+ Nat.mul_div_mul_left _ _ (Nat.pos_of_ne_zero ha)]
+#align nat.div_mul_div_le_div Nat.div_mul_div_le_div
+
+lemma eq_zero_of_le_half (h : n ≤ n / 2) : n = 0 := eq_zero_of_le_div (le_refl _) h
+#align nat.eq_zero_of_le_half Nat.eq_zero_of_le_half
+
+lemma le_half_of_half_lt_sub (h : a / 2 < a - b) : b ≤ a / 2 := by
+ rw [Nat.le_div_iff_mul_le Nat.two_pos]
+ rw [Nat.div_lt_iff_lt_mul Nat.two_pos, Nat.mul_sub_right_distrib, Nat.lt_sub_iff_add_lt,
+ Nat.mul_two a] at h
+ exact le_of_lt (Nat.lt_of_add_lt_add_left h)
+#align nat.le_half_of_half_lt_sub Nat.le_half_of_half_lt_sub
+
+lemma half_le_of_sub_le_half (h : a - b ≤ a / 2) : a / 2 ≤ b := by
+ rw [Nat.le_div_iff_mul_le Nat.two_pos, Nat.mul_sub_right_distrib, Nat.sub_le_iff_le_add,
+ Nat.mul_two, Nat.add_le_add_iff_left] at h
+ rw [← Nat.mul_div_left b Nat.two_pos]
+ exact Nat.div_le_div_right h
+#align nat.half_le_of_sub_le_half Nat.half_le_of_sub_le_half
+
+protected lemma div_le_of_le_mul' (h : m ≤ k * n) : m / k ≤ n := by
+ obtain rfl | hk := k.eq_zero_or_pos
+ · simp
+ · refine Nat.le_of_mul_le_mul_left ?_ hk
+ calc
+ k * (m / k) ≤ m % k + k * (m / k) := Nat.le_add_left _ _
+ _ = m := mod_add_div _ _
+ _ ≤ k * n := h
+#align nat.div_le_of_le_mul' Nat.div_le_of_le_mul'
+
+protected lemma div_le_self' (m n : ℕ) : m / n ≤ m := by
+ obtain rfl | hn := n.eq_zero_or_pos
+ · simp
+ · refine Nat.div_le_of_le_mul' ?_
+ calc
+ m = 1 * m := by rw [Nat.one_mul]
+ _ ≤ n * m := Nat.mul_le_mul_right _ hn
+#align nat.div_le_self' Nat.div_le_self'
+
+lemma two_mul_odd_div_two (hn : n % 2 = 1) : 2 * (n / 2) = n - 1 := by
+ conv => rhs; rw [← Nat.mod_add_div n 2, hn, Nat.add_sub_cancel_left]
+#align nat.two_mul_odd_div_two Nat.two_mul_odd_div_two
+
+@[gcongr]
+lemma div_le_div_left (hcb : c ≤ b) (hc : 0 < c) : a / b ≤ a / c :=
+ (Nat.le_div_iff_mul_le hc).2 <| le_trans (Nat.mul_le_mul_left _ hcb) (div_mul_le_self _ _)
+#align nat.div_le_div_left Nat.div_le_div_left
+
+lemma div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
+ constructor
+ · intro
+ match n with
+ | 0 => simp_all
+ | 1 => right; rfl
+ | n+2 =>
+ left
+ have : m / (n + 2) ≤ m / 2 := div_le_div_left (by simp) (by decide)
+ refine eq_zero_of_le_half ?_
+ simp_all
+ · rintro (rfl | rfl) <;> simp
+#align nat.div_eq_self Nat.div_eq_self
+
+lemma div_eq_sub_mod_div : m / n = (m - m % n) / n := by
+ obtain rfl | hn := n.eq_zero_or_pos
+ · rw [Nat.div_zero, Nat.div_zero]
+ · have : m - m % n = n * (m / n) := by
+ rw [Nat.sub_eq_iff_eq_add (Nat.mod_le _ _), Nat.add_comm, mod_add_div]
+ rw [this, mul_div_right _ hn]
+#align nat.div_eq_sub_mod_div Nat.div_eq_sub_mod_div
+
+/-!
+### `pow`
+
+#### TODO
+
+* Rename `Nat.pow_le_pow_of_le_left` to `Nat.pow_le_pow_left`, protect it, remove the alias
+* Rename `Nat.pow_le_pow_of_le_right` to `Nat.pow_le_pow_right`, protect it, remove the alias
+-/
+
+#align nat.pow_le_pow_of_le_left Nat.pow_le_pow_left
+#align nat.pow_le_pow_of_le_right Nat.pow_le_pow_right
+#align nat.pow_le_iff_lt_right Nat.pow_le_pow_iff_right
+#align nat.pow_lt_iff_lt_right Nat.pow_lt_pow_iff_right
+#align nat.pow_lt_pow_succ Nat.pow_lt_pow_succ
+
+protected lemma pow_lt_pow_left (h : a < b) : ∀ {n : ℕ}, n ≠ 0 → a ^ n < b ^ n
+ | 1, _ => by simpa
+ | n + 2, _ => Nat.mul_lt_mul_of_lt_of_le (Nat.pow_lt_pow_left h n.succ_ne_zero) (Nat.le_of_lt h)
+ (zero_lt_of_lt h)
+#align nat.pow_lt_pow_of_lt_left Nat.pow_lt_pow_left
+
+protected lemma pow_lt_pow_right (ha : 1 < a) (h : m < n) : a ^ m < a ^ n :=
+ (Nat.pow_lt_pow_iff_right ha).2 h
+
+protected lemma pow_le_pow_iff_left {n : ℕ} (hn : n ≠ 0) : a ^ n ≤ b ^ n ↔ a ≤ b where
+ mp := by simpa only [← Nat.not_le, not_imp_not] using (Nat.pow_lt_pow_left · hn)
+ mpr h := Nat.pow_le_pow_left h _
+#align nat.pow_le_iff_le_left Nat.pow_le_pow_iff_left
+
+protected lemma pow_lt_pow_iff_left (hn : n ≠ 0) : a ^ n < b ^ n ↔ a < b := by
+ simp only [← Nat.not_le, Nat.pow_le_pow_iff_left hn]
+#align nat.pow_lt_iff_lt_left Nat.pow_lt_pow_iff_left
+
+lemma pow_left_injective (hn : n ≠ 0) : Injective (fun a : ℕ ↦ a ^ n) := by
+ simp [Injective, le_antisymm_iff, Nat.pow_le_pow_iff_left hn]
+#align nat.pow_left_injective Nat.pow_left_injective
+
+protected lemma pow_right_injective (ha : 2 ≤ a) : Injective (a ^ ·) :=by
+ simp [Injective, le_antisymm_iff, Nat.pow_le_pow_iff_right ha]
+#align nat.pow_right_injective Nat.pow_right_injective
+
+-- We want to use this lemma earlier than the lemma simp can prove it with
+@[simp, nolint simpNF] protected lemma pow_eq_zero {a : ℕ} : ∀ {n : ℕ}, a ^ n = 0 ↔ a = 0 ∧ n ≠ 0
+ | 0 => by simp
+ | n + 1 => by rw [Nat.pow_succ, mul_eq_zero, Nat.pow_eq_zero]; omega
+
+lemma le_self_pow (hn : n ≠ 0) : ∀ a : ℕ, a ≤ a ^ n
+ | 0 => zero_le _
+ | a + 1 => by simpa using Nat.pow_le_pow_right a.succ_pos (Nat.one_le_iff_ne_zero.2 hn)
+#align nat.le_self_pow Nat.le_self_pow
+
+lemma lt_pow_self (ha : 1 < a) : ∀ n : ℕ, n < a ^ n
+ | 0 => by simp
+ | n + 1 =>
+ calc
+ n + 1 < a ^ n + 1 := Nat.add_lt_add_right (lt_pow_self ha _) _
+ _ ≤ a ^ (n + 1) := Nat.pow_lt_pow_succ ha
+#align nat.lt_pow_self Nat.lt_pow_self
+
+lemma lt_two_pow (n : ℕ) : n < 2 ^ n := lt_pow_self (by decide) n
+#align nat.lt_two_pow Nat.lt_two_pow
+
+lemma one_le_pow (n m : ℕ) (h : 0 < m) : 1 ≤ m ^ n := by simpa using Nat.pow_le_pow_of_le_left h n
+#align nat.one_le_pow Nat.one_le_pow
+
+lemma one_le_pow' (n m : ℕ) : 1 ≤ (m + 1) ^ n := one_le_pow n (m + 1) (succ_pos m)
+#align nat.one_le_pow' Nat.one_le_pow'
+
+#align nat.one_le_two_pow Nat.one_le_two_pow
+
+lemma one_lt_pow (hn : n ≠ 0) (ha : 1 < a) : 1 < a ^ n := by simpa using Nat.pow_lt_pow_left ha hn
+#align nat.one_lt_pow Nat.one_lt_pow
+
+lemma two_pow_succ (n : ℕ) : 2 ^ (n + 1) = 2 ^ n + 2 ^ n := by simp [Nat.pow_succ, Nat.mul_two]
+
+lemma one_lt_pow' (n m : ℕ) : 1 < (m + 2) ^ (n + 1) :=
+ one_lt_pow n.succ_ne_zero (Nat.lt_of_sub_eq_succ rfl)
+#align nat.one_lt_pow' Nat.one_lt_pow'
+
+@[simp] lemma one_lt_pow_iff {n : ℕ} (hn : n ≠ 0) : ∀ {a}, 1 < a ^ n ↔ 1 < a
+ | 0 => by simp [Nat.zero_pow (Nat.pos_of_ne_zero hn)]
+ | 1 => by simp
+ | a + 2 => by simp [one_lt_pow hn]
+ -- one_lt_pow_iff_of_nonneg (zero_le _) h
+#align nat.one_lt_pow_iff Nat.one_lt_pow_iff
+
+#align nat.one_lt_two_pow Nat.one_lt_two_pow
+
+lemma one_lt_two_pow' (n : ℕ) : 1 < 2 ^ (n + 1) := one_lt_pow n.succ_ne_zero (by decide)
+#align nat.one_lt_two_pow' Nat.one_lt_two_pow'
+
+lemma mul_lt_mul_pow_succ (ha : 0 < a) (hb : 1 < b) : n * b < a * b ^ (n + 1) := by
+ rw [Nat.pow_succ, ← Nat.mul_assoc, Nat.mul_lt_mul_right (lt_trans Nat.zero_lt_one hb)]
+ exact Nat.lt_of_le_of_lt (Nat.le_mul_of_pos_left _ ha)
+ ((Nat.mul_lt_mul_left ha).2 $ Nat.lt_pow_self hb _)
+#align nat.mul_lt_mul_pow_succ Nat.mul_lt_mul_pow_succ
+
+lemma sq_sub_sq (a b : ℕ) : a ^ 2 - b ^ 2 = (a + b) * (a - b) := by
+ simpa [Nat.pow_succ] using Nat.mul_self_sub_mul_self_eq a b
+#align nat.sq_sub_sq Nat.sq_sub_sq
+
+alias pow_two_sub_pow_two := sq_sub_sq
+#align nat.pow_two_sub_pow_two Nat.pow_two_sub_pow_two
+
protected lemma div_pow (h : a ∣ b) : (b / a) ^ c = b ^ c / a ^ c := by
obtain rfl | hc := c.eq_zero_or_pos
· simp
@@ -567,8 +949,103 @@ def decreasingInduction' {P : ℕ → Sort*} {m n : ℕ} (h : ∀ k < n, m ≤ k
exact hP
#align nat.decreasing_induction' Nat.decreasingInduction'
+/-- Given a predicate on two naturals `P : ℕ → ℕ → Prop`, `P a b` is true for all `a < b` if
+`P (a + 1) (a + 1)` is true for all `a`, `P 0 (b + 1)` is true for all `b` and for all
+`a < b`, `P (a + 1) b` is true and `P a (b + 1)` is true implies `P (a + 1) (b + 1)` is true. -/
+@[elab_as_elim]
+theorem diag_induction (P : ℕ → ℕ → Prop) (ha : ∀ a, P (a + 1) (a + 1)) (hb : ∀ b, P 0 (b + 1))
+ (hd : ∀ a b, a < b → P (a + 1) b → P a (b + 1) → P (a + 1) (b + 1)) : ∀ a b, a < b → P a b
+ | 0, b + 1, _ => hb _
+ | a + 1, b + 1, h => by
+ apply hd _ _ (Nat.add_lt_add_iff_right.1 h)
+ · have this : a + 1 = b ∨ a + 1 < b := by omega
+ have wf : (a + 1) + b < (a + 1) + (b + 1) := by simp
+ rcases this with (rfl | h)
+ · exact ha _
+ apply diag_induction P ha hb hd (a + 1) b h
+ have _ : a + (b + 1) < (a + 1) + (b + 1) := by simp
+ apply diag_induction P ha hb hd a (b + 1)
+ apply lt_of_le_of_lt (Nat.le_succ _) h
+ termination_by a b _c => a + b
+ decreasing_by all_goals assumption
+#align nat.diag_induction Nat.diag_induction
+
+/-- A subset of `ℕ` containing `k : ℕ` and closed under `Nat.succ` contains every `n ≥ k`. -/
+lemma set_induction_bounded {S : Set ℕ} (hk : k ∈ S) (h_ind : ∀ k : ℕ, k ∈ S → k + 1 ∈ S)
+ (hnk : k ≤ n) : n ∈ S :=
+ @leRecOn (fun n => n ∈ S) k n hnk @h_ind hk
+#align nat.set_induction_bounded Nat.set_induction_bounded
+
+/-- A subset of `ℕ` containing zero and closed under `Nat.succ` contains all of `ℕ`. -/
+lemma set_induction {S : Set ℕ} (hb : 0 ∈ S) (h_ind : ∀ k : ℕ, k ∈ S → k + 1 ∈ S) (n : ℕ) :
+ n ∈ S :=
+ set_induction_bounded hb h_ind (zero_le n)
+#align nat.set_induction Nat.set_induction
+
/-! ### `mod`, `dvd` -/
+#align nat.pow_dvd_of_le_of_pow_dvd Nat.pow_dvd_of_le_of_pow_dvd
+#align nat.dvd_of_pow_dvd Nat.dvd_of_pow_dvd
+#align nat.mod_pow_succ Nat.mod_pow_succ
+#align nat.pow_dvd_pow_iff_pow_le_pow Nat.pow_dvd_pow_iff_pow_le_pow
+#align nat.pow_dvd_pow_iff_le_right Nat.pow_dvd_pow_iff_le_right
+#align nat.pow_dvd_pow_iff_le_right' Nat.pow_dvd_pow_iff_le_right'
+#align nat.mod_mul_right_div_self Nat.mod_mul_right_div_self
+#align nat.mod_mul_left_div_self Nat.mod_mul_left_div_self
+
+lemma mul_div_mul_comm_of_dvd_dvd (hba : b ∣ a) (hdc : d ∣ c) :
+ a * c / (b * d) = a / b * (c / d) := by
+ obtain rfl | hb := b.eq_zero_or_pos; · simp
+ obtain rfl | hd := d.eq_zero_or_pos; · simp
+ obtain ⟨_, rfl⟩ := hba
+ obtain ⟨_, rfl⟩ := hdc
+ rw [Nat.mul_mul_mul_comm, Nat.mul_div_cancel_left _ hb, Nat.mul_div_cancel_left _ hd,
+ Nat.mul_div_cancel_left _ (Nat.mul_pos hb hd)]
+#align nat.mul_div_mul_comm_of_dvd_dvd Nat.mul_div_mul_comm_of_dvd_dvd
+
+@[simp] lemma mul_mod_mod (a b c : ℕ) : (a * (b % c)) % c = a * b % c := by
+ rw [mul_mod, mod_mod, ← mul_mod]
+
+@[simp] lemma mod_mul_mod (a b c : ℕ) : (a % c * b) % c = a * b % c := by
+ rw [mul_mod, mod_mod, ← mul_mod]
+
+lemma pow_mod (a b n : ℕ) : a ^ b % n = (a % n) ^ b % n := by
+ induction' b with b ih; rfl; simp [Nat.pow_succ, Nat.mul_mod, ih]
+#align nat.pow_mod Nat.pow_mod
+
+lemma not_pos_pow_dvd : ∀ {a n : ℕ} (_ : 1 < a) (_ : 1 < n), ¬ a ^ n ∣ a
+ | succ a, succ n, hp, hk, h =>
+ have : succ a * succ a ^ n ∣ succ a * 1 := by simpa [pow_succ'] using h
+ have : succ a ^ n ∣ 1 := Nat.dvd_of_mul_dvd_mul_left (succ_pos _) this
+ have he : succ a ^ n = 1 := eq_one_of_dvd_one this
+ have : n < succ a ^ n := lt_pow_self hp n
+ have : n < 1 := by rwa [he] at this
+ have : n = 0 := Nat.eq_zero_of_le_zero <| le_of_lt_succ this
+ have : 1 < 1 := by rwa [this] at hk
+ absurd this (by decide)
+#align nat.not_pos_pow_dvd Nat.not_pos_pow_dvd
+
+lemma lt_of_pow_dvd_right (hb : b ≠ 0) (ha : 2 ≤ a) (h : a ^ n ∣ b) : n < b := by
+ rw [← Nat.pow_lt_pow_iff_right (succ_le_iff.1 ha)]
+ exact lt_of_le_of_lt (le_of_dvd (Nat.pos_iff_ne_zero.2 hb) h) (lt_pow_self ha _)
+#align nat.lt_of_pow_dvd_right Nat.lt_of_pow_dvd_right
+
+lemma div_dvd_of_dvd (h : n ∣ m) : m / n ∣ m := ⟨n, (Nat.div_mul_cancel h).symm⟩
+#align nat.div_dvd_of_dvd Nat.div_dvd_of_dvd
+
+protected lemma div_div_self (h : n ∣ m) (hm : m ≠ 0) : m / (m / n) = n := by
+ rcases h with ⟨_, rfl⟩
+ rw [Nat.mul_ne_zero_iff] at hm
+ rw [mul_div_right _ (Nat.pos_of_ne_zero hm.1), mul_div_left _ (Nat.pos_of_ne_zero hm.2)]
+#align nat.div_div_self Nat.div_div_self
+
+lemma not_dvd_of_pos_of_lt (h1 : 0 < n) (h2 : n < m) : ¬m ∣ n := by
+ rintro ⟨k, rfl⟩
+ rcases Nat.eq_zero_or_pos k with (rfl | hk)
+ · exact lt_irrefl 0 h1
+ · exact not_lt.2 (Nat.le_mul_of_pos_right _ hk) h2
+#align nat.not_dvd_of_pos_of_lt Nat.not_dvd_of_pos_of_lt
+
lemma mod_eq_iff_lt (hn : n ≠ 0) : m % n = m ↔ m < n :=
⟨fun h ↦ by rw [← h]; exact mod_lt _ $ Nat.pos_iff_ne_zero.2 hn, mod_eq_of_lt⟩
#align nat.mod_eq_iff_lt Nat.mod_eq_iff_lt
@@ -595,6 +1072,42 @@ protected lemma div_mod_unique (h : 0 < b) :
rw [add_mul_div_left _ _ h, add_mul_mod_self_left]; simp [div_eq_of_lt, mod_eq_of_lt, h₂]⟩
#align nat.div_mod_unique Nat.div_mod_unique
+/-- If `m` and `n` are equal mod `k`, `m - n` is zero mod `k`. -/
+lemma sub_mod_eq_zero_of_mod_eq (h : m % k = n % k) : (m - n) % k = 0 := by
+ rw [← Nat.mod_add_div m k, ← Nat.mod_add_div n k, ← h, ← Nat.sub_sub,
+ Nat.add_sub_cancel_left, ← Nat.mul_sub_left_distrib k, Nat.mul_mod_right]
+#align nat.sub_mod_eq_zero_of_mod_eq Nat.sub_mod_eq_zero_of_mod_eq
+
+@[simp] lemma one_mod (n : ℕ) : 1 % (n + 2) = 1 :=
+ Nat.mod_eq_of_lt (Nat.add_lt_add_right n.succ_pos 1)
+#align nat.one_mod Nat.one_mod
+
+lemma one_mod_of_ne_one : ∀ {n : ℕ}, n ≠ 1 → 1 % n = 1
+ | 0, _ | (n + 2), _ => by simp
+
+lemma dvd_sub_mod (k : ℕ) : n ∣ k - k % n :=
+ ⟨k / n, Nat.sub_eq_of_eq_add (Nat.div_add_mod k n).symm⟩
+#align nat.dvd_sub_mod Nat.dvd_sub_mod
+
+lemma add_mod_eq_ite :
+ (m + n) % k = if k ≤ m % k + n % k then m % k + n % k - k else m % k + n % k := by
+ cases k; simp only [zero_eq, mod_zero, zero_le, ↓reduceIte, Nat.sub_zero]
+ rw [Nat.add_mod]
+ split_ifs with h
+ · rw [Nat.mod_eq_sub_mod h, Nat.mod_eq_of_lt]
+ exact (Nat.sub_lt_iff_lt_add h).mpr (Nat.add_lt_add (m.mod_lt (zero_lt_succ _))
+ (n.mod_lt (zero_lt_succ _)))
+ · exact Nat.mod_eq_of_lt (lt_of_not_ge h)
+#align nat.add_mod_eq_ite Nat.add_mod_eq_ite
+
+/-- `m` is not divisible by `n` if it is between `n * k` and `n * (k + 1)` for some `k`. -/
+theorem not_dvd_of_between_consec_multiples (h1 : n * k < m) (h2 : m < n * (k + 1)) : ¬n ∣ m := by
+ rintro ⟨d, rfl⟩
+ have := Nat.lt_of_mul_lt_mul_left h1
+ have := Nat.lt_of_mul_lt_mul_left h2
+ omega
+#align nat.not_dvd_of_between_consec_multiples Nat.not_dvd_of_between_consec_multiples
+
-- TODO: Replace `Nat.dvd_add_iff_left`
protected lemma dvd_add_left (h : a ∣ c) : a ∣ b + c ↔ a ∣ b := (Nat.dvd_add_iff_left h).symm
#align nat.dvd_add_left Nat.dvd_add_left
@@ -643,11 +1156,6 @@ lemma eq_zero_of_dvd_of_div_eq_zero (hab : a ∣ b) (h : b / a = 0) : b = 0 := b
rw [← Nat.div_mul_cancel hab, h, Nat.zero_mul]
#align nat.eq_zero_of_dvd_of_div_eq_zero Nat.eq_zero_of_dvd_of_div_eq_zero
-@[gcongr]
-lemma div_le_div_left (hcb : c ≤ b) (hc : 0 < c) : a / b ≤ a / c :=
- (Nat.le_div_iff_mul_le hc).2 <| le_trans (Nat.mul_le_mul_left _ hcb) (div_mul_le_self _ _)
-#align nat.div_le_div_left Nat.div_le_div_left
-
@[gcongr]
protected theorem div_le_div {a b c d : ℕ} (h1 : a ≤ b) (h2 : d ≤ c) (h3 : d ≠ 0) : a / c ≤ b / d :=
calc a / c ≤ b / c := Nat.div_le_div_right h1
@@ -717,6 +1225,23 @@ lemma find_comp_succ (h₁ : ∃ n, p n) (h₂ : ∃ n, p (n + 1)) (h0 : ¬ p 0)
exacts [h0, @Nat.find_min (fun n ↦ p (n + 1)) _ h₂ _ (succ_lt_succ_iff.1 hn)]
#align nat.find_comp_succ Nat.find_comp_succ
+-- Porting note (#10618): removing `simp` attribute as `simp` can prove it
+lemma find_pos (h : ∃ n : ℕ, p n) : 0 < Nat.find h ↔ ¬p 0 :=
+ Nat.pos_iff_ne_zero.trans (Nat.find_eq_zero _).not
+#align nat.find_pos Nat.find_pos
+
+lemma find_add {hₘ : ∃ m, p (m + n)} {hₙ : ∃ n, p n} (hn : n ≤ Nat.find hₙ) :
+ Nat.find hₘ + n = Nat.find hₙ := by
+ refine le_antisymm ((le_find_iff _ _).2 fun m hm hpm => Nat.not_le.2 hm ?_) ?_
+ · have hnm : n ≤ m := le_trans hn (find_le hpm)
+ refine Nat.add_le_of_le_sub hnm (find_le ?_)
+ rwa [Nat.sub_add_cancel hnm]
+ · rw [← Nat.sub_le_iff_le_add]
+ refine (le_find_iff _ _).2 fun m hm hpm => Nat.not_le.2 hm ?_
+ rw [Nat.sub_le_iff_le_add]
+ exact find_le hpm
+#align nat.find_add Nat.find_add
+
end Find
/-! ### `Nat.findGreatest` -/
@@ -749,6 +1274,90 @@ lemma findGreatest_of_not (h : ¬ P (n + 1)) : findGreatest P (n + 1) = findGrea
simp [Nat.findGreatest, h]
#align nat.find_greatest_of_not Nat.findGreatest_of_not
+lemma findGreatest_eq_iff :
+ Nat.findGreatest P k = m ↔ m ≤ k ∧ (m ≠ 0 → P m) ∧ ∀ ⦃n⦄, m < n → n ≤ k → ¬P n := by
+ induction' k with k ihk generalizing m
+ · rw [eq_comm, Iff.comm]
+ simp only [zero_eq, Nat.le_zero, ne_eq, findGreatest_zero, and_iff_left_iff_imp]
+ rintro rfl
+ exact ⟨fun h ↦ (h rfl).elim, fun n hlt heq ↦ by omega⟩
+ · by_cases hk : P (k + 1)
+ · rw [findGreatest_eq hk]
+ constructor
+ · rintro rfl
+ exact ⟨le_refl _, fun _ ↦ hk, fun n hlt hle ↦ by omega⟩
+ · rintro ⟨hle, h0, hm⟩
+ rcases Decidable.eq_or_lt_of_le hle with (rfl | hlt)
+ exacts [rfl, (hm hlt (le_refl _) hk).elim]
+ · rw [findGreatest_of_not hk, ihk]
+ constructor
+ · rintro ⟨hle, hP, hm⟩
+ refine ⟨le_trans hle k.le_succ, hP, fun n hlt hle ↦ ?_⟩
+ rcases Decidable.eq_or_lt_of_le hle with (rfl | hlt')
+ exacts [hk, hm hlt <| Nat.lt_succ_iff.1 hlt']
+ · rintro ⟨hle, hP, hm⟩
+ refine ⟨Nat.lt_succ_iff.1 (lt_of_le_of_ne hle ?_), hP,
+ fun n hlt hle ↦ hm hlt (le_trans hle k.le_succ)⟩
+ rintro rfl
+ exact hk (hP k.succ_ne_zero)
+#align nat.find_greatest_eq_iff Nat.findGreatest_eq_iff
+
+lemma findGreatest_eq_zero_iff : Nat.findGreatest P k = 0 ↔ ∀ ⦃n⦄, 0 < n → n ≤ k → ¬P n := by
+ simp [findGreatest_eq_iff]
+#align nat.find_greatest_eq_zero_iff Nat.findGreatest_eq_zero_iff
+
+@[simp] lemma findGreatest_pos : 0 < Nat.findGreatest P k ↔ ∃ n, 0 < n ∧ n ≤ k ∧ P n := by
+ rw [Nat.pos_iff_ne_zero, Ne.def, findGreatest_eq_zero_iff]; push_neg; rfl
+
+lemma findGreatest_spec (hmb : m ≤ n) (hm : P m) : P (Nat.findGreatest P n) := by
+ by_cases h : Nat.findGreatest P n = 0
+ · cases m
+ · rwa [h]
+ exact ((findGreatest_eq_zero_iff.1 h) (zero_lt_succ _) hmb hm).elim
+ · exact (findGreatest_eq_iff.1 rfl).2.1 h
+#align nat.find_greatest_spec Nat.findGreatest_spec
+
+lemma findGreatest_le (n : ℕ) : Nat.findGreatest P n ≤ n :=
+ (findGreatest_eq_iff.1 rfl).1
+#align nat.find_greatest_le Nat.findGreatest_le
+
+lemma le_findGreatest (hmb : m ≤ n) (hm : P m) : m ≤ Nat.findGreatest P n :=
+ le_of_not_lt fun hlt => (findGreatest_eq_iff.1 rfl).2.2 hlt hmb hm
+#align nat.le_find_greatest Nat.le_findGreatest
+
+lemma findGreatest_mono_right (P : ℕ → Prop) [DecidablePred P] {m n} (hmn : m ≤ n) :
+ Nat.findGreatest P m ≤ Nat.findGreatest P n := by
+ induction' hmn with k hmk ih
+ · simp
+ rw [findGreatest_succ]
+ split_ifs
+ · exact le_trans ih $ le_trans (findGreatest_le _) (le_succ _)
+ · exact ih
+#align nat.find_greatest_mono_right Nat.findGreatest_mono_right
+
+lemma findGreatest_mono_left [DecidablePred Q] (hPQ : ∀ n, P n → Q n) (n : ℕ) :
+ Nat.findGreatest P n ≤ Nat.findGreatest Q n := by
+ induction' n with n hn
+ · rfl
+ by_cases h : P (n + 1)
+ · rw [findGreatest_eq h, findGreatest_eq (hPQ _ h)]
+ · rw [findGreatest_of_not h]
+ exact le_trans hn (Nat.findGreatest_mono_right _ <| le_succ _)
+#align nat.find_greatest_mono_left Nat.findGreatest_mono_left
+
+lemma findGreatest_mono [DecidablePred Q] (hPQ : ∀ n, P n → Q n) (hmn : m ≤ n) :
+ Nat.findGreatest P m ≤ Nat.findGreatest Q n :=
+ le_trans (Nat.findGreatest_mono_right _ hmn) (findGreatest_mono_left hPQ _)
+#align nat.find_greatest_mono Nat.findGreatest_mono
+
+theorem findGreatest_is_greatest (hk : Nat.findGreatest P n < k) (hkb : k ≤ n) : ¬P k :=
+ (findGreatest_eq_iff.1 rfl).2.2 hk hkb
+#align nat.find_greatest_is_greatest Nat.findGreatest_is_greatest
+
+theorem findGreatest_of_ne_zero (h : Nat.findGreatest P n = m) (h0 : m ≠ 0) : P m :=
+ (findGreatest_eq_iff.1 h).2.1 h0
+#align nat.find_greatest_of_ne_zero Nat.findGreatest_of_ne_zero
+
end FindGreatest
/-! ### Decidability of predicates -/
@@ -759,4 +1368,19 @@ end FindGreatest
#align nat.decidable_exists_lt Nat.decidableExistsLT
#align nat.decidable_exists_le Nat.decidableExistsLE
+instance decidableLoHi (lo hi : ℕ) (P : ℕ → Prop) [H : DecidablePred P] :
+ Decidable (∀ x, lo ≤ x → x < hi → P x) :=
+ decidable_of_iff (∀ x < hi - lo, P (lo + x)) $ by
+ refine ⟨fun al x hl hh ↦ ?_,
+ fun al x h ↦ al _ (Nat.le_add_right _ _) (Nat.lt_sub_iff_add_lt'.1 h)⟩
+ have := al (x - lo) ((Nat.sub_lt_sub_iff_right hl).2 hh)
+ rwa [Nat.add_sub_cancel' hl] at this
+#align nat.decidable_lo_hi Nat.decidableLoHi
+
+instance decidableLoHiLe (lo hi : ℕ) (P : ℕ → Prop) [DecidablePred P] :
+ Decidable (∀ x, lo ≤ x → x ≤ hi → P x) :=
+ decidable_of_iff (∀ x, lo ≤ x → x < hi + 1 → P x) <|
+ ball_congr fun _ _ => imp_congr Nat.lt_succ_iff Iff.rfl
+#align nat.decidable_lo_hi_le Nat.decidableLoHiLe
+
end Nat
Move basic Nat
lemmas from Data.Nat.Order.Basic
and Data.Nat.Pow
to Data.Nat.Defs
. Most proofs need adapting, but that's easily solved by replacing the general mathlib lemmas by the new Std Nat
-specific lemmas and using omega
.
Data.Nat.Pow
to Algebra.GroupPower.Order
Data.Nat.Pow
to Algebra.GroupPower.Order
bit
/bit0
/bit1
lemmas from Data.Nat.Order.Basic
to Data.Nat.Bits
Data.Nat.Order.Basic
anymoreNat
-specific lemmas to help fix the fallout (look for nolint simpNF
)Nat.mul_self_le_mul_self_iff
and Nat.mul_self_lt_mul_self_iff
around (they were misnamed)Nat.one_lt_pow
implicit@@ -10,12 +10,25 @@ import Mathlib.Algebra.GroupWithZero.Defs
#align_import data.nat.basic from "leanprover-community/mathlib"@"bd835ef554f37ef9b804f0903089211f89cb370b"
/-!
-# Basic instances for the natural numbers
+# Algebraic instances for the natural numbers
-This file contains:
-* Algebraic instances on the natural numbers
-* Basic lemmas about natural numbers that require more imports than available in
- `Data.Nat.Defs`.
+This file contains algebraic instances on the natural numbers and a few lemmas about them.
+
+## Implementation note
+
+Std has a home-baked development of the algebraic and order theoretic theory of `ℕ` which, in
+particular, is not typeclass-mediated. This is useful to set up the algebra and finiteness libraries
+in mathlib (naturals show up as indices in lists, cardinality in finsets, powers in groups, ...).
+This home-baked development is pursued in `Data.Nat.Defs`.
+
+Less basic uses of `ℕ` should however use the typeclass-mediated development. This file is the one
+giving access to the algebraic instances. `Data.Nat.Order.Basic` is the one giving access to the
+algebraic order instances.
+
+## TODO
+
+The names of this file, `Data.Nat.Defs` and `Data.Nat.Order.Basic` are archaic and don't match up
+with reality anymore. Rename them.
-/
open Multiplicative
The termination checker has been getting more capable, and many of the termination_by
or decreasing_by
clauses in Mathlib are no longer needed.
(Note that termination_by?
will show the automatically derived termination expression, so no information is being lost by removing these.)
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -550,7 +550,6 @@ def pincerRecursion {P : ℕ → ℕ → Sort*} (Ha0 : ∀ m : ℕ, P m 0) (H0b
| m, 0 => Ha0 m
| 0, n => H0b n
| Nat.succ m, Nat.succ n => H _ _ (pincerRecursion Ha0 H0b H _ _) (pincerRecursion Ha0 H0b H _ _)
-termination_by n m => n + m
#align nat.pincer_recursion Nat.pincerRecursion
/-- Decreasing induction: if `P (k+1)` implies `P k` for all `m ≤ k < n`, then `P n` implies `P m`.
@@ -703,7 +703,7 @@ lemma find_eq_iff (h : ∃ n : ℕ, p n) : Nat.find h = m ↔ p m ∧ ∀ n < m,
@[simp] lemma find_eq_zero (h : ∃ n : ℕ, p n) : Nat.find h = 0 ↔ p 0 := by simp [find_eq_iff]
#align nat.find_eq_zero Nat.find_eq_zero
-lemma find_mono (h : ∀ n, q n → p n) {hp : ∃ n, p n} {hq : ∃ n, q n} : Nat.find hp ≤ Nat.find hq :=
+lemma find_mono (h : ∀ n, q n → p n) {hp : ∃ n, p n} {hq : ∃ n, q n} : Nat.find hp ≤ Nat.find hq :=
Nat.find_min' _ (h _ (Nat.find_spec hq))
#align nat.find_mono Nat.find_mono
@@ -714,17 +714,17 @@ lemma find_le {h : ∃ n, p n} (hn : p n) : Nat.find h ≤ n :=
lemma find_comp_succ (h₁ : ∃ n, p n) (h₂ : ∃ n, p (n + 1)) (h0 : ¬ p 0) :
Nat.find h₁ = Nat.find h₂ + 1 := by
refine' (find_eq_iff _).2 ⟨Nat.find_spec h₂, fun n hn ↦ _⟩
- cases' n with n
+ cases n
exacts [h0, @Nat.find_min (fun n ↦ p (n + 1)) _ h₂ _ (succ_lt_succ_iff.1 hn)]
#align nat.find_comp_succ Nat.find_comp_succ
end Find
-/-! ### `find_greatest` -/
+/-! ### `Nat.findGreatest` -/
section FindGreatest
-/-- `find_greatest P n` is the largest `i ≤ bound` such that `P i` holds, or `0` if no such `i`
+/-- `Nat.findGreatest P n` is the largest `i ≤ bound` such that `P i` holds, or `0` if no such `i`
exists -/
def findGreatest (P : ℕ → Prop) [DecidablePred P] : ℕ → ℕ
| 0 => 0
@@ -323,16 +323,8 @@ lemma mul_div_le_mul_div_assoc (a b c : ℕ) : a * (b / c) ≤ a * b / c :=
(by rw [Nat.mul_assoc]; exact Nat.mul_le_mul_left _ (Nat.div_mul_le_self _ _))
#align nat.mul_div_le_mul_div_assoc Nat.mul_div_le_mul_div_assoc
-protected lemma eq_mul_of_div_eq_right (H1 : b ∣ a) (H2 : a / b = c) : a = b * c := by
- rw [← H2, Nat.mul_div_cancel' H1]
#align nat.eq_mul_of_div_eq_right Nat.eq_mul_of_div_eq_right
-
-protected lemma div_eq_iff_eq_mul_right (H : 0 < b) (H' : b ∣ a) : a / b = c ↔ a = b * c :=
- ⟨Nat.eq_mul_of_div_eq_right H', Nat.div_eq_of_eq_mul_right H⟩
#align nat.div_eq_iff_eq_mul_right Nat.div_eq_iff_eq_mul_right
-
-protected lemma div_eq_iff_eq_mul_left (H : 0 < b) (H' : b ∣ a) : a / b = c ↔ a = c * b := by
- rw [Nat.mul_comm]; exact Nat.div_eq_iff_eq_mul_right H H'
#align nat.div_eq_iff_eq_mul_left Nat.div_eq_iff_eq_mul_left
protected lemma eq_mul_of_div_eq_left (H1 : b ∣ a) (H2 : a / b = c) : a = c * b := by
@@ -91,13 +91,7 @@ alias ⟨of_le_succ, _⟩ := le_succ_iff
#align nat.of_le_succ Nat.of_le_succ
#align nat.lt_succ_iff_lt_or_eq Nat.lt_succ_iff_lt_or_eq
-
-lemma eq_of_lt_succ_of_not_lt (hmn : m < n + 1) (h : ¬ m < n) : m = n :=
- (Nat.lt_succ_iff_lt_or_eq.1 hmn).resolve_left h
#align nat.eq_of_lt_succ_of_not_lt Nat.eq_of_lt_succ_of_not_lt
-
-lemma eq_of_le_of_lt_succ (h₁ : n ≤ m) (h₂ : m < n + 1) : m = n :=
- Nat.le_antisymm (le_of_succ_le_succ h₂) h₁
#align nat.eq_of_le_of_lt_succ Nat.eq_of_le_of_lt_succ
lemma lt_iff_le_pred : ∀ {n}, 0 < n → (m < n ↔ m ≤ n - 1) | _ + 1, _ => Nat.lt_succ_iff
@@ -219,14 +213,8 @@ lemma pred_add_self (n : ℕ) : pred n + n = (2 * n).pred := sub_one_add_self n
@[simp] lemma add_def : Nat.add m n = m + n := rfl
#align nat.add_def Nat.add_def
-lemma exists_eq_add_of_le (h : m ≤ n) : ∃ k : ℕ, n = m + k := ⟨n - m, (add_sub_of_le h).symm⟩
#align nat.exists_eq_add_of_le Nat.exists_eq_add_of_le
-
-lemma exists_eq_add_of_le' (h : m ≤ n) : ∃ k : ℕ, n = k + m := ⟨n - m, (Nat.sub_add_cancel h).symm⟩
#align nat.exists_eq_add_of_le' Nat.exists_eq_add_of_le'
-
-lemma exists_eq_add_of_lt (h : m < n) : ∃ k : ℕ, n = m + k + 1 :=
- ⟨n - (m + 1), by rw [Nat.add_right_comm, add_sub_of_le h]⟩
#align nat.exists_eq_add_of_lt Nat.exists_eq_add_of_lt
/-! ### `mul` -/
@@ -632,11 +620,6 @@ protected lemma mul_dvd_mul_iff_right (hc : 0 < c) : a * c ∣ b * c ↔ a ∣ b
#align nat.mul_dvd_mul_iff_right Nat.mul_dvd_mul_iff_right
#align nat.dvd_one Nat.dvd_one
-
-@[simp] lemma mod_mod_of_dvd (a : ℕ) (h : c ∣ b) : a % b % c = a % c := by
- conv_rhs => rw [← mod_add_div a b]
- obtain ⟨x, rfl⟩ := h
- rw [Nat.mul_assoc, add_mul_mod_self_left]
#align nat.mod_mod_of_dvd Nat.mod_mod_of_dvd
-- Moved to Std
@[gcongr]
tags around (#9393)
import Mathlib.Tactic.GCongr.Core
to Algebra/Order/Ring/Lemmas
.@[gcongr]
tags next to the lemmas.See Zulip thread
Co-authored-by: Jeremy Tan Jie Rui <reddeloostw@gmail.com>
@@ -7,6 +7,7 @@ import Mathlib.Init.Data.Nat.Lemmas
import Mathlib.Logic.Function.Basic
import Mathlib.Logic.Nontrivial.Defs
import Mathlib.Tactic.Cases
+import Mathlib.Tactic.GCongr.Core
import Mathlib.Tactic.PushNeg
import Mathlib.Tactic.Use
@@ -37,6 +38,7 @@ variable {a b c d m n k : ℕ} {p q : ℕ → Prop}
instance nontrivial : Nontrivial ℕ := ⟨⟨0, 1, Nat.zero_ne_one⟩⟩
+attribute [gcongr] Nat.succ_le_succ
attribute [simp] Nat.not_lt_zero Nat.succ_ne_zero Nat.succ_ne_self Nat.zero_ne_one Nat.one_ne_zero
-- Nat.zero_ne_bit1 Nat.bit1_ne_zero Nat.bit0_ne_one Nat.one_ne_bit0 Nat.bit0_ne_bit1
-- Nat.bit1_ne_bit0
@@ -305,6 +307,7 @@ lemma one_le_div_iff (hb : 0 < b) : 1 ≤ a / b ↔ b ≤ a := by rw [le_div_iff
lemma div_lt_one_iff (hb : 0 < b) : a / b < 1 ↔ a < b := by simp only [← not_le, one_le_div_iff hb]
#align nat.div_lt_one_iff Nat.div_lt_one_iff
+@[gcongr]
protected lemma div_le_div_right (h : a ≤ b) : a / c ≤ b / c :=
(c.eq_zero_or_pos.elim fun hc ↦ by simp [hc]) fun hc ↦
(le_div_iff_mul_le' hc).2 <| le_trans (Nat.div_mul_le_self _ _) h
@@ -666,10 +669,16 @@ lemma eq_zero_of_dvd_of_div_eq_zero (hab : a ∣ b) (h : b / a = 0) : b = 0 := b
rw [← Nat.div_mul_cancel hab, h, Nat.zero_mul]
#align nat.eq_zero_of_dvd_of_div_eq_zero Nat.eq_zero_of_dvd_of_div_eq_zero
+@[gcongr]
lemma div_le_div_left (hcb : c ≤ b) (hc : 0 < c) : a / b ≤ a / c :=
(Nat.le_div_iff_mul_le hc).2 <| le_trans (Nat.mul_le_mul_left _ hcb) (div_mul_le_self _ _)
#align nat.div_le_div_left Nat.div_le_div_left
+@[gcongr]
+protected theorem div_le_div {a b c d : ℕ} (h1 : a ≤ b) (h2 : d ≤ c) (h3 : d ≠ 0) : a / c ≤ b / d :=
+ calc a / c ≤ b / c := Nat.div_le_div_right h1
+ _ ≤ b / d := Nat.div_le_div_left h2 (Nat.pos_of_ne_zero h3)
+
-- Moved to Std
#align nat.mul_div_le Nat.mul_div_le
@@ -74,7 +74,6 @@ alias _root_.LT.lt.nat_succ_le := succ_le_of_lt
lemma not_succ_lt_self : ¬ succ n < n := not_lt_of_ge n.le_succ
#align nat.not_succ_lt_self Nat.not_succ_lt_self
-lemma lt_succ_iff : m < succ n ↔ m ≤ n := ⟨le_of_lt_succ, lt_succ_of_le⟩
#align nat.lt_succ_iff Nat.lt_succ_iff
lemma succ_le_iff : succ m ≤ n ↔ m < n := ⟨lt_of_succ_le, succ_le_of_lt⟩
@@ -89,18 +88,17 @@ lemma le_succ_iff : m ≤ n.succ ↔ m ≤ n ∨ m = n.succ := by
alias ⟨of_le_succ, _⟩ := le_succ_iff
#align nat.of_le_succ Nat.of_le_succ
-lemma lt_succ_iff_lt_or_eq : m < n.succ ↔ m < n ∨ m = n := lt_succ_iff.trans Nat.le_iff_lt_or_eq
#align nat.lt_succ_iff_lt_or_eq Nat.lt_succ_iff_lt_or_eq
lemma eq_of_lt_succ_of_not_lt (hmn : m < n + 1) (h : ¬ m < n) : m = n :=
- (lt_succ_iff_lt_or_eq.1 hmn).resolve_left h
+ (Nat.lt_succ_iff_lt_or_eq.1 hmn).resolve_left h
#align nat.eq_of_lt_succ_of_not_lt Nat.eq_of_lt_succ_of_not_lt
lemma eq_of_le_of_lt_succ (h₁ : n ≤ m) (h₂ : m < n + 1) : m = n :=
Nat.le_antisymm (le_of_succ_le_succ h₂) h₁
#align nat.eq_of_le_of_lt_succ Nat.eq_of_le_of_lt_succ
-lemma lt_iff_le_pred : ∀ {n}, 0 < n → (m < n ↔ m ≤ n - 1) | _ + 1, _ => lt_succ_iff
+lemma lt_iff_le_pred : ∀ {n}, 0 < n → (m < n ↔ m ≤ n - 1) | _ + 1, _ => Nat.lt_succ_iff
#align nat.lt_iff_le_pred Nat.lt_iff_le_pred
lemma le_of_pred_lt : ∀ {m}, pred m < n → m ≤ n
@@ -112,11 +110,11 @@ lemma lt_iff_add_one_le : m < n ↔ m + 1 ≤ n := by rw [succ_le_iff]
#align nat.lt_iff_add_one_le Nat.lt_iff_add_one_le
-- Just a restatement of `Nat.lt_succ_iff` using `+1`.
-lemma lt_add_one_iff : m < n + 1 ↔ m ≤ n := lt_succ_iff
+lemma lt_add_one_iff : m < n + 1 ↔ m ≤ n := Nat.lt_succ_iff
#align nat.lt_add_one_iff Nat.lt_add_one_iff
-- A flipped version of `lt_add_one_iff`.
-lemma lt_one_add_iff : m < 1 + n ↔ m ≤ n := by simp only [Nat.add_comm, lt_succ_iff]
+lemma lt_one_add_iff : m < 1 + n ↔ m ≤ n := by simp only [Nat.add_comm, Nat.lt_succ_iff]
#align nat.lt_one_add_iff Nat.lt_one_add_iff
-- This is true reflexively, by the definition of `≤` on ℕ,
@@ -173,7 +171,7 @@ lemma or_exists_succ : p 0 ∨ (∃ n, p (n + 1)) ↔ ∃ n, p n :=
#align nat.or_exists_succ Nat.or_exists_succ
lemma forall_lt_succ : (∀ m < n + 1, p m) ↔ (∀ m < n, p m) ∧ p n := by
- simp only [lt_succ_iff, Nat.le_iff_lt_or_eq, or_comm, forall_eq_or_imp, and_comm]
+ simp only [Nat.lt_succ_iff, Nat.le_iff_lt_or_eq, or_comm, forall_eq_or_imp, and_comm]
#align nat.forall_lt_succ Nat.forall_lt_succ
lemma exists_lt_succ : (∃ m < n + 1, p m) ↔ (∃ m < n, p m) ∨ p n := by
@@ -285,7 +283,8 @@ lemma one_lt_mul_iff : 1 < m * n ↔ 0 < m ∧ 0 < n ∧ (1 < m ∨ 1 < n) := by
attribute [simp] Nat.div_self
lemma div_le_iff_le_mul_add_pred (hb : 0 < b) : a / b ≤ c ↔ a ≤ b * c + (b - 1) := by
- rw [← lt_succ_iff, div_lt_iff_lt_mul hb, succ_mul, Nat.mul_comm]; cases hb <;> exact lt_succ_iff
+ rw [← Nat.lt_succ_iff, div_lt_iff_lt_mul hb, succ_mul, Nat.mul_comm]
+ cases hb <;> exact Nat.lt_succ_iff
#align nat.div_le_iff_le_mul_add_pred Nat.div_le_iff_le_mul_add_pred
/-- A version of `Nat.div_lt_self` using successors, rather than additional hypotheses. -/
@@ -706,7 +705,7 @@ lemma find_eq_iff (h : ∃ n : ℕ, p n) : Nat.find h = m ↔ p m ∧ ∀ n < m,
#align nat.find_lt_iff Nat.find_lt_iff
@[simp] lemma find_le_iff (h : ∃ n : ℕ, p n) (n : ℕ) : Nat.find h ≤ n ↔ ∃ m ≤ n, p m := by
- simp only [exists_prop, ← lt_succ_iff, find_lt_iff]
+ simp only [exists_prop, ← Nat.lt_succ_iff, find_lt_iff]
#align nat.find_le_iff Nat.find_le_iff
@[simp] lemma le_find_iff (h : ∃ n : ℕ, p n) (n : ℕ) : n ≤ Nat.find h ↔ ∀ m < n, ¬ p m := by
@@ -771,44 +770,10 @@ end FindGreatest
/-! ### Decidability of predicates -/
--- To work around lean4#2552, we use `match` instead of `if/casesOn` with decidable instances.
-instance decidableBallLT :
- ∀ (n : Nat) (P : ∀ k, k < n → Prop) [∀ n h, Decidable (P n h)], Decidable (∀ n h, P n h)
-| 0, _, _ => isTrue fun _ ↦ (by cases ·)
-| n + 1, P, H =>
- match decidableBallLT n (P · <| lt_succ_of_lt ·) with
- | isFalse h => isFalse (h fun _ _ ↦ · _ _)
- | isTrue h =>
- match H n Nat.le.refl with
- | isFalse p => isFalse (p <| · _ _)
- | isTrue p => isTrue fun _ h' ↦ (lt_succ_iff_lt_or_eq.1 h').elim (h _) fun hn ↦ hn ▸ p
#align nat.decidable_ball_lt Nat.decidableBallLT
-
--- To verify we don't have a regression on the speed, we put a difficult example.
--- any regression should take a huge amount of heartbeats -- we are currently at 187621.
--- For reference, the instance using `casesOn` took 44544 for 4; this one takes 1299 for 4.
-example : ∀ m, m < 25 → ∀ n, n < 25 → ∀ c, c < 25 → m ^ 2 + n ^ 2 + c ^ 2 ≠ 7 := by decide
-
-instance decidableForallFin (P : Fin n → Prop) [DecidablePred P] : Decidable (∀ i, P i) :=
- decidable_of_iff (∀ k h, P ⟨k, h⟩) ⟨fun m ⟨k, h⟩ ↦ m k h, fun m k h ↦ m ⟨k, h⟩⟩
#align nat.decidable_forall_fin Nat.decidableForallFin
-
-instance decidableBallLe (n : ℕ) (P : ∀ k ≤ n, Prop) [∀ n h, Decidable (P n h)] :
- Decidable (∀ n h, P n h) :=
- decidable_of_iff (∀ (k) (h : k < succ n), P k (le_of_lt_succ h))
- ⟨fun m k h ↦ m k (lt_succ_of_le h), fun m k _ ↦ m k _⟩
-#align nat.decidable_ball_le Nat.decidableBallLe
-
-instance decidableExistsLT [h : DecidablePred p] : DecidablePred fun n ↦ ∃ m : ℕ, m < n ∧ p m
- | 0 => isFalse (by simp)
- | n + 1 =>
- @decidable_of_decidable_of_iff _ _ (@instDecidableOr _ _ (decidableExistsLT n) (h n))
- (by simp only [lt_succ_iff_lt_or_eq, or_and_right, exists_or, exists_eq_left])
+#align nat.decidable_ball_le Nat.decidableBallLE
#align nat.decidable_exists_lt Nat.decidableExistsLT
-
-instance decidableExistsLe [DecidablePred p] : DecidablePred fun n ↦ ∃ m : ℕ, m ≤ n ∧ p m :=
- fun n ↦ decidable_of_iff (∃ m, m < n + 1 ∧ p m)
- (exists_congr fun _ ↦ and_congr_left' lt_succ_iff)
-#align nat.decidable_exists_le Nat.decidableExistsLe
+#align nat.decidable_exists_le Nat.decidableExistsLE
end Nat
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
@@ -568,7 +568,7 @@ def pincerRecursion {P : ℕ → ℕ → Sort*} (Ha0 : ∀ m : ℕ, P m 0) (H0b
| m, 0 => Ha0 m
| 0, n => H0b n
| Nat.succ m, Nat.succ n => H _ _ (pincerRecursion Ha0 H0b H _ _) (pincerRecursion Ha0 H0b H _ _)
-termination_by pincerRecursion Ha0 Hab H n m => n + m
+termination_by n m => n + m
#align nat.pincer_recursion Nat.pincerRecursion
/-- Decreasing induction: if `P (k+1)` implies `P k` for all `m ≤ k < n`, then `P n` implies `P m`.
@@ -6,9 +6,6 @@ Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
import Mathlib.Algebra.Group.TypeTags
import Mathlib.Algebra.Ring.Defs
import Mathlib.Algebra.GroupWithZero.Defs
-import Mathlib.Algebra.Ring.Defs
-import Mathlib.Data.Nat.Defs
-import Mathlib.Order.Basic
#align_import data.nat.basic from "leanprover-community/mathlib"@"bd835ef554f37ef9b804f0903089211f89cb370b"
@@ -277,8 +277,8 @@ lemma one_lt_mul_iff : 1 < m * n ↔ 0 < m ∧ 0 < n ∧ (1 < m ∨ 1 < n) := by
· simp at h
· exact Nat.not_lt_of_le (Nat.mul_le_mul h'.1 h'.2) h
· obtain hm | hn := h.2.2
- · exact Nat.mul_lt_mul hm h.2.1 Nat.zero_lt_one
- · exact Nat.mul_lt_mul' h.1 hn h.1
+ · exact Nat.mul_lt_mul_of_lt_of_le' hm h.2.1 Nat.zero_lt_one
+ · exact Nat.mul_lt_mul_of_le_of_lt h.1 hn h.1
/-! ### `div` -/
Nat
file (#9551)
Data.Nat.Basic
is currently made of two things:
I need the first ones earlier in the algebraic order hierarchy, hence the split.
Nat
file (#9551)
Data.Nat.Basic
is currently made of two things:
I need the first ones earlier in the algebraic order hierarchy, hence the split.
@@ -5,43 +5,27 @@ Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
-/
import Mathlib.Algebra.Group.TypeTags
import Mathlib.Algebra.Ring.Defs
-import Mathlib.Init.Data.Nat.Lemmas
+import Mathlib.Algebra.GroupWithZero.Defs
+import Mathlib.Algebra.Ring.Defs
+import Mathlib.Data.Nat.Defs
import Mathlib.Order.Basic
-import Mathlib.Tactic.PushNeg
-import Mathlib.Tactic.Use
#align_import data.nat.basic from "leanprover-community/mathlib"@"bd835ef554f37ef9b804f0903089211f89cb370b"
/-!
-# Basic operations on the natural numbers
+# Basic instances for the natural numbers
This file contains:
-- instances on the natural numbers
-- some basic lemmas about natural numbers
-- extra recursors:
- * `le_rec_on`, `le_induction`: recursion and induction principles starting at non-zero numbers
- * `decreasing_induction`: recursion growing downwards
- * `le_rec_on'`, `decreasing_induction'`: versions with slightly weaker assumptions
- * `strong_rec'`: recursion based on strong inequalities
-- decidability instances on predicates about the natural numbers
-
-Many theorems that used to live in this file have been moved to `Data.Nat.Order`,
-so that this file requires fewer imports.
-For each section here there is a corresponding section in that file with additional results.
-It may be possible to move some of these results here, by tweaking their proofs.
-
-
+* Algebraic instances on the natural numbers
+* Basic lemmas about natural numbers that require more imports than available in
+ `Data.Nat.Defs`.
-/
-
-universe u v
+open Multiplicative
namespace Nat
-/-! ### instances -/
-
-instance nontrivial : Nontrivial ℕ :=
- ⟨⟨0, 1, Nat.zero_ne_one⟩⟩
+/-! ### Instances -/
instance commSemiring : CommSemiring ℕ where
add := Nat.add
@@ -72,7 +56,6 @@ instance commSemiring : CommSemiring ℕ where
/-! Extra instances to short-circuit type class resolution and ensure computability -/
-
instance addCommMonoid : AddCommMonoid ℕ :=
inferInstance
@@ -103,27 +86,18 @@ instance distrib : Distrib ℕ :=
instance semiring : Semiring ℕ :=
inferInstance
-protected theorem nsmul_eq_mul (m n : ℕ) : m • n = m * n :=
- rfl
-#align nat.nsmul_eq_mul Nat.nsmul_eq_mul
-
--- Moved to core
-#align nat.eq_of_mul_eq_mul_right Nat.eq_of_mul_eq_mul_right
-
instance cancelCommMonoidWithZero : CancelCommMonoidWithZero ℕ :=
{ (inferInstance : CommMonoidWithZero ℕ) with
mul_left_cancel_of_ne_zero :=
fun h1 h2 => Nat.eq_of_mul_eq_mul_left (Nat.pos_of_ne_zero h1) h2 }
#align nat.cancel_comm_monoid_with_zero Nat.cancelCommMonoidWithZero
-attribute [simp]
- Nat.not_lt_zero Nat.succ_ne_zero Nat.succ_ne_self Nat.zero_ne_one Nat.one_ne_zero
- -- Nat.zero_ne_bit1 Nat.bit1_ne_zero Nat.bit0_ne_one Nat.one_ne_bit0 Nat.bit0_ne_bit1
- -- Nat.bit1_ne_bit0
+/-! ### Extra lemmas -/
-section Multiplicative
+protected lemma nsmul_eq_mul (m n : ℕ) : m • n = m * n := rfl
+#align nat.nsmul_eq_mul Nat.nsmul_eq_mul
-open Multiplicative
+section Multiplicative
lemma toAdd_pow (a : Multiplicative ℕ) (b : ℕ) : toAdd (a ^ b) = toAdd a * b := mul_comm _ _
#align nat.to_add_pow Nat.toAdd_pow
@@ -132,871 +106,4 @@ lemma toAdd_pow (a : Multiplicative ℕ) (b : ℕ) : toAdd (a ^ b) = toAdd a * b
#align nat.of_add_mul Nat.ofAdd_mul
end Multiplicative
-
-variable {m n k : ℕ}
-
-/-!
-### Recursion and `forall`/`exists`
--/
-
--- Porting note:
--- this doesn't work as a simp lemma in Lean 4
--- @[simp]
-theorem and_forall_succ {p : ℕ → Prop} : (p 0 ∧ ∀ n, p (n + 1)) ↔ ∀ n, p n :=
- ⟨fun h n => Nat.casesOn n h.1 h.2, fun h => ⟨h _, fun _ => h _⟩⟩
-#align nat.and_forall_succ Nat.and_forall_succ
-
--- Porting note:
--- this doesn't work as a simp lemma in Lean 4
--- @[simp]
-theorem or_exists_succ {p : ℕ → Prop} : (p 0 ∨ ∃ n, p (n + 1)) ↔ ∃ n, p n :=
- ⟨fun h => h.elim (fun h0 => ⟨0, h0⟩) fun ⟨n, hn⟩ => ⟨n + 1, hn⟩, by
- rintro ⟨_ | n, hn⟩
- exacts [Or.inl hn, Or.inr ⟨n, hn⟩]⟩
-#align nat.or_exists_succ Nat.or_exists_succ
-
-/-! ### `succ` -/
-
-
-theorem _root_.LT.lt.nat_succ_le {n m : ℕ} (h : n < m) : succ n ≤ m :=
- succ_le_of_lt h
-#align has_lt.lt.nat_succ_le LT.lt.nat_succ_le
-
--- Moved to Std
-#align nat.succ_eq_one_add Nat.succ_eq_one_add
-
-theorem eq_of_lt_succ_of_not_lt {a b : ℕ} (h1 : a < b + 1) (h2 : ¬a < b) : a = b :=
- have h3 : a ≤ b := le_of_lt_succ h1
- Or.elim (eq_or_lt_of_not_lt h2) (fun h => h) fun h => absurd h (not_lt_of_ge h3)
-#align nat.eq_of_lt_succ_of_not_lt Nat.eq_of_lt_succ_of_not_lt
-
-theorem eq_of_le_of_lt_succ {n m : ℕ} (h₁ : n ≤ m) (h₂ : m < n + 1) : m = n :=
- Nat.le_antisymm (le_of_succ_le_succ h₂) h₁
-#align nat.eq_of_le_of_lt_succ Nat.eq_of_le_of_lt_succ
-
--- Moved to Std
-#align nat.one_add Nat.one_add
-
-theorem succ_pos' {n : ℕ} : 0 < succ n :=
- succ_pos n
-#align nat.succ_pos' Nat.succ_pos'
-
--- Moved to Std
-#align nat.succ_inj' Nat.succ_inj'
-
-theorem succ_injective : Function.Injective Nat.succ := fun _ _ => succ.inj
-#align nat.succ_injective Nat.succ_injective
-
-theorem succ_ne_succ {n m : ℕ} : succ n ≠ succ m ↔ n ≠ m :=
- succ_injective.ne_iff
-#align nat.succ_ne_succ Nat.succ_ne_succ
-
--- Porting note: no longer a simp lemma, as simp can prove this
-theorem succ_succ_ne_one (n : ℕ) : n.succ.succ ≠ 1 :=
- succ_ne_succ.mpr n.succ_ne_zero
-#align nat.succ_succ_ne_one Nat.succ_succ_ne_one
-
-@[simp]
-theorem one_lt_succ_succ (n : ℕ) : 1 < n.succ.succ :=
- succ_lt_succ <| succ_pos n
-#align nat.one_lt_succ_succ Nat.one_lt_succ_succ
-
--- Porting note: Nat.succ_le_succ_iff is in Std
-
-#align nat.max_succ_succ Nat.succ_max_succ
-
-theorem not_succ_lt_self {n : ℕ} : ¬succ n < n :=
- not_lt_of_ge (Nat.le_succ _)
-#align nat.not_succ_lt_self Nat.not_succ_lt_self
-
-theorem lt_succ_iff {m n : ℕ} : m < succ n ↔ m ≤ n :=
- ⟨le_of_lt_succ, lt_succ_of_le⟩
-#align nat.lt_succ_iff Nat.lt_succ_iff
-
-theorem succ_le_iff {m n : ℕ} : succ m ≤ n ↔ m < n :=
- ⟨lt_of_succ_le, succ_le_of_lt⟩
-#align nat.succ_le_iff Nat.succ_le_iff
-
-theorem lt_iff_add_one_le {m n : ℕ} : m < n ↔ m + 1 ≤ n := by rw [succ_le_iff]
-#align nat.lt_iff_add_one_le Nat.lt_iff_add_one_le
-
--- Just a restatement of `Nat.lt_succ_iff` using `+1`.
-theorem lt_add_one_iff {a b : ℕ} : a < b + 1 ↔ a ≤ b :=
- lt_succ_iff
-#align nat.lt_add_one_iff Nat.lt_add_one_iff
-
--- A flipped version of `lt_add_one_iff`.
-theorem lt_one_add_iff {a b : ℕ} : a < 1 + b ↔ a ≤ b := by simp only [add_comm, lt_succ_iff]
-#align nat.lt_one_add_iff Nat.lt_one_add_iff
-
--- This is true reflexively, by the definition of `≤` on ℕ,
--- but it's still useful to have, to convince Lean to change the syntactic type.
-theorem add_one_le_iff {a b : ℕ} : a + 1 ≤ b ↔ a < b :=
- Iff.refl _
-#align nat.add_one_le_iff Nat.add_one_le_iff
-
-theorem one_add_le_iff {a b : ℕ} : 1 + a ≤ b ↔ a < b := by simp only [add_comm, add_one_le_iff]
-#align nat.one_add_le_iff Nat.one_add_le_iff
-
-theorem of_le_succ {n m : ℕ} (H : n ≤ m.succ) : n ≤ m ∨ n = m.succ :=
- H.lt_or_eq_dec.imp le_of_lt_succ id
-#align nat.of_le_succ Nat.of_le_succ
-
-#align nat.succ_lt_succ_iff Nat.succ_lt_succ_iff
-
-theorem div_le_iff_le_mul_add_pred {m n k : ℕ} (n0 : 0 < n) : m / n ≤ k ↔ m ≤ n * k + (n - 1) := by
- rw [← lt_succ_iff, div_lt_iff_lt_mul n0, succ_mul, mul_comm]
- cases n
- · cases n0
-
- exact lt_succ_iff
-#align nat.div_le_iff_le_mul_add_pred Nat.div_le_iff_le_mul_add_pred
-
-theorem two_lt_of_ne : ∀ {n}, n ≠ 0 → n ≠ 1 → n ≠ 2 → 2 < n
- | 0, h, _, _ => (h rfl).elim
- | 1, _, h, _ => (h rfl).elim
- | 2, _, _, h => (h rfl).elim
- -- Porting note: was `by decide`
- | n + 3, _, _, _ => by rw [Nat.lt_iff_add_one_le]; convert Nat.le_add_left 3 n
-#align nat.two_lt_of_ne Nat.two_lt_of_ne
-
-theorem forall_lt_succ {P : ℕ → Prop} {n : ℕ} : (∀ m < n + 1, P m) ↔ (∀ m < n, P m) ∧ P n := by
- simp only [lt_succ_iff, Decidable.le_iff_eq_or_lt, forall_eq_or_imp, and_comm]
-#align nat.forall_lt_succ Nat.forall_lt_succ
-
-theorem exists_lt_succ {P : ℕ → Prop} {n : ℕ} : (∃ m < n + 1, P m) ↔ (∃ m < n, P m) ∨ P n := by
- rw [← not_iff_not]
- push_neg
- exact forall_lt_succ
-#align nat.exists_lt_succ Nat.exists_lt_succ
-
-/-! ### `add` -/
-
--- Sometimes a bare `Nat.add` or similar appears as a consequence of unfolding
--- during pattern matching. These lemmas package them back up as typeclass
--- mediated operations.
-@[simp]
-theorem add_def {a b : ℕ} : Nat.add a b = a + b :=
- rfl
-#align nat.add_def Nat.add_def
-
-@[simp]
-theorem mul_def {a b : ℕ} : Nat.mul a b = a * b :=
- rfl
-#align nat.mul_def Nat.mul_def
-
-theorem exists_eq_add_of_le (h : m ≤ n) : ∃ k : ℕ, n = m + k :=
- ⟨n - m, (add_sub_of_le h).symm⟩
-#align nat.exists_eq_add_of_le Nat.exists_eq_add_of_le
-
-theorem exists_eq_add_of_le' (h : m ≤ n) : ∃ k : ℕ, n = k + m :=
- ⟨n - m, (Nat.sub_add_cancel h).symm⟩
-#align nat.exists_eq_add_of_le' Nat.exists_eq_add_of_le'
-
-theorem exists_eq_add_of_lt (h : m < n) : ∃ k : ℕ, n = m + k + 1 :=
- ⟨n - (m + 1), by rw [Nat.add_right_comm, add_sub_of_le h]⟩
-#align nat.exists_eq_add_of_lt Nat.exists_eq_add_of_lt
-
-/-! ### `pred` -/
-
-@[simp]
-theorem add_succ_sub_one (n m : ℕ) : n + succ m - 1 = n + m := by rw [add_succ, Nat.add_one_sub_one]
-#align nat.add_succ_sub_one Nat.add_succ_sub_one
-
-@[simp]
-theorem succ_add_sub_one (n m : ℕ) : succ n + m - 1 = n + m := by rw [succ_add, Nat.add_one_sub_one]
-#align nat.succ_add_sub_one Nat.succ_add_sub_one
-
-theorem pred_eq_sub_one (n : ℕ) : pred n = n - 1 :=
- rfl
-#align nat.pred_eq_sub_one Nat.pred_eq_sub_one
-
-theorem pred_eq_of_eq_succ {m n : ℕ} (H : m = n.succ) : m.pred = n := by simp [H]
-#align nat.pred_eq_of_eq_succ Nat.pred_eq_of_eq_succ
-
-@[simp]
-theorem pred_eq_succ_iff {n m : ℕ} : pred n = succ m ↔ n = m + 2 := by
- cases n <;> constructor <;> rintro ⟨⟩ <;> rfl
-#align nat.pred_eq_succ_iff Nat.pred_eq_succ_iff
-
-theorem pred_sub (n m : ℕ) : pred n - m = pred (n - m) := by
- rw [← Nat.sub_one, Nat.sub_sub, one_add, sub_succ]
-#align nat.pred_sub Nat.pred_sub
-
--- Moved to Std
-#align nat.le_pred_of_lt Nat.le_pred_of_lt
-
-theorem le_of_pred_lt {m n : ℕ} : pred m < n → m ≤ n :=
- match m with
- | 0 => le_of_lt
- | _ + 1 => id
-#align nat.le_of_pred_lt Nat.le_of_pred_lt
-
-theorem self_add_sub_one (n : ℕ) : n + (n - 1) = 2 * n - 1 := by
- cases n
- · rfl
- · rw [two_mul]
- convert (add_succ_sub_one (Nat.succ _) _).symm
-
-theorem sub_one_add_self (n : ℕ) : (n - 1) + n = 2 * n - 1 :=
- add_comm _ n ▸ self_add_sub_one n
-
-theorem self_add_pred (n : ℕ) : n + pred n = (2 * n).pred :=
- self_add_sub_one n
-
-theorem pred_add_self (n : ℕ) : pred n + n = (2 * n).pred :=
- sub_one_add_self n
-
-/-- This ensures that `simp` succeeds on `pred (n + 1) = n`. -/
-@[simp]
-theorem pred_one_add (n : ℕ) : pred (1 + n) = n := by rw [add_comm, add_one, Nat.pred_succ]
-#align nat.pred_one_add Nat.pred_one_add
-
-/-! ### `mul` -/
-
-
-theorem two_mul_ne_two_mul_add_one {n m} : 2 * n ≠ 2 * m + 1 :=
- mt (congr_arg (· % 2))
- (by rw [add_comm, add_mul_mod_self_left, mul_mod_right, mod_eq_of_lt] <;> simp)
-#align nat.two_mul_ne_two_mul_add_one Nat.two_mul_ne_two_mul_add_one
-
-theorem mul_ne_mul_left {a b c : ℕ} (ha : 0 < a) : b * a ≠ c * a ↔ b ≠ c :=
- (mul_left_injective₀ ha.ne').ne_iff
-#align nat.mul_ne_mul_left Nat.mul_ne_mul_left
-
-theorem mul_ne_mul_right {a b c : ℕ} (ha : 0 < a) : a * b ≠ a * c ↔ b ≠ c :=
- (mul_right_injective₀ ha.ne').ne_iff
-#align nat.mul_ne_mul_right Nat.mul_ne_mul_right
-
-theorem mul_right_eq_self_iff {a b : ℕ} (ha : 0 < a) : a * b = a ↔ b = 1 :=
- suffices a * b = a * 1 ↔ b = 1 by rwa [mul_one] at this
- mul_right_inj' ha.ne'
-#align nat.mul_right_eq_self_iff Nat.mul_right_eq_self_iff
-
-theorem mul_left_eq_self_iff {a b : ℕ} (hb : 0 < b) : a * b = b ↔ a = 1 := by
- rw [mul_comm, Nat.mul_right_eq_self_iff hb]
-#align nat.mul_left_eq_self_iff Nat.mul_left_eq_self_iff
-
-theorem lt_succ_iff_lt_or_eq {n i : ℕ} : n < i.succ ↔ n < i ∨ n = i :=
- lt_succ_iff.trans Decidable.le_iff_lt_or_eq
-#align nat.lt_succ_iff_lt_or_eq Nat.lt_succ_iff_lt_or_eq
-
-set_option push_neg.use_distrib true in
-/-- The product of two natural numbers is greater than 1 if and only if
- at least one of them is greater than 1 and both are positive. -/
-lemma one_lt_mul_iff : 1 < m * n ↔ 0 < m ∧ 0 < n ∧ (1 < m ∨ 1 < n) := by
- constructor <;> intro h
- · by_contra h'; push_neg at h'; simp_rw [Nat.le_zero] at h'
- obtain rfl | rfl | h' := h'
- · simp at h
- · simp at h
- · exact (Nat.mul_le_mul h'.1 h'.2).not_lt h
- · obtain hm | hn := h.2.2
- · exact Nat.mul_lt_mul hm h.2.1 Nat.zero_lt_one
- · exact Nat.mul_lt_mul' h.1 hn h.1
-
-/-!
-### Recursion and induction principles
-
-This section is here due to dependencies -- the lemmas here require some of the lemmas
-proved above, and some of the results in later sections depend on the definitions in this section.
--/
-
--- Porting note: The type ascriptions of these two theorems need to be changed,
--- as mathport wrote a lambda that wasn't there in mathlib3, that prevents `simp` applying them.
-
-@[simp]
-theorem rec_zero {C : ℕ → Sort u} (h0 : C 0) (h : ∀ n, C n → C (n + 1)) :
- Nat.rec h0 h 0 = h0 :=
- rfl
-#align nat.rec_zero Nat.rec_zero
-
-@[simp]
-theorem rec_add_one {C : ℕ → Sort u} (h0 : C 0) (h : ∀ n, C n → C (n + 1)) (n : ℕ) :
- Nat.rec h0 h (n + 1) = h n (Nat.rec h0 h n) :=
- rfl
-#align nat.rec_add_one Nat.rec_add_one
-
-/-- Recursion starting at a non-zero number: given a map `C k → C (k+1)` for each `k`,
-there is a map from `C n` to each `C m`, `n ≤ m`. For a version where the assumption is only made
-when `k ≥ n`, see `leRecOn`. -/
-@[elab_as_elim]
-def leRecOn {C : ℕ → Sort u} {n : ℕ} : ∀ {m : ℕ}, n ≤ m → (∀ {k}, C k → C (k + 1)) → C n → C m
- | 0, H, _, x => Eq.recOn (Nat.eq_zero_of_le_zero H) x
- | m + 1, H, next, x =>
- Or.by_cases (of_le_succ H) (fun h : n ≤ m => next <| leRecOn h (@next) x)
- fun h : n = m + 1 => Eq.recOn h x
-#align nat.le_rec_on Nat.leRecOn
-
-theorem leRecOn_self {C : ℕ → Sort u} {n} {h : n ≤ n} {next : ∀ {k}, C k → C (k + 1)} (x : C n) :
- (leRecOn h next x : C n) = x := by
- cases n <;> unfold leRecOn Eq.recOn
- · simp
- · unfold Or.by_cases
- rw [dif_neg (Nat.not_succ_le_self _)]
-#align nat.le_rec_on_self Nat.leRecOn_self
-
-theorem leRecOn_succ {C : ℕ → Sort u} {n m} (h1 : n ≤ m) {h2 : n ≤ m + 1} {next} (x : C n) :
- (leRecOn h2 (@next) x : C (m + 1)) = next (leRecOn h1 (@next) x : C m) := by
- conv =>
- lhs
- rw [leRecOn, Or.by_cases, dif_pos h1]
-#align nat.le_rec_on_succ Nat.leRecOn_succ
-
-theorem leRecOn_succ' {C : ℕ → Sort u} {n} {h : n ≤ n + 1} {next : ∀ {k}, C k → C (k + 1)}
- (x : C n) :
- (leRecOn h next x : C (n + 1)) = next x := by rw [leRecOn_succ (le_refl n), leRecOn_self]
-#align nat.le_rec_on_succ' Nat.leRecOn_succ'
-
-theorem leRecOn_trans {C : ℕ → Sort u} {n m k} (hnm : n ≤ m) (hmk : m ≤ k) {next} (x : C n) :
- (leRecOn (le_trans hnm hmk) (@next) x : C k) = leRecOn hmk (@next) (leRecOn hnm (@next) x) := by
- induction' hmk with k hmk ih
- · rw [leRecOn_self]
-
- rw [leRecOn_succ (le_trans hnm hmk), ih, leRecOn_succ]
-#align nat.le_rec_on_trans Nat.leRecOn_trans
-
-theorem leRecOn_succ_left {C : ℕ → Sort u} {n m} (h1 : n ≤ m) (h2 : n + 1 ≤ m)
- {next : ∀ {k}, C k → C (k + 1)} (x : C n) :
- (leRecOn h2 next (next x) : C m) = (leRecOn h1 next x : C m) := by
- rw [Subsingleton.elim h1 (le_trans (le_succ n) h2), leRecOn_trans (le_succ n) h2, leRecOn_succ']
-#align nat.le_rec_on_succ_left Nat.leRecOn_succ_left
-
-theorem leRecOn_injective {C : ℕ → Sort u} {n m} (hnm : n ≤ m) (next : ∀ {k}, C k → C (k + 1))
- (Hnext : ∀ n, Function.Injective (@next n)) :
- Function.Injective (@leRecOn C n m hnm next) := by
- induction' hnm with m hnm ih
- · intro x y H
- rwa [leRecOn_self, leRecOn_self] at H
-
- intro x y H
- rw [leRecOn_succ hnm, leRecOn_succ hnm] at H
- exact ih (Hnext _ H)
-#align nat.le_rec_on_injective Nat.leRecOn_injective
-
-theorem leRecOn_surjective {C : ℕ → Sort u} {n m} (hnm : n ≤ m) (next : ∀ {k}, C k → C (k + 1))
- (Hnext : ∀ n, Function.Surjective (@next n)) :
- Function.Surjective (@leRecOn C n m hnm next) := by
- induction' hnm with m hnm ih
- · intro x
- use x
- rw [leRecOn_self]
-
- intro x
- rcases Hnext _ x with ⟨w, rfl⟩
- rcases ih w with ⟨x, rfl⟩
- use x
- rw [leRecOn_succ]
-#align nat.le_rec_on_surjective Nat.leRecOn_surjective
-
-/-- Recursion principle based on `<`. -/
-@[elab_as_elim]
-protected def strongRec' {p : ℕ → Sort u} (H : ∀ n, (∀ m, m < n → p m) → p n) : ∀ n : ℕ, p n
- | n => H n fun m _ => Nat.strongRec' H m
-#align nat.strong_rec' Nat.strongRec'
-
-/-- Recursion principle based on `<` applied to some natural number. -/
-@[elab_as_elim]
-def strongRecOn' {P : ℕ → Sort*} (n : ℕ) (h : ∀ n, (∀ m, m < n → P m) → P n) : P n :=
- Nat.strongRec' h n
-#align nat.strong_rec_on' Nat.strongRecOn'
-
-theorem strongRecOn'_beta {P : ℕ → Sort*} {h} {n : ℕ} :
- (strongRecOn' n h : P n) = h n fun m _ => (strongRecOn' m h : P m) := by
- simp only [strongRecOn']
- rw [Nat.strongRec']
-#align nat.strong_rec_on_beta' Nat.strongRecOn'_beta
-
-/-- Induction principle starting at a non-zero number. For maps to a `Sort*` see `le_rec_on`.
-To use in an induction proof, the syntax is `induction n, hn using Nat.le_induction` (or the same
-for `induction'`). -/
-@[elab_as_elim]
-theorem le_induction {m} {P : ∀ (n : Nat) (_ : m ≤ n), Prop} (base : P m le_rfl)
- (succ : ∀ (n : Nat) (hn : m ≤ n), P n hn → P (n + 1) (hn.trans <| Nat.le_succ _)) :
- ∀ (n : Nat) (hn : m ≤ n), P n hn := by
- apply Nat.le.rec
- · exact base
- · intros n hn
- apply succ n hn
-#align nat.le_induction Nat.le_induction
-
-/-- Decreasing induction: if `P (k+1)` implies `P k`, then `P n` implies `P m` for all `m ≤ n`.
-Also works for functions to `Sort*`. For a version assuming only the assumption for `k < n`, see
-`decreasing_induction'`. -/
-@[elab_as_elim]
-def decreasingInduction {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {m n : ℕ} (mn : m ≤ n)
- (hP : P n) : P m :=
- leRecOn mn (fun {k} ih hsk => ih <| h k hsk) (fun h => h) hP
-#align nat.decreasing_induction Nat.decreasingInduction
-
-@[simp]
-theorem decreasingInduction_self {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {n : ℕ} (nn : n ≤ n)
- (hP : P n) :
- (decreasingInduction h nn hP : P n) = hP := by
- dsimp only [decreasingInduction]
- rw [leRecOn_self]
-#align nat.decreasing_induction_self Nat.decreasingInduction_self
-
-theorem decreasingInduction_succ {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {m n : ℕ} (mn : m ≤ n)
- (msn : m ≤ n + 1) (hP : P (n + 1)) :
- (decreasingInduction h msn hP : P m) = decreasingInduction h mn (h n hP) := by
- dsimp only [decreasingInduction]
- rw [leRecOn_succ]
-#align nat.decreasing_induction_succ Nat.decreasingInduction_succ
-
-@[simp]
-theorem decreasingInduction_succ' {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {m : ℕ}
- (msm : m ≤ m + 1) (hP : P (m + 1)) : (decreasingInduction h msm hP : P m) = h m hP := by
- dsimp only [decreasingInduction]
- rw [leRecOn_succ']
-#align nat.decreasing_induction_succ' Nat.decreasingInduction_succ'
-
-theorem decreasingInduction_trans {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {m n k : ℕ}
- (mn : m ≤ n) (nk : n ≤ k) (hP : P k) :
- (decreasingInduction h (le_trans mn nk) hP : P m) =
- decreasingInduction h mn (decreasingInduction h nk hP) := by
- induction' nk with k nk ih
- · rw [decreasingInduction_self]
- · rw [decreasingInduction_succ h (le_trans mn nk), ih, decreasingInduction_succ]
-#align nat.decreasing_induction_trans Nat.decreasingInduction_trans
-
-theorem decreasingInduction_succ_left {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {m n : ℕ}
- (smn : m + 1 ≤ n) (mn : m ≤ n) (hP : P n) :
- (decreasingInduction h mn hP : P m) = h m (decreasingInduction h smn hP) := by
- rw [Subsingleton.elim mn (le_trans (le_succ m) smn), decreasingInduction_trans,
- decreasingInduction_succ']
- apply Nat.le_succ
-#align nat.decreasing_induction_succ_left Nat.decreasingInduction_succ_left
-
-/-- Given `P : ℕ → ℕ → Sort*`, if for all `a b : ℕ` we can extend `P` from the rectangle
-strictly below `(a,b)` to `P a b`, then we have `P n m` for all `n m : ℕ`.
-Note that for non-`Prop` output it is preferable to use the equation compiler directly if possible,
-since this produces equation lemmas. -/
-@[elab_as_elim]
-def strongSubRecursion {P : ℕ → ℕ → Sort*} (H : ∀ a b, (∀ x y, x < a → y < b → P x y) → P a b) :
- ∀ n m : ℕ, P n m
- | n, m => H n m fun x y _ _ => strongSubRecursion H x y
-#align nat.strong_sub_recursion Nat.strongSubRecursion
-
-/-- Given `P : ℕ → ℕ → Sort*`, if we have `P i 0` and `P 0 i` for all `i : ℕ`,
-and for any `x y : ℕ` we can extend `P` from `(x,y+1)` and `(x+1,y)` to `(x+1,y+1)`
-then we have `P n m` for all `n m : ℕ`.
-Note that for non-`Prop` output it is preferable to use the equation compiler directly if possible,
-since this produces equation lemmas. -/
-@[elab_as_elim]
-def pincerRecursion {P : ℕ → ℕ → Sort*} (Ha0 : ∀ a : ℕ, P a 0) (H0b : ∀ b : ℕ, P 0 b)
- (H : ∀ x y : ℕ, P x y.succ → P x.succ y → P x.succ y.succ) : ∀ n m : ℕ, P n m
- | a, 0 => Ha0 a
- | 0, b => H0b b
- | Nat.succ a, Nat.succ b => H _ _ (pincerRecursion Ha0 H0b H _ _) (pincerRecursion Ha0 H0b H _ _)
-termination_by pincerRecursion Ha0 Hab H n m => n + m
-#align nat.pincer_recursion Nat.pincerRecursion
-
-/-- Recursion starting at a non-zero number: given a map `C k → C (k+1)` for each `k ≥ n`,
-there is a map from `C n` to each `C m`, `n ≤ m`. -/
-@[elab_as_elim]
-def leRecOn' {C : ℕ → Sort*} {n : ℕ} :
- ∀ {m : ℕ}, n ≤ m → (∀ ⦃k⦄, n ≤ k → C k → C (k + 1)) → C n → C m
- | 0, H, _, x => Eq.recOn (Nat.eq_zero_of_le_zero H) x
- | m + 1, H, next, x =>
- Or.by_cases (of_le_succ H) (fun h : n ≤ m => next h <| leRecOn' h next x)
- fun h : n = m + 1 => Eq.recOn h x
-#align nat.le_rec_on' Nat.leRecOn'
-
-/-- Decreasing induction: if `P (k+1)` implies `P k` for all `m ≤ k < n`, then `P n` implies `P m`.
-Also works for functions to `Sort*`. Weakens the assumptions of `decreasing_induction`. -/
-@[elab_as_elim]
-def decreasingInduction' {P : ℕ → Sort*} {m n : ℕ} (h : ∀ k < n, m ≤ k → P (k + 1) → P k)
- (mn : m ≤ n) (hP : P n) :
- P m := by
- revert h hP
- refine' leRecOn' mn _ _
- · intro n mn ih h hP
- apply ih
- · exact fun k hk => h k (Nat.lt.step hk)
- · exact h n (lt_succ_self n) mn hP
- · intro _ hP
- exact hP
-#align nat.decreasing_induction' Nat.decreasingInduction'
-
-/-! ### `div` -/
-
-attribute [simp] Nat.div_self
-
-/-- A version of `Nat.div_lt_self` using successors, rather than additional hypotheses. -/
-theorem div_lt_self' (n b : ℕ) : (n + 1) / (b + 2) < n + 1 :=
- Nat.div_lt_self (Nat.succ_pos n) (Nat.succ_lt_succ (Nat.succ_pos _))
-#align nat.div_lt_self' Nat.div_lt_self'
-
-theorem le_div_iff_mul_le' {x y : ℕ} {k : ℕ} (k0 : 0 < k) : x ≤ y / k ↔ x * k ≤ y :=
- le_div_iff_mul_le k0
-#align nat.le_div_iff_mul_le' Nat.le_div_iff_mul_le'
-
-theorem div_lt_iff_lt_mul' {x y : ℕ} {k : ℕ} (k0 : 0 < k) : x / k < y ↔ x < y * k :=
- lt_iff_lt_of_le_iff_le <| le_div_iff_mul_le' k0
-#align nat.div_lt_iff_lt_mul' Nat.div_lt_iff_lt_mul'
-
-theorem one_le_div_iff {a b : ℕ} (hb : 0 < b) : 1 ≤ a / b ↔ b ≤ a := by
- rw [le_div_iff_mul_le hb, one_mul]
-#align nat.one_le_div_iff Nat.one_le_div_iff
-
-theorem div_lt_one_iff {a b : ℕ} (hb : 0 < b) : a / b < 1 ↔ a < b :=
- lt_iff_lt_of_le_iff_le <| one_le_div_iff hb
-#align nat.div_lt_one_iff Nat.div_lt_one_iff
-
-protected theorem div_le_div_right {n m : ℕ} (h : n ≤ m) {k : ℕ} : n / k ≤ m / k :=
- ((Nat.eq_zero_or_pos k).elim fun k0 => by simp [k0]) fun hk =>
- (le_div_iff_mul_le' hk).2 <| le_trans (Nat.div_mul_le_self _ _) h
-#align nat.div_le_div_right Nat.div_le_div_right
-
-theorem lt_of_div_lt_div {m n k : ℕ} : m / k < n / k → m < n :=
- lt_imp_lt_of_le_imp_le fun h => Nat.div_le_div_right h
-#align nat.lt_of_div_lt_div Nat.lt_of_div_lt_div
-
-protected theorem div_pos {a b : ℕ} (hba : b ≤ a) (hb : 0 < b) : 0 < a / b :=
- Nat.pos_of_ne_zero fun h =>
- lt_irrefl a
- (calc
- a = a % b := by simpa [h] using (mod_add_div a b).symm
- _ < b := Nat.mod_lt a hb
- _ ≤ a := hba
- )
-#align nat.div_pos Nat.div_pos
-
-theorem lt_mul_of_div_lt {a b c : ℕ} (h : a / c < b) (w : 0 < c) : a < b * c :=
- lt_of_not_ge <| not_le_of_gt h ∘ (Nat.le_div_iff_mul_le w).2
-#align nat.lt_mul_of_div_lt Nat.lt_mul_of_div_lt
-
-theorem mul_div_le_mul_div_assoc (a b c : ℕ) : a * (b / c) ≤ a * b / c :=
- if hc0 : c = 0 then by simp [hc0]
- else
- (Nat.le_div_iff_mul_le (Nat.pos_of_ne_zero hc0)).2
- (by rw [mul_assoc]; exact Nat.mul_le_mul_left _ (Nat.div_mul_le_self _ _))
-#align nat.mul_div_le_mul_div_assoc Nat.mul_div_le_mul_div_assoc
-
-protected theorem eq_mul_of_div_eq_right {a b c : ℕ} (H1 : b ∣ a) (H2 : a / b = c) : a = b * c := by
- rw [← H2, Nat.mul_div_cancel' H1]
-#align nat.eq_mul_of_div_eq_right Nat.eq_mul_of_div_eq_right
-
-protected theorem div_eq_iff_eq_mul_right {a b c : ℕ} (H : 0 < b) (H' : b ∣ a) :
- a / b = c ↔ a = b * c :=
- ⟨Nat.eq_mul_of_div_eq_right H', Nat.div_eq_of_eq_mul_right H⟩
-#align nat.div_eq_iff_eq_mul_right Nat.div_eq_iff_eq_mul_right
-
-protected theorem div_eq_iff_eq_mul_left {a b c : ℕ} (H : 0 < b) (H' : b ∣ a) :
- a / b = c ↔ a = c * b := by
- rw [mul_comm]
- exact Nat.div_eq_iff_eq_mul_right H H'
-#align nat.div_eq_iff_eq_mul_left Nat.div_eq_iff_eq_mul_left
-
-protected theorem eq_mul_of_div_eq_left {a b c : ℕ} (H1 : b ∣ a) (H2 : a / b = c) : a = c * b := by
- rw [mul_comm, Nat.eq_mul_of_div_eq_right H1 H2]
-#align nat.eq_mul_of_div_eq_left Nat.eq_mul_of_div_eq_left
-
-protected theorem mul_div_cancel_left' {a b : ℕ} (Hd : a ∣ b) : a * (b / a) = b := by
- rw [mul_comm, Nat.div_mul_cancel Hd]
-#align nat.mul_div_cancel_left' Nat.mul_div_cancel_left'
-
-#align nat.mul_div_mul_left Nat.mul_div_mul_left
-#align nat.mul_div_mul_right Nat.mul_div_mul_right
-
-theorem lt_div_mul_add {a b : ℕ} (hb : 0 < b) : a < a / b * b + b := by
- rw [← Nat.succ_mul, ← Nat.div_lt_iff_lt_mul hb]
- exact Nat.lt_succ_self _
-#align nat.lt_div_mul_add Nat.lt_div_mul_add
-
-@[simp]
-protected theorem div_left_inj {a b d : ℕ} (hda : d ∣ a) (hdb : d ∣ b) : a / d = b / d ↔ a = b := by
- refine ⟨fun h => ?_, congr_arg fun n => n / d⟩
- rw [← Nat.mul_div_cancel' hda, ← Nat.mul_div_cancel' hdb, h]
-#align nat.div_left_inj Nat.div_left_inj
-
-theorem div_mul_div_comm {l : ℕ} (hmn : n ∣ m) (hkl : l ∣ k) :
- (m / n) * (k / l) = (m * k) / (n * l) := by
- obtain ⟨x, rfl⟩ := hmn
- obtain ⟨y, rfl⟩ := hkl
- rcases n.eq_zero_or_pos with rfl | hn
- · simp
- rcases l.eq_zero_or_pos with rfl | hl
- · simp
- rw [Nat.mul_div_cancel_left _ hn, Nat.mul_div_cancel_left _ hl, mul_assoc n, Nat.mul_left_comm x,
- ← mul_assoc n, Nat.mul_div_cancel_left _ (Nat.mul_pos hn hl)]
-#align nat.div_mul_div_comm Nat.div_mul_div_comm
-
-protected theorem div_pow {a b c : ℕ} (h : a ∣ b) : (b / a) ^ c = b ^ c / a ^ c := by
- rcases c.eq_zero_or_pos with rfl | hc
- · simp
- rcases a.eq_zero_or_pos with rfl | ha
- · simp [Nat.zero_pow hc]
- refine (Nat.div_eq_of_eq_mul_right (pos_pow_of_pos c ha) ?_).symm
- rw [← Nat.mul_pow, Nat.mul_div_cancel_left' h]
-
-/-! ### `mod`, `dvd` -/
-
-
-theorem mod_eq_iff_lt {a b : ℕ} (h : b ≠ 0) : a % b = a ↔ a < b := by
- cases b
- contradiction
- exact ⟨fun h => h.ge.trans_lt (mod_lt _ (succ_pos _)), mod_eq_of_lt⟩
-#align nat.mod_eq_iff_lt Nat.mod_eq_iff_lt
-
-@[simp]
-theorem mod_succ_eq_iff_lt {a b : ℕ} : a % b.succ = a ↔ a < b.succ :=
- mod_eq_iff_lt (succ_ne_zero _)
-#align nat.mod_succ_eq_iff_lt Nat.mod_succ_eq_iff_lt
-
-@[simp]
-theorem mod_succ (n : ℕ) : n % n.succ = n :=
- Nat.mod_eq_of_lt (Nat.lt_succ_self _)
-
--- Porting note `Nat.div_add_mod` is now in core.
-
-theorem mod_add_div' (m k : ℕ) : m % k + m / k * k = m := by
- rw [mul_comm]
- exact mod_add_div _ _
-#align nat.mod_add_div' Nat.mod_add_div'
-
-theorem div_add_mod' (m k : ℕ) : m / k * k + m % k = m := by
- rw [mul_comm]
- exact div_add_mod _ _
-#align nat.div_add_mod' Nat.div_add_mod'
-
-/-- See also `Nat.divModEquiv` for a similar statement as an `Equiv`. -/
-protected theorem div_mod_unique {n k m d : ℕ} (h : 0 < k) :
- n / k = d ∧ n % k = m ↔ m + k * d = n ∧ m < k :=
- ⟨fun ⟨e₁, e₂⟩ => e₁ ▸ e₂ ▸ ⟨mod_add_div _ _, mod_lt _ h⟩, fun ⟨h₁, h₂⟩ =>
- h₁ ▸ by
- rw [add_mul_div_left _ _ h, add_mul_mod_self_left]
- simp [div_eq_of_lt, mod_eq_of_lt, h₂]⟩
-#align nat.div_mod_unique Nat.div_mod_unique
-
-protected theorem dvd_add_left {k m n : ℕ} (h : k ∣ n) : k ∣ m + n ↔ k ∣ m :=
- (Nat.dvd_add_iff_left h).symm
-#align nat.dvd_add_left Nat.dvd_add_left
-
-protected theorem dvd_add_right {k m n : ℕ} (h : k ∣ m) : k ∣ m + n ↔ k ∣ n :=
- (Nat.dvd_add_iff_right h).symm
-#align nat.dvd_add_right Nat.dvd_add_right
-
-protected theorem mul_dvd_mul_iff_left {a b c : ℕ} (ha : 0 < a) : a * b ∣ a * c ↔ b ∣ c :=
- exists_congr fun d => by rw [mul_assoc, mul_right_inj' ha.ne']
-#align nat.mul_dvd_mul_iff_left Nat.mul_dvd_mul_iff_left
-
-protected theorem mul_dvd_mul_iff_right {a b c : ℕ} (hc : 0 < c) : a * c ∣ b * c ↔ a ∣ b :=
- exists_congr fun d => by rw [Nat.mul_right_comm, mul_left_inj' hc.ne']
-#align nat.mul_dvd_mul_iff_right Nat.mul_dvd_mul_iff_right
-
-#align nat.dvd_one Nat.dvd_one
-
-@[simp]
-theorem mod_mod_of_dvd (n : Nat) {m k : Nat} (h : m ∣ k) : n % k % m = n % m := by
- conv_rhs => rw [← mod_add_div n k]
- rcases h with ⟨t, rfl⟩
- rw [mul_assoc, add_mul_mod_self_left]
-#align nat.mod_mod_of_dvd Nat.mod_mod_of_dvd
-
--- Moved to Std
-#align nat.mod_mod Nat.mod_mod
-#align nat.mod_add_mod Nat.mod_add_mod
-#align nat.add_mod_mod Nat.add_mod_mod
-#align nat.add_mod Nat.add_mod
-
-theorem add_mod_eq_add_mod_right {m n k : ℕ} (i : ℕ) (H : m % n = k % n) :
- (m + i) % n = (k + i) % n := by
- rw [← mod_add_mod, ← mod_add_mod k, H]
-#align nat.add_mod_eq_add_mod_right Nat.add_mod_eq_add_mod_right
-
-theorem add_mod_eq_add_mod_left {m n k : ℕ} (i : ℕ) (H : m % n = k % n) :
- (i + m) % n = (i + k) % n := by
- rw [add_comm, add_mod_eq_add_mod_right _ H, add_comm]
-#align nat.add_mod_eq_add_mod_left Nat.add_mod_eq_add_mod_left
-
--- Moved to Std
-#align nat.mul_mod Nat.mul_mod
-
-theorem mul_dvd_of_dvd_div {a b c : ℕ} (hab : c ∣ b) (h : a ∣ b / c) : c * a ∣ b :=
- have h1 : ∃ d, b / c = a * d := h
- let ⟨d, hd⟩ := h1
- have h3 : b = a * d * c := Nat.eq_mul_of_div_eq_left hab hd
- -- Porting note: was `cc`
- show ∃ d, b = c * a * d from ⟨d, by rwa [mul_comm, ← mul_assoc] at h3⟩
-#align nat.mul_dvd_of_dvd_div Nat.mul_dvd_of_dvd_div
-
-theorem eq_of_dvd_of_div_eq_one {a b : ℕ} (w : a ∣ b) (h : b / a = 1) : a = b := by
- rw [← Nat.div_mul_cancel w, h, one_mul]
-#align nat.eq_of_dvd_of_div_eq_one Nat.eq_of_dvd_of_div_eq_one
-
-theorem 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]
-#align nat.eq_zero_of_dvd_of_div_eq_zero Nat.eq_zero_of_dvd_of_div_eq_zero
-
-theorem 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 (Nat.mul_le_mul_left _ h₁) (div_mul_le_self _ _)
-#align nat.div_le_div_left Nat.div_le_div_left
-
-theorem lt_iff_le_pred : ∀ {m n : ℕ}, 0 < n → (m < n ↔ m ≤ n - 1)
- | _, _ + 1, _ => lt_succ_iff
-#align nat.lt_iff_le_pred Nat.lt_iff_le_pred
-
--- Moved to Std
-#align nat.mul_div_le Nat.mul_div_le
-
-theorem lt_mul_div_succ (m : ℕ) {n : ℕ} (n0 : 0 < n) : m < n * (m / n + 1) := by
- rw [mul_comm, ← Nat.div_lt_iff_lt_mul' n0]
- exact lt_succ_self _
-#align nat.lt_mul_div_succ Nat.lt_mul_div_succ
-
--- TODO: Std4 claimed this name but flipped the order of multiplication
-theorem mul_add_mod' (a b c : ℕ) : (a * b + c) % b = c % b := by rw [mul_comm, Nat.mul_add_mod]
-#align nat.mul_add_mod Nat.mul_add_mod'
-
-theorem mul_add_mod_of_lt {a b c : ℕ} (h : c < b) : (a * b + c) % b = c := by
- rw [Nat.mul_add_mod', Nat.mod_eq_of_lt h]
-#align nat.mul_add_mod_of_lt Nat.mul_add_mod_of_lt
-
-theorem pred_eq_self_iff {n : ℕ} : n.pred = n ↔ n = 0 := by
- cases n <;> simp [(Nat.succ_ne_self _).symm]
-#align nat.pred_eq_self_iff Nat.pred_eq_self_iff
-
-/-! ### `find` -/
-
-
-section Find
-
-variable {p q : ℕ → Prop} [DecidablePred p] [DecidablePred q]
-
-theorem find_eq_iff (h : ∃ n : ℕ, p n) : Nat.find h = m ↔ p m ∧ ∀ n < m, ¬p n := by
- constructor
- · rintro rfl
- exact ⟨Nat.find_spec h, fun _ => Nat.find_min h⟩
- · rintro ⟨hm, hlt⟩
- exact le_antisymm (Nat.find_min' h hm) (not_lt.1 <| imp_not_comm.1 (hlt _) <| Nat.find_spec h)
-#align nat.find_eq_iff Nat.find_eq_iff
-
-@[simp]
-theorem find_lt_iff (h : ∃ n : ℕ, p n) (n : ℕ) : Nat.find h < n ↔ ∃ m < n, p m :=
- ⟨fun h2 => ⟨Nat.find h, h2, Nat.find_spec h⟩,
- fun ⟨_, hmn, hm⟩ => (Nat.find_min' h hm).trans_lt hmn⟩
-#align nat.find_lt_iff Nat.find_lt_iff
-
-@[simp]
-theorem find_le_iff (h : ∃ n : ℕ, p n) (n : ℕ) : Nat.find h ≤ n ↔ ∃ m ≤ n, p m := by
- simp only [exists_prop, ← lt_succ_iff, find_lt_iff]
-#align nat.find_le_iff Nat.find_le_iff
-
-@[simp]
-theorem le_find_iff (h : ∃ n : ℕ, p n) (n : ℕ) : n ≤ Nat.find h ↔ ∀ m < n, ¬p m := by
- simp_rw [← not_lt, find_lt_iff, not_exists, not_and]
-#align nat.le_find_iff Nat.le_find_iff
-
-@[simp]
-theorem lt_find_iff (h : ∃ n : ℕ, p n) (n : ℕ) : n < Nat.find h ↔ ∀ m ≤ n, ¬p m := by
- simp only [← succ_le_iff, le_find_iff, succ_le_succ_iff]
-#align nat.lt_find_iff Nat.lt_find_iff
-
-@[simp]
-theorem find_eq_zero (h : ∃ n : ℕ, p n) : Nat.find h = 0 ↔ p 0 := by simp [find_eq_iff]
-#align nat.find_eq_zero Nat.find_eq_zero
-
-theorem find_mono (h : ∀ n, q n → p n) {hp : ∃ n, p n} {hq : ∃ n, q n} :
- Nat.find hp ≤ Nat.find hq :=
- Nat.find_min' _ (h _ (Nat.find_spec hq))
-#align nat.find_mono Nat.find_mono
-
-theorem find_le {h : ∃ n, p n} (hn : p n) : Nat.find h ≤ n :=
- (Nat.find_le_iff _ _).2 ⟨n, le_rfl, hn⟩
-#align nat.find_le Nat.find_le
-
-theorem find_comp_succ (h₁ : ∃ n, p n) (h₂ : ∃ n, p (n + 1)) (h0 : ¬p 0) :
- Nat.find h₁ = Nat.find h₂ + 1 := by
- refine' (find_eq_iff _).2 ⟨Nat.find_spec h₂, fun n hn => _⟩
- cases' n with n
- exacts [h0, @Nat.find_min (fun n => p (n + 1)) _ h₂ _ (succ_lt_succ_iff.1 hn)]
-#align nat.find_comp_succ Nat.find_comp_succ
-
-end Find
-
-/-! ### `find_greatest` -/
-
-
-section FindGreatest
-
-/-- `find_greatest P b` is the largest `i ≤ bound` such that `P i` holds, or `0` if no such `i`
-exists -/
-protected def findGreatest (P : ℕ → Prop) [DecidablePred P] : ℕ → ℕ
- | 0 => 0
- | n + 1 => if P (n + 1) then n + 1 else Nat.findGreatest P n
-#align nat.find_greatest Nat.findGreatest
-
-variable {P Q : ℕ → Prop} [DecidablePred P] {b : ℕ}
-
-@[simp]
-theorem findGreatest_zero : Nat.findGreatest P 0 = 0 :=
- rfl
-#align nat.find_greatest_zero Nat.findGreatest_zero
-
-theorem findGreatest_succ (n : ℕ) :
- Nat.findGreatest P (n + 1) = if P (n + 1) then n + 1 else Nat.findGreatest P n :=
- rfl
-#align nat.find_greatest_succ Nat.findGreatest_succ
-
-@[simp]
-theorem findGreatest_eq : ∀ {b}, P b → Nat.findGreatest P b = b
- | 0, _ => rfl
- | n + 1, h => by simp [Nat.findGreatest, h]
-#align nat.find_greatest_eq Nat.findGreatest_eq
-
-@[simp]
-theorem findGreatest_of_not (h : ¬P (b + 1)) :
- Nat.findGreatest P (b + 1) = Nat.findGreatest P b := by
- simp [Nat.findGreatest, h]
-#align nat.find_greatest_of_not Nat.findGreatest_of_not
-
-end FindGreatest
-
-/-! ### decidability of predicates -/
-
--- To work around lean4#2552, we use `match` instead of `if/casesOn` with decidable instances.
-instance decidableBallLT :
- ∀ (n : Nat) (P : ∀ k, k < n → Prop) [∀ n h, Decidable (P n h)], Decidable (∀ n h, P n h)
-| 0, _, _ => isTrue fun _ => (by cases ·)
-| (n+1), P, H =>
- match decidableBallLT n (P · <| lt_succ_of_lt ·) with
- | isFalse h => isFalse (h fun _ _ => · _ _)
- | isTrue h =>
- match H n Nat.le.refl with
- | isFalse p => isFalse (p <| · _ _)
- | isTrue p => isTrue fun _ h' => (Nat.le_of_lt_succ h').lt_or_eq_dec.elim (h _) (· ▸ p)
-#align nat.decidable_ball_lt Nat.decidableBallLT
-
--- To verify we don't have a regression on the speed, we put a difficult example.
--- any regression should take a huge amount of heartbeats -- we are currently at 187621.
--- For reference, the instance using `casesOn` took 44544 for 4; this one takes 1299 for 4.
-example : ∀ a, a < 25 → ∀ b, b < 25 → ∀ c, c < 25 → a ^ 2 + b ^ 2 + c ^ 2 ≠ 7 := by decide
-
-instance decidableForallFin {n : ℕ} (P : Fin n → Prop) [DecidablePred P] :
- Decidable (∀ i, P i) :=
- decidable_of_iff (∀ k h, P ⟨k, h⟩) ⟨fun a ⟨k, h⟩ => a k h, fun a k h => a ⟨k, h⟩⟩
-#align nat.decidable_forall_fin Nat.decidableForallFin
-
-instance decidableBallLe (n : ℕ) (P : ∀ k ≤ n, Prop) [∀ n h, Decidable (P n h)] :
- Decidable (∀ n h, P n h) :=
- decidable_of_iff (∀ (k) (h : k < succ n), P k (le_of_lt_succ h))
- ⟨fun a k h => a k (lt_succ_of_le h), fun a k _ => a k _⟩
-#align nat.decidable_ball_le Nat.decidableBallLe
-
-instance decidableExistsLT {P : ℕ → Prop} [h : DecidablePred P] :
- DecidablePred fun n => ∃ m : ℕ, m < n ∧ P m
- | 0 => isFalse (by simp)
- | n + 1 =>
- @decidable_of_decidable_of_iff _ _ (@instDecidableOr _ _ (decidableExistsLT n) (h n))
- (by simp only [lt_succ_iff_lt_or_eq, or_and_right, exists_or, exists_eq_left]; apply Iff.refl)
-#align nat.decidable_exists_lt Nat.decidableExistsLT
-
-instance decidableExistsLe {P : ℕ → Prop} [DecidablePred P] :
- DecidablePred fun n => ∃ m : ℕ, m ≤ n ∧ P m :=
- fun n => decidable_of_iff (∃ m, m < n + 1 ∧ P m)
- (exists_congr fun _ => and_congr_left' lt_succ_iff)
-#align nat.decidable_exists_le Nat.decidableExistsLe
-
end Nat
@@ -3,10 +3,10 @@ Copyright (c) 2014 Floris van Doorn (c) 2016 Microsoft Corporation. All rights r
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
-/
+import Mathlib.Algebra.Group.TypeTags
+import Mathlib.Algebra.Ring.Defs
import Mathlib.Init.Data.Nat.Lemmas
import Mathlib.Order.Basic
-import Mathlib.Algebra.GroupWithZero.Defs
-import Mathlib.Algebra.Ring.Defs
import Mathlib.Tactic.PushNeg
import Mathlib.Tactic.Use
@@ -121,6 +121,18 @@ attribute [simp]
-- Nat.zero_ne_bit1 Nat.bit1_ne_zero Nat.bit0_ne_one Nat.one_ne_bit0 Nat.bit0_ne_bit1
-- Nat.bit1_ne_bit0
+section Multiplicative
+
+open Multiplicative
+
+lemma toAdd_pow (a : Multiplicative ℕ) (b : ℕ) : toAdd (a ^ b) = toAdd a * b := mul_comm _ _
+#align nat.to_add_pow Nat.toAdd_pow
+
+@[simp] lemma ofAdd_mul (a b : ℕ) : ofAdd (a * b) = ofAdd a ^ b := (toAdd_pow _ _).symm
+#align nat.of_add_mul Nat.ofAdd_mul
+
+end Multiplicative
+
variable {m n k : ℕ}
/-!
@@ -774,9 +774,6 @@ protected theorem mul_dvd_mul_iff_right {a b c : ℕ} (hc : 0 < c) : a * c ∣ b
exists_congr fun d => by rw [Nat.mul_right_comm, mul_left_inj' hc.ne']
#align nat.mul_dvd_mul_iff_right Nat.mul_dvd_mul_iff_right
-@[simp] -- TODO: move to Std4
-theorem dvd_one {a : ℕ} : a ∣ 1 ↔ a = 1 :=
- ⟨eq_one_of_dvd_one, fun h ↦ h.symm ▸ Nat.dvd_refl _⟩
#align nat.dvd_one Nat.dvd_one
@[simp]
Adds the attribute elab_as_elim
directly to the declarations of strongSubRecursion
and pincerRecursion
, rather than in separate commands.
This change was made possible by https://github.com/leanprover/lean4/commit/8a573b5d87a42bd19307522ee747aaed44d9d71c, which fixed https://github.com/leanprover/lean4/issues/1900.
@@ -560,21 +560,18 @@ theorem decreasingInduction_succ_left {P : ℕ → Sort*} (h : ∀ n, P (n + 1)
strictly below `(a,b)` to `P a b`, then we have `P n m` for all `n m : ℕ`.
Note that for non-`Prop` output it is preferable to use the equation compiler directly if possible,
since this produces equation lemmas. -/
+@[elab_as_elim]
def strongSubRecursion {P : ℕ → ℕ → Sort*} (H : ∀ a b, (∀ x y, x < a → y < b → P x y) → P a b) :
∀ n m : ℕ, P n m
| n, m => H n m fun x y _ _ => strongSubRecursion H x y
#align nat.strong_sub_recursion Nat.strongSubRecursion
--- Porting note:
--- we can't put this on the definition itself because of
--- https://github.com/leanprover/lean4/issues/1900
-attribute [elab_as_elim] strongSubRecursion
-
/-- Given `P : ℕ → ℕ → Sort*`, if we have `P i 0` and `P 0 i` for all `i : ℕ`,
and for any `x y : ℕ` we can extend `P` from `(x,y+1)` and `(x+1,y)` to `(x+1,y+1)`
then we have `P n m` for all `n m : ℕ`.
Note that for non-`Prop` output it is preferable to use the equation compiler directly if possible,
since this produces equation lemmas. -/
+@[elab_as_elim]
def pincerRecursion {P : ℕ → ℕ → Sort*} (Ha0 : ∀ a : ℕ, P a 0) (H0b : ∀ b : ℕ, P 0 b)
(H : ∀ x y : ℕ, P x y.succ → P x.succ y → P x.succ y.succ) : ∀ n m : ℕ, P n m
| a, 0 => Ha0 a
@@ -583,11 +580,6 @@ def pincerRecursion {P : ℕ → ℕ → Sort*} (Ha0 : ∀ a : ℕ, P a 0) (H0b
termination_by pincerRecursion Ha0 Hab H n m => n + m
#align nat.pincer_recursion Nat.pincerRecursion
--- Porting note:
--- we can't put this on the definition itself because of
--- https://github.com/leanprover/lean4/issues/1900
-attribute [elab_as_elim] pincerRecursion
-
/-- Recursion starting at a non-zero number: given a map `C k → C (k+1)` for each `k ≥ n`,
there is a map from `C n` to each `C m`, `n ≤ m`. -/
@[elab_as_elim]
Nat.dvd_one
to Data.Nat.Basic
; it should go to Std4;Fin.ofNat_eq_val
to Fin.ofNat''_eq_cast
;@[simp]
lemmas Fin.val_nat_cast
, Fin.nat_cast_self
, and Fin.nat_cast_eq_zero
;@[simp]
to Fin.cast_nat_eq_last
and ZMod.val_nat_cast
;binomial_apply_last
, as the LHS of binomial_apply_self
is no longer in simp normal form.@@ -782,11 +782,14 @@ protected theorem mul_dvd_mul_iff_right {a b c : ℕ} (hc : 0 < c) : a * c ∣ b
exists_congr fun d => by rw [Nat.mul_right_comm, mul_left_inj' hc.ne']
#align nat.mul_dvd_mul_iff_right Nat.mul_dvd_mul_iff_right
+@[simp] -- TODO: move to Std4
+theorem dvd_one {a : ℕ} : a ∣ 1 ↔ a = 1 :=
+ ⟨eq_one_of_dvd_one, fun h ↦ h.symm ▸ Nat.dvd_refl _⟩
+#align nat.dvd_one Nat.dvd_one
+
@[simp]
theorem mod_mod_of_dvd (n : Nat) {m k : Nat} (h : m ∣ k) : n % k % m = n % m := by
- conv =>
- rhs
- rw [← mod_add_div n k]
+ conv_rhs => rw [← mod_add_div n k]
rcases h with ⟨t, rfl⟩
rw [mul_assoc, add_mul_mod_self_left]
#align nat.mod_mod_of_dvd Nat.mod_mod_of_dvd
@@ -741,6 +741,10 @@ theorem mod_succ_eq_iff_lt {a b : ℕ} : a % b.succ = a ↔ a < b.succ :=
mod_eq_iff_lt (succ_ne_zero _)
#align nat.mod_succ_eq_iff_lt Nat.mod_succ_eq_iff_lt
+@[simp]
+theorem mod_succ (n : ℕ) : n % n.succ = n :=
+ Nat.mod_eq_of_lt (Nat.lt_succ_self _)
+
-- Porting note `Nat.div_add_mod` is now in core.
theorem mod_add_div' (m k : ℕ) : m % k + m / k * k = m := by
@@ -716,7 +716,7 @@ theorem div_mul_div_comm {l : ℕ} (hmn : n ∣ m) (hkl : l ∣ k) :
rcases l.eq_zero_or_pos with rfl | hl
· simp
rw [Nat.mul_div_cancel_left _ hn, Nat.mul_div_cancel_left _ hl, mul_assoc n, Nat.mul_left_comm x,
- ←mul_assoc n, Nat.mul_div_cancel_left _ (Nat.mul_pos hn hl)]
+ ← mul_assoc n, Nat.mul_div_cancel_left _ (Nat.mul_pos hn hl)]
#align nat.div_mul_div_comm Nat.div_mul_div_comm
protected theorem div_pow {a b c : ℕ} (h : a ∣ b) : (b / a) ^ c = b ^ c / a ^ c := by
@@ -725,7 +725,7 @@ protected theorem div_pow {a b c : ℕ} (h : a ∣ b) : (b / a) ^ c = b ^ c / a
rcases a.eq_zero_or_pos with rfl | ha
· simp [Nat.zero_pow hc]
refine (Nat.div_eq_of_eq_mul_right (pos_pow_of_pos c ha) ?_).symm
- rw [←Nat.mul_pow, Nat.mul_div_cancel_left' h]
+ rw [← Nat.mul_pow, Nat.mul_div_cancel_left' h]
/-! ### `mod`, `dvd` -/
@@ -811,7 +811,7 @@ theorem mul_dvd_of_dvd_div {a b c : ℕ} (hab : c ∣ b) (h : a ∣ b / c) : c *
let ⟨d, hd⟩ := h1
have h3 : b = a * d * c := Nat.eq_mul_of_div_eq_left hab hd
-- Porting note: was `cc`
- show ∃ d, b = c * a * d from ⟨d, by rwa [mul_comm, ←mul_assoc] at h3⟩
+ show ∃ d, b = c * a * d from ⟨d, by rwa [mul_comm, ← mul_assoc] at h3⟩
#align nat.mul_dvd_of_dvd_div Nat.mul_dvd_of_dvd_div
theorem eq_of_dvd_of_div_eq_one {a b : ℕ} (w : a ∣ b) (h : b / a = 1) : a = b := by
Notably leanprover/std4#366 changed the definition of testBit
(to something equivalent) when upstreaming it, which broke a handful of proofs.
Other conflicting changes in Std, resolved for now by priming the mathlib name:
Std.BitVec.adc
: the type was changed from BitVec (n + 1)
to Bool × BitVec w
Nat.mul_add_mod
: the type was changed from (a * b + c) % b = c % b
to (b * a + c) % b = c % b
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Alex Keizer <alex@keizer.dev> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
@@ -838,11 +838,12 @@ theorem lt_mul_div_succ (m : ℕ) {n : ℕ} (n0 : 0 < n) : m < n * (m / n + 1) :
exact lt_succ_self _
#align nat.lt_mul_div_succ Nat.lt_mul_div_succ
-theorem mul_add_mod (a b c : ℕ) : (a * b + c) % b = c % b := by simp [Nat.add_mod]
-#align nat.mul_add_mod Nat.mul_add_mod
+-- TODO: Std4 claimed this name but flipped the order of multiplication
+theorem mul_add_mod' (a b c : ℕ) : (a * b + c) % b = c % b := by rw [mul_comm, Nat.mul_add_mod]
+#align nat.mul_add_mod Nat.mul_add_mod'
theorem mul_add_mod_of_lt {a b c : ℕ} (h : c < b) : (a * b + c) % b = c := by
- rw [Nat.mul_add_mod, Nat.mod_eq_of_lt h]
+ rw [Nat.mul_add_mod', Nat.mod_eq_of_lt h]
#align nat.mul_add_mod_of_lt Nat.mul_add_mod_of_lt
theorem pred_eq_self_iff {n : ℕ} : n.pred = n ↔ n = 0 := by
@@ -288,11 +288,11 @@ theorem exists_eq_add_of_lt (h : m < n) : ∃ k : ℕ, n = m + k + 1 :=
/-! ### `pred` -/
@[simp]
-theorem add_succ_sub_one (n m : ℕ) : n + succ m - 1 = n + m := by rw [add_succ, succ_sub_one]
+theorem add_succ_sub_one (n m : ℕ) : n + succ m - 1 = n + m := by rw [add_succ, Nat.add_one_sub_one]
#align nat.add_succ_sub_one Nat.add_succ_sub_one
@[simp]
-theorem succ_add_sub_one (n m : ℕ) : succ n + m - 1 = n + m := by rw [succ_add, succ_sub_one]
+theorem succ_add_sub_one (n m : ℕ) : succ n + m - 1 = n + m := by rw [succ_add, Nat.add_one_sub_one]
#align nat.succ_add_sub_one Nat.succ_add_sub_one
theorem pred_eq_sub_one (n : ℕ) : pred n = n - 1 :=
Adds the missing lemma Nat.div_pow, which seemed to be missing (at least, exact?%
couldn't find it with all of Mathlib imported). Also moves div_mul_div_comm
higher in the hierarchy (and golf) because it doesn't need the ordered semiring instance, cf the docstring of Data/Nat/Order/Basic
.
Co-authored-by: Bhavik Mehta <bm489@cam.ac.uk>
@@ -707,6 +707,26 @@ protected theorem div_left_inj {a b d : ℕ} (hda : d ∣ a) (hdb : d ∣ b) : a
rw [← Nat.mul_div_cancel' hda, ← Nat.mul_div_cancel' hdb, h]
#align nat.div_left_inj Nat.div_left_inj
+theorem div_mul_div_comm {l : ℕ} (hmn : n ∣ m) (hkl : l ∣ k) :
+ (m / n) * (k / l) = (m * k) / (n * l) := by
+ obtain ⟨x, rfl⟩ := hmn
+ obtain ⟨y, rfl⟩ := hkl
+ rcases n.eq_zero_or_pos with rfl | hn
+ · simp
+ rcases l.eq_zero_or_pos with rfl | hl
+ · simp
+ rw [Nat.mul_div_cancel_left _ hn, Nat.mul_div_cancel_left _ hl, mul_assoc n, Nat.mul_left_comm x,
+ ←mul_assoc n, Nat.mul_div_cancel_left _ (Nat.mul_pos hn hl)]
+#align nat.div_mul_div_comm Nat.div_mul_div_comm
+
+protected theorem div_pow {a b c : ℕ} (h : a ∣ b) : (b / a) ^ c = b ^ c / a ^ c := by
+ rcases c.eq_zero_or_pos with rfl | hc
+ · simp
+ rcases a.eq_zero_or_pos with rfl | ha
+ · simp [Nat.zero_pow hc]
+ refine (Nat.div_eq_of_eq_mul_right (pos_pow_of_pos c ha) ?_).symm
+ rw [←Nat.mul_pow, Nat.mul_div_cancel_left' h]
+
/-! ### `mod`, `dvd` -/
@@ -165,7 +165,6 @@ theorem eq_of_le_of_lt_succ {n m : ℕ} (h₁ : n ≤ m) (h₂ : m < n + 1) : m
-- Moved to Std
#align nat.one_add Nat.one_add
-@[simp]
theorem succ_pos' {n : ℕ} : 0 < succ n :=
succ_pos n
#align nat.succ_pos' Nat.succ_pos'
@@ -192,13 +192,7 @@ theorem one_lt_succ_succ (n : ℕ) : 1 < n.succ.succ :=
-- Porting note: Nat.succ_le_succ_iff is in Std
-theorem max_succ_succ {m n : ℕ} : max (succ m) (succ n) = succ (max m n) := by
- by_cases h1 : m ≤ n
- rw [max_eq_right h1, max_eq_right (succ_le_succ h1)]
- · rw [not_le] at h1
- have h2 := le_of_lt h1
- rw [max_eq_left h2, max_eq_left (succ_le_succ h2)]
-#align nat.max_succ_succ Nat.max_succ_succ
+#align nat.max_succ_succ Nat.succ_max_succ
theorem not_succ_lt_self {n : ℕ} : ¬succ n < n :=
not_lt_of_ge (Nat.le_succ _)
match
with Decidable
. (#7232)
This works around leanprover/lean4#2552 - fix found by @b-mehta. I changed the Nat
instance where the issue was found, and some List
instances in hope it fixes mysterious slowdowns with Finset
decidability. Any more instances changed would probably be good.
@@ -934,23 +934,24 @@ end FindGreatest
/-! ### decidability of predicates -/
+-- To work around lean4#2552, we use `match` instead of `if/casesOn` with decidable instances.
instance decidableBallLT :
- ∀ (n : Nat) (P : ∀ k < n, Prop) [∀ n h, Decidable (P n h)], Decidable (∀ n h, P n h)
-| 0, P, _ => isTrue fun n h => by cases h
-| (n+1), P, H => by
- cases' decidableBallLT n fun k h => P k (lt_succ_of_lt h) with h h
- · refine' isFalse (mt _ h)
- intro hn k h
- apply hn
- by_cases p : P n (lt_succ_self n)
- · exact
- isTrue fun k h' =>
- (le_of_lt_succ h').lt_or_eq_dec.elim (h _) fun e =>
- match k, e, h' with
- | _, rfl, _ => p
- · exact isFalse (mt (fun hn => hn _ _) p)
+ ∀ (n : Nat) (P : ∀ k, k < n → Prop) [∀ n h, Decidable (P n h)], Decidable (∀ n h, P n h)
+| 0, _, _ => isTrue fun _ => (by cases ·)
+| (n+1), P, H =>
+ match decidableBallLT n (P · <| lt_succ_of_lt ·) with
+ | isFalse h => isFalse (h fun _ _ => · _ _)
+ | isTrue h =>
+ match H n Nat.le.refl with
+ | isFalse p => isFalse (p <| · _ _)
+ | isTrue p => isTrue fun _ h' => (Nat.le_of_lt_succ h').lt_or_eq_dec.elim (h _) (· ▸ p)
#align nat.decidable_ball_lt Nat.decidableBallLT
+-- To verify we don't have a regression on the speed, we put a difficult example.
+-- any regression should take a huge amount of heartbeats -- we are currently at 187621.
+-- For reference, the instance using `casesOn` took 44544 for 4; this one takes 1299 for 4.
+example : ∀ a, a < 25 → ∀ b, b < 25 → ∀ c, c < 25 → a ^ 2 + b ^ 2 + c ^ 2 ≠ 7 := by decide
+
instance decidableForallFin {n : ℕ} (P : Fin n → Prop) [DecidablePred P] :
Decidable (∀ i, P i) :=
decidable_of_iff (∀ k h, P ⟨k, h⟩) ⟨fun a ⟨k, h⟩ => a k h, fun a k h => a ⟨k, h⟩⟩
@@ -376,6 +376,20 @@ theorem lt_succ_iff_lt_or_eq {n i : ℕ} : n < i.succ ↔ n < i ∨ n = i :=
lt_succ_iff.trans Decidable.le_iff_lt_or_eq
#align nat.lt_succ_iff_lt_or_eq Nat.lt_succ_iff_lt_or_eq
+set_option push_neg.use_distrib true in
+/-- The product of two natural numbers is greater than 1 if and only if
+ at least one of them is greater than 1 and both are positive. -/
+lemma one_lt_mul_iff : 1 < m * n ↔ 0 < m ∧ 0 < n ∧ (1 < m ∨ 1 < n) := by
+ constructor <;> intro h
+ · by_contra h'; push_neg at h'; simp_rw [Nat.le_zero] at h'
+ obtain rfl | rfl | h' := h'
+ · simp at h
+ · simp at h
+ · exact (Nat.mul_le_mul h'.1 h'.2).not_lt h
+ · obtain hm | hn := h.2.2
+ · exact Nat.mul_lt_mul hm h.2.1 Nat.zero_lt_one
+ · exact Nat.mul_lt_mul' h.1 hn h.1
+
/-!
### Recursion and induction principles
@@ -327,6 +327,21 @@ theorem le_of_pred_lt {m n : ℕ} : pred m < n → m ≤ n :=
| _ + 1 => id
#align nat.le_of_pred_lt Nat.le_of_pred_lt
+theorem self_add_sub_one (n : ℕ) : n + (n - 1) = 2 * n - 1 := by
+ cases n
+ · rfl
+ · rw [two_mul]
+ convert (add_succ_sub_one (Nat.succ _) _).symm
+
+theorem sub_one_add_self (n : ℕ) : (n - 1) + n = 2 * n - 1 :=
+ add_comm _ n ▸ self_add_sub_one n
+
+theorem self_add_pred (n : ℕ) : n + pred n = (2 * n).pred :=
+ self_add_sub_one n
+
+theorem pred_add_self (n : ℕ) : pred n + n = (2 * n).pred :=
+ sub_one_add_self n
+
/-- This ensures that `simp` succeeds on `pred (n + 1) = n`. -/
@[simp]
theorem pred_one_add (n : ℕ) : pred (1 + n) = n := by rw [add_comm, add_one, Nat.pred_succ]
I know that this is contrary to what we've done previously, but:
norm_num
/ ring
/ linarith
)(Oh
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -7,6 +7,8 @@ import Mathlib.Init.Data.Nat.Lemmas
import Mathlib.Order.Basic
import Mathlib.Algebra.GroupWithZero.Defs
import Mathlib.Algebra.Ring.Defs
+import Mathlib.Tactic.PushNeg
+import Mathlib.Tactic.Use
#align_import data.nat.basic from "leanprover-community/mathlib"@"bd835ef554f37ef9b804f0903089211f89cb370b"
@@ -3,6 +3,7 @@ Copyright (c) 2014 Floris van Doorn (c) 2016 Microsoft Corporation. All rights r
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
-/
+import Mathlib.Init.Data.Nat.Lemmas
import Mathlib.Order.Basic
import Mathlib.Algebra.GroupWithZero.Defs
import Mathlib.Algebra.Ring.Defs
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
-/
import Mathlib.Order.Basic
-import Mathlib.Algebra.GroupWithZero.Basic
+import Mathlib.Algebra.GroupWithZero.Defs
import Mathlib.Algebra.Ring.Defs
#align_import data.nat.basic from "leanprover-community/mathlib"@"bd835ef554f37ef9b804f0903089211f89cb370b"
@@ -286,7 +286,7 @@ theorem exists_eq_add_of_le' (h : m ≤ n) : ∃ k : ℕ, n = k + m :=
#align nat.exists_eq_add_of_le' Nat.exists_eq_add_of_le'
theorem exists_eq_add_of_lt (h : m < n) : ∃ k : ℕ, n = m + k + 1 :=
- ⟨n - (m + 1), by rw [add_right_comm, add_sub_of_le h]⟩
+ ⟨n - (m + 1), by rw [Nat.add_right_comm, add_sub_of_le h]⟩
#align nat.exists_eq_add_of_lt Nat.exists_eq_add_of_lt
/-! ### `pred` -/
@@ -730,7 +730,7 @@ protected theorem mul_dvd_mul_iff_left {a b c : ℕ} (ha : 0 < a) : a * b ∣ a
#align nat.mul_dvd_mul_iff_left Nat.mul_dvd_mul_iff_left
protected theorem mul_dvd_mul_iff_right {a b c : ℕ} (hc : 0 < c) : a * c ∣ b * c ↔ a ∣ b :=
- exists_congr fun d => by rw [mul_right_comm, mul_left_inj' hc.ne']
+ exists_congr fun d => by rw [Nat.mul_right_comm, mul_left_inj' hc.ne']
#align nat.mul_dvd_mul_iff_right Nat.mul_dvd_mul_iff_right
@[simp]
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -460,11 +460,11 @@ protected def strongRec' {p : ℕ → Sort u} (H : ∀ n, (∀ m, m < n → p m)
/-- Recursion principle based on `<` applied to some natural number. -/
@[elab_as_elim]
-def strongRecOn' {P : ℕ → Sort _} (n : ℕ) (h : ∀ n, (∀ m, m < n → P m) → P n) : P n :=
+def strongRecOn' {P : ℕ → Sort*} (n : ℕ) (h : ∀ n, (∀ m, m < n → P m) → P n) : P n :=
Nat.strongRec' h n
#align nat.strong_rec_on' Nat.strongRecOn'
-theorem strongRecOn'_beta {P : ℕ → Sort _} {h} {n : ℕ} :
+theorem strongRecOn'_beta {P : ℕ → Sort*} {h} {n : ℕ} :
(strongRecOn' n h : P n) = h n fun m _ => (strongRecOn' m h : P m) := by
simp only [strongRecOn']
rw [Nat.strongRec']
@@ -487,20 +487,20 @@ theorem le_induction {m} {P : ∀ (n : Nat) (_ : m ≤ n), Prop} (base : P m le_
Also works for functions to `Sort*`. For a version assuming only the assumption for `k < n`, see
`decreasing_induction'`. -/
@[elab_as_elim]
-def decreasingInduction {P : ℕ → Sort _} (h : ∀ n, P (n + 1) → P n) {m n : ℕ} (mn : m ≤ n)
+def decreasingInduction {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {m n : ℕ} (mn : m ≤ n)
(hP : P n) : P m :=
leRecOn mn (fun {k} ih hsk => ih <| h k hsk) (fun h => h) hP
#align nat.decreasing_induction Nat.decreasingInduction
@[simp]
-theorem decreasingInduction_self {P : ℕ → Sort _} (h : ∀ n, P (n + 1) → P n) {n : ℕ} (nn : n ≤ n)
+theorem decreasingInduction_self {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {n : ℕ} (nn : n ≤ n)
(hP : P n) :
(decreasingInduction h nn hP : P n) = hP := by
dsimp only [decreasingInduction]
rw [leRecOn_self]
#align nat.decreasing_induction_self Nat.decreasingInduction_self
-theorem decreasingInduction_succ {P : ℕ → Sort _} (h : ∀ n, P (n + 1) → P n) {m n : ℕ} (mn : m ≤ n)
+theorem decreasingInduction_succ {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {m n : ℕ} (mn : m ≤ n)
(msn : m ≤ n + 1) (hP : P (n + 1)) :
(decreasingInduction h msn hP : P m) = decreasingInduction h mn (h n hP) := by
dsimp only [decreasingInduction]
@@ -508,13 +508,13 @@ theorem decreasingInduction_succ {P : ℕ → Sort _} (h : ∀ n, P (n + 1) →
#align nat.decreasing_induction_succ Nat.decreasingInduction_succ
@[simp]
-theorem decreasingInduction_succ' {P : ℕ → Sort _} (h : ∀ n, P (n + 1) → P n) {m : ℕ}
+theorem decreasingInduction_succ' {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {m : ℕ}
(msm : m ≤ m + 1) (hP : P (m + 1)) : (decreasingInduction h msm hP : P m) = h m hP := by
dsimp only [decreasingInduction]
rw [leRecOn_succ']
#align nat.decreasing_induction_succ' Nat.decreasingInduction_succ'
-theorem decreasingInduction_trans {P : ℕ → Sort _} (h : ∀ n, P (n + 1) → P n) {m n k : ℕ}
+theorem decreasingInduction_trans {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {m n k : ℕ}
(mn : m ≤ n) (nk : n ≤ k) (hP : P k) :
(decreasingInduction h (le_trans mn nk) hP : P m) =
decreasingInduction h mn (decreasingInduction h nk hP) := by
@@ -523,7 +523,7 @@ theorem decreasingInduction_trans {P : ℕ → Sort _} (h : ∀ n, P (n + 1) →
· rw [decreasingInduction_succ h (le_trans mn nk), ih, decreasingInduction_succ]
#align nat.decreasing_induction_trans Nat.decreasingInduction_trans
-theorem decreasingInduction_succ_left {P : ℕ → Sort _} (h : ∀ n, P (n + 1) → P n) {m n : ℕ}
+theorem decreasingInduction_succ_left {P : ℕ → Sort*} (h : ∀ n, P (n + 1) → P n) {m n : ℕ}
(smn : m + 1 ≤ n) (mn : m ≤ n) (hP : P n) :
(decreasingInduction h mn hP : P m) = h m (decreasingInduction h smn hP) := by
rw [Subsingleton.elim mn (le_trans (le_succ m) smn), decreasingInduction_trans,
@@ -535,7 +535,7 @@ theorem decreasingInduction_succ_left {P : ℕ → Sort _} (h : ∀ n, P (n + 1)
strictly below `(a,b)` to `P a b`, then we have `P n m` for all `n m : ℕ`.
Note that for non-`Prop` output it is preferable to use the equation compiler directly if possible,
since this produces equation lemmas. -/
-def strongSubRecursion {P : ℕ → ℕ → Sort _} (H : ∀ a b, (∀ x y, x < a → y < b → P x y) → P a b) :
+def strongSubRecursion {P : ℕ → ℕ → Sort*} (H : ∀ a b, (∀ x y, x < a → y < b → P x y) → P a b) :
∀ n m : ℕ, P n m
| n, m => H n m fun x y _ _ => strongSubRecursion H x y
#align nat.strong_sub_recursion Nat.strongSubRecursion
@@ -550,7 +550,7 @@ and for any `x y : ℕ` we can extend `P` from `(x,y+1)` and `(x+1,y)` to `(x+1,
then we have `P n m` for all `n m : ℕ`.
Note that for non-`Prop` output it is preferable to use the equation compiler directly if possible,
since this produces equation lemmas. -/
-def pincerRecursion {P : ℕ → ℕ → Sort _} (Ha0 : ∀ a : ℕ, P a 0) (H0b : ∀ b : ℕ, P 0 b)
+def pincerRecursion {P : ℕ → ℕ → Sort*} (Ha0 : ∀ a : ℕ, P a 0) (H0b : ∀ b : ℕ, P 0 b)
(H : ∀ x y : ℕ, P x y.succ → P x.succ y → P x.succ y.succ) : ∀ n m : ℕ, P n m
| a, 0 => Ha0 a
| 0, b => H0b b
@@ -566,7 +566,7 @@ attribute [elab_as_elim] pincerRecursion
/-- Recursion starting at a non-zero number: given a map `C k → C (k+1)` for each `k ≥ n`,
there is a map from `C n` to each `C m`, `n ≤ m`. -/
@[elab_as_elim]
-def leRecOn' {C : ℕ → Sort _} {n : ℕ} :
+def leRecOn' {C : ℕ → Sort*} {n : ℕ} :
∀ {m : ℕ}, n ≤ m → (∀ ⦃k⦄, n ≤ k → C k → C (k + 1)) → C n → C m
| 0, H, _, x => Eq.recOn (Nat.eq_zero_of_le_zero H) x
| m + 1, H, next, x =>
@@ -577,7 +577,7 @@ def leRecOn' {C : ℕ → Sort _} {n : ℕ} :
/-- Decreasing induction: if `P (k+1)` implies `P k` for all `m ≤ k < n`, then `P n` implies `P m`.
Also works for functions to `Sort*`. Weakens the assumptions of `decreasing_induction`. -/
@[elab_as_elim]
-def decreasingInduction' {P : ℕ → Sort _} {m n : ℕ} (h : ∀ k < n, m ≤ k → P (k + 1) → P k)
+def decreasingInduction' {P : ℕ → Sort*} {m n : ℕ} (h : ∀ k < n, m ≤ k → P (k + 1) → P k)
(mn : m ≤ n) (hP : P n) :
P m := by
revert h hP
Various adaptations to changes when Fin
API was moved to Std. One notable change is that many lemmas are now stated in terms of i ≠ 0
(for i : Fin n
) rather then i.1 ≠ 0
, and as a consequence many Fin.vne_of_ne
applications have been added or removed, mostly removed.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Wojciech Nawrocki <wjnawrocki@protonmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
@@ -234,8 +234,6 @@ theorem of_le_succ {n m : ℕ} (H : n ≤ m.succ) : n ≤ m ∨ n = m.succ :=
H.lt_or_eq_dec.imp le_of_lt_succ id
#align nat.of_le_succ Nat.of_le_succ
-theorem succ_lt_succ_iff {m n : ℕ} : succ m < succ n ↔ m < n :=
- ⟨lt_of_succ_lt_succ, succ_lt_succ⟩
#align nat.succ_lt_succ_iff Nat.succ_lt_succ_iff
theorem div_le_iff_le_mul_add_pred {m n k : ℕ} (n0 : 0 < n) : m / n ≤ k ↔ m ≤ n * k + (n - 1) := by
@@ -2,16 +2,13 @@
Copyright (c) 2014 Floris van Doorn (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
-
-! This file was ported from Lean 3 source module data.nat.basic
-! leanprover-community/mathlib commit bd835ef554f37ef9b804f0903089211f89cb370b
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Order.Basic
import Mathlib.Algebra.GroupWithZero.Basic
import Mathlib.Algebra.Ring.Defs
+#align_import data.nat.basic from "leanprover-community/mathlib"@"bd835ef554f37ef9b804f0903089211f89cb370b"
+
/-!
# Basic operations on the natural numbers
@@ -140,7 +140,7 @@ theorem and_forall_succ {p : ℕ → Prop} : (p 0 ∧ ∀ n, p (n + 1)) ↔ ∀
theorem or_exists_succ {p : ℕ → Prop} : (p 0 ∨ ∃ n, p (n + 1)) ↔ ∃ n, p n :=
⟨fun h => h.elim (fun h0 => ⟨0, h0⟩) fun ⟨n, hn⟩ => ⟨n + 1, hn⟩, by
rintro ⟨_ | n, hn⟩
- exacts[Or.inl hn, Or.inr ⟨n, hn⟩]⟩
+ exacts [Or.inl hn, Or.inr ⟨n, hn⟩]⟩
#align nat.or_exists_succ Nat.or_exists_succ
/-! ### `succ` -/
@@ -862,7 +862,7 @@ theorem find_comp_succ (h₁ : ∃ n, p n) (h₂ : ∃ n, p (n + 1)) (h0 : ¬p 0
Nat.find h₁ = Nat.find h₂ + 1 := by
refine' (find_eq_iff _).2 ⟨Nat.find_spec h₂, fun n hn => _⟩
cases' n with n
- exacts[h0, @Nat.find_min (fun n => p (n + 1)) _ h₂ _ (succ_lt_succ_iff.1 hn)]
+ exacts [h0, @Nat.find_min (fun n => p (n + 1)) _ h₂ _ (succ_lt_succ_iff.1 hn)]
#align nat.find_comp_succ Nat.find_comp_succ
end Find
This makes a mathlib4 version of mathlib3's tactic.basic
, now called Mathlib.Tactic.Common
, which imports all tactics which do not have significant theory requirements, and then is imported all across the base of the hierarchy.
This ensures that all common tactics are available nearly everywhere in the library, rather than having to be imported one-by-one as you need them.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -11,9 +11,6 @@ Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
import Mathlib.Order.Basic
import Mathlib.Algebra.GroupWithZero.Basic
import Mathlib.Algebra.Ring.Defs
-import Mathlib.Tactic.Convert
-import Mathlib.Tactic.PushNeg
-import Mathlib.Tactic.Use
/-!
# Basic operations on the natural numbers
Nat.rec_zero
and Nat.rec_add_one
(#3839)
theorem rec_zero {C : ℕ → Sort u} (h0 : C 0) (h : ∀ n, C n → C (n + 1)) :
(Nat.rec h0 h : ∀ n, C n) 0 = h0 :=
rfl
The above theorem is elaborated as follow:
theorem rec_zero {C : ℕ → Sort u} (h0 : C 0) (h : ∀ n, C n → C (n + 1)) :
(fun n => Nat.rec h0 h n) 0 = h0 :=
rfl
This form of the theorem isn't generic. This PR fixes this problem.
Co-authored-by: Pol_tta <52843868+Komyyy@users.noreply.github.com>
@@ -373,16 +373,18 @@ This section is here due to dependencies -- the lemmas here require some of the
proved above, and some of the results in later sections depend on the definitions in this section.
-/
+-- Porting note: The type ascriptions of these two theorems need to be changed,
+-- as mathport wrote a lambda that wasn't there in mathlib3, that prevents `simp` applying them.
@[simp]
theorem rec_zero {C : ℕ → Sort u} (h0 : C 0) (h : ∀ n, C n → C (n + 1)) :
- (Nat.rec h0 h : ∀ n, C n) 0 = h0 :=
+ Nat.rec h0 h 0 = h0 :=
rfl
#align nat.rec_zero Nat.rec_zero
@[simp]
theorem rec_add_one {C : ℕ → Sort u} (h0 : C 0) (h : ∀ n, C n → C (n + 1)) (n : ℕ) :
- (Nat.rec h0 h : ∀ n, C n) (n + 1) = h n ((Nat.rec h0 h : ∀ n, C n) n) :=
+ Nat.rec h0 h (n + 1) = h n (Nat.rec h0 h n) :=
rfl
#align nat.rec_add_one Nat.rec_add_one
This PR fixes two things:
align
statements for definitions and theorems and instances that are separated by two newlines from the relevant declaration (s/\n\n#align/\n#align
). This is often seen in the mathport output after ending calc
blocks.#align
statements. (This was needed for a script I wrote for #3630.)@@ -201,7 +201,6 @@ theorem max_succ_succ {m n : ℕ} : max (succ m) (succ n) = succ (max m n) := by
· rw [not_le] at h1
have h2 := le_of_lt h1
rw [max_eq_left h2, max_eq_left (succ_le_succ h2)]
-
#align nat.max_succ_succ Nat.max_succ_succ
theorem not_succ_lt_self {n : ℕ} : ¬succ n < n :=
@@ -595,7 +594,6 @@ def decreasingInduction' {P : ℕ → Sort _} {m n : ℕ} (h : ∀ k < n, m ≤
· exact h n (lt_succ_self n) mn hP
· intro _ hP
exact hP
-
#align nat.decreasing_induction' Nat.decreasingInduction'
/-! ### `div` -/
@@ -823,10 +821,8 @@ theorem find_eq_iff (h : ∃ n : ℕ, p n) : Nat.find h = m ↔ p m ∧ ∀ n <
constructor
· rintro rfl
exact ⟨Nat.find_spec h, fun _ => Nat.find_min h⟩
-
· rintro ⟨hm, hlt⟩
exact le_antisymm (Nat.find_min' h hm) (not_lt.1 <| imp_not_comm.1 (hlt _) <| Nat.find_spec h)
-
#align nat.find_eq_iff Nat.find_eq_iff
@[simp]
@@ -927,7 +923,6 @@ instance decidableBallLT :
match k, e, h' with
| _, rfl, _ => p
· exact isFalse (mt (fun hn => hn _ _) p)
-
#align nat.decidable_ball_lt Nat.decidableBallLT
instance decidableForallFin {n : ℕ} (P : Fin n → Prop) [DecidablePred P] :
Also fixes a lemma statement to use %
notation like it did in Lean3
Co-authored-by: Jon Eugster <eugster.jon@gmail.com>
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
! This file was ported from Lean 3 source module data.nat.basic
-! leanprover-community/mathlib commit 2609ad04e2b77aceb2200e273daf11cc65856fda
+! leanprover-community/mathlib commit bd835ef554f37ef9b804f0903089211f89cb370b
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -716,6 +716,7 @@ theorem div_add_mod' (m k : ℕ) : m / k * k + m % k = m := by
exact div_add_mod _ _
#align nat.div_add_mod' Nat.div_add_mod'
+/-- See also `Nat.divModEquiv` for a similar statement as an `Equiv`. -/
protected theorem div_mod_unique {n k m d : ℕ} (h : 0 < k) :
n / k = d ∧ n % k = m ↔ m + k * d = n ∧ m < k :=
⟨fun ⟨e₁, e₂⟩ => e₁ ▸ e₂ ▸ ⟨mod_add_div _ _, mod_lt _ h⟩, fun ⟨h₁, h₂⟩ =>
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
! This file was ported from Lean 3 source module data.nat.basic
-! leanprover-community/mathlib commit 2f3994e1b117b1e1da49bcfb67334f33460c3ce4
+! leanprover-community/mathlib commit 2609ad04e2b77aceb2200e273daf11cc65856fda
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
Nat.exists_eq_add_of_le'
(#1662)
Also golf 2 proofs. This is a forward-port of leanprover-community/mathlib#18203.
@@ -273,7 +273,6 @@ theorem exists_lt_succ {P : ℕ → Prop} {n : ℕ} : (∃ m < n + 1, P m) ↔ (
/-! ### `add` -/
-
-- Sometimes a bare `Nat.add` or similar appears as a consequence of unfolding
-- during pattern matching. These lemmas package them back up as typeclass
-- mediated operations.
@@ -287,25 +286,20 @@ theorem mul_def {a b : ℕ} : Nat.mul a b = a * b :=
rfl
#align nat.mul_def Nat.mul_def
-theorem exists_eq_add_of_le : ∀ {m n : ℕ}, m ≤ n → ∃ k : ℕ, n = m + k
- | 0, 0, _ => ⟨0, by simp⟩
- | 0, n + 1, h => ⟨n + 1, by simp⟩
- | m + 1, n + 1, h =>
- let ⟨k, hk⟩ := exists_eq_add_of_le (Nat.le_of_succ_le_succ h)
- ⟨k, by simp [hk, add_comm, add_left_comm]; rfl⟩
+theorem exists_eq_add_of_le (h : m ≤ n) : ∃ k : ℕ, n = m + k :=
+ ⟨n - m, (add_sub_of_le h).symm⟩
#align nat.exists_eq_add_of_le Nat.exists_eq_add_of_le
-theorem exists_eq_add_of_lt : ∀ {m n : ℕ}, m < n → ∃ k : ℕ, n = m + k + 1
- | 0, 0, h => False.elim <| lt_irrefl _ h
- | 0, n + 1, _ => ⟨n, by simp⟩
- | m + 1, n + 1, h =>
- let ⟨k, hk⟩ := exists_eq_add_of_le (Nat.le_of_succ_le_succ h)
- ⟨k, by simp [hk]⟩
+theorem exists_eq_add_of_le' (h : m ≤ n) : ∃ k : ℕ, n = k + m :=
+ ⟨n - m, (Nat.sub_add_cancel h).symm⟩
+#align nat.exists_eq_add_of_le' Nat.exists_eq_add_of_le'
+
+theorem exists_eq_add_of_lt (h : m < n) : ∃ k : ℕ, n = m + k + 1 :=
+ ⟨n - (m + 1), by rw [add_right_comm, add_sub_of_le h]⟩
#align nat.exists_eq_add_of_lt Nat.exists_eq_add_of_lt
/-! ### `pred` -/
-
@[simp]
theorem add_succ_sub_one (n m : ℕ) : n + succ m - 1 = n + m := by rw [add_succ, succ_sub_one]
#align nat.add_succ_sub_one Nat.add_succ_sub_one
@@ -151,7 +151,7 @@ theorem or_exists_succ {p : ℕ → Prop} : (p 0 ∨ ∃ n, p (n + 1)) ↔ ∃ n
theorem _root_.LT.lt.nat_succ_le {n m : ℕ} (h : n < m) : succ n ≤ m :=
succ_le_of_lt h
-#align nat._root_.has_lt.lt.nat_succ_le LT.lt.nat_succ_le
+#align has_lt.lt.nat_succ_le LT.lt.nat_succ_le
-- Moved to Std
#align nat.succ_eq_one_add Nat.succ_eq_one_add
The line (line 559)
attribute [elab_as_elim] strongSubRecursion
has been copy-pasted a couple of line below (line 577) but someone forgot to change the name of the result.
@@ -574,7 +574,7 @@ termination_by pincerRecursion Ha0 Hab H n m => n + m
-- Porting note:
-- we can't put this on the definition itself because of
-- https://github.com/leanprover/lean4/issues/1900
-attribute [elab_as_elim] strongSubRecursion
+attribute [elab_as_elim] pincerRecursion
/-- Recursion starting at a non-zero number: given a map `C k → C (k+1)` for each `k ≥ n`,
there is a map from `C n` to each `C m`, `n ≤ m`. -/
@@ -483,14 +483,17 @@ theorem strongRecOn'_beta {P : ℕ → Sort _} {h} {n : ℕ} :
rw [Nat.strongRec']
#align nat.strong_rec_on_beta' Nat.strongRecOn'_beta
-/-- Induction principle starting at a non-zero number. For maps to a `Sort*` see `le_rec_on`. -/
+/-- Induction principle starting at a non-zero number. For maps to a `Sort*` see `le_rec_on`.
+To use in an induction proof, the syntax is `induction n, hn using Nat.le_induction` (or the same
+for `induction'`). -/
@[elab_as_elim]
-theorem le_induction {P : Nat → Prop} {m} (h0 : P m) (h1 : ∀ n, m ≤ n → P n → P (n + 1)) :
- ∀ n, m ≤ n → P n := by
+theorem le_induction {m} {P : ∀ (n : Nat) (_ : m ≤ n), Prop} (base : P m le_rfl)
+ (succ : ∀ (n : Nat) (hn : m ≤ n), P n hn → P (n + 1) (hn.trans <| Nat.le_succ _)) :
+ ∀ (n : Nat) (hn : m ≤ n), P n hn := by
apply Nat.le.rec
- · exact h0
+ · exact base
· intros n hn
- apply h1 n hn
+ apply succ n hn
#align nat.le_induction Nat.le_induction
/-- Decreasing induction: if `P (k+1)` implies `P k`, then `P n` implies `P m` for all `m ≤ n`.
@@ -28,7 +28,7 @@ This file contains:
* `strong_rec'`: recursion based on strong inequalities
- decidability instances on predicates about the natural numbers
-Many theorems that used to live in this file have been moved to `data.nat.order`,
+Many theorems that used to live in this file have been moved to `Data.Nat.Order`,
so that this file requires fewer imports.
For each section here there is a corresponding section in that file with additional results.
It may be possible to move some of these results here, by tweaking their proofs.
@@ -219,7 +219,7 @@ theorem succ_le_iff {m n : ℕ} : succ m ≤ n ↔ m < n :=
theorem lt_iff_add_one_le {m n : ℕ} : m < n ↔ m + 1 ≤ n := by rw [succ_le_iff]
#align nat.lt_iff_add_one_le Nat.lt_iff_add_one_le
--- Just a restatement of `nat.lt_succ_iff` using `+1`.
+-- Just a restatement of `Nat.lt_succ_iff` using `+1`.
theorem lt_add_one_iff {a b : ℕ} : a < b + 1 ↔ a ≤ b :=
lt_succ_iff
#align nat.lt_add_one_iff Nat.lt_add_one_iff
@@ -274,7 +274,7 @@ theorem exists_lt_succ {P : ℕ → Prop} {n : ℕ} : (∃ m < n + 1, P m) ↔ (
/-! ### `add` -/
--- Sometimes a bare `nat.add` or similar appears as a consequence of unfolding
+-- Sometimes a bare `Nat.add` or similar appears as a consequence of unfolding
-- during pattern matching. These lemmas package them back up as typeclass
-- mediated operations.
@[simp]
@@ -605,7 +605,7 @@ def decreasingInduction' {P : ℕ → Sort _} {m n : ℕ} (h : ∀ k < n, m ≤
attribute [simp] Nat.div_self
-/-- A version of `nat.div_lt_self` using successors, rather than additional hypotheses. -/
+/-- A version of `Nat.div_lt_self` using successors, rather than additional hypotheses. -/
theorem div_lt_self' (n b : ℕ) : (n + 1) / (b + 2) < n + 1 :=
Nat.div_lt_self (Nat.succ_pos n) (Nat.succ_lt_succ (Nat.succ_pos _))
#align nat.div_lt_self' Nat.div_lt_self'
@@ -914,11 +914,11 @@ end FindGreatest
/-! ### decidability of predicates -/
-instance decidableBallLt :
+instance decidableBallLT :
∀ (n : Nat) (P : ∀ k < n, Prop) [∀ n h, Decidable (P n h)], Decidable (∀ n h, P n h)
| 0, P, _ => isTrue fun n h => by cases h
| (n+1), P, H => by
- cases' decidableBallLt n fun k h => P k (lt_succ_of_lt h) with h h
+ cases' decidableBallLT n fun k h => P k (lt_succ_of_lt h) with h h
· refine' isFalse (mt _ h)
intro hn k h
apply hn
@@ -930,7 +930,7 @@ instance decidableBallLt :
| _, rfl, _ => p
· exact isFalse (mt (fun hn => hn _ _) p)
-#align nat.decidable_ball_lt Nat.decidableBallLt
+#align nat.decidable_ball_lt Nat.decidableBallLT
instance decidableForallFin {n : ℕ} (P : Fin n → Prop) [DecidablePred P] :
Decidable (∀ i, P i) :=
@@ -943,13 +943,13 @@ instance decidableBallLe (n : ℕ) (P : ∀ k ≤ n, Prop) [∀ n h, Decidable (
⟨fun a k h => a k (lt_succ_of_le h), fun a k _ => a k _⟩
#align nat.decidable_ball_le Nat.decidableBallLe
-instance decidableExistsLt {P : ℕ → Prop} [h : DecidablePred P] :
+instance decidableExistsLT {P : ℕ → Prop} [h : DecidablePred P] :
DecidablePred fun n => ∃ m : ℕ, m < n ∧ P m
| 0 => isFalse (by simp)
| n + 1 =>
- @decidable_of_decidable_of_iff _ _ (@instDecidableOr _ _ (decidableExistsLt n) (h n))
+ @decidable_of_decidable_of_iff _ _ (@instDecidableOr _ _ (decidableExistsLT n) (h n))
(by simp only [lt_succ_iff_lt_or_eq, or_and_right, exists_or, exists_eq_left]; apply Iff.refl)
-#align nat.decidable_exists_lt Nat.decidableExistsLt
+#align nat.decidable_exists_lt Nat.decidableExistsLT
instance decidableExistsLe {P : ℕ → Prop} [DecidablePred P] :
DecidablePred fun n => ∃ m : ℕ, m ≤ n ∧ P m :=
Is*CancelMulZero
(#1137)
This is a Lean 4 version of leanprover-community/mathlib#17963
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
! This file was ported from Lean 3 source module data.nat.basic
-! leanprover-community/mathlib commit 70d50ecfd4900dd6d328da39ab7ebd516abe4025
+! leanprover-community/mathlib commit 2f3994e1b117b1e1da49bcfb67334f33460c3ce4
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -116,9 +116,7 @@ protected theorem nsmul_eq_mul (m n : ℕ) : m • n = m * n :=
instance cancelCommMonoidWithZero : CancelCommMonoidWithZero ℕ :=
{ (inferInstance : CommMonoidWithZero ℕ) with
mul_left_cancel_of_ne_zero :=
- fun {_ _ _} h1 h2 => Nat.eq_of_mul_eq_mul_left (Nat.pos_of_ne_zero h1) h2,
- mul_right_cancel_of_ne_zero :=
- fun {_ _ _} h1 h2 => Nat.eq_of_mul_eq_mul_right (Nat.pos_of_ne_zero h1) h2 }
+ fun h1 h2 => Nat.eq_of_mul_eq_mul_left (Nat.pos_of_ne_zero h1) h2 }
#align nat.cancel_comm_monoid_with_zero Nat.cancelCommMonoidWithZero
attribute [simp]
@@ -227,7 +227,7 @@ theorem lt_add_one_iff {a b : ℕ} : a < b + 1 ↔ a ≤ b :=
#align nat.lt_add_one_iff Nat.lt_add_one_iff
-- A flipped version of `lt_add_one_iff`.
-theorem lt_one_add_iff {a b : ℕ} : a < 1 + b ↔ a ≤ b := by simp only [add_comm, lt_succ_iff]; rfl
+theorem lt_one_add_iff {a b : ℕ} : a < 1 + b ↔ a ≤ b := by simp only [add_comm, lt_succ_iff]
#align nat.lt_one_add_iff Nat.lt_one_add_iff
-- This is true reflexively, by the definition of `≤` on ℕ,
@@ -236,7 +236,7 @@ theorem add_one_le_iff {a b : ℕ} : a + 1 ≤ b ↔ a < b :=
Iff.refl _
#align nat.add_one_le_iff Nat.add_one_le_iff
-theorem one_add_le_iff {a b : ℕ} : 1 + a ≤ b ↔ a < b := by simp only [add_comm, add_one_le_iff]; rfl
+theorem one_add_le_iff {a b : ℕ} : 1 + a ≤ b ↔ a < b := by simp only [add_comm, add_one_le_iff]
#align nat.one_add_le_iff Nat.one_add_le_iff
theorem of_le_succ {n m : ℕ} (H : n ≤ m.succ) : n ≤ m ∨ n = m.succ :=
@@ -264,7 +264,7 @@ theorem two_lt_of_ne : ∀ {n}, n ≠ 0 → n ≠ 1 → n ≠ 2 → 2 < n
#align nat.two_lt_of_ne Nat.two_lt_of_ne
theorem forall_lt_succ {P : ℕ → Prop} {n : ℕ} : (∀ m < n + 1, P m) ↔ (∀ m < n, P m) ∧ P n := by
- simp only [lt_succ_iff, Decidable.le_iff_eq_or_lt, forall_eq_or_imp, and_comm]; rfl
+ simp only [lt_succ_iff, Decidable.le_iff_eq_or_lt, forall_eq_or_imp, and_comm]
#align nat.forall_lt_succ Nat.forall_lt_succ
theorem exists_lt_succ {P : ℕ → Prop} {n : ℕ} : (∃ m < n + 1, P m) ↔ (∃ m < n, P m) ∨ P n := by
@@ -681,14 +681,7 @@ protected theorem mul_div_cancel_left' {a b : ℕ} (Hd : a ∣ b) : a * (b / a)
rw [mul_comm, Nat.div_mul_cancel Hd]
#align nat.mul_div_cancel_left' Nat.mul_div_cancel_left'
---TODO: Update `nat.mul_div_mul` in the core?
-/-- Alias of `nat.mul_div_mul` -/
-protected theorem mul_div_mul_left (a b : ℕ) {c : ℕ} (hc : 0 < c) : c * a / (c * b) = a / b :=
- Nat.mul_div_mul a b hc
#align nat.mul_div_mul_left Nat.mul_div_mul_left
-
-protected theorem mul_div_mul_right (a b : ℕ) {c : ℕ} (hc : 0 < c) : a * c / (b * c) = a / b := by
- rw [mul_comm, mul_comm b, a.mul_div_mul_left b hc]
#align nat.mul_div_mul_right Nat.mul_div_mul_right
theorem lt_div_mul_add {a b : ℕ} (hb : 0 < b) : a < a / b * b + b := by
@@ -848,17 +841,17 @@ theorem find_lt_iff (h : ∃ n : ℕ, p n) (n : ℕ) : Nat.find h < n ↔ ∃ m
@[simp]
theorem find_le_iff (h : ∃ n : ℕ, p n) (n : ℕ) : Nat.find h ≤ n ↔ ∃ m ≤ n, p m := by
- simp only [exists_prop, ← lt_succ_iff, find_lt_iff]; rfl
+ simp only [exists_prop, ← lt_succ_iff, find_lt_iff]
#align nat.find_le_iff Nat.find_le_iff
@[simp]
theorem le_find_iff (h : ∃ n : ℕ, p n) (n : ℕ) : n ≤ Nat.find h ↔ ∀ m < n, ¬p m := by
- simp_rw [← not_lt, find_lt_iff, not_exists, not_and]; rfl
+ simp_rw [← not_lt, find_lt_iff, not_exists, not_and]
#align nat.le_find_iff Nat.le_find_iff
@[simp]
theorem lt_find_iff (h : ∃ n : ℕ, p n) (n : ℕ) : n < Nat.find h ↔ ∀ m ≤ n, ¬p m := by
- simp only [← succ_le_iff, le_find_iff, succ_le_succ_iff]; rfl
+ simp only [← succ_le_iff, le_find_iff, succ_le_succ_iff]
#align nat.lt_find_iff Nat.lt_find_iff
@[simp]
The script used to do this is included. The yaml file was obtained from https://raw.githubusercontent.com/wiki/leanprover-community/mathlib/mathlib4-port-status.md
@@ -2,6 +2,11 @@
Copyright (c) 2014 Floris van Doorn (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
+
+! This file was ported from Lean 3 source module data.nat.basic
+! leanprover-community/mathlib commit 70d50ecfd4900dd6d328da39ab7ebd516abe4025
+! Please do not edit these lines, except to modify the commit id
+! if you have ported upstream changes.
-/
import Mathlib.Order.Basic
import Mathlib.Algebra.GroupWithZero.Basic
All dependencies are ported!