------------------------------------------------------------------------ -- The Agda standard library -- -- A bunch of properties about natural number operations ------------------------------------------------------------------------ -- See README.Nat for some examples showing how this module can be -- used. module Data.Nat.Properties where open import Algebra open import Algebra.Morphism open import Function open import Function.Injection using (_↣_) open import Data.Nat.Base open import Data.Product open import Data.Sum open import Level using (0ℓ) open import Relation.Binary open import Relation.Binary.PropositionalEquality open import Relation.Nullary open import Relation.Nullary.Decidable using (via-injection; map′) open import Relation.Nullary.Negation using (contradiction) open import Algebra.FunctionProperties (_≡_ {A = ℕ}) hiding (LeftCancellative; RightCancellative; Cancellative) open import Algebra.FunctionProperties using (LeftCancellative; RightCancellative; Cancellative) open import Algebra.FunctionProperties.Consequences (setoid ℕ) open import Algebra.Structures (_≡_ {A = ℕ}) open ≡-Reasoning ------------------------------------------------------------------------ -- Properties of _≡_ suc-injective : ∀ {m n} → suc m ≡ suc n → m ≡ n suc-injective refl = refl infix 4 _≟_ _≟_ : Decidable {A = ℕ} _≡_ zero ≟ zero = yes refl zero ≟ suc n = no λ() suc m ≟ zero = no λ() suc m ≟ suc n with m ≟ n ... | yes refl = yes refl ... | no m≢n = no (m≢n ∘ suc-injective) ≡-isDecEquivalence : IsDecEquivalence (_≡_ {A = ℕ}) ≡-isDecEquivalence = record { isEquivalence = isEquivalence ; _≟_ = _≟_ } ≡-decSetoid : DecSetoid 0ℓ 0ℓ ≡-decSetoid = record { Carrier = ℕ ; _≈_ = _≡_ ; isDecEquivalence = ≡-isDecEquivalence } ------------------------------------------------------------------------ -- Properties of _≤_ ≤-pred : ∀ {m n} → suc m ≤ suc n → m ≤ n ≤-pred (s≤s m≤n) = m≤n -- Relation-theoretic properties of _≤_ ≤-reflexive : _≡_ ⇒ _≤_ ≤-reflexive {zero} refl = z≤n ≤-reflexive {suc m} refl = s≤s (≤-reflexive refl) ≤-refl : Reflexive _≤_ ≤-refl = ≤-reflexive refl ≤-antisym : Antisymmetric _≡_ _≤_ ≤-antisym z≤n z≤n = refl ≤-antisym (s≤s m≤n) (s≤s n≤m) with ≤-antisym m≤n n≤m ... | refl = refl ≤-trans : Transitive _≤_ ≤-trans z≤n _ = z≤n ≤-trans (s≤s m≤n) (s≤s n≤o) = s≤s (≤-trans m≤n n≤o) ≤-total : Total _≤_ ≤-total zero _ = inj₁ z≤n ≤-total _ zero = inj₂ z≤n ≤-total (suc m) (suc n) with ≤-total m n ... | inj₁ m≤n = inj₁ (s≤s m≤n) ... | inj₂ n≤m = inj₂ (s≤s n≤m) infix 4 _≤?_ _≥?_ _≤?_ : Decidable _≤_ zero ≤? _ = yes z≤n suc m ≤? zero = no λ() suc m ≤? suc n with m ≤? n ... | yes m≤n = yes (s≤s m≤n) ... | no m≰n = no (m≰n ∘ ≤-pred) _≥?_ : Decidable _≥_ _≥?_ = flip _≤?_ ≤-isPreorder : IsPreorder _≡_ _≤_ ≤-isPreorder = record { isEquivalence = isEquivalence ; reflexive = ≤-reflexive ; trans = ≤-trans } ≤-preorder : Preorder 0ℓ 0ℓ 0ℓ ≤-preorder = record { isPreorder = ≤-isPreorder } ≤-isPartialOrder : IsPartialOrder _≡_ _≤_ ≤-isPartialOrder = record { isPreorder = ≤-isPreorder ; antisym = ≤-antisym } ≤-poset : Poset 0ℓ 0ℓ 0ℓ ≤-poset = record { isPartialOrder = ≤-isPartialOrder } ≤-isTotalOrder : IsTotalOrder _≡_ _≤_ ≤-isTotalOrder = record { isPartialOrder = ≤-isPartialOrder ; total = ≤-total } ≤-totalOrder : TotalOrder 0ℓ 0ℓ 0ℓ ≤-totalOrder = record { isTotalOrder = ≤-isTotalOrder } ≤-isDecTotalOrder : IsDecTotalOrder _≡_ _≤_ ≤-isDecTotalOrder = record { isTotalOrder = ≤-isTotalOrder ; _≟_ = _≟_ ; _≤?_ = _≤?_ } ≤-decTotalOrder : DecTotalOrder 0ℓ 0ℓ 0ℓ ≤-decTotalOrder = record { isDecTotalOrder = ≤-isDecTotalOrder } -- Other properties of _≤_ s≤s-injective : ∀ {m n} {p q : m ≤ n} → s≤s p ≡ s≤s q → p ≡ q s≤s-injective refl = refl ≤-irrelevance : Irrelevant _≤_ ≤-irrelevance z≤n z≤n = refl ≤-irrelevance (s≤s m≤n₁) (s≤s m≤n₂) = cong s≤s (≤-irrelevance m≤n₁ m≤n₂) ≤-step : ∀ {m n} → m ≤ n → m ≤ 1 + n ≤-step z≤n = z≤n ≤-step (s≤s m≤n) = s≤s (≤-step m≤n) n≤1+n : ∀ n → n ≤ 1 + n n≤1+n _ = ≤-step ≤-refl 1+n≰n : ∀ {n} → 1 + n ≰ n 1+n≰n (s≤s le) = 1+n≰n le n≤0⇒n≡0 : ∀ {n} → n ≤ 0 → n ≡ 0 n≤0⇒n≡0 z≤n = refl pred-mono : pred Preserves _≤_ ⟶ _≤_ pred-mono z≤n = z≤n pred-mono (s≤s le) = le ≤pred⇒≤ : ∀ {m n} → m ≤ pred n → m ≤ n ≤pred⇒≤ {m} {zero} le = le ≤pred⇒≤ {m} {suc n} le = ≤-step le ≤⇒pred≤ : ∀ {m n} → m ≤ n → pred m ≤ n ≤⇒pred≤ {zero} le = le ≤⇒pred≤ {suc m} le = ≤-trans (n≤1+n m) le ------------------------------------------------------------------------ -- Properties of _<_ -- Relation theoretic properties of _<_ <-irrefl : Irreflexive _≡_ _<_ <-irrefl refl (s≤s n (λ()) (λ()) (s≤s z≤n) <-cmp (suc m) (suc n) with <-cmp m n ... | tri< ≤ ≢ ≱ = tri< (s≤s ≤) (≢ ∘ suc-injective) (≱ ∘ ≤-pred) ... | tri≈ ≰ ≡ ≱ = tri≈ (≰ ∘ ≤-pred) (cong suc ≡) (≱ ∘ ≤-pred) ... | tri> ≰ ≢ ≥ = tri> (≰ ∘ ≤-pred) (≢ ∘ suc-injective) (s≤s ≥) infix 4 _?_ _?_ : Decidable _>_ _>?_ = flip _ : _≰_ ⇒ _>_ ≰⇒> {zero} z≰n = contradiction z≤n z≰n ≰⇒> {suc m} {zero} _ = s≤s z≤n ≰⇒> {suc m} {suc n} m≰n = s≤s (≰⇒> (m≰n ∘ s≤s)) ≰⇒≥ : _≰_ ⇒ _≥_ ≰⇒≥ = <⇒≤ ∘ ≰⇒> ≮⇒≥ : _≮_ ⇒ _≥_ ≮⇒≥ {_} {zero} _ = z≤n ≮⇒≥ {zero} {suc j} 1≮j+1 = contradiction (s≤s z≤n) 1≮j+1 ≮⇒≥ {suc i} {suc j} i+1≮j+1 = s≤s (≮⇒≥ (i+1≮j+1 ∘ s≤s)) ≤∧≢⇒< : ∀ {m n} → m ≤ n → m ≢ n → m < n ≤∧≢⇒< {_} {zero} z≤n m≢n = contradiction refl m≢n ≤∧≢⇒< {_} {suc n} z≤n m≢n = s≤s z≤n ≤∧≢⇒< {_} {suc n} (s≤s m≤n) 1+m≢1+n = s≤s (≤∧≢⇒< m≤n (1+m≢1+n ∘ cong suc)) n≮n : ∀ n → n ≮ n n≮n n = <-irrefl (refl {x = n}) m′?_ _≤′?_ : Decidable _≤′_ x ≤′? y = map′ ≤⇒≤′ ≤′⇒≤ (x ≤? y) _<′?_ : Decidable _<′_ x <′? y = suc x ≤′? y _≥′?_ : Decidable _≥′_ _≥′?_ = flip _≤′?_ _>′?_ : Decidable _>′_ _>′?_ = flip _<′?_ ------------------------------------------------------------------------ -- Properties of _≤″_ ≤″⇒≤ : _≤″_ ⇒ _≤_ ≤″⇒≤ {zero} (less-than-or-equal refl) = z≤n ≤″⇒≤ {suc m} (less-than-or-equal refl) = s≤s (≤″⇒≤ (less-than-or-equal refl)) ≤⇒≤″ : _≤_ ⇒ _≤″_ ≤⇒≤″ m≤n = less-than-or-equal (proof m≤n) where k : ∀ m n → m ≤ n → ℕ k zero n _ = n k (suc m) zero () k (suc m) (suc n) m≤n = k m n (≤-pred m≤n) proof : ∀ {m n} (m≤n : m ≤ n) → m + k m n m≤n ≡ n proof z≤n = refl proof (s≤s m≤n) = cong suc (proof m≤n) -- Decidablity for _≤″_ infix 4 _≤″?_ _<″?_ _≥″?_ _>″?_ _≤″?_ : Decidable _≤″_ x ≤″? y = map′ ≤⇒≤″ ≤″⇒≤ (x ≤? y) _<″?_ : Decidable _<″_ x <″? y = suc x ≤″? y _≥″?_ : Decidable _≥″_ _≥″?_ = flip _≤″?_ _>″?_ : Decidable _>″_ _>″?_ = flip _<″?_ ------------------------------------------------------------------------ -- Properties of _+_ -- Algebraic properties of _+_ +-suc : ∀ m n → m + suc n ≡ suc (m + n) +-suc zero n = refl +-suc (suc m) n = cong suc (+-suc m n) +-assoc : Associative _+_ +-assoc zero _ _ = refl +-assoc (suc m) n o = cong suc (+-assoc m n o) +-identityˡ : LeftIdentity 0 _+_ +-identityˡ _ = refl +-identityʳ : RightIdentity 0 _+_ +-identityʳ zero = refl +-identityʳ (suc n) = cong suc (+-identityʳ n) +-identity : Identity 0 _+_ +-identity = +-identityˡ , +-identityʳ +-comm : Commutative _+_ +-comm zero n = sym (+-identityʳ n) +-comm (suc m) n = begin suc m + n ≡⟨⟩ suc (m + n) ≡⟨ cong suc (+-comm m n) ⟩ suc (n + m) ≡⟨ sym (+-suc n m) ⟩ n + suc m ∎ +-isSemigroup : IsSemigroup _+_ +-isSemigroup = record { isEquivalence = isEquivalence ; assoc = +-assoc ; ∙-cong = cong₂ _+_ } +-semigroup : Semigroup 0ℓ 0ℓ +-semigroup = record { isSemigroup = +-isSemigroup } +-0-isMonoid : IsMonoid _+_ 0 +-0-isMonoid = record { isSemigroup = +-isSemigroup ; identity = +-identity } +-0-monoid : Monoid 0ℓ 0ℓ +-0-monoid = record { isMonoid = +-0-isMonoid } +-0-isCommutativeMonoid : IsCommutativeMonoid _+_ 0 +-0-isCommutativeMonoid = record { isSemigroup = +-isSemigroup ; identityˡ = +-identityˡ ; comm = +-comm } +-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ +-0-commutativeMonoid = record { isCommutativeMonoid = +-0-isCommutativeMonoid } -- Other properties of _+_ and _≡_ +-cancelˡ-≡ : LeftCancellative _≡_ _+_ +-cancelˡ-≡ zero eq = eq +-cancelˡ-≡ (suc m) eq = +-cancelˡ-≡ m (cong pred eq) +-cancelʳ-≡ : RightCancellative _≡_ _+_ +-cancelʳ-≡ = comm+cancelˡ⇒cancelʳ +-comm +-cancelˡ-≡ +-cancel-≡ : Cancellative _≡_ _+_ +-cancel-≡ = +-cancelˡ-≡ , +-cancelʳ-≡ m≢1+m+n : ∀ m {n} → m ≢ suc (m + n) m≢1+m+n zero () m≢1+m+n (suc m) eq = m≢1+m+n m (cong pred eq) i+1+j≢i : ∀ i {j} → i + suc j ≢ i i+1+j≢i zero () i+1+j≢i (suc i) = (i+1+j≢i i) ∘ suc-injective i+j≡0⇒i≡0 : ∀ i {j} → i + j ≡ 0 → i ≡ 0 i+j≡0⇒i≡0 zero eq = refl i+j≡0⇒i≡0 (suc i) () i+j≡0⇒j≡0 : ∀ i {j} → i + j ≡ 0 → j ≡ 0 i+j≡0⇒j≡0 i {j} i+j≡0 = i+j≡0⇒i≡0 j (trans (+-comm j i) (i+j≡0)) -- Properties of _+_ and orderings +-cancelˡ-≤ : LeftCancellative _≤_ _+_ +-cancelˡ-≤ zero le = le +-cancelˡ-≤ (suc m) (s≤s le) = +-cancelˡ-≤ m le +-cancelʳ-≤ : RightCancellative _≤_ _+_ +-cancelʳ-≤ {m} n o le = +-cancelˡ-≤ m (subst₂ _≤_ (+-comm n m) (+-comm o m) le) +-cancel-≤ : Cancellative _≤_ _+_ +-cancel-≤ = +-cancelˡ-≤ , +-cancelʳ-≤ ≤-stepsˡ : ∀ {m n} o → m ≤ n → m ≤ o + n ≤-stepsˡ zero m≤n = m≤n ≤-stepsˡ (suc o) m≤n = ≤-step (≤-stepsˡ o m≤n) ≤-stepsʳ : ∀ {m n} o → m ≤ n → m ≤ n + o ≤-stepsʳ {m} o m≤n = subst (m ≤_) (+-comm o _) (≤-stepsˡ o m≤n) m≤m+n : ∀ m n → m ≤ m + n m≤m+n zero n = z≤n m≤m+n (suc m) n = s≤s (m≤m+n m n) n≤m+n : ∀ m n → n ≤ m + n n≤m+n m zero = z≤n n≤m+n m (suc n) = subst (suc n ≤_) (sym (+-suc m n)) (s≤s (n≤m+n m n)) m+n≤o⇒m≤o : ∀ m {n o} → m + n ≤ o → m ≤ o m+n≤o⇒m≤o zero m+n≤o = z≤n m+n≤o⇒m≤o (suc m) (s≤s m+n≤o) = s≤s (m+n≤o⇒m≤o m m+n≤o) m+n≤o⇒n≤o : ∀ m {n o} → m + n ≤ o → n ≤ o m+n≤o⇒n≤o zero n≤o = n≤o m+n≤o⇒n≤o (suc m) m+n