Basic operations on the natural numbers #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
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 numbersdecreasing_induction
: recursion growing downwardsle_rec_on'
,decreasing_induction'
: versions with slightly weaker assumptionsstrong_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.
instances #
Equations
- nat.comm_semiring = {add := nat.add, add_assoc := nat.add_assoc, zero := 0, zero_add := nat.zero_add, add_zero := nat.add_zero, nsmul := λ (m n : ℕ), m * n, nsmul_zero' := nat.zero_mul, nsmul_succ' := nat.comm_semiring._proof_1, add_comm := nat.add_comm, mul := nat.mul, left_distrib := nat.left_distrib, right_distrib := nat.right_distrib, zero_mul := nat.zero_mul, mul_zero := nat.mul_zero, mul_assoc := nat.mul_assoc, one := 1, one_mul := nat.one_mul, mul_one := nat.mul_one, nat_cast := λ (n : ℕ), n, nat_cast_zero := nat.comm_semiring._proof_2, nat_cast_succ := nat.comm_semiring._proof_3, npow := semiring.npow._default 1 nat.mul nat.one_mul nat.mul_one, npow_zero' := nat.comm_semiring._proof_4, npow_succ' := nat.comm_semiring._proof_5, mul_comm := nat.mul_comm}
Extra instances to short-circuit type class resolution and ensure computability
Equations
Equations
Equations
Equations
Equations
Equations
Equations
Equations
- nat.cancel_comm_monoid_with_zero = {mul := comm_semiring.mul nat.comm_semiring, mul_assoc := _, one := comm_semiring.one nat.comm_semiring, one_mul := _, mul_one := _, npow := comm_semiring.npow nat.comm_semiring, npow_zero' := _, npow_succ' := _, mul_comm := _, zero := comm_semiring.zero nat.comm_semiring, zero_mul := _, mul_zero := _, mul_left_cancel_of_ne_zero := nat.cancel_comm_monoid_with_zero._proof_1}
Recursion and forall
/exists
#
succ
#
add
#
pred
#
mul
#
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.
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 le_rec_on'
.
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
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'
.
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
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.
Equations
- nat.strong_sub_recursion H n m = H n m (λ (x y : ℕ) (hx : x < n) (hy : y < m), nat.strong_sub_recursion H x y)
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.
Equations
- nat.pincer_recursion Ha0 H0b H a.succ b.succ = H a b (nat.pincer_recursion Ha0 H0b H a b.succ) (nat.pincer_recursion Ha0 H0b H a.succ b)
- nat.pincer_recursion Ha0 H0b H n.succ 0 = Ha0 n.succ
- nat.pincer_recursion Ha0 H0b H 0 n.succ = H0b n.succ
- nat.pincer_recursion Ha0 H0b H 0 0 = Ha0 0
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
.
Equations
- nat.le_rec_on' H next x = _.by_cases (λ (h : n ≤ m), next h (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
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
.
Equations
- nat.decreasing_induction' h mn hP = nat.le_rec_on' mn (λ (n : ℕ) (mn : m ≤ n) (ih : (Π (k : ℕ), k < n → m ≤ k → P (k + 1) → P k) → P n → P m) (h : Π (k : ℕ), k < n + 1 → m ≤ k → P (k + 1) → P k) (hP : P (n + 1)), ih (λ (k : ℕ) (hk : k < n), h k _) (h n _ mn hP)) (λ (h : Π (k : ℕ), k < m → m ≤ k → P (k + 1) → P k) (hP : P m), hP) h hP
div
#
A version of nat.div_lt_self
using successors, rather than additional hypotheses.
mod
, dvd
#
find
#
find_greatest
#
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
decidability of predicates #
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
Equations
- nat.decidable_forall_fin P = decidable_of_iff (∀ (k : ℕ) (h : k < n), P ⟨k, h⟩) _
Equations
- nat.decidable_exists_lt (n + 1) = decidable_of_decidable_of_iff or.decidable _
- nat.decidable_exists_lt 0 = decidable.is_false nat.decidable_exists_lt._main._proof_1
Equations
- nat.decidable_exists_le = λ (n : ℕ), decidable_of_iff (∃ (m : ℕ), m < n + 1 ∧ P m) _