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) 2022 Yury Kudryashov. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yury Kudryashov
! This file was ported from Lean 3 source module data.enat.basic
! leanprover-community/mathlib commit ceb887ddf3344dab425292e497fa2af91498437c
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathlib.Data.Nat.SuccPred
import Mathlib.Algebra.CharZero.Lemmas
import Mathlib.Algebra.Order.Sub.WithTop
import Mathlib.Algebra.Order.Ring.WithTop
/-!
# Definition and basic properties of extended natural numbers
In this file we define `ENat` (notation: `ββ`) to be `WithTop β` and prove some basic lemmas
about this type.
## Implementation details
There are two natural coercions from `β` to `WithTop β = ENat`: `WithTop.some` and `Nat.cast`. In
Lean 3, this difference was hidden in typeclass instances. Since these instances were definitionally
equal, we did not duplicate generic lemmas about `WithTop Ξ±` and `WithTop.some` coercion for `ENat`
and `Nat.cast` coercion. If you need to apply a lemma about `WithTop`, you may either rewrite back
and forth using `ENat.some_eq_coe`, or restate the lemma for `ENat`.
-/
/-- Extended natural numbers `ββ = WithTop β`. -/
def ENat : Type :=
WithTop β
deriving Zero,
-- AddCommMonoidWithOne,
CanonicallyOrderedCommSemiring, Nontrivial,
LinearOrder, Bot, Top, CanonicallyLinearOrderedAddMonoid, Sub,
LinearOrderedAddCommMonoidWithTop, WellFoundedRelation, Inhabited
-- OrderBot, OrderTop, OrderedSub, SuccOrder, WellFoundedLt, CharZero
#align enat ENat
-- Porting Note: In `Data.Nat.ENatPart` proofs timed out when having
-- the `deriving AddCommMonoidWithOne`, and it seems to work without.
/-- Extended natural numbers `ββ = WithTop β`. -/
notation "ββ" => ENat
namespace ENat
--Porting note: instances that derive failed to find
instance : OrderBot : (Ξ± : Type ?u.7602) β [inst : LE Ξ± ] β Type ?u.7602 OrderBot ββ := WithTop.orderBot
instance : OrderTop : (Ξ± : Type ?u.8131) β [inst : LE Ξ± ] β Type ?u.8131 OrderTop ββ := WithTop.orderTop
instance : OrderedSub : (Ξ± : Type ?u.8522) β [inst : LE Ξ± ] β [inst : Add Ξ± ] β [inst : Sub Ξ± ] β Prop OrderedSub ββ := inferInstanceAs : β (Ξ± : Sort ?u.8884) [i : Ξ± ], Ξ± inferInstanceAs ( OrderedSub : (Ξ± : Type ?u.8885) β [inst : LE Ξ± ] β [inst : Add Ξ± ] β [inst : Sub Ξ± ] β Prop OrderedSub ( WithTop β ))
instance : SuccOrder ββ := inferInstanceAs : (Ξ± : Sort ?u.9272) β [i : Ξ± ] β Ξ± inferInstanceAs ( SuccOrder ( WithTop β ))
instance : WellFoundedLT : (Ξ± : Type ?u.9762) β [inst : LT Ξ± ] β Prop WellFoundedLT ββ := inferInstanceAs : β (Ξ± : Sort ?u.9933) [i : Ξ± ], Ξ± inferInstanceAs ( WellFoundedLT : (Ξ± : Type ?u.9934) β [inst : LT Ξ± ] β Prop WellFoundedLT ( WithTop β ))
instance : CharZero ββ := inferInstanceAs : β (Ξ± : Sort ?u.10303) [i : Ξ± ], Ξ± inferInstanceAs ( CharZero ( WithTop : Type ?u.10305 β Type ?u.10305 WithTop β ))
instance : IsWellOrder : (Ξ± : Type ?u.10510) β (Ξ± β Ξ± β Prop ) β Prop IsWellOrder ββ (Β· < Β·) where
variable { m n : ββ }
/-- Lemmas about `WithTop` expect (and can output) `WithTop.some` but the normal form for coercion
`β β ββ` is `Nat.cast`. -/
@[ simp ] theorem some_eq_coe : WithTop.some = Nat.cast some_eq_coe : ( WithTop.some : {Ξ± : Type ?u.10918} β Ξ± β WithTop Ξ± WithTop.some : β β ββ ) = Nat.cast := rfl : β {Ξ± : Sort ?u.11047} {a : Ξ± }, a = a rfl
--Porting note: `simp` and `norm_cast` can prove it
--@[simp, norm_cast]
theorem coe_zero : (( 0 : β ) : ββ ) = 0 :=
rfl : β {Ξ± : Sort ?u.11159} {a : Ξ± }, a = a rfl
#align enat.coe_zero ENat.coe_zero
--Porting note: `simp` and `norm_cast` can prove it
--@[simp, norm_cast]
theorem coe_one : (( 1 : β ) : ββ ) = 1 :=
rfl : β {Ξ± : Sort ?u.11269} {a : Ξ± }, a = a rfl
#align enat.coe_one ENat.coe_one
--Porting note: `simp` and `norm_cast` can prove it
--@[simp, norm_cast]
theorem coe_add : β (m n : β ), β(m + n ) = βm + βn coe_add ( m n : β ) : β( m + n ) = ( m + n : ββ ) :=
rfl : β {Ξ± : Sort ?u.11897} {a : Ξ± }, a = a rfl
#align enat.coe_add ENat.coe_add : β (m n : β ), β(m + n ) = βm + βn ENat.coe_add
@[ simp , norm_cast ]
theorem coe_sub : β (m n : β ), β(m - n ) = βm - βn coe_sub ( m n : β ) : β( m - n ) = ( m - n : ββ ) :=
rfl : β {Ξ± : Sort ?u.12203} {a : Ξ± }, a = a rfl
#align enat.coe_sub ENat.coe_sub : β (m n : β ), β(m - n ) = βm - βn ENat.coe_sub
--Porting note: `simp` and `norm_cast` can prove it
--@[simp, norm_cast]
theorem coe_mul : β (m n : β ), β(m * n ) = βm * βn coe_mul ( m n : β ) : β( m * n ) = ( m * n : ββ ) :=
WithTop.coe_mul
#align enat.coe_mul ENat.coe_mul : β (m n : β ), β(m * n ) = βm * βn ENat.coe_mul
instance canLift : CanLift ββ β (β) fun n => n β β€ :=
WithTop.canLift
#align enat.can_lift ENat.canLift
/-- Conversion of `ββ` to `β` sending `β` to `0`. -/
def toNat : MonoidWithZeroHom ββ β
where
toFun := WithTop.untop' : {Ξ± : Type ?u.13289} β Ξ± β WithTop Ξ± β Ξ± WithTop.untop' 0
map_one' := rfl : β {Ξ± : Sort ?u.13327} {a : Ξ± }, a = a rfl
map_zero' := rfl : β {Ξ± : Sort ?u.13308} {a : Ξ± }, a = a rfl
map_mul' := WithTop.untop'_zero_mul
#align enat.to_nat ENat.toNat
@[ simp ]
theorem toNat_coe ( n : β ) : toNat n = n :=
rfl : β {Ξ± : Sort ?u.14928} {a : Ξ± }, a = a rfl
#align enat.to_nat_coe ENat.toNat_coe : β (n : β ), βtoNat βn = n ENat.toNat_coe
@[ simp ]
theorem toNat_top : toNat β€ = 0 :=
rfl : β {Ξ± : Sort ?u.15587} {a : Ξ± }, a = a rfl
#align enat.to_nat_top ENat.toNat_top
--Porting note: new definition copied from `WithTop`
/-- Recursor for `ENat` using the preferred forms `β€` and `βa`. -/
@[elab_as_elim]
def recTopCoe { C : ββ β Sort _ } ( hβ : C β€ ) ( hβ : (a : β ) β C βa hβ : β a : β , C a ) : β n : ββ , C n
| none => hβ
| Option.some : {Ξ± : Type ?u.15731} β Ξ± β Option Ξ± Option.some a => hβ : (a : β ) β C βa hβ a
--Porting note: new theorem copied from `WithTop`
@[ simp ]
theorem recTopCoe_top { C : ββ β Sort _ } ( d : C β€ ) ( f : β a : β , C a ) :
@ recTopCoe C d f β€ = d :=
rfl : β {Ξ± : Sort ?u.16061} {a : Ξ± }, a = a rfl
--Porting note: new theorem copied from `WithTop`
@[ simp ]
theorem recTopCoe_coe { C : ββ β Sort _ } ( d : C β€ ) ( f : β a : β , C a ) ( x : β ) :
@ recTopCoe C d f β x = f x :=
rfl : β {Ξ± : Sort ?u.16229} {a : Ξ± }, a = a rfl
--Porting note: new theorem copied from `WithTop`
@[ simp ]
theorem top_ne_coe ( a : β ) : β€ β ( a : ββ ) :=
fun .
--Porting note: new theorem copied from `WithTop`
@[ simp ]
theorem coe_ne_top ( a : β ) : ( a : ββ ) β β€ :=
fun .
--Porting note: new theorem copied from `WithTop`
@[ simp ]
theorem top_sub_coe ( a : β ) : ( β€ : ββ ) - a = β€ :=
WithTop.top_sub_coe : β {Ξ± : Type ?u.16835} [inst : Sub Ξ± ] [inst_1 : Zero Ξ± ] {a : Ξ± }, β€ - βa = β€ WithTop.top_sub_coe
--Porting note: new theorem copied from `WithTop`
theorem sub_top ( a : ββ ) : a - β€ = 0 :=
WithTop.sub_top
@[ simp ]
theorem coe_toNat_eq_self : ENat.toNat ( n : ββ ) = n β n β β€ :=
ENat.recTopCoe : β {C : ββ β Sort ?u.19296 }, C β€ β (β (a : β ), C βa ) β β (n : ββ ), C n ENat.recTopCoe ( by simp ) ( fun _ => by simp [ toNat_coe ] ) n
#align enat.coe_to_nat_eq_self ENat.coe_toNat_eq_self
alias coe_toNat_eq_self β _ coe_toNat
#align enat.coe_to_nat ENat.coe_toNat
theorem coe_toNat_le_self ( n : ββ ) : β( toNat n ) β€ n :=
ENat.recTopCoe : β {C : ββ β Sort ?u.20711 }, C β€ β (β (a : β ), C βa ) β β (n : ββ ), C n ENat.recTopCoe le_top ( fun _ => le_rfl ) n
#align enat.coe_to_nat_le_self ENat.coe_toNat_le_self
theorem toNat_add { m n : ββ } ( hm : m β β€ ) ( hn : n β β€ ) : toNat ( m + n ) = toNat m + toNat n := by
lift m to β using hm
lift n to β using hn
rfl
#align enat.to_nat_add ENat.toNat_add
theorem toNat_sub { n : ββ } ( hn : n β β€ ) ( m : ββ ) : toNat ( m - n ) = toNat m - toNat n := by
lift n to β using hn
induction m using ENat.recTopCoe
Β· rw [ top_sub_coe , toNat_top , zero_tsub ]
Β· rw [ β coe_sub : β (m n : β ), β(m - n ) = βm - βn coe_sub, toNat_coe , toNat_coe , toNat_coe ]
#align enat.to_nat_sub ENat.toNat_sub
theorem toNat_eq_iff { m : ββ } { n : β } ( hn : n β 0 ) : toNat m = n β m = n := by
induction m using ENat.recTopCoe <;> simp [ hn . symm : β {Ξ± : Sort ?u.26376} {a b : Ξ± }, a β b β b β a symm]
#align enat.to_nat_eq_iff ENat.toNat_eq_iff
@[ simp ]
theorem succ_def ( m : ββ ) : Order.succ m = m + 1 := by cases m <;> rfl
#align enat.succ_def ENat.succ_def
theorem add_one_le_of_lt : m < n β m + 1 β€ n add_one_le_of_lt ( h : m < n ) : m + 1 β€ n :=
m . succ_def βΈ Order.succ_le_of_lt h
#align enat.add_one_le_of_lt ENat.add_one_le_of_lt : β {m n : ββ }, m < n β m + 1 β€ n ENat.add_one_le_of_lt
theorem add_one_le_iff ( hm : m β β€ ) : m + 1 β€ n β m < n :=
m . succ_def βΈ ( Order.succ_le_iff_of_not_isMax <| by rwa [ isMax_iff_eq_top ] )
#align enat.add_one_le_iff ENat.add_one_le_iff
theorem one_le_iff_pos : 1 β€ n β 0 < n :=
add_one_le_iff WithTop.zero_ne_top : β {Ξ± : Type ?u.30242} [inst : Zero Ξ± ], 0 β β€ WithTop.zero_ne_top
#align enat.one_le_iff_pos ENat.one_le_iff_pos
theorem one_le_iff_ne_zero : 1 β€ n β n β 0 :=
one_le_iff_pos . trans pos_iff_ne_zero
#align enat.one_le_iff_ne_zero ENat.one_le_iff_ne_zero
theorem le_of_lt_add_one : m < n + 1 β m β€ n le_of_lt_add_one ( h : m < n + 1 ) : m β€ n :=
Order.le_of_lt_succ <| n . succ_def . symm : β {Ξ± : Sort ?u.31522} {a b : Ξ± }, a = b β b = a symm βΈ h
#align enat.le_of_lt_add_one ENat.le_of_lt_add_one : β {m n : ββ }, m < n + 1 β m β€ n ENat.le_of_lt_add_one
@[elab_as_elim]
theorem nat_induction { P : ββ β Prop } ( a : ββ ) ( h0 : P 0 ) ( hsuc : β n : β , P n β P n . succ )
( htop : (β (n : β ), P βn ) β P β€ htop : (β n : β , P n ) β P β€ ) : P a := by
have A : β n : β , P n := fun n => Nat.recOn n h0 hsuc
cases a
. exact htop : (β (n : β ), P βn ) β P β€ htop A
. exact A _
#align enat.nat_induction ENat.nat_induction
end ENat