mathlib documentation

data.​nat.​basic

data.​nat.​basic

Basic operations on the natural numbers

This files has some basic lemmas about natural numbers, definition of the choice function, and extra recursors:

@[instance]

Equations
@[instance]

Equations
theorem nat.​mul_self_le_mul_self {n m : ℕ} :
n ≤ m → n * n ≤ m * m

theorem nat.​mul_self_lt_mul_self {n m : ℕ} :
n < m → n * n < m * m

theorem nat.​mul_self_le_mul_self_iff {n m : ℕ} :
n ≤ m ↔ n * n ≤ m * m

theorem nat.​mul_self_lt_mul_self_iff {n m : ℕ} :
n < m ↔ n * n < m * m

theorem nat.​le_mul_self (n : ℕ) :
n ≤ n * n

theorem nat.​eq_of_mul_eq_mul_right {n m k : ℕ} :
0 < m → n * m = k * m → n = k

@[instance]

Equations
theorem nat.​one_add (n : ℕ) :
1 + n = n.succ

@[simp]
theorem nat.​add_def {a b : ℕ} :
a.add b = a + b

@[simp]
theorem nat.​mul_def {a b : ℕ} :
a.mul b = a * b

@[simp]
theorem nat.​succ_pos' {n : ℕ} :
0 < n.succ

theorem nat.​succ_inj' {n m : ℕ} :
n.succ = m.succ ↔ n = m

theorem nat.​succ_le_succ_iff {m n : ℕ} :
m.succ ≤ n.succ ↔ m ≤ n

theorem nat.​zero_max {m : ℕ} :
max 0 m = m

theorem nat.​max_succ_succ {m n : ℕ} :
max m.succ n.succ = (max m n).succ

theorem nat.​not_succ_lt_self {n : ℕ} :
¬n.succ < n

theorem nat.​lt_succ_iff {m n : ℕ} :
m < n.succ ↔ m ≤ n

theorem nat.​succ_le_iff {m n : ℕ} :
m.succ ≤ n ↔ m < n

theorem nat.​lt_iff_add_one_le {m n : ℕ} :
m < n ↔ m + 1 ≤ n

theorem nat.​lt_add_one_iff {a b : ℕ} :
a < b + 1 ↔ a ≤ b

theorem nat.​lt_one_add_iff {a b : ℕ} :
a < 1 + b ↔ a ≤ b

theorem nat.​add_one_le_iff {a b : ℕ} :
a + 1 ≤ b ↔ a < b

theorem nat.​one_add_le_iff {a b : ℕ} :
1 + a ≤ b ↔ a < b

theorem nat.​of_le_succ {n m : ℕ} :
n ≤ m.succ → n ≤ m ∨ n = m.succ

def nat.​le_rec_on {C : ℕ → Sort u} {n m : ℕ} :
n ≤ m → (Π {k : ℕ}, C k → C (k + 1)) → C n → C m

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.

Equations
theorem nat.​le_rec_on_self {C : ℕ → Sort u} {n : ℕ} {h : n ≤ n} {next : Π {k : ℕ}, C k → C (k + 1)} (x : C n) :
nat.le_rec_on h next x = x

theorem nat.​le_rec_on_succ {C : ℕ → Sort u} {n m : ℕ} (h1 : n ≤ m) {h2 : n ≤ m + 1} {next : Π {k : ℕ}, C k → C (k + 1)} (x : C n) :
nat.le_rec_on h2 next x = next (nat.le_rec_on h1 next x)

theorem nat.​le_rec_on_succ' {C : ℕ → Sort u} {n : ℕ} {h : n ≤ n + 1} {next : Π {k : ℕ}, C k → C (k + 1)} (x : C n) :
nat.le_rec_on h next x = next x

theorem nat.​le_rec_on_trans {C : ℕ → Sort u} {n m k : ℕ} (hnm : n ≤ m) (hmk : m ≤ k) {next : Π {k : ℕ}, C k → C (k + 1)} (x : C n) :
nat.le_rec_on _ next x = nat.le_rec_on hmk next (nat.le_rec_on hnm next x)

theorem nat.​le_rec_on_succ_left {C : ℕ → Sort u} {n m : ℕ} (h1 : n ≤ m) (h2 : n + 1 ≤ m) {next : Π ⦃k : ℕ⦄, C k → C (k + 1)} (x : C n) :
nat.le_rec_on h2 next (next x) = nat.le_rec_on h1 next x

theorem nat.​le_rec_on_injective {C : ℕ → Sort u} {n m : ℕ} (hnm : n ≤ m) (next : Π (n : ℕ), C n → C (n + 1)) :
(∀ (n : ℕ), function.injective (next n)) → function.injective (nat.le_rec_on hnm next)

theorem nat.​le_rec_on_surjective {C : ℕ → Sort u} {n m : ℕ} (hnm : n ≤ m) (next : Π (n : ℕ), C n → C (n + 1)) :
(∀ (n : ℕ), function.surjective (next n)) → function.surjective (nat.le_rec_on hnm next)

theorem nat.​pred_eq_of_eq_succ {m n : ℕ} :
m = n.succ → m.pred = n

@[simp]
theorem nat.​pred_eq_succ_iff {n m : ℕ} :
n.pred = m.succ ↔ n = m + 2

theorem nat.​pred_sub (n m : ℕ) :
n.pred - m = (n - m).pred

@[simp]
theorem nat.​add_succ_sub_one (n m : ℕ) :
n + m.succ - 1 = n + m

@[simp]
theorem nat.​succ_add_sub_one (n m : ℕ) :
n.succ + m - 1 = n + m

