Built with
doc-gen4 , running Lean4.
Bubbles (
) indicate interactive fragments: hover for details, tap to reveal contents.
Use
Ctrl+โ Ctrl+โ to navigate,
Ctrl+๐ฑ๏ธ to focus.
On Mac, use
Cmd instead of
Ctrl .
/-
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
/-!
# Basic operations on 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.
-/
universe u v
namespace Nat
/-! ### instances -/
instance nontrivial : Nontrivial โ :=
โจโจ 0 , 1 , Nat.zero_ne_one โฉโฉ
instance commSemiring : CommSemiring โ where
add := Nat.add
add_assoc := Nat.add_assoc : โ (n m k : โ ), n + m + k = n + (m + k ) Nat.add_assoc
zero := Nat.zero
zero_add := Nat.zero_add : โ (n : โ ), 0 + n = n Nat.zero_add
add_zero := Nat.add_zero : โ (n : โ ), n + 0 = n Nat.add_zero
add_comm := Nat.add_comm : โ (n m : โ ), n + m = m + n Nat.add_comm
mul := Nat.mul
mul_assoc := Nat.mul_assoc : โ (n m k : โ ), n * m * k = n * (m * k ) Nat.mul_assoc
one := Nat.succ Nat.zero
one_mul := Nat.one_mul : โ (n : โ ), 1 * n = n Nat.one_mul
mul_one := Nat.mul_one : โ (n : โ ), n * 1 = n Nat.mul_one
left_distrib := Nat.left_distrib : โ (n m k : โ ), n * (m + k ) = n * m + n * k Nat.left_distrib
right_distrib := Nat.right_distrib : โ (n m k : โ ), (n + m ) * k = n * k + m * k Nat.right_distrib
zero_mul := Nat.zero_mul : โ (n : โ ), 0 * n = 0 Nat.zero_mul
mul_zero := Nat.mul_zero : โ (n : โ ), n * 0 = 0 Nat.mul_zero
mul_comm := Nat.mul_comm : โ (n m : โ ), n * m = m * n Nat.mul_comm
natCast n := n
natCast_zero := rfl : โ {ฮฑ : Sort ?u.279} {a : ฮฑ }, a = a rfl
natCast_succ n := rfl : โ {ฮฑ : Sort ?u.285} {a : ฮฑ }, a = a rfl
nsmul m n := m * n
nsmul_zero := Nat.zero_mul : โ (n : โ ), 0 * n = 0 Nat.zero_mul
nsmul_succ _ _ := by (fun m n => m * n ) (xโยน + 1 ) xโ = xโ + (fun m n => m * n ) xโยน xโ dsimp only (xโยน + 1 ) * xโ = xโ + xโยน * xโ ; (xโยน + 1 ) * xโ = xโ + xโยน * xโ (fun m n => m * n ) (xโยน + 1 ) xโ = xโ + (fun m n => m * n ) xโยน xโ rw [ (xโยน + 1 ) * xโ = xโ + xโยน * xโ Nat.add_comm : โ (n m : โ ), n + m = m + n Nat.add_comm, (1 + xโยน ) * xโ = xโ + xโยน * xโ (xโยน + 1 ) * xโ = xโ + xโยน * xโ Nat.right_distrib : โ (n m k : โ ), (n + m ) * k = n * k + m * k Nat.right_distrib, 1 * xโ + xโยน * xโ = xโ + xโยน * xโ (xโยน + 1 ) * xโ = xโ + xโยน * xโ Nat.one_mul : โ (n : โ ), 1 * n = n Nat.one_mulxโ + xโยน * xโ = xโ + xโยน * xโ ]
npow m n := n ^ m
npow_zero := Nat.pow_zero : โ (n : โ ), n ^ 0 = 1 Nat.pow_zero
npow_succ _ _ := Nat.pow_succ'
/-! Extra instances to short-circuit type class resolution and ensure computability -/
instance addCommMonoid : AddCommMonoid : Type ?u.892 โ Type ?u.892 AddCommMonoid โ :=
inferInstance : {ฮฑ : Sort ?u.894} โ [i : ฮฑ ] โ ฮฑ inferInstance
instance addMonoid : AddMonoid : Type ?u.1154 โ Type ?u.1154 AddMonoid โ :=
inferInstance : {ฮฑ : Sort ?u.1156} โ [i : ฮฑ ] โ ฮฑ inferInstance
instance monoid : Monoid โ :=
inferInstance : {ฮฑ : Sort ?u.1408} โ [i : ฮฑ ] โ ฮฑ inferInstance
instance commMonoid : CommMonoid : Type ?u.1586 โ Type ?u.1586 CommMonoid โ :=
inferInstance : {ฮฑ : Sort ?u.1588} โ [i : ฮฑ ] โ ฮฑ inferInstance
instance commSemigroup : CommSemigroup : Type ?u.1721 โ Type ?u.1721 CommSemigroup โ :=
inferInstance : {ฮฑ : Sort ?u.1723} โ [i : ฮฑ ] โ ฮฑ inferInstance
instance semigroup : Semigroup : Type ?u.1890 โ Type ?u.1890 Semigroup โ :=
inferInstance : {ฮฑ : Sort ?u.1892} โ [i : ฮฑ ] โ ฮฑ inferInstance
instance addCommSemigroup : AddCommSemigroup : Type ?u.2056 โ Type ?u.2056 AddCommSemigroup โ :=
inferInstance : {ฮฑ : Sort ?u.2058} โ [i : ฮฑ ] โ ฮฑ inferInstance
instance addSemigroup : AddSemigroup : Type ?u.2156 โ Type ?u.2156 AddSemigroup โ :=
inferInstance : {ฮฑ : Sort ?u.2158} โ [i : ฮฑ ] โ ฮฑ inferInstance
instance distrib : Distrib โ :=
inferInstance : {ฮฑ : Sort ?u.2246} โ [i : ฮฑ ] โ ฮฑ inferInstance
instance semiring : Semiring โ :=
inferInstance : {ฮฑ : Sort ?u.2416} โ [i : ฮฑ ] โ ฮฑ inferInstance
protected theorem nsmul_eq_mul : โ (m n : โ ), m โข n = m * n nsmul_eq_mul ( m n : โ ) : m โข n = m * n :=
rfl : โ {ฮฑ : Sort ?u.2602} {a : ฮฑ }, a = a rfl
#align nat.nsmul_eq_mul Nat.nsmul_eq_mul : โ (m n : โ ), m โข n = m * n Nat.nsmul_eq_mul
-- Moved to core
#align nat.eq_of_mul_eq_mul_right Nat.eq_of_mul_eq_mul_right : โ {n m k : โ }, 0 < m โ n * m = k * m โ n = k Nat.eq_of_mul_eq_mul_right
instance cancelCommMonoidWithZero : CancelCommMonoidWithZero : Type ?u.2611 โ Type ?u.2611 CancelCommMonoidWithZero โ :=
{ ( inferInstance : {ฮฑ : Sort ?u.2617} โ [i : ฮฑ ] โ ฮฑ inferInstance : CommMonoidWithZero : Type ?u.2616 โ Type ?u.2616 CommMonoidWithZero โ ) with
mul_left_cancel_of_ne_zero :=
fun h1 h2 => Nat.eq_of_mul_eq_mul_left : โ {m k n : โ }, 0 < n โ n * m = n * k โ m = k Nat.eq_of_mul_eq_mul_left ( Nat.pos_of_ne_zero : โ {n : โ }, n โ 0 โ 0 < n Nat.pos_of_ne_zero h1 ) h2 }
#align nat.cancel_comm_monoid_with_zero Nat.cancelCommMonoidWithZero
attribute [ simp ]
Nat.not_lt_zero : โ (n : โ ), ยฌ n < 0 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 : โ }
/-!
### 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 : โ {motive : โ โ Sort ?u.3060 } (t : โ ), motive zero โ (โ (n : โ ), motive (succ n ) ) โ motive t Nat.casesOn n h . 1 h . 2 , fun h => โจ h _ , fun _ => h _ โฉโฉ
#align nat.and_forall_succ Nat.and_forall_succ : โ {p : โ โ Prop }, (p 0 โง โ (n : โ ), p (n + 1 ) ) โ โ (n : โ ), p n 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 or_exists_succ { p : โ โ Prop } : ( p 0 โจ โ n , p ( n + 1 )) โ โ n , p n :=
โจ fun h => h . elim : โ {a b c : Prop }, a โจ b โ (a โ c ) โ (b โ c ) โ c elim ( fun h0 => โจ 0 , h0 โฉ) fun โจ n , hn โฉ => โจ n + 1 , hn โฉ, by
(โ n , p n ) โ p 0 โจ โ n , p (n + 1 ) rintro โจ_ | n, hnโฉ : โ n , p n
โจ_ | n โจ_ | n, hnโฉ : โ n , p n
, hn : unknown free variable '_uniq.3446'
hn โจ_ | n, hnโฉ : โ n , p n
โฉ
(โ n , p n ) โ p 0 โจ โ n , p (n + 1 ) exacts [ Or.inl : โ {a b : Prop }, a โ a โจ b Or.inl hn , Or.inr : โ {a b : Prop }, b โ a โจ b Or.inr โจ n , hn โฉ] โฉ
#align nat.or_exists_succ Nat.or_exists_succ : โ {p : โ โ Prop }, (p 0 โจ โ n , p (n + 1 ) ) โ โ n , p n Nat.or_exists_succ
/-! ### `succ` -/
theorem _root_.LT.lt.nat_succ_le : โ {n m : โ }, n < m โ succ n โค m _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 : โ (n : โ ), succ n = 1 + n Nat.succ_eq_one_add
theorem eq_of_lt_succ_of_not_lt : โ {a b : โ }, a < b + 1 โ ยฌ a < b โ a = b 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 : โ {a b c : Prop }, a โจ b โ (a โ c ) โ (b โ c ) โ c Or.elim ( eq_or_lt_of_not_lt h2 ) ( fun h => h ) fun h => absurd : โ {a : Prop } {b : Sort ?u.3697}, a โ ยฌ a โ b absurd h ( not_lt_of_ge h3 )
#align nat.eq_of_lt_succ_of_not_lt Nat.eq_of_lt_succ_of_not_lt : โ {a b : โ }, a < b + 1 โ ยฌ a < b โ a = b Nat.eq_of_lt_succ_of_not_lt
theorem eq_of_le_of_lt_succ : โ {n m : โ }, n โค m โ m < n + 1 โ m = n eq_of_le_of_lt_succ { n m : โ } ( hโ : n โค m ) ( hโ : m < n + 1 ) : m = n :=
Nat.le_antisymm : โ {n m : โ }, n โค m โ m โค n โ n = m 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 : โ {n m : โ }, n โค m โ m < n + 1 โ m = n Nat.eq_of_le_of_lt_succ
-- 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'
-- Moved to Std
#align nat.succ_inj' Nat.succ_inj'
theorem succ_injective : Function.Injective : {ฮฑ : Sort ?u.3928} โ {ฮฒ : Sort ?u.3927} โ (ฮฑ โ ฮฒ ) โ Prop 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 : โ {a b : Prop }, (a โ b ) โ b โ a 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
theorem max_succ_succ { m n : โ } : max : {ฮฑ : Type ?u.4149} โ [self : Max ฮฑ ] โ ฮฑ โ ฮฑ โ ฮฑ max ( succ m ) ( succ n ) = succ ( max : {ฮฑ : Type ?u.4155} โ [self : Max ฮฑ ] โ ฮฑ โ ฮฑ โ ฮฑ max m n ) := by
by_cases h1 : m โค n mโ, nโ, k, m, n : โ h1 : m โค n pos neg
rw [ mโ, nโ, k, m, n : โ h1 : m โค n pos neg max_eq_right h1 , mโ, nโ, k, m, n : โ h1 : m โค n pos neg mโ, nโ, k, m, n : โ h1 : m โค n pos neg max_eq_right ( succ_le_succ h1 ) mโ, nโ, k, m, n : โ h1 : m โค n pos neg ]
ยท rw [ not_le mโ, nโ, k, m, n : โ h1 : n < m neg ] mโ, nโ, k, m, n : โ h1 : n < m neg at h1 mโ, nโ, k, m, n : โ h1 : n < m neg
have h2 := le_of_lt h1 mโ, nโ, k, m, n : โ h1 : n < m h2 : n โค m neg
rw [ mโ, nโ, k, m, n : โ h1 : n < m h2 : n โค m neg max_eq_left h2 , mโ, nโ, k, m, n : โ h1 : n < m h2 : n โค m neg mโ, nโ, k, m, n : โ h1 : n < m h2 : n โค m neg max_eq_left ( succ_le_succ h2 ) mโ, nโ, k, m, n : โ h1 : n < m h2 : n โค m neg ]
#align nat.max_succ_succ Nat.max_succ_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 : โ {a c b d : Prop }, (a โ c ) โ (b โ d ) โ a โจ b โ c โจ d imp le_of_lt_succ id : โ {ฮฑ : Sort ?u.5449}, ฮฑ โ ฮฑ 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 : โ }, 0 < n โ (m / n โค k โ m โค n * k + (n - 1 ) ) div_le_iff_le_mul_add_pred { m n k : โ } ( n0 : 0 < n ) : m / n โค k โ m โค n * k + ( n - 1 ) := by
mโ, nโ, kโ, m, n, k : โ n0 : 0 < n rw [ mโ, nโ, kโ, m, n, k : โ n0 : 0 < n โ lt_succ_iff , mโ, nโ, kโ, m, n, k : โ n0 : 0 < n mโ, nโ, kโ, m, n, k : โ n0 : 0 < n div_lt_iff_lt_mul n0 , mโ, nโ, kโ, m, n, k : โ n0 : 0 < n mโ, nโ, kโ, m, n, k : โ n0 : 0 < n succ_mul , mโ, nโ, kโ, m, n, k : โ n0 : 0 < n mโ, nโ, kโ, m, n, k : โ n0 : 0 < n mul_comm mโ, nโ, kโ, m, n, k : โ n0 : 0 < n ] mโ, nโ, kโ, m, n, k : โ n0 : 0 < n
mโ, nโ, kโ, m, n, k : โ n0 : 0 < n cases n
mโ, nโ, kโ, m, n, k : โ n0 : 0 < n ยท cases n0
mโ, nโ, kโ, m, n, k : โ n0 : 0 < n exact lt_succ_iff
#align nat.div_le_iff_le_mul_add_pred Nat.div_le_iff_le_mul_add_pred : โ {m n k : โ }, 0 < n โ (m / n โค k โ m โค n * k + (n - 1 ) ) Nat.div_le_iff_le_mul_add_pred
theorem two_lt_of_ne : โ {n : โ }, n โ 0 โ n โ 1 โ n โ 2 โ 2 < n two_lt_of_ne : โ { n }, n โ 0 โ n โ 1 โ n โ 2 โ 2 < n
| 0 , h , _, _ => ( h rfl : โ {ฮฑ : Sort ?u.6259} {a : ฮฑ }, a = a rfl). elim
| 1 , _, h , _ => ( h rfl : โ {ฮฑ : Sort ?u.6299} {a : ฮฑ }, a = a rfl). elim
| 2 , _, _, h => ( h rfl : โ {ฮฑ : Sort ?u.6336} {a : ฮฑ }, a = a rfl). elim
-- Porting note: was `by decide`
| n + 3, _, _, _ => by m, nโ, k, n : โ xโยฒ : n + 3 โ 0 xโยน : n + 3 โ 1 xโ : n + 3 โ 2 rw [ m, nโ, k, n : โ xโยฒ : n + 3 โ 0 xโยน : n + 3 โ 1 xโ : n + 3 โ 2 Nat.lt_iff_add_one_le m, nโ, k, n : โ xโยฒ : n + 3 โ 0 xโยน : n + 3 โ 1 xโ : n + 3 โ 2 ] m, nโ, k, n : โ xโยฒ : n + 3 โ 0 xโยน : n + 3 โ 1 xโ : n + 3 โ 2 ; m, nโ, k, n : โ xโยฒ : n + 3 โ 0 xโยน : n + 3 โ 1 xโ : n + 3 โ 2 m, nโ, k, n : โ xโยฒ : n + 3 โ 0 xโยน : n + 3 โ 1 xโ : n + 3 โ 2 convert Nat.le_add_left : โ (n m : โ ), n โค m + n Nat.le_add_left 3 n
#align nat.two_lt_of_ne Nat.two_lt_of_ne : โ {n : โ }, n โ 0 โ n โ 1 โ n โ 2 โ 2 < n 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 : โ {ฮฑ : Sort ?u.7069} {p q : ฮฑ โ Prop } {a' : ฮฑ }, (โ (a : ฮฑ ), a = a' โจ q a โ p a ) โ p a' โง โ (a : ฮฑ ), q a โ p a 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 : โ {ฮฑ : Sort ?u.7695} {a : ฮฑ }, a = a rfl
#align nat.add_def Nat.add_def
@[ simp ]
theorem mul_def { a b : โ } : Nat.mul a b = a * b :=
rfl : โ {ฮฑ : Sort ?u.7771} {a : ฮฑ }, a = a rfl
#align nat.mul_def Nat.mul_def
theorem exists_eq_add_of_le : m โค n โ โ k , n = m + k exists_eq_add_of_le ( h : m โค n ) : โ k : โ , n = m + k :=
โจ n - m , ( add_sub_of_le : โ {a b : โ }, a โค b โ a + (b - a ) = b add_sub_of_le h ). symm : โ {ฮฑ : Sort ?u.7908} {a b : ฮฑ }, a = b โ b = a symm โฉ
#align nat.exists_eq_add_of_le Nat.exists_eq_add_of_le : โ {m n : โ }, m โค n โ โ k , n = m + k Nat.exists_eq_add_of_le
theorem exists_eq_add_of_le' : m โค n โ โ k , n = k + m exists_eq_add_of_le' ( h : m โค n ) : โ k : โ , n = k + m :=
โจ n - m , ( Nat.sub_add_cancel : โ {n m : โ }, m โค n โ n - m + m = n Nat.sub_add_cancel h ). symm : โ {ฮฑ : Sort ?u.8046} {a b : ฮฑ }, a = b โ b = a symm โฉ
#align nat.exists_eq_add_of_le' Nat.exists_eq_add_of_le' : โ {m n : โ }, m โค n โ โ k , n = k + m Nat.exists_eq_add_of_le'
theorem exists_eq_add_of_lt : โ {m n : โ }, m < n โ โ k , n = m + k + 1 exists_eq_add_of_lt ( h : m < n ) : โ k : โ , n = m + k + 1 :=
โจ n - ( m + 1 ), by n = m + (n - (m + 1 ) ) + 1 rw [ n = m + (n - (m + 1 ) ) + 1 add_right_comm , n = m + 1 + (n - (m + 1 ) ) n = m + (n - (m + 1 ) ) + 1 add_sub_of_le : โ {a b : โ }, a โค b โ a + (b - a ) = b add_sub_of_le h ] โฉ
#align nat.exists_eq_add_of_lt Nat.exists_eq_add_of_lt : โ {m n : โ }, m < n โ โ k , n = m + k + 1 Nat.exists_eq_add_of_lt
/-! ### `pred` -/
@[ simp ]
theorem add_succ_sub_one : โ (n m : โ ), n + succ m - 1 = n + m 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 : โ (n m : โ ), n + succ m - 1 = n + m Nat.add_succ_sub_one
@[ simp ]
theorem succ_add_sub_one : โ (n m : โ ), succ n + m - 1 = n + m succ_add_sub_one ( n m : โ ) : succ n + m - 1 = n + m := by rw [ succ_add , succ_sub_one ]
#align nat.succ_add_sub_one Nat.succ_add_sub_one : โ (n m : โ ), succ n + m - 1 = n + m Nat.succ_add_sub_one
theorem pred_eq_sub_one : โ (n : โ ), pred n = n - 1 pred_eq_sub_one ( n : โ ) : pred n = n - 1 :=
rfl : โ {ฮฑ : Sort ?u.8810} {a : ฮฑ }, a = a rfl
#align nat.pred_eq_sub_one Nat.pred_eq_sub_one : โ (n : โ ), pred n = n - 1 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 : โ {m n : โ }, m = succ n โ pred m = n 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 <;> zero.mp zero.mpr succ.mp succ.mpr rintro โจโฉ <;> succ.mp.refl succ.mpr.refl 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 : โ (n m k : โ ), n - m - k = n - (m + k ) 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 : โ {m n : โ }, m < n โ m โค n - 1 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 : โ {ฮฑ : Sort ?u.9749}, ฮฑ โ ฮฑ id
#align nat.le_of_pred_lt Nat.le_of_pred_lt
/-- This ensures that `simp` succeeds on `pred (n + 1) = n`. -/
@[ simp ]
theorem pred_one_add : โ (n : โ ), pred (1 + n ) = n 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 : โ (n : โ ), pred (1 + n ) = n Nat.pred_one_add
/-! ### `mul` -/
theorem two_mul_ne_two_mul_add_one : โ {n m : โ }, 2 * n โ 2 * m + 1 two_mul_ne_two_mul_add_one { n m } : 2 * n โ 2 * m + 1 :=
mt : โ {a b : Prop }, (a โ b ) โ ยฌ b โ ยฌ a mt ( congr_arg : โ {ฮฑ : Sort ?u.10389} {ฮฒ : Sort ?u.10388} {aโ aโ : ฮฑ } (f : ฮฑ โ ฮฒ ), aโ = aโ โ f aโ = f aโ congr_arg (ยท % 2) )
( by rw [ add_comm , add_mul_mod_self_left : โ (x y z : โ ), (x + y * z ) % y = x % y add_mul_mod_self_left, mul_mod_right : โ (m n : โ ), m * n % m = 0 mul_mod_right, mod_eq_of_lt : โ {a b : โ }, a < b โ a % b = a mod_eq_of_lt] <;> simp )
#align nat.two_mul_ne_two_mul_add_one Nat.two_mul_ne_two_mul_add_one : โ {n m : โ }, 2 * n โ 2 * m + 1 Nat.two_mul_ne_two_mul_add_one
theorem mul_ne_mul_left : โ {a b c : โ }, 0 < a โ (b * a โ c * a โ b โ c ) 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 : โ {a b c : โ }, 0 < a โ (b * a โ c * a โ b โ c ) Nat.mul_ne_mul_left
theorem mul_ne_mul_right : โ {a b c : โ }, 0 < a โ (a * b โ a * c โ b โ c ) 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 : โ {a b c : โ }, 0 < a โ (a * b โ a * c โ b โ c ) Nat.mul_ne_mul_right
theorem mul_right_eq_self_iff : โ {a b : โ }, 0 < a โ (a * b = a โ b = 1 ) 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 : โ {a b : โ }, 0 < a โ (a * b = a โ b = 1 ) Nat.mul_right_eq_self_iff
theorem mul_left_eq_self_iff : โ {a b : โ }, 0 < b โ (a * b = b โ a = 1 ) 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 : โ {a b : โ }, 0 < a โ (a * b = a โ b = 1 ) Nat.mul_right_eq_self_iff hb ]
#align nat.mul_left_eq_self_iff Nat.mul_left_eq_self_iff : โ {a b : โ }, 0 < b โ (a * b = b โ a = 1 ) 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
/-!
### 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 ) ), rec h0 h 0 = h0 rec_zero { C : โ โ Sort u } ( h0 : C 0 ) ( h : (n : โ ) โ C n โ C (n + 1 ) h : โ n , C n โ C ( n + 1 )) :
Nat.rec : {motive : โ โ Sort ?u.12061 } โ motive zero โ ((n : โ ) โ motive n โ motive (succ n ) ) โ (t : โ ) โ motive t Nat.rec h0 h : (n : โ ) โ C n โ C (n + 1 ) h 0 = h0 :=
rfl : โ {ฮฑ : Sort ?u.12119} {a : ฮฑ }, a = a rfl
#align nat.rec_zero Nat.rec_zero : โ {C : โ โ Sort u } (h0 : C 0 ) (h : (n : โ ) โ C n โ C (n + 1 ) ), rec h0 h 0 = h0 Nat.rec_zero
@[ simp ]
theorem rec_add_one : โ {C : โ โ Sort u } (h0 : C 0 ) (h : (n : โ ) โ C n โ C (n + 1 ) ) (n : โ ), rec h0 h (n + 1 ) = h n (rec h0 h n ) rec_add_one { C : โ โ Sort u } ( h0 : C 0 ) ( h : (n : โ ) โ C n โ C (n + 1 ) h : โ n , C n โ C ( n + 1 )) ( n : โ ) :
Nat.rec : {motive : โ โ Sort ?u.12340 } โ motive zero โ ((n : โ ) โ motive n โ motive (succ n ) ) โ (t : โ ) โ motive t Nat.rec h0 h : (n : โ ) โ C n โ C (n + 1 ) h ( n + 1 ) = h : (n : โ ) โ C n โ C (n + 1 ) h n ( Nat.rec : {motive : โ โ Sort ?u.12267 } โ motive zero โ ((n : โ ) โ motive n โ motive (succ n ) ) โ (t : โ ) โ motive t Nat.rec h0 h : (n : โ ) โ C n โ C (n + 1 ) h n ) :=
rfl : โ {ฮฑ : Sort ?u.12429} {a : ฮฑ }, a = a rfl
#align nat.rec_add_one Nat.rec_add_one : โ {C : โ โ Sort u } (h0 : C 0 ) (h : (n : โ ) โ C n โ C (n + 1 ) ) (n : โ ), rec h0 h (n + 1 ) = h n (rec h0 h n ) 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 leRecOn { C : โ โ Sort u } { n : โ } : โ { m : โ }, n โค m โ (โ { k }, C k โ C ( k + 1 )) โ C n โ C m
| 0 , H , _, x => Eq.recOn : {ฮฑ : Sort ?u.12643} โ
{a : ฮฑ } โ
{motive : (a_1 : ฮฑ ) โ a = a_1 โ Sort ?u.12644 } โ {a_1 : ฮฑ } โ (t : a = a_1 ) โ motive a (_ : a = a ) โ motive a_1 t Eq.recOn ( Nat.eq_zero_of_le_zero : โ {n : โ }, n โค 0 โ n = 0 Nat.eq_zero_of_le_zero H ) x
| m + 1, H , next : {k : โ } โ C k โ C (k + 1 ) next , x =>
Or.by_cases : {p q : Prop } โ [inst : Decidable p ] โ {ฮฑ : Sort ?u.12773} โ p โจ q โ (p โ ฮฑ ) โ (q โ ฮฑ ) โ ฮฑ Or.by_cases ( of_le_succ H ) ( fun h : n โค m => next : {k : โ } โ C k โ C (k + 1 ) next <| leRecOn : {C : โ โ Sort u } โ {n m : โ } โ n โค m โ ({k : โ } โ C k โ C (k + 1 ) ) โ C n โ C m leRecOn h ( @ next : {k : โ } โ C k โ C (k + 1 ) next ) x )
fun h : n = m + 1 => Eq.recOn : {ฮฑ : Sort ?u.12922} โ
{a : ฮฑ } โ
{motive : (a_1 : ฮฑ ) โ a = a_1 โ Sort ?u.12923 } โ {a_1 : ฮฑ } โ (t : a = a_1 ) โ motive a (_ : a = a ) โ motive a_1 t Eq.recOn h x
#align nat.le_rec_on Nat.leRecOn : {C : โ โ Sort u } โ {n m : โ } โ n โค m โ ({k : โ } โ C k โ C (k + 1 ) ) โ C n โ C m Nat.leRecOn
theorem leRecOn_self : โ {C : โ โ Sort u } {n : โ } {h : n โค n } {next : {k : โ } โ C k โ C (k + 1 ) } (x : C n ), leRecOn h (fun {k } => next ) x = x leRecOn_self { C : โ โ Sort u } { n } { h : n โค n } { next : {k : โ } โ C k โ C (k + 1 ) next : โ { k }, C k โ C ( k + 1 )} ( x : C n ) :
( leRecOn : {C : โ โ Sort ?u.13905 } โ {n m : โ } โ n โค m โ ({k : โ } โ C k โ C (k + 1 ) ) โ C n โ C m leRecOn h next : {k : โ } โ C k โ C (k + 1 ) next x : C n ) = x := by
cases n <;> unfold leRecOn : {C : โ โ Sort u } โ {n m : โ } โ n โค m โ ({k : โ } โ C k โ C (k + 1 ) ) โ C n โ C m leRecOn Eq.recOn : {ฮฑ : Sort u_1} โ
{a : ฮฑ } โ {motive : (a_1 : ฮฑ ) โ a = a_1 โ Sort u } โ {a_1 : ฮฑ } โ (t : a = a_1 ) โ motive a (_ : a = a ) โ motive a_1 t Eq.recOn
ยท simp
ยท unfold Or.by_cases : {p q : Prop } โ [inst : Decidable p ] โ {ฮฑ : Sort u} โ p โจ q โ (p โ ฮฑ ) โ (q โ ฮฑ ) โ ฮฑ Or.by_casessucc (if hp : succ nโ โค nโ then (fun h => (fun {k } => next ) (leRecOn h (fun {k } => next ) x ) ) hp
else (fun h => h โธ x ) (_ : succ nโ = succ nโ ) ) = x
rw [ succ (if hp : succ nโ โค nโ then (fun h => (fun {k } => next ) (leRecOn h (fun {k } => next ) x ) ) hp
else (fun h => h โธ x ) (_ : succ nโ = succ nโ ) ) = x dif_neg ( Nat.not_succ_le_self _ ) succ (fun h => h โธ x ) (_ : succ nโ = succ nโ ) = x ]
#align nat.le_rec_on_self Nat.leRecOn_self : โ {C : โ โ Sort u } {n : โ } {h : n โค n } {next : {k : โ } โ C k โ C (k + 1 ) } (x : C n ), leRecOn h (fun {k } => next ) x = x Nat.leRecOn_self
theorem leRecOn_succ : โ {C : โ โ Sort u } {n m : โ } (h1 : n โค m ) {h2 : n โค m + 1 } {next : {k : โ } โ C k โ C (k + 1 ) } (x : C n ),
leRecOn h2 next x = next (leRecOn h1 next x ) leRecOn_succ { C : โ โ Sort u } { n m } ( h1 : n โค m ) { h2 : n โค m + 1 } { next } ( x : C n ) :
( leRecOn : {C : โ โ Sort ?u.16188 } โ {n m : โ } โ n โค m โ ({k : โ } โ C k โ C (k + 1 ) ) โ C n โ C m leRecOn h2 ( @ next ) x : C ( m + 1 )) = next ( leRecOn : {C : โ โ Sort ?u.16236 } โ {n m : โ } โ n โค m โ ({k : โ } โ C k โ C (k + 1 ) ) โ C n โ C m leRecOn h1 ( @ next ) x : C m ) := by
conv =>
lhs
rw [ leRecOn : {C : โ โ Sort ?u.16353 } โ {n m : โ } โ n โค m โ ({k : โ } โ C k โ C (k + 1 ) ) โ C n โ C m leRecOn, Or.by_cases : {p q : Prop } โ [inst : Decidable p ] โ {ฮฑ : Sort ?u.16582} โ p โจ q โ (p โ ฮฑ ) โ (q โ ฮฑ ) โ ฮฑ Or.by_cases, dif_pos : โ {c : Prop } {h : Decidable c } (hc : c ) {ฮฑ : Sort ?u.16583} {t : c โ ฮฑ } {e : ยฌ c โ ฮฑ }, dite c t e = t hc dif_pos h1 ]
#align nat.le_rec_on_succ Nat.leRecOn_succ : โ {C : โ โ Sort u } {n m : โ } (h1 : n โค m ) {h2 : n โค m + 1 } {next : {k : โ } โ C k โ C (k + 1 ) } (x : C n ),
leRecOn h2 next x = next (leRecOn h1 next x ) 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 (fun {k } => next ) x = next x leRecOn_succ' { C : โ โ Sort u } { n } { h : n โค n + 1 } { next : {k : โ } โ C k โ C (k + 1 ) next : โ { k }, C k โ C ( k + 1 )}
( x : C n ) :
( leRecOn : {C : โ โ Sort ?u.16882 } โ {n m : โ } โ n โค m โ ({k : โ } โ C k โ C (k + 1 ) ) โ C n โ C m leRecOn h next : {k : โ } โ C k โ C (k + 1 ) next x : C ( n + 1 )) = next : {k : โ } โ C k โ C (k + 1 ) next x := by leRecOn h (fun {k } => next ) x = next x rw [ leRecOn h (fun {k } => next ) x = next x leRecOn_succ : โ {C : โ โ Sort ?u.16957 } {n m : โ } (h1 : n โค m ) {h2 : n โค m + 1 } {next : {k : โ } โ C k โ C (k + 1 ) } (x : C n ),
leRecOn h2 next x = next (leRecOn h1 next x ) leRecOn_succ ( le_refl n ), next (leRecOn (_ : n โค n ) (fun {k } => next ) x ) = next x leRecOn h (fun {k } => next ) x = next x leRecOn_self : โ {C : โ โ Sort ?u.17001 } {n : โ } {h : n โค n } {next : {k : โ } โ C k โ C (k + 1 ) } (x : C n ),
leRecOn h (fun {k } => next ) x = x leRecOn_self]
#align nat.le_rec_on_succ' Nat.leRecOn_succ' : โ {C : โ โ Sort u } {n : โ } {h : n โค n + 1 } {next : {k : โ } โ C k โ C (k + 1 ) } (x : C n ),
leRecOn h (fun {k } => next ) x = next x Nat.leRecOn_succ'
theorem leRecOn_trans { C : โ โ Sort u } { n m k } ( hnm : n โค m ) ( hmk : m โค k ) { next } ( x : C n ) :
( leRecOn : {C : โ โ Sort ?u.17148 } โ {n m : โ } โ n โค m โ ({k : โ } โ C k โ C (k + 1 ) ) โ C n โ C m leRecOn ( le_trans hnm hmk ) ( @ next ) x : C k ) = leRecOn : {C : โ โ Sort ?u.17251 } โ {n m : โ } โ n โค m โ ({k : โ } โ C k โ C (k + 1 ) ) โ C n โ C m leRecOn hmk ( @ next ) ( leRecOn : {C : โ โ Sort ?u.17280 } โ {n m : โ } โ n โค m โ ({k : โ } โ C k โ C (k + 1 ) ) โ C n โ C m leRecOn hnm ( @ next ) x ) := by
mโ, nโ, kโ : โ C : โ โ Sort un, m, k : โ hnm : n โค m hmk : m โค k next : {k : โ } โ C k โ C (k + 1 ) x : C n induction' hmk with k hmk ih mโ, nโ, kโ : โ C : โ โ Sort un, m, k : โ hnm : n โค m next : {k : โ } โ C k โ C (k + 1 ) x : C n refl step
mโ, nโ, kโ : โ C : โ โ Sort un, m, k : โ hnm : n โค m hmk : m โค k next : {k : โ } โ C k โ C (k + 1 ) x : C n ยท mโ, nโ, kโ : โ C : โ โ Sort un, m, k : โ hnm : n โค m next : {k : โ } โ C k โ C (k + 1 ) x : C n refl mโ, nโ, kโ : โ C : โ โ Sort un, m, k : โ hnm : n โค m next : {k : โ } โ C k โ C (k + 1 ) x : C n refl step rw [ mโ, nโ, kโ : โ C : โ โ Sort un, m, k : โ hnm : n โค m next : {k : โ } โ C k โ C (k + 1 ) x : C n refl leRecOn_self : โ {C : โ โ Sort ?u.17355 } {n : โ } {h : n โค n } {next : {k : โ } โ C k โ C (k + 1 ) } (x : C n ),
leRecOn h (fun {k } => next ) x = x leRecOn_selfmโ, nโ, kโ : โ C : โ โ Sort un, m, k : โ hnm : n โค m next : {k : โ } โ C k โ C (k + 1 ) x : C n refl ]
mโ, nโ, kโ : โ C : โ โ Sort un, m, k : โ hnm : n โค m hmk : m โค k next : {k : โ } โ C k โ C (k + 1 ) x : C n rw [