{-# OPTIONS --cubical --no-import-sorts --no-exact-split --safe #-} module Cubical.Data.Nat.Order where open import Cubical.Foundations.Prelude open import Cubical.Foundations.Function open import Cubical.Foundations.HLevels open import Cubical.Data.Empty as open import Cubical.Data.Sigma open import Cubical.Data.Sum as open import Cubical.Data.Nat.Base open import Cubical.Data.Nat.Properties open import Cubical.Induction.WellFounded open import Cubical.Relation.Nullary infix 4 _≤_ _<_ _≤_ : Type₀ m n = Σ[ k ] k + m n _<_ : Type₀ m < n = suc m n data Trichotomy (m n : ) : Type₀ where lt : m < n Trichotomy m n eq : m n Trichotomy m n gt : n < m Trichotomy m n private variable k l m n : private witness-prop : j isProp (j + m n) witness-prop {m} {n} j = isSetℕ (j + m) n m≤n-isProp : isProp (m n) m≤n-isProp {m} {n} (k , p) (l , q) = Σ≡Prop witness-prop lemma where lemma : k l lemma = inj-+m (p (sym q)) zero-≤ : 0 n zero-≤ {n} = n , +-zero n suc-≤-suc : m n suc m suc n suc-≤-suc (k , p) = k , (+-suc k _) (cong suc p) ≤-+k : m n m + k n + k ≤-+k {m} {k = k} (i , p) = i , +-assoc i m k cong (_+ k) p ≤-k+ : m n k + m k + n ≤-k+ {m} {n} {k} = subst (_≤ k + n) (+-comm m k) subst (m + k ≤_) (+-comm n k) ≤-+k pred-≤-pred : suc m suc n m n pred-≤-pred (k , p) = k , injSuc ((sym (+-suc k _)) p) ≤-refl : m m ≤-refl = 0 , refl ≤-suc : m n m suc n ≤-suc (k , p) = suc k , cong suc p ≤-predℕ : predℕ n n ≤-predℕ {zero} = ≤-refl ≤-predℕ {suc n} = ≤-suc ≤-refl ≤-trans : k m m n k n ≤-trans {k} {m} {n} (i , p) (j , q) = i + j , l2 (l1 q) where l1 : j + i + k j + m l1 = (sym (+-assoc j i k)) (cong (j +_) p) l2 : i + j + k j + i + k l2 = cong (_+ k) (+-comm i j) ≤-antisym : m n n m m n ≤-antisym {m} (i , p) (j , q) = (cong (_+ m) l3) p where l1 : j + i + m m l1 = (sym (+-assoc j i m)) ((cong (j +_) p) q) l2 : j + i 0 l2 = m+n≡n→m≡0 l1 l3 : 0 i l3 = sym (snd (m+n≡0→m≡0×n≡0 l2)) ≤-k+-cancel : k + m k + n m n ≤-k+-cancel {k} {m} (l , p) = l , inj-m+ (sub k m p) where sub : k m k + (l + m) l + (k + m) sub k m = +-assoc k l m cong (_+ m) (+-comm k l) sym (+-assoc l k m) ≤-+k-cancel : m + k n + k m n ≤-+k-cancel {m} {k} {n} (l , p) = l , cancelled where cancelled : l + m n cancelled = inj-+m (sym (+-assoc l m k) p) ≤-·k : m n m · k n · k ≤-·k {m} {n} {k} (d , r) = d · k , reason where reason : d · k + m · k n · k reason = d · k + m · k ≡⟨ ·-distribʳ d m k (d + m) · k ≡⟨ cong ( k) r n · k <-k+-cancel : k + m < k + n m < n <-k+-cancel {k} {m} {n} = ≤-k+-cancel subst (_≤ k + n) (sym (+-suc k m)) ¬-<-zero : ¬ m < 0 ¬-<-zero (k , p) = snotz ((sym (+-suc k _)) p) ¬m<m : ¬ m < m ¬m<m {m} = ¬-<-zero ≤-+k-cancel {k = m} ≤0→≡0 : n 0 n 0 ≤0→≡0 {zero} ineq = refl ≤0→≡0 {suc n} ineq = ⊥.rec (¬-<-zero ineq) predℕ-≤-predℕ : m n (predℕ m) (predℕ n) predℕ-≤-predℕ {zero} {zero} ineq = ≤-refl predℕ-≤-predℕ {zero} {suc n} ineq = zero-≤ predℕ-≤-predℕ {suc m} {zero} ineq = ⊥.rec (¬-<-zero ineq) predℕ-≤-predℕ {suc m} {suc n} ineq = pred-≤-pred ineq ¬m+n<m : ¬ m + n < m ¬m+n<m {m} {n} = ¬-<-zero <-k+-cancel subst (m + n <_) (sym (+-zero m)) <-weaken : m < n m n <-weaken (k , p) = suc k , sym (+-suc k _) p ≤<-trans : l m m < n l < n ≤<-trans p = ≤-trans (suc-≤-suc p) <≤-trans : l < m m n l < n <≤-trans = ≤-trans <-trans : l < m m < n l < n <-trans p = ≤<-trans (<-weaken p) <-asym : m < n ¬ n m <-asym m<n = ¬m<m <≤-trans m<n <-+k : m < n m + k < n + k <-+k p = ≤-+k p <-k+ : m < n k + m < k + n <-k+ {m} {n} {k} p = subst km km k + n) (+-suc k m) (≤-k+ p) <-·sk : m < n m · suc k < n · suc k <-·sk {m} {n} {k} (d , r) = (d · suc k + k) , reason where reason : (d · suc k + k) + suc (m · suc k) n · suc k reason = (d · suc k + k) + suc (m · suc k) ≡⟨ sym (+-assoc (d · suc k) k _) d · suc k + (k + suc (m · suc k)) ≡[ i ]⟨ d · suc k + +-suc k (m · suc k) i d · suc k + suc m · suc k ≡⟨ ·-distribʳ d (suc m) (suc k) (d + suc m) · suc k ≡⟨ cong ( suc k) r n · suc k Trichotomy-suc : Trichotomy m n Trichotomy (suc m) (suc n) Trichotomy-suc (lt m<n) = lt (suc-≤-suc m<n) Trichotomy-suc (eq m=n) = eq (cong suc m=n) Trichotomy-suc (gt n<m) = gt (suc-≤-suc n<m) _≟_ : m n Trichotomy m n zero zero = eq refl zero suc n = lt (n , +-comm n 1) suc m zero = gt (m , +-comm m 1) suc m suc n = Trichotomy-suc (m n) <-split : m < suc n (m < n) (m n) <-split {n = zero} = inr snd m+n≡0→m≡0×n≡0 snd pred-≤-pred <-split {zero} {suc n} = λ _ inl (suc-≤-suc zero-≤) <-split {suc m} {suc n} = ⊎.map suc-≤-suc (cong suc) <-split pred-≤-pred private acc-suc : Acc _<_ n Acc _<_ (suc n) acc-suc a = acc λ y y<sn case <-split y<sn of λ { (inl y<n) access a y y<n ; (inr y≡n) subst _ (sym y≡n) a } <-wellfounded : WellFounded _<_ <-wellfounded zero = acc λ _ ⊥.rec ¬-<-zero <-wellfounded (suc n) = acc-suc (<-wellfounded n) <→≢ : n < m ¬ n m <→≢ {n} {m} p q = ¬m<m (subst (_< m) q p) module _ (b₀ : ) (P : Type₀) (base : n n < suc b₀ P n) (step : n P n P (suc b₀ + n)) where open WFI (<-wellfounded) private dichotomy : b n (n < b) (Σ[ m ] n b + m) dichotomy b n = case n b return _ (n < b) (Σ[ m ] n b + m)) of λ { (lt o) inl o ; (eq p) inr (0 , p sym (+-zero b)) ; (gt (m , p)) inr (suc m , sym p +-suc m b +-comm (suc m) b) } dichotomy<≡ : b n (n<b : n < b) dichotomy b n inl n<b dichotomy<≡ b n n<b = case dichotomy b n return d d inl n<b) of λ { (inl x) cong inl (m≤n-isProp x n<b) ; (inr (m , p)) ⊥.rec (<-asym n<b (m , sym (p +-comm b m))) } dichotomy+≡ : b m n (p : n b + m) dichotomy b n inr (m , p) dichotomy+≡ b m n p = case dichotomy b n return d d inr (m , p)) of λ { (inl n<b) ⊥.rec (<-asym n<b (m , +-comm m b sym p)) ; (inr (m' , q)) cong inr (Σ≡Prop x isSetℕ n (b + x)) (inj-m+ {m = b} (sym q p))) } b = suc b₀ lemma₁ : ∀{x y z} x suc z + y y < x lemma₁ {y = y} {z} p = z , +-suc z y sym p subStep : (n : ) (∀ m m < n P m) (n < b) (Σ[ m ] n b + m) P n subStep n _ (inl l) = base n l subStep n rec (inr (m , p)) = transport (cong P (sym p)) (step m (rec m (lemma₁ p))) wfStep : (n : ) (∀ m m < n P m) P n wfStep n rec = subStep n rec (dichotomy b n) wfStepLemma₀ : n (n<b : n < b) rec wfStep n rec base n n<b wfStepLemma₀ n n<b rec = cong (subStep n rec) (dichotomy<≡ b n n<b) wfStepLemma₁ : n rec wfStep (b + n) rec step n (rec n (lemma₁ refl)) wfStepLemma₁ n rec = cong (subStep (b + n) rec) (dichotomy+≡ b n (b + n) refl) transportRefl _ +induction : n P n +induction = induction wfStep +inductionBase : n (l : n < b) +induction n base n l +inductionBase n l = induction-compute wfStep n wfStepLemma₀ n l _ +inductionStep : n +induction (b + n) step n (+induction n) +inductionStep n = induction-compute wfStep (b + n) wfStepLemma₁ n _ module <-Reasoning where -- TODO: would it be better to mirror the way it is done in the agda-stdlib? infixr 2 _<⟨_⟩_ _≤<⟨_⟩_ _≤⟨_⟩_ _<≤⟨_⟩_ _≡<⟨_⟩_ _≡≤⟨_⟩_ _<≡⟨_⟩_ _≤≡⟨_⟩_ _<⟨_⟩_ : k k < n n < m k < m _ <⟨ p q = <-trans p q _≤<⟨_⟩_ : k k n n < m k < m _ ≤<⟨ p q = ≤<-trans p q _≤⟨_⟩_ : k k n n m k m _ ≤⟨ p q = ≤-trans p q _<≤⟨_⟩_ : k k < n n m k < m _ <≤⟨ p q = <≤-trans p q _≡≤⟨_⟩_ : k k l l m k m _ ≡≤⟨ p q = subst k k _) (sym p) q _≡<⟨_⟩_ : k k l l < m k < m _ ≡<⟨ p q = _ ≡≤⟨ cong suc p q _≤≡⟨_⟩_ : k k l l m k m _ ≤≡⟨ p q = subst l _ l) q p _<≡⟨_⟩_ : k k < l l m k < m _ <≡⟨ p q = _ ≤≡⟨ p q