{-# OPTIONS --safe #-}
module Data.Nat.Properties where
open import Prelude
open import Agda.Builtin.Nat using (_+_; _-_) public
case-nat : (P : ℕ → Type p)
→ P zero
→ (∀ n → P (suc n))
→ ∀ n → P n
case-nat P z s zero = z
case-nat P z s (suc n) = s n
case-nat′ : A → (ℕ → A) → ℕ → A
case-nat′ = case-nat _
is-zero : ℕ → Bool
is-zero = case-nat′ true (const false)
private variable n m : ℕ
zero≢suc : zero ≢ suc n
zero≢suc = true≢false ∘ cong is-zero
suc≢zero : suc n ≢ zero
suc≢zero = false≢true ∘ cong is-zero
module DiscreteNat where
_≡ᴮ_ : ℕ → ℕ → Bool
zero ≡ᴮ zero = true
suc x ≡ᴮ suc y = x ≡ᴮ y
_ ≡ᴮ _ = false
sound : (x y : ℕ) → T (x ≡ᴮ y) → x ≡ y
sound zero zero p = refl
sound (suc x) (suc y) p = cong suc (sound x y p)
complete : (x : ℕ) → T (x ≡ᴮ x)
complete zero = _
complete (suc x) = complete x
discreteNat : Discrete ℕ
discreteNat = from-bool-eq record { DiscreteNat }
isSetNat : isSet ℕ
isSetNat = Discrete→isSet discreteNat
suc-inj : suc n ≡ suc m → n ≡ m
suc-inj {n = n} = cong (case-nat′ n id)
+-suc : ∀ n m → n + suc m ≡ suc n + m
+-suc zero m = refl
+-suc (suc n) m = cong suc (+-suc n m)
+-zero : ∀ n → n + zero ≡ n
+-zero zero = refl
+-zero (suc n) = cong suc (+-zero n)
+-comm : ∀ n m → n + m ≡ m + n
+-comm zero m = sym (+-zero m)
+-comm (suc n) m = cong suc (+-comm n m) ; sym (+-suc m n)
data Ordering : ℕ → ℕ → Type where
less : ∀ m k → Ordering m (suc (m + k))
equal : ∀ m → Ordering m m
greater : ∀ m k → Ordering (suc (m + k)) m
compare : ∀ m n → Ordering m n
compare zero zero = equal zero
compare (suc m) zero = greater zero m
compare zero (suc n) = less zero n
compare (suc m) (suc n) with compare m n
... | less m k = less (suc m) k
... | equal m = equal (suc m)
... | greater n k = greater (suc n) k
NonZero : ℕ → Type
NonZero zero = ⊥
NonZero (suc n) = ⊤
open import Agda.Builtin.Nat using (mod-helper)
_mod_ : (n m : ℕ) → ⦃ _ : NonZero m ⦄ → ℕ
n mod suc m = mod-helper 0 m n m