Basic operations on the natural numbers
This files has some basic lemmas about natural numbers, definition of the choice
function,
and extra recursors:
le_rec_on
,le_induction
: recursion and induction principles starting at non-zero numbers.decreasing_induction
: recursion growing downwards.strong_rec'
: recursion based on strong inequalities.
@[instance]
Equations
- nat.comm_semiring = {add := nat.add, add_assoc := nat.add_assoc, zero := 0, zero_add := nat.zero_add, add_zero := nat.add_zero, add_comm := nat.add_comm, mul := nat.mul, mul_assoc := nat.mul_assoc, one := 1, one_mul := nat.one_mul, mul_one := nat.mul_one, zero_mul := nat.zero_mul, mul_zero := nat.mul_zero, left_distrib := nat.left_distrib, right_distrib := nat.right_distrib, mul_comm := nat.mul_comm}
@[instance]
Equations
- nat.decidable_linear_ordered_semiring = {add := comm_semiring.add nat.comm_semiring, add_assoc := _, zero := comm_semiring.zero nat.comm_semiring, zero_add := _, add_zero := _, add_comm := _, mul := comm_semiring.mul nat.comm_semiring, mul_assoc := _, one := comm_semiring.one nat.comm_semiring, one_mul := _, mul_one := _, zero_mul := _, mul_zero := _, left_distrib := _, right_distrib := _, add_left_cancel := nat.add_left_cancel, add_right_cancel := nat.add_right_cancel, le := decidable_linear_order.le nat.decidable_linear_order, lt := nat.lt, le_refl := _, le_trans := _, lt_iff_le_not_le := _, le_antisymm := _, add_le_add_left := nat.add_le_add_left, le_of_add_le_add_left := nat.le_of_add_le_add_left, mul_lt_mul_of_pos_left := nat.mul_lt_mul_of_pos_left, mul_lt_mul_of_pos_right := nat.mul_lt_mul_of_pos_right, le_total := _, zero_lt_one := nat.decidable_linear_ordered_semiring._proof_1, decidable_le := decidable_linear_order.decidable_le nat.decidable_linear_order, decidable_eq := nat.decidable_eq, decidable_lt := decidable_linear_order.decidable_lt nat.decidable_linear_order}
@[instance]
Equations
- nat.decidable_linear_ordered_cancel_add_comm_monoid = {add := decidable_linear_ordered_semiring.add nat.decidable_linear_ordered_semiring, add_assoc := _, zero := decidable_linear_ordered_semiring.zero nat.decidable_linear_ordered_semiring, zero_add := _, add_zero := _, add_comm := _, add_left_cancel := nat.add_left_cancel, add_right_cancel := _, le := decidable_linear_ordered_semiring.le nat.decidable_linear_ordered_semiring, lt := decidable_linear_ordered_semiring.lt nat.decidable_linear_ordered_semiring, le_refl := _, le_trans := _, lt_iff_le_not_le := _, le_antisymm := _, add_le_add_left := _, le_of_add_le_add_left := _, le_total := _, decidable_le := decidable_linear_ordered_semiring.decidable_le nat.decidable_linear_ordered_semiring, decidable_eq := decidable_linear_ordered_semiring.decidable_eq nat.decidable_linear_ordered_semiring, decidable_lt := decidable_linear_ordered_semiring.decidable_lt nat.decidable_linear_ordered_semiring}
@[instance]
@[instance]
Equations
@[instance]
Equations
@[instance]
Equations
@[instance]
@[instance]
Equations
@[instance]
Equations
@[instance]
@[instance]
Equations
- nat.canonically_ordered_comm_semiring = {add := ordered_add_comm_monoid.add infer_instance, add_assoc := nat.canonically_ordered_comm_semiring._proof_1, zero := ordered_add_comm_monoid.zero infer_instance, zero_add := nat.canonically_ordered_comm_semiring._proof_2, add_zero := nat.canonically_ordered_comm_semiring._proof_3, add_comm := nat.canonically_ordered_comm_semiring._proof_4, le := ordered_add_comm_monoid.le infer_instance, lt := ordered_add_comm_monoid.lt infer_instance, le_refl := nat.canonically_ordered_comm_semiring._proof_5, le_trans := nat.canonically_ordered_comm_semiring._proof_6, lt_iff_le_not_le := nat.canonically_ordered_comm_semiring._proof_7, le_antisymm := nat.canonically_ordered_comm_semiring._proof_8, add_le_add_left := nat.canonically_ordered_comm_semiring._proof_9, lt_of_add_lt_add_left := nat.canonically_ordered_comm_semiring._proof_10, bot := 0, bot_le := nat.zero_le, le_iff_exists_add := nat.canonically_ordered_comm_semiring._proof_11, mul := linear_ordered_semiring.mul infer_instance, mul_assoc := nat.canonically_ordered_comm_semiring._proof_12, one := linear_ordered_semiring.one infer_instance, one_mul := nat.canonically_ordered_comm_semiring._proof_13, mul_one := nat.canonically_ordered_comm_semiring._proof_14, zero_mul := nat.canonically_ordered_comm_semiring._proof_15, mul_zero := nat.canonically_ordered_comm_semiring._proof_16, left_distrib := nat.canonically_ordered_comm_semiring._proof_17, right_distrib := nat.canonically_ordered_comm_semiring._proof_18, mul_comm := nat.canonically_ordered_comm_semiring._proof_19, exists_pair_ne := _, eq_zero_or_eq_zero_of_mul_eq_zero := nat.canonically_ordered_comm_semiring._proof_20}
@[instance]
Equations
- nat.subtype.semilattice_sup_bot s = {bot := ⟨nat.find _, _⟩, le := linear_order.le (subtype.linear_order s), lt := linear_order.lt (subtype.linear_order s), le_refl := _, le_trans := _, lt_iff_le_not_le := _, le_antisymm := _, bot_le := _, sup := lattice.sup lattice_of_decidable_linear_order, le_sup_left := _, le_sup_right := _, sup_le := _}
@[instance]
Equations
- nat.nat.comm_cancel_monoid_with_zero = {mul := comm_monoid_with_zero.mul infer_instance, mul_assoc := nat.nat.comm_cancel_monoid_with_zero._proof_1, one := comm_monoid_with_zero.one infer_instance, one_mul := nat.nat.comm_cancel_monoid_with_zero._proof_2, mul_one := nat.nat.comm_cancel_monoid_with_zero._proof_3, mul_comm := nat.nat.comm_cancel_monoid_with_zero._proof_4, zero := comm_monoid_with_zero.zero infer_instance, zero_mul := nat.nat.comm_cancel_monoid_with_zero._proof_5, mul_zero := nat.nat.comm_cancel_monoid_with_zero._proof_6, mul_left_cancel_of_ne_zero := nat.nat.comm_cancel_monoid_with_zero._proof_7, mul_right_cancel_of_ne_zero := nat.nat.comm_cancel_monoid_with_zero._proof_8}
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
- nat.le_rec_on H next x = _.by_cases (λ (h : n ≤ m), next (nat.le_rec_on h next x)) (λ (h : n = m + 1), h.rec_on x)
- nat.le_rec_on H next x = _.rec_on x
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)
Recursion principle based on <
.
Equations
- nat.strong_rec' H n = H n (λ (m : ℕ) (hm : m < n), nat.strong_rec' H m)
Recursion principle based on <
applied to some natural number.
Equations
- n.strong_rec_on' h = nat.strong_rec' h n
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)
A version of nat.div_lt_self
using successors, rather than additional hypotheses.
@[instance]
def
nat.decidable_ball_lt
(n : ℕ)
(P : Π (k : ℕ), k < n → Prop)
[H : Π (n_1 : ℕ) (h : n_1 < n), decidable (P n_1 h)] :
Equations
- n.decidable_ball_lt P = nat.rec (λ (P : Π (k : ℕ), k < 0 → Prop) (H : Π (n : ℕ) (h : n < 0), decidable (P n h)), decidable.is_true _) (λ (n : ℕ) (IH : Π (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)) (P : Π (k : ℕ), k < n.succ → Prop) (H : Π (n_1 : ℕ) (h : n_1 < n.succ), decidable (P n_1 h)), (IH (λ (k : ℕ) (h : k < n), P k _)).cases_on (λ (h : ¬∀ (n_1 : ℕ) (h : n_1 < n), (λ (k : ℕ) (h : k < n), P k _) n_1 h), decidable.is_false _) (λ (h : ∀ (n_1 : ℕ) (h : n_1 < n), (λ (k : ℕ) (h : k < n), P k _) n_1 h), dite (P n _) (λ (p : P n _), decidable.is_true _) (λ (p : ¬P n _), decidable.is_false _))) n P
@[instance]
Equations
- nat.decidable_forall_fin P = decidable_of_iff (∀ (k : ℕ) (h : k < n), P ⟨k, h⟩) _
@[instance]
Equations
- lo.decidable_lo_hi hi P = decidable_of_iff (∀ (x : ℕ), x < hi - lo → P (lo + x)) _
@[instance]
Equations
- lo.decidable_lo_hi_le hi P = decidable_of_iff (∀ (x : ℕ), lo ≤ x → x < hi + 1 → P x) _
@[simp]
Partial predecessor operation. Returns ppred n = some m
if n = m + 1
, otherwise none
.
Equations
- (n + 1).ppred = option.some n
- 0.ppred = option.none
@[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]
@[simp]
find_greatest P b
is the largest i ≤ bound
such that P i
holds, or 0
if no such i
exists
Equations
- nat.find_greatest P (n + 1) = ite (P (n + 1)) (n + 1) (nat.find_greatest P n)
- nat.find_greatest P 0 = 0
@[simp]
@[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.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
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
- nat.decreasing_induction h mn hP = nat.le_rec_on mn (λ (k : ℕ) (ih : P k → P m) (hsk : P (k + 1)), ih (h k hsk)) (λ (h : P m), h) hP
@[simp]
theorem
nat.decreasing_induction_self
{P : ℕ → Sort u_1}
(h : Π (n : ℕ), P (n + 1) → P n)
{n : ℕ}
(nn : n ≤ n)
(hP : P n) :
nat.decreasing_induction h nn hP = hP
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)) :
nat.decreasing_induction h msn hP = nat.decreasing_induction h mn (h n 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) :
nat.decreasing_induction h _ hP = nat.decreasing_induction h mn (nat.decreasing_induction h nk hP)
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) :
nat.decreasing_induction h mn hP = h m (nat.decreasing_induction h smn hP)