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