{-# 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