theorem nat.​pred_eq_sub_one (n : ℕ) :
n.pred = n - 1

theorem nat.​one_le_of_lt {n m : ℕ} :
n < m → 1 ≤ m

theorem nat.​le_pred_of_lt {n m : ℕ} :
m < n → m ≤ n - 1

theorem nat.​le_of_pred_lt {m n : ℕ} :
m.pred < n → m ≤ n

@[simp]
theorem nat.​pred_one_add (n : ℕ) :
(1 + n).pred = n

This ensures that simp succeeds on pred (n + 1) = n.

theorem nat.​pos_iff_ne_zero {n : ℕ} :
0 < n ↔ n ≠ 0

theorem nat.​eq_of_lt_succ_of_not_lt {a b : ℕ} :
a < b + 1 → ¬a < b → a = b

theorem nat.​le_sub_add (n m : ℕ) :
n ≤ n - m + m

theorem nat.​sub_add_eq_max (n m : ℕ) :
n - m + m = max n m

theorem nat.​add_sub_eq_max (n m : ℕ) :
n + (m - n) = max n m

theorem nat.​sub_add_min (n m : ℕ) :
n - m + min n m = n

theorem nat.​add_sub_cancel' {n m : ℕ} :
m ≤ n → m + (n - m) = n

theorem nat.​sub_eq_of_eq_add {m n k : ℕ} :
k = m + n → k - m = n

theorem nat.​sub_cancel {a b c : ℕ} :
a ≤ b → a ≤ c → b - a = c - a → b = c

theorem nat.​sub_sub_sub_cancel_right {a b c : ℕ} :
c ≤ b → a - c - (b - c) = a - b

theorem nat.​add_sub_cancel_right (n m k : ℕ) :
n + (m + k) - k = n + m

theorem nat.​sub_add_eq_add_sub {a b c : ℕ} :
b ≤ a → a - b + c = a + c - b

theorem nat.​sub_min (n m : ℕ) :
n - min n m = n - m

theorem nat.​sub_sub_assoc {a b c : ℕ} :
b ≤ a → c ≤ b → a - (b - c) = a - b + c

theorem nat.​lt_of_sub_pos {m n : ℕ} :
0 < n - m → m < n

theorem nat.​lt_of_sub_lt_sub_right {m n k : ℕ} :
m - k < n - k → m < n

theorem nat.​lt_of_sub_lt_sub_left {m n k : ℕ} :
m - n < m - k → k < n

theorem nat.​sub_lt_self {m n : ℕ} :
0 < m → 0 < n → m - n < m

theorem nat.​le_sub_right_of_add_le {m n k : ℕ} :
m + k ≤ n → m ≤ n - k

theorem nat.​le_sub_left_of_add_le {m n k : ℕ} :
k + m ≤ n → m ≤ n - k

theorem nat.​lt_sub_right_of_add_lt {m n k : ℕ} :
m + k < n → m < n - k

theorem nat.​lt_sub_left_of_add_lt {m n k : ℕ} :
k + m < n → m < n - k

theorem nat.​add_lt_of_lt_sub_right {m n k : ℕ} :
m < n - k → m + k < n

theorem nat.​add_lt_of_lt_sub_left {m n k : ℕ} :
m < n - k → k + m < n

theorem nat.​le_add_of_sub_le_right {m n k : ℕ} :
n - k ≤ m → n ≤ m + k

theorem nat.​le_add_of_sub_le_left {m n k : ℕ} :
n - k ≤ m → n ≤ k + m

theorem nat.​lt_add_of_sub_lt_right {m n k : ℕ} :
n - k < m → n < m + k

theorem nat.​lt_add_of_sub_lt_left {m n k : ℕ} :
n - k < m → n < k + m

theorem nat.​sub_le_left_of_le_add {m n k : ℕ} :
n ≤ k + m → n - k ≤ m

theorem nat.​sub_le_right_of_le_add {m n k : ℕ} :
n ≤ m + k → n - k ≤ m

theorem nat.​sub_lt_left_iff_lt_add {m n k : ℕ} :
n ≤ k → (k - n < m ↔ k < n + m)

theorem nat.​le_sub_left_iff_add_le {m n k : ℕ} :
m ≤ k → (n ≤ k - m ↔ m + n ≤ k)

theorem nat.​le_sub_right_iff_add_le {m n k : ℕ} :
n ≤ k → (m ≤ k - n ↔ m + n ≤ k)

theorem nat.​lt_sub_left_iff_add_lt {m n k : ℕ} :
n < k - m ↔ m + n < k

theorem nat.​lt_sub_right_iff_add_lt {m n k : ℕ} :
m < k - n ↔ m + n < k

theorem nat.​sub_le_left_iff_le_add {m n k : ℕ} :
m - n ≤ k ↔ m ≤ n + k

theorem nat.​sub_le_right_iff_le_add {m n k : ℕ} :
m - k ≤ n ↔ m ≤ n + k

theorem nat.​sub_lt_right_iff_lt_add {m n k : ℕ} :
k ≤ m → (m - k < n ↔ m < n + k)

theorem nat.​sub_le_sub_left_iff {m n k : ℕ} :
k ≤ m → (m - n ≤ m - k ↔ k ≤ n)

theorem nat.​sub_lt_sub_right_iff {m n k : ℕ} :
k ≤ m → (m - k < n - k ↔ m < n)

theorem nat.​sub_lt_sub_left_iff {m n k : ℕ} :
n ≤ m → (m - n < m - k ↔ k < n)

theorem nat.​sub_le_iff {m n k : ℕ} :
m - n ≤ k ↔ m - k ≤ n

theorem nat.​sub_le_self (n m : ℕ) :
n - m ≤ n

theorem nat.​sub_lt_iff {m n k : ℕ} :
n ≤ m → k ≤ m → (m - n < k ↔ m - k < n)

theorem nat.​pred_le_iff {n m : ℕ} :
n.pred ≤ m ↔ n ≤ m.succ

theorem nat.​lt_pred_iff {n m : ℕ} :
n < m.pred ↔ n.succ < m

theorem nat.​lt_of_lt_pred {a b : ℕ} :
a < b - 1 → a < b

theorem nat.​mul_ne_zero {n m : ℕ} :
n ≠ 0 → m ≠ 0 → n * m ≠ 0

@[simp]
theorem nat.​mul_eq_zero {a b : ℕ} :
a * b = 0 ↔ a = 0 ∨ b = 0

@[simp]
theorem nat.​zero_eq_mul {a b : ℕ} :
0 = a * b ↔ a = 0 ∨ b = 0

theorem nat.​eq_zero_of_double_le {a : ℕ} :
2 * a ≤ a → a = 0

theorem nat.​eq_zero_of_mul_le {a b : ℕ} :
2 ≤ b → b * a ≤ a → a = 0

theorem nat.​le_mul_of_pos_left {m n : ℕ} :
0 < n → m ≤ n * m

theorem nat.​le_mul_of_pos_right {m n : ℕ} :
0 < n → m ≤ m * n

theorem nat.​two_mul_ne_two_mul_add_one {n m : ℕ} :
2 * n ≠ 2 * m + 1

def nat.​strong_rec' {p : ℕ → Sort u} (H : Π (n : ℕ), (Π (m : ℕ), m < n → p m) → p n) (n : ℕ) :
p n

Recursion principle based on <.

Equations
def nat.​strong_rec_on' {P : ℕ → Sort u_1} (n : ℕ) :
(Π (n : ℕ), (Π (m : ℕ), m < n → P m) → P n) → P n

Recursion principle based on < applied to some natural number.

Equations
theorem nat.​strong_rec_on_beta' {P : ℕ → Sort u_1} {h : Π (n : ℕ), (Π (m : ℕ), m < n → P m) → P n} {n : ℕ} :
n.strong_rec_on' h = h n (λ (m : ℕ) (hmn : m < n), m.strong_rec_on' h)

theorem nat.​div_le_of_le_mul' {m n k : ℕ} :
m ≤ k * n → m / k ≤ n

theorem nat.​div_le_self' (m n : ℕ) :
m / n ≤ m

theorem nat.​div_lt_self' (n b : ℕ) :
(n + 1) / (b + 2) < n + 1

A version of nat.div_lt_self using successors, rather than additional hypotheses.

theorem nat.​le_div_iff_mul_le' {x y k : ℕ} :
0 < k → (x ≤ y / k ↔ x * k ≤ y)

theorem nat.​div_mul_le_self' (m n : ℕ) :
m / n * n ≤ m

theorem nat.​div_lt_iff_lt_mul' {x y k : ℕ} :
0 < k → (x / k < y ↔ x < y * k)

theorem nat.​div_le_div_right {n m : ℕ} (h : n ≤ m) {k : ℕ} :
n / k ≤ m / k

theorem nat.​lt_of_div_lt_div {m n k : ℕ} :
m / k < n / k → m < n

theorem nat.​eq_mul_of_div_eq_right {a b c : ℕ} :
b ∣ a → a / b = c → a = b * c

theorem nat.​div_eq_iff_eq_mul_right {a b c : ℕ} :
0 < b → b ∣ a → (a / b = c ↔ a = b * c)

theorem nat.​div_eq_iff_eq_mul_left {a b c : ℕ} :
0 < b → b ∣ a → (a / b = c ↔ a = c * b)

theorem nat.​eq_mul_of_div_eq_left {a b c : ℕ} :
b ∣ a → a / b = c → a = c * b

theorem nat.​mul_div_cancel_left' {a b : ℕ} :
a ∣ b → a * (b / a) = b

theorem nat.​div_mod_unique {n k m d : ℕ} :
0 < k → (n / k = d ∧ n % k = m ↔ m + k * d = n ∧ m < k)

theorem nat.​two_mul_odd_div_two {n : ℕ} :
n % 2 = 1 → 2 * (n / 2) = n - 1

theorem nat.​div_dvd_of_dvd {a b : ℕ} :
b ∣ a → a / b ∣ a

theorem nat.​div_pos {a b : ℕ} :
b ≤ a → 0 < b → 0 < a / b

theorem nat.​mul_left_inj {a b c : ℕ} :
0 < a → (b * a = c * a ↔ b = c)

theorem nat.​mul_right_inj {a b c : ℕ} :
0 < a → (a * b = a * c ↔ b = c)

theorem nat.​div_div_self {a b : ℕ} :
b ∣ a → 0 < a → a / (a / b) = b

theorem nat.​div_lt_of_lt_mul {m n k : ℕ} :
m < n * k → m / n < k

theorem nat.​lt_mul_of_div_lt {a b c : ℕ} :
a / c < b → 0 < c → a < b * c

theorem nat.​div_eq_zero_iff {a b : ℕ} :
0 < b → (a / b = 0 ↔ a < b)

theorem nat.​eq_zero_of_le_div {a b : ℕ} :
2 ≤ b → a ≤ a / b → a = 0

theorem nat.​mul_div_le_mul_div_assoc (a b c : ℕ) :
a * (b / c) ≤ a * b / c

theorem nat.​div_mul_div_le_div (a b c : ℕ) :
a / c * b / a ≤ b / c

theorem nat.​eq_zero_of_le_half {a : ℕ} :
a ≤ a / 2 → a = 0

theorem nat.​mod_mul_right_div_self (a b c : ℕ) :
a % (b * c) / b = a / b % c

theorem nat.​mod_mul_left_div_self (a b c : ℕ) :
a % (c * b) / b = a / b % c

theorem nat.​triangle_succ (n : ℕ) :
(n + 1) * (n + 1 - 1) / 2 = n * (n - 1) / 2 + n

@[simp]
theorem nat.​dvd_one {n : ℕ} :
n ∣ 1 ↔ n = 1

theorem nat.​dvd_add_left {k m n : ℕ} :
k ∣ n → (k ∣ m + n ↔ k ∣ m)

theorem nat.​dvd_add_right {k m n : ℕ} :
k ∣ m → (k ∣ m + n ↔ k ∣ n)

@[simp]
theorem nat.​not_two_dvd_bit1 (n : ℕ) :

@[simp]
theorem nat.​dvd_add_self_left {m n : ℕ} :
m ∣ m + n ↔ m ∣ n

A natural number m divides the sum m + n if and only if m divides b.

@[simp]
theorem nat.​dvd_add_self_right {m n : ℕ} :
m ∣ n + m ↔ m ∣ n

A natural number m divides the sum n + m if and only if m divides b.

theorem nat.​mul_dvd_mul_iff_left {a b c : ℕ} :
0 < a → (a * b ∣ a * c ↔ b ∣ c)

theorem nat.​mul_dvd_mul_iff_right {a b c : ℕ} :
0 < c → (a * c ∣ b * c ↔ a ∣ b)

theorem nat.​succ_div (a b : ℕ) :
(a + 1) / b = a / b + ite (b ∣ a + 1) 1 0

theorem nat.​succ_div_of_dvd {a b : ℕ} :
b ∣ a + 1 → (a + 1) / b = a / b + 1

theorem nat.​succ_div_of_not_dvd {a b : ℕ} :
¬b ∣ a + 1 → (a + 1) / b = a / b

@[simp]
theorem nat.​mod_mod_of_dvd (n : ℕ) {m k : ℕ} :
m ∣ k → n % k % m = n % m

@[simp]
theorem nat.​mod_mod (a n : ℕ) :
a % n % n = a % n

theorem nat.​sub_mod_eq_zero_of_mod_eq {a b c : ℕ} :
a % c = b % c → (a - b) % c = 0

If a and b are equal mod c, a - b is zero mod c.

@[simp]
theorem nat.​one_mod (n : ℕ) :
1 % (n + 2) = 1

theorem nat.​dvd_sub_mod {n : ℕ} (k : ℕ) :
n ∣ k - k % n

@[simp]
theorem nat.​mod_add_mod (m n k : ℕ) :
(m % n + k) % n = (m + k) % n

@[simp]
theorem nat.​add_mod_mod (m n k : ℕ) :
(m + n % k) % k = (m + n) % k

theorem nat.​add_mod (a b n : ℕ) :
(a + b) % n = (a % n + b % n) % n

theorem nat.​add_mod_eq_add_mod_right {m n k : ℕ} (i : ℕ) :
m % n = k % n → (m + i) % n = (k + i) % n

theorem nat.​add_mod_eq_add_mod_left {m n k : ℕ} (i : ℕ) :
m % n = k % n → (i + m) % n = (i + k) % n

theorem nat.​mul_mod (a b n : ℕ) :
a * b % n = a % n * (b % n) % n

theorem nat.​add_pos_left {m : ℕ} (h : 0 < m) (n : ℕ) :
0 < m + n

theorem nat.​add_pos_right (m : ℕ) {n : ℕ} :
0 < n → 0 < m + n

theorem nat.​add_pos_iff_pos_or_pos (m n : ℕ) :
0 < m + n ↔ 0 < m ∨ 0 < n

theorem nat.​add_eq_one_iff {a b : ℕ} :
a + b = 1 ↔ a = 0 ∧ b = 1 ∨ a = 1 ∧ b = 0

theorem nat.​mul_eq_one_iff {a b : ℕ} :
a * b = 1 ↔ a = 1 ∧ b = 1

theorem nat.​mul_right_eq_self_iff {a b : ℕ} :
0 < a → (a * b = a ↔ b = 1)

theorem nat.​mul_left_eq_self_iff {a b : ℕ} :
0 < b → (a * b = b ↔ a = 1)

theorem nat.​lt_succ_iff_lt_or_eq {n i : ℕ} :
n < i.succ ↔ n < i ∨ n = i

theorem nat.​le_zero_iff {i : ℕ} :
i ≤ 0 ↔ i = 0

theorem nat.​le_add_one_iff {i j : ℕ} :
i ≤ j + 1 ↔ i ≤ j ∨ i = j + 1

theorem nat.​mul_self_inj {n m : ℕ} :
n * n = m * m ↔ n = m

@[instance]
def nat.​succ_pos'' (n : ℕ) :
fact (0 < n.succ)

Equations
  • _ = _
@[instance]
def nat.​pos_of_one_lt (n : ℕ) [h : fact (1 < n)] :
fact (0 < n)

Equations
  • _ = _
@[instance]
def nat.​decidable_ball_lt (n : ℕ) (P : Π (k : ℕ), k < n → Prop) [H : Π (n_1 : ℕ) (h : n_1 < n), decidable (P n_1 h)] :
decidable (∀ (n_1 : ℕ) (h : n_1 < n), P n_1 h)

Equations
@[instance]
def nat.​decidable_forall_fin {n : ℕ} (P : fin n → Prop) [H : decidable_pred P] :
decidable (∀ (i : fin n), P i)

Equations
@[instance]
def nat.​decidable_ball_le (n : ℕ) (P : Π (k : ℕ), k ≤ n → Prop) [H : Π (n_1 : ℕ) (h : n_1 ≤ n), decidable (P n_1 h)] :
decidable (∀ (n_1 : ℕ) (h : n_1 ≤ n), P n_1 h)

Equations
@[instance]
def nat.​decidable_lo_hi (lo hi : ℕ) (P : ℕ → Prop) [H : decidable_pred P] :
decidable (∀ (x : ℕ), lo ≤ x → x < hi → P x)

Equations
@[instance]
def nat.​decidable_lo_hi_le (lo hi : ℕ) (P : ℕ → Prop) [H : decidable_pred P] :
decidable (∀ (x : ℕ), lo ≤ x → x ≤ hi → P x)

Equations
theorem nat.​bit0_le {n m : ℕ} :
n ≤ m → bit0 n ≤ bit0 m

theorem nat.​bit1_le {n m : ℕ} :
n ≤ m → bit1 n ≤ bit1 m

theorem nat.​bit_le (b : bool) {n m : ℕ} :
n ≤ m → nat.bit b n ≤ nat.bit b m

theorem nat.​bit_ne_zero (b : bool) {n : ℕ} :
n ≠ 0 → nat.bit b n ≠ 0

theorem nat.​bit0_le_bit (b : bool) {m n : ℕ} :
m ≤ n → bit0 m ≤ nat.bit b n

theorem nat.​bit_le_bit1 (b : bool) {m n : ℕ} :
m ≤ n → nat.bit b m ≤ bit1 n

theorem nat.​bit_lt_bit0 (b : bool) {n m : ℕ} :
n < m → nat.bit b n < bit0 m

theorem nat.​bit_lt_bit (a b : bool) {n m : ℕ} :
n < m → nat.bit a n < nat.bit b m

@[simp]
theorem nat.​bit0_le_bit1_iff {n k : ℕ} :
bit0 k ≤ bit1 n ↔ k ≤ n

@[simp]
theorem nat.​bit0_lt_bit1_iff {n k : ℕ} :
bit0 k < bit1 n ↔ k ≤ n

@[simp]
theorem nat.​bit1_le_bit0_iff {n k : ℕ} :
bit1 k ≤ bit0 n ↔ k < n

@[simp]
theorem nat.​bit1_lt_bit0_iff {n k : ℕ} :
bit1 k < bit0 n ↔ k < n

@[simp]
theorem nat.​one_le_bit0_iff {n : ℕ} :
1 ≤ bit0 n ↔ 0 < n

@[simp]
theorem nat.​one_lt_bit0_iff {n : ℕ} :
1 < bit0 n ↔ 1 ≤ n

@[simp]
theorem nat.​bit_le_bit_iff {n k : ℕ} {b : bool} :
nat.bit b k ≤ nat.bit b n ↔ k ≤ n

@[simp]
theorem nat.​bit_lt_bit_iff {n k : ℕ} {b : bool} :
nat.bit b k < nat.bit b n ↔ k < n

@[simp]
theorem nat.​bit_le_bit1_iff {n k : ℕ} {b : bool} :
nat.bit b k ≤ bit1 n ↔ k ≤ n

theorem nat.​pos_of_bit0_pos {n : ℕ} :
0 < bit0 n → 0 < n

def nat.​bit_cases {C : ℕ → Sort u} (H : Π (b : bool) (n : ℕ), C (nat.bit b n)) (n : ℕ) :
C n

Define a function on ℕ depending on parity of the argument.

Equations
@[simp]
def nat.​ppred  :

Partial predecessor operation. Returns ppred n = some m if n = m + 1, otherwise none.

Equations
@[simp]
def nat.​psub  :
ℕ → ℕ → option ℕ

Partial subtraction operation. Returns psub m n = some k if m = n + k, otherwise none.

Equations
theorem nat.​sub_eq_psub (m n : ℕ) :
m - n = (m.psub n).get_or_else 0

@[simp]
theorem nat.​ppred_eq_some {m n : ℕ} :

@[simp]
theorem nat.​ppred_eq_none {n : ℕ} :

theorem nat.​psub_eq_some {m n k : ℕ} :
m.psub n = option.some k ↔ k + n = m

theorem nat.​psub_eq_none (m n : ℕ) :

theorem nat.​ppred_eq_pred {n : ℕ} :
0 < n → n.ppred = option.some n.pred

theorem nat.​psub_eq_sub {m n : ℕ} :
n ≤ m → m.psub n = option.some (m - n)

theorem nat.​psub_add (m n k : ℕ) :
m.psub (n + k) = m.psub n >>= λ (x : ℕ), x.psub k

@[simp]
theorem nat.​one_pow (n : ℕ) :
1 ^ n = 1

theorem nat.​pow_add (a m n : ℕ) :
a ^ (m + n) = a ^ m * a ^ n

theorem nat.​pow_two (a : ℕ) :
a ^ 2 = a * a

theorem nat.​pow_dvd_pow (a : ℕ) {m n : ℕ} :
m ≤ n → a ^ m ∣ a ^ n

theorem nat.​pow_dvd_pow_of_dvd {a b : ℕ} (h : a ∣ b) (n : ℕ) :
a ^ n ∣ b ^ n

theorem nat.​mul_pow (a b n : ℕ) :
(a * b) ^ n = a ^ n * b ^ n

theorem nat.​pow_mul (a b n : ℕ) :
n ^ (a * b) = (n ^ a) ^ b

theorem nat.​pow_pos {p : ℕ} (hp : 0 < p) (n : ℕ) :
0 < p ^ n

theorem nat.​pow_eq_mul_pow_sub (p : ℕ) {m n : ℕ} :
m ≤ n → p ^ m * p ^ (n - m) = p ^ n

theorem nat.​pow_lt_pow_succ {p : ℕ} (h : 1 < p) (n : ℕ) :
p ^ n < p ^ (n + 1)

theorem nat.​lt_pow_self {p : ℕ} (h : 1 < p) (n : ℕ) :
n < p ^ n

theorem nat.​lt_two_pow (n : ℕ) :
n < 2 ^ n

theorem nat.​one_le_pow (n m : ℕ) :
0 < m → 1 ≤ m ^ n

theorem nat.​one_le_pow' (n m : ℕ) :
1 ≤ (m + 1) ^ n

theorem nat.​one_le_two_pow (n : ℕ) :
1 ≤ 2 ^ n

theorem nat.​one_lt_pow (n m : ℕ) :
0 < n → 1 < m → 1 < m ^ n

theorem nat.​one_lt_pow' (n m : ℕ) :
1 < (m + 2) ^ (n + 1)

theorem nat.​one_lt_two_pow (n : ℕ) :
0 < n → 1 < 2 ^ n

theorem nat.​one_lt_two_pow' (n : ℕ) :
1 < 2 ^ (n + 1)

theorem nat.​pow_le_iff_le_right {x m n : ℕ} :
2 ≤ x → (x ^ m ≤ x ^ n ↔ m ≤ n)

theorem nat.​pow_lt_iff_lt_right {x m n : ℕ} :
2 ≤ x → (x ^ m < x ^ n ↔ m < n)

theorem nat.​pow_dvd_pow_iff_pow_le_pow {k l x : ℕ} :
0 < x → (x ^ k ∣ x ^ l ↔ x ^ k ≤ x ^ l)

theorem nat.​pow_dvd_pow_iff_le_right {x k l : ℕ} :
1 < x → (x ^ k ∣ x ^ l ↔ k ≤ l)

If 1 < x, then x^k divides x^l if and only if k is at most l.

theorem nat.​pow_dvd_pow_iff_le_right' {b k l : ℕ} :
(b + 2) ^ k ∣ (b + 2) ^ l ↔ k ≤ l

theorem nat.​pow_left_strict_mono {m : ℕ} :
1 ≤ m → strict_mono (λ (x : ℕ), x ^ m)

theorem nat.​pow_le_iff_le_left {m x y : ℕ} :
1 ≤ m → (x ^ m ≤ y ^ m ↔ x ≤ y)

theorem nat.​pow_lt_iff_lt_left {m x y : ℕ} :
1 ≤ m → (x ^ m < y ^ m ↔ x < y)

theorem nat.​pow_left_injective {m : ℕ} :
1 ≤ m → function.injective (λ (x : ℕ), x ^ m)

theorem nat.​not_pos_pow_dvd {p k : ℕ} :
1 < p → 1 < k → ¬p ^ k ∣ p

@[simp]
theorem nat.​bodd_div2_eq (n : ℕ) :
n.bodd_div2 = (n.bodd, n.div2)

@[simp]
theorem nat.​bodd_bit0 (n : ℕ) :

@[simp]
theorem nat.​bodd_bit1 (n : ℕ) :

@[simp]
theorem nat.​div2_bit0 (n : ℕ) :
(bit0 n).div2 = n

@[simp]
theorem nat.​div2_bit1 (n : ℕ) :
(bit1 n).div2 = n

theorem nat.​shiftl'_ne_zero_left (b : bool) {m : ℕ} (h : m ≠ 0) (n : ℕ) :

theorem nat.​shiftl'_tt_ne_zero (m : ℕ) {n : ℕ} :
n ≠ 0 → nat.shiftl' bool.tt m n ≠ 0

@[simp]
theorem nat.​size_zero  :
0.size = 0

@[simp]
theorem nat.​size_bit {b : bool} {n : ℕ} :
nat.bit b n ≠ 0 → (nat.bit b n).size = n.size.succ

@[simp]
theorem nat.​size_bit0 {n : ℕ} :
n ≠ 0 → (bit0 n).size = n.size.succ

@[simp]
theorem nat.​size_bit1 (n : ℕ) :

@[simp]
theorem nat.​size_one  :
1.size = 1

@[simp]
theorem nat.​size_shiftl' {b : bool} {m n : ℕ} :
nat.shiftl' b m n ≠ 0 → (nat.shiftl' b m n).size = m.size + n

@[simp]
theorem nat.​size_shiftl {m : ℕ} (h : m ≠ 0) (n : ℕ) :
(m.shiftl n).size = m.size + n

theorem nat.​lt_size_self (n : ℕ) :
n < 2 ^ n.size

theorem nat.​size_le {m n : ℕ} :
m.size ≤ n ↔ m < 2 ^ n

theorem nat.​lt_size {m n : ℕ} :
m < n.size ↔ 2 ^ m ≤ n

theorem nat.​size_pos {n : ℕ} :
0 < n.size ↔ 0 < n

theorem nat.​size_eq_zero {n : ℕ} :
n.size = 0 ↔ n = 0

theorem nat.​size_pow {n : ℕ} :
(2 ^ n).size = n + 1

theorem nat.​size_le_size {m n : ℕ} :
m ≤ n → m.size ≤ n.size

@[simp]
def nat.​fact  :
ℕ → ℕ

fact n is the factorial of n.

Equations
@[simp]
theorem nat.​fact_zero  :
0.fact = 1

@[simp]
theorem nat.​fact_succ (n : ℕ) :

@[simp]
theorem nat.​fact_one  :
1.fact = 1

theorem nat.​fact_pos (n : ℕ) :
0 < n.fact

theorem nat.​fact_ne_zero (n : ℕ) :
n.fact ≠ 0

theorem nat.​fact_dvd_fact {m n : ℕ} :
m ≤ n → m.fact ∣ n.fact

theorem nat.​dvd_fact {m n : ℕ} :
0 < m → m ≤ n → m ∣ n.fact

theorem nat.​fact_le {m n : ℕ} :
m ≤ n → m.fact ≤ n.fact

theorem nat.​fact_mul_pow_le_fact {m n : ℕ} :
m.fact * m.succ ^ n ≤ (m + n).fact

theorem nat.​fact_lt {m n : ℕ} :
0 < n → (n.fact < m.fact ↔ n < m)

theorem nat.​one_lt_fact {n : ℕ} :
1 < n.fact ↔ 1 < n

theorem nat.​fact_eq_one {n : ℕ} :
n.fact = 1 ↔ n ≤ 1

theorem nat.​fact_inj {m n : ℕ} :
1 < n.fact → (n.fact = m.fact ↔ n = m)

def nat.​choose  :
ℕ → ℕ → ℕ

choose n k is the number of k-element subsets in an n-element set. Also known as binomial coefficients.

Equations
@[simp]
theorem nat.​choose_zero_right (n : ℕ) :
n.choose 0 = 1

@[simp]
theorem nat.​choose_zero_succ (k : ℕ) :
0.choose k.succ = 0

theorem nat.​choose_succ_succ (n k : ℕ) :

theorem nat.​choose_eq_zero_of_lt {n k : ℕ} :
n < k → n.choose k = 0

@[simp]
theorem nat.​choose_self (n : ℕ) :
n.choose n = 1

@[simp]
theorem nat.​choose_succ_self (n : ℕ) :
n.choose n.succ = 0

@[simp]
theorem nat.​choose_one_right (n : ℕ) :
n.choose 1 = n

theorem nat.​choose_two_right (n : ℕ) :
n.choose 2 = n * (n - 1) / 2

choose n 2 is the n-th triangle number.

theorem nat.​choose_pos {n k : ℕ} :
k ≤ n → 0 < n.choose k

theorem nat.​succ_mul_choose_eq (n k : ℕ) :

theorem nat.​choose_mul_fact_mul_fact {n k : ℕ} :
k ≤ n → n.choose k * k.fact * (n - k).fact = n.fact

theorem nat.​choose_eq_fact_div_fact {n k : ℕ} :
k ≤ n → n.choose k = n.fact / (k.fact * (n - k).fact)

theorem nat.​fact_mul_fact_dvd_fact {n k : ℕ} :
k ≤ n → k.fact * (n - k).fact ∣ n.fact

@[simp]
theorem nat.​choose_symm {n k : ℕ} :
k ≤ n → n.choose (n - k) = n.choose k

theorem nat.​choose_symm_of_eq_add {n a b : ℕ} :
n = a + b → n.choose a = n.choose b

theorem nat.​choose_symm_add {a b : ℕ} :
(a + b).choose a = (a + b).choose b

theorem nat.​choose_symm_half (m : ℕ) :
(2 * m + 1).choose (m + 1) = (2 * m + 1).choose m

theorem nat.​choose_succ_right_eq (n k : ℕ) :
n.choose (k + 1) * (k + 1) = n.choose k * (n - k)

@[simp]
theorem nat.​choose_succ_self_right (n : ℕ) :
(n + 1).choose n = n + 1

theorem nat.​choose_mul_succ_eq (n k : ℕ) :
n.choose k * (n + 1) = (n + 1).choose k * (n + 1 - k)

theorem nat.​units_eq_one (u : units ℕ) :
u = 1

@[simp]
theorem nat.​is_unit_iff {n : ℕ} :
is_unit n ↔ n = 1

@[simp]
theorem nat.​find_eq_zero {p : ℕ → Prop} [decidable_pred p] (h : ∃ (n : ℕ), p n) :
nat.find h = 0 ↔ p 0

@[simp]
theorem nat.​find_pos {p : ℕ → Prop} [decidable_pred p] (h : ∃ (n : ℕ), p n) :
0 < nat.find h ↔ ¬p 0

def nat.​find_greatest (P : ℕ → Prop) [decidable_pred P] :
ℕ → ℕ

find_greatest P b is the largest i ≤ bound such that P i holds, or 0 if no such i exists

Equations
@[simp]
theorem nat.​find_greatest_zero {P : ℕ → Prop} [decidable_pred P] :

@[simp]
theorem nat.​find_greatest_eq {P : ℕ → Prop} [decidable_pred P] {b : ℕ} :
P b → nat.find_greatest P b = b

@[simp]
theorem nat.​find_greatest_of_not {P : ℕ → Prop} [decidable_pred P] {b : ℕ} :
¬P (b + 1) → nat.find_greatest P (b + 1) = nat.find_greatest P b

theorem nat.​find_greatest_spec_and_le {P : ℕ → Prop} [decidable_pred P] {b m : ℕ} :
m ≤ b → P m → P (nat.find_greatest P b) ∧ m ≤ nat.find_greatest P b

theorem nat.​find_greatest_spec {P : ℕ → Prop} [decidable_pred P] {b : ℕ} :
(∃ (m : ℕ), m ≤ b ∧ P m) → P (nat.find_greatest P b)

theorem nat.​find_greatest_le {P : ℕ → Prop} [decidable_pred P] {b : ℕ} :

theorem nat.​le_find_greatest {P : ℕ → Prop} [decidable_pred P] {b m : ℕ} :
m ≤ b → P m → m ≤ nat.find_greatest P b

theorem nat.​find_greatest_is_greatest {P : ℕ → Prop} [decidable_pred P] {b : ℕ} (a : ∃ (m : ℕ), m ≤ b ∧ P m) (k : ℕ) :
nat.find_greatest P b < k ∧ k ≤ b → ¬P k

theorem nat.​find_greatest_eq_zero {P : ℕ → Prop} [decidable_pred P] {b : ℕ} :
(∀ (n : ℕ), n ≤ b → ¬P n) → nat.find_greatest P b = 0

theorem nat.​find_greatest_of_ne_zero {P : ℕ → Prop} [decidable_pred P] {b m : ℕ} :
nat.find_greatest P b = m → m ≠ 0 → P m

theorem nat.​dvd_div_of_mul_dvd {a b c : ℕ} :
a * b ∣ c → b ∣ c / a

theorem nat.​mul_dvd_of_dvd_div {a b c : ℕ} :
c ∣ b → a ∣ b / c → c * a ∣ b

theorem nat.​div_mul_div {a b c d : ℕ} :
b ∣ a → d ∣ c → a / b * (c / d) = a * c / (b * d)

@[simp]
theorem nat.​div_div_div_eq_div {a b c : ℕ} :
b ∣ a → a ∣ c → c / (a / b) / b = c / a

theorem nat.​pow_dvd_of_le_of_pow_dvd {p m n k : ℕ} :
m ≤ n → p ^ n ∣ k → p ^ m ∣ k

theorem nat.​dvd_of_pow_dvd {p k m : ℕ} :
1 ≤ k → p ^ k ∣ m → p ∣ m

theorem nat.​eq_of_dvd_of_div_eq_one {a b : ℕ} :
a ∣ b → b / a = 1 → a = b

theorem nat.​eq_zero_of_dvd_of_div_eq_zero {a b : ℕ} :
a ∣ b → b / a = 0 → b = 0

theorem nat.​eq_zero_of_dvd_of_lt {a b : ℕ} :
a ∣ b → b < a → b = 0

If a small natural number is divisible by a larger natural number, the small number is zero.

theorem nat.​div_le_div_left {a b c : ℕ} :
c ≤ b → 0 < c → a / b ≤ a / c

theorem nat.​div_eq_self {a b : ℕ} :
a / b = a ↔ a = 0 ∨ b = 1

theorem nat.​exists_eq_add_of_le {m n : ℕ} :
m ≤ n → (∃ (k : ℕ), n = m + k)

theorem nat.​exists_eq_add_of_lt {m n : ℕ} :
m < n → (∃ (k : ℕ), n = m + k + 1)

theorem nat.​with_bot.​add_eq_zero_iff {n m : with_bot ℕ} :
n + m = 0 ↔ n = 0 ∧ m = 0

theorem nat.​with_bot.​add_eq_one_iff {n m : with_bot ℕ} :
n + m = 1 ↔ n = 0 ∧ m = 1 ∨ n = 1 ∧ m = 0

@[simp]

@[simp]

theorem nat.​le_induction {P : ℕ → Prop} {m : ℕ} (h0 : P m) (h1 : ∀ (n : ℕ), m ≤ n → P n → P (n + 1)) (n : ℕ) :
m ≤ n → P n

Induction principle starting at a non-zero number. For maps to a Sort* see le_rec_on.

def nat.​decreasing_induction {P : ℕ → Sort u_1} (h : Π (n : ℕ), P (n + 1) → P n) {m n : ℕ} :
m ≤ n → P n → P m

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*.

Equations
@[simp]
theorem nat.​decreasing_induction_self {P : ℕ → Sort u_1} (h : Π (n : ℕ), P (n + 1) → P n) {n : ℕ} (nn : n ≤ n) (hP : P n) :

theorem nat.​decreasing_induction_succ {P : ℕ → Sort u_1} (h : Π (n : ℕ), P (n + 1) → P n) {m n : ℕ} (mn : m ≤ n) (msn : m ≤ n + 1) (hP : P (n + 1)) :

@[simp]
theorem nat.​decreasing_induction_succ' {P : ℕ → Sort u_1} (h : Π (n : ℕ), P (n + 1) → P n) {m : ℕ} (msm : m ≤ m + 1) (hP : P (m + 1)) :
nat.decreasing_induction h msm hP = h m hP

theorem nat.​decreasing_induction_trans {P : ℕ → Sort u_1} (h : Π (n : ℕ), P (n + 1) → P n) {m n k : ℕ} (mn : m ≤ n) (nk : n ≤ k) (hP : P k) :

theorem nat.​decreasing_induction_succ_left {P : ℕ → Sort u_1} (h : Π (n : ℕ), P (n + 1) → P n) {m n : ℕ} (smn : m + 1 ≤ n) (mn : m ≤ n) (hP : P n) :

def nat.​log  :
ℕ → ℕ → ℕ

log b n, is the logarithm of natural number n in base b. It returns the largest k:ℕ such that b^k ≤ n, so if b^k = n, it returns exactly k.

Equations
theorem nat.​pow_le_iff_le_log (x y : ℕ) {b : ℕ} :
1 < b → 1 ≤ y → (b ^ x ≤ y ↔ x ≤ b.log y)

theorem nat.​log_pow (b x : ℕ) :
1 < b → b.log (b ^ x) = x

theorem nat.​pow_succ_log_gt_self (b x : ℕ) :
1 < b → 1 ≤ x → x < b ^ (b.log x).succ

theorem nat.​pow_log_le_self (b x : ℕ) :
1 < b → 1 ≤ x → b ^ b.log x ≤ x