module Cubical.Data.Nat.Order.Inductive where
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.Function
open import Cubical.Foundations.HLevels
open import Cubical.Foundations.Transport
open import Cubical.Data.Nat
open import Cubical.Data.Nat.Order
open import Cubical.Data.Empty as ⊥
open import Cubical.Data.Unit
open import Cubical.Data.Sigma
open import Cubical.Data.Sum
open import Cubical.Data.Bool hiding (_≤_)
open import Cubical.Induction.WellFounded
open import Cubical.Relation.Nullary
private
variable
ℓ : Level
R : Type ℓ
P : ℕ → Type ℓ
k l m n : ℕ
infix 4 _<ᵗ_ _≤ᵗ_ _>ᵗ_ _≥ᵗ_
_<ᵗ_ : (n m : ℕ) → Type
n <ᵗ m = Bool→Type (n <ᵇ m)
_≤ᵗ_ : (n m : ℕ) → Type
n ≤ᵗ m = n <ᵗ suc m
_>ᵗ_ : (n m : ℕ) → Type
n >ᵗ m = m <ᵗ n
_≥ᵗ_ : (n m : ℕ) → Type
n ≥ᵗ m = m ≤ᵗ n
private
_ : ∀ {n} → (n <ᵗ zero) ≡ ⊥
_ = refl
_ : ∀ {m} → (zero <ᵗ suc m) ≡ Unit
_ = refl
_ : ∀ {n m} → (suc n <ᵗ suc m) ≡ (n <ᵗ m)
_ = refl
_<ᵗ?_ : (m n : ℕ) → Dec (m <ᵗ n)
m <ᵗ? n = m <ᵇ? n
_≤ᵗ?_ : (m n : ℕ) → Dec (m ≤ᵗ n)
m ≤ᵗ? n = m <ᵇ? (suc 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
Trichotomyᵗ-suc : {n m : ℕ} → Trichotomyᵗ n m
→ Trichotomyᵗ (suc n) (suc m)
Trichotomyᵗ-suc (lt x) = lt x
Trichotomyᵗ-suc (eq x) = eq (cong suc x)
Trichotomyᵗ-suc (gt x) = gt x
_≟ᵗ_ : ∀ m n → Trichotomyᵗ m n
zero ≟ᵗ zero = eq refl
zero ≟ᵗ suc n = lt tt
suc m ≟ᵗ zero = gt tt
suc m ≟ᵗ suc n = Trichotomyᵗ-suc (m ≟ᵗ n)
isProp<ᵗ : isProp (n <ᵗ m)
isProp<ᵗ = isPropBool→Type
isProp≤ᵗ : isProp (n ≤ᵗ m)
isProp≤ᵗ = isPropBool→Type
≤ᵗ-+ˡ : m ≤ᵗ n → k + m ≤ᵗ k + n
≤ᵗ-+ˡ {k = zero} m≤n = m≤n
≤ᵗ-+ˡ {k = suc k} m≤n = ≤ᵗ-+ˡ {k = k} m≤n
≤ᵗ-+ʳ : m ≤ᵗ n → m + k ≤ᵗ n + k
≤ᵗ-+ʳ {m} {n} {k} m≤n
= transport (λ i → +-comm k m i ≤ᵗ +-comm k n i) (≤ᵗ-+ˡ {m} {n} {k} m≤n)
≤ᵗ-refl : ∀ m → m ≤ᵗ m
≤ᵗ-refl zero = _
≤ᵗ-refl (suc m) = ≤ᵗ-refl m
≤ᵗ-trans : k ≤ᵗ m → m ≤ᵗ n → k ≤ᵗ n
≤ᵗ-trans {zero} _ _ = _
≤ᵗ-trans {suc k} {suc m} {suc n} = ≤ᵗ-trans {k} {m} {n}
≤ᵗ-antisym : m ≤ᵗ n → n ≤ᵗ m → m ≡ n
≤ᵗ-antisym {zero} {zero} _ _ = refl
≤ᵗ-antisym {suc m} {suc n} m≤n n≤m = cong suc (≤ᵗ-antisym m≤n n≤m)
≤ᵗ-+-cancelˡ : k + m ≤ᵗ k + n → m ≤ᵗ n
≤ᵗ-+-cancelˡ {k = zero} m≤n = m≤n
≤ᵗ-+-cancelˡ {k = suc k} m≤n = ≤ᵗ-+-cancelˡ {k} m≤n
≤ᵗ-+-cancelʳ : m + k ≤ᵗ n + k → m ≤ᵗ n
≤ᵗ-+-cancelʳ {m} {k} {n}
= ≤ᵗ-+-cancelˡ {k} {m} {n} ∘ transport λ i → +-comm m k i ≤ᵗ +-comm n k i
≤ᵗ0→≡0 : n ≤ᵗ 0 → n ≡ 0
≤ᵗ0→≡0 {zero} _ = refl
≤ᵗSumLeft : ∀ k → k ≤ᵗ k + n
≤ᵗSumLeft zero = _
≤ᵗSumLeft (suc k) = ≤ᵗSumLeft k
≤ᵗSumRight : ∀ n → n ≤ᵗ k + n
≤ᵗSumRight {k} n = transport (λ i → n ≤ᵗ +-comm n k i) (≤ᵗSumLeft n)
¬<ᵗ→≥ᵗ : {m n : ℕ} → ¬ m <ᵗ n → n ≤ᵗ m
¬<ᵗ→≥ᵗ {m} {n} = ¬<ᵇ→≥ᵇ m n
¬≤ᵗ→>ᵗ : {m n : ℕ} → ¬ m ≤ᵗ n → n <ᵗ m
¬≤ᵗ→>ᵗ {m} {n} = ¬≤ᵇ→>ᵇ m n
<ᵗsuc : {m : ℕ} → m <ᵗ suc m
<ᵗsuc {m = zero} = tt
<ᵗsuc {m = suc m} = <ᵗsuc {m = m}
<ᵗ-trans-suc : {n m : ℕ} → n <ᵗ m → n <ᵗ suc m
<ᵗ-trans-suc {n = zero} {suc m} x = tt
<ᵗ-trans-suc {n = suc n} {suc m} x = <ᵗ-trans-suc {n = n} x
¬-sucℕ-<ᵗ : {n : ℕ} → ¬ (suc n) <ᵗ n
¬-sucℕ-<ᵗ {suc n} = ¬-sucℕ-<ᵗ {n}
<ᵗ-trans : {n m k : ℕ} → n <ᵗ m → m <ᵗ k → n <ᵗ k
<ᵗ-trans {n = zero} {suc m} {suc k} _ _ = tt
<ᵗ-trans {n = suc n} {suc m} {suc k} = <ᵗ-trans {n = n} {m} {k}
<ᵗ-irrefl : {m : ℕ} → ¬ (m <ᵗ m)
<ᵗ-irrefl {m = suc m} p = <ᵗ-irrefl {m = m} p
¬SumLeft<ᵗ : {m n : ℕ} → ¬ m + n <ᵗ m
¬SumLeft<ᵗ {suc m} = ¬SumLeft<ᵗ {m}
<ᵗ-weaken : {m n : ℕ} → m <ᵗ n → m ≤ᵗ n
<ᵗ-weaken {zero} _ = _
<ᵗ-weaken {suc m} {suc n} = <ᵗ-weaken {m}
<ᵗ-+ : {n k : ℕ} → n <ᵗ suc (k + n)
<ᵗ-+ {n = zero} {k} = tt
<ᵗ-+ {n = suc n} {k} =
subst (n <ᵗ_) (sym (+-suc k n)) (<ᵗ-+ {n = n} {k})
¬squeeze : {n m : ℕ} → ¬ ((n <ᵗ m) × (m <ᵗ suc n))
¬squeeze {n = suc n} {suc m} = ¬squeeze {n = n} {m = m}
<ᵗ→< : {n m : ℕ} → n <ᵗ m → n < m
<ᵗ→< {n = zero} {suc m} p = m , +-comm m 1
<ᵗ→< {n = suc n} {suc m} p = suc-≤-suc (<ᵗ→< {n = n} {m = m} p)
<→<ᵗ : {n m : ℕ} → n < m → n <ᵗ m
<→<ᵗ {n = zero} {m = zero} x =
snotz (sym (+-suc (fst x) 0) ∙ snd x)
<→<ᵗ {n = zero} {m = suc m} _ = tt
<→<ᵗ {n = suc n} {m = zero} x =
snotz (sym (+-suc (fst x) (suc n)) ∙ snd x)
<→<ᵗ {n = suc n} {m = suc m} p = <→<ᵗ {n = n} {m = m} (pred-≤-pred p)
<ᵗ-asym : ∀ {m n} → m <ᵗ n → n ≤ m → ⊥
<ᵗ-asym p = <-asym (<ᵗ→< p)
<ᵗ-asym' : {m n : ℕ} → m <ᵗ n → ¬ n <ᵗ m
<ᵗ-asym' {m} m<n n<m = <ᵗ-irrefl {m} (<ᵗ-trans {m} {_} {m} m<n n<m)
<ᵗ→≢ : {n m : ℕ} → n <ᵗ m → ¬ n ≡ m
<ᵗ→≢ {n} {m} p q = <ᵗ-irrefl {m = m} (subst {x = n} (_<ᵗ m) q p)
_≟ᶠ_ : ∀ m n → Trichotomyᵗ m n
m ≟ᶠ n with m <ᵗ? n
... | yes m<n = lt m<n
... | no ¬m<n with n <ᵗ? m
... | yes n<m = gt n<m
... | no ¬n<m = eq (≤ᵗ-antisym (¬<ᵇ→≥ᵇ n m ¬n<m) (¬<ᵇ→≥ᵇ m n ¬m<n))
≤ᵗ-split : {m n : ℕ} → m ≤ᵗ n → (m <ᵗ n) ⊎ (m ≡ n)
≤ᵗ-split {m} {n} m≤n with m <ᵗ? n
... | yes m<n = inl m<n
... | no ¬m<n = inr (≤ᵗ-antisym m≤n (¬<ᵇ→≥ᵇ m n ¬m<n))
private
acc-suc : ∀ {n} → Acc _<ᵗ_ n → Acc _<ᵗ_ (suc n)
acc-suc {n} (acc ih) = acc λ where
zero _ → acc (λ m p → ⊥.rec p)
(suc m) p → acc-suc (ih m p)
<ᵗ-wellfounded : WellFounded _<ᵗ_
<ᵗ-wellfounded zero = acc λ _ → ⊥.rec
<ᵗ-wellfounded (suc n) = acc-suc ((<ᵗ-wellfounded n))
module _ {n m : ℕ} where
isPropTrichotomyᵗ : isProp (Trichotomyᵗ n m)
isPropTrichotomyᵗ (lt x) (lt y) i = lt (isProp<ᵗ {n = n} {m} x y i)
isPropTrichotomyᵗ (lt x) (eq y) = ⊥.rec (<ᵗ-irrefl {m} (subst (_<ᵗ m) y x))
isPropTrichotomyᵗ (lt x) (gt y) = ⊥.rec (<ᵗ-irrefl {m} (<ᵗ-trans {m} {n} {m} y x))
isPropTrichotomyᵗ (eq x) (lt y) = ⊥.rec (<ᵗ-irrefl {m} (subst (_<ᵗ m) x y))
isPropTrichotomyᵗ (eq x) (eq y) i = eq (isSetℕ n m x y i)
isPropTrichotomyᵗ (eq x) (gt y) = ⊥.rec (<ᵗ-irrefl {n} (subst (_<ᵗ n) (sym x) y))
isPropTrichotomyᵗ (gt x) (lt y) = ⊥.rec (<ᵗ-irrefl {n} (<ᵗ-trans {n} {m} {n} y x))
isPropTrichotomyᵗ (gt x) (eq y) = ⊥.rec (<ᵗ-irrefl {n} (subst (_<ᵗ n) (sym y) x))
isPropTrichotomyᵗ (gt x) (gt y) i = gt (isProp<ᵗ {n = m} {n} x y i)
module falseDichotomies where
lt-eq : {n m : ℕ} → ¬ (m <ᵗ n) × (m ≡ suc n)
lt-eq {n = n} (p , q) = ¬-sucℕ-<ᵗ {n = n} (subst (_<ᵗ n) q p)
lt-gt : {n m : ℕ} → ¬ (m <ᵗ n) × (suc n <ᵗ m)
lt-gt {n = n} {m} (p , q) =
¬-sucℕ-<ᵗ {n = n} (<ᵗ-trans {n = suc n} {m} {n} q p)
eq-eq : {n m : ℕ} → ¬ (m ≡ n) × (m ≡ suc n)
eq-eq {n = n} (p , q) =
<ᵗ-irrefl {n} (subst (_<ᵗ suc n) (sym p ∙ q) (<ᵗsuc {n}))
eq-gt : {n m : ℕ} → ¬ (m ≡ n) × (suc n <ᵗ m)
eq-gt (p , q) = lt-eq (q , cong suc (sym p))
gt-lt : {n m : ℕ} → ¬ (n <ᵗ m) × (m <ᵗ suc n)
gt-lt {n = n} {m = m} = ¬squeeze {n = n} {m = m}
module WellFounded where
wf-<ᵗ : WellFounded _<ᵗ_
wf-rec-<ᵗ : ∀ n → WFRec _<ᵗ_ (Acc _<ᵗ_) n
wf-<ᵗ n = acc (wf-rec-<ᵗ n)
wf-rec-<ᵗ (suc n) m m≤n with ≤ᵗ-split {m} {n} m≤n
... | inl m<n = wf-rec-<ᵗ n m m<n
... | inr m≡n = subst⁻ (Acc _<ᵗ_) m≡n (wf-<ᵗ n)
wf-elim : (∀ n → (∀ m → m <ᵗ n → P m) → P n) → ∀ n → P n
wf-elim = WFI.induction WellFounded.wf-<ᵗ
wf-rec : (∀ n → (∀ m → m <ᵗ n → R) → R) → ℕ → R
wf-rec {R = R} = wf-elim {P = λ _ → R}
module Minimal where
Least : ∀{ℓ} → (ℕ → Type ℓ) → (ℕ → Type ℓ)
Least P m = P m × (∀ n → n <ᵗ m → ¬ P n)
isPropLeast : (∀ m → isProp (P m)) → ∀ m → isProp (Least P m)
isPropLeast pP m
= isPropΣ (pP m) (λ _ → isPropΠ3 λ _ _ _ → isProp⊥)
Least→ : Σ _ (Least P) → Σ _ P
Least→ = map-snd fst
private
search-lemma : ∀ n → ¬ P 0 → (∀ m → m <ᵗ n → ¬ P (suc m)) → ∀ m → m <ᵗ suc n → ¬ P m
search-lemma n ¬P0 ¬P<1+n zero = λ _ → ¬P0
search-lemma n ¬P0 ¬P<1+n (suc m) = ¬P<1+n m
search
: (∀ m → Dec (P m))
→ ∀ n → (Σ[ m ∈ ℕ ] Least P m) ⊎ (∀ m → m <ᵗ n → ¬ P m)
search {P = P} dec zero = inr λ _ b _ → b
search {P = P} dec (suc n) with dec 0
... | yes P0 = inl (0 , P0 , λ _ b _ → b)
... | no ¬P0 with search {P = P ∘ suc} (dec ∘ suc) n
... | inl (m , P1+m , ¬P<1+m) = inl (suc m , P1+m , search-lemma m ¬P0 ¬P<1+m)
... | inr ¬P<1+n = inr (search-lemma n ¬P0 ¬P<1+n)
→Least : (∀ m → Dec (P m)) → Σ _ P → Σ _ (Least P)
→Least dec (n , Pn) with search dec n
... | inl least = least
... | inr ¬P<n = n , Pn , ¬P<n
Least-unique : ∀ m n → Least P m → Least P n → m ≡ n
Least-unique m n (Pm , ¬P<m) (Pn , ¬P<n) with m ≟ᶠ n
... | lt m<n = ⊥.rec (¬P<n m m<n Pm)
... | eq m≡n = m≡n
... | gt n<m = ⊥.rec (¬P<m n n<m Pn)
isPropΣLeast : (∀ m → isProp (P m)) → isProp (Σ _ (Least P))
isPropΣLeast pP (m , LPm) (n , LPn)
= ΣPathP λ where
.fst → Least-unique m n LPm LPn
.snd → isOfHLevel→isOfHLevelDep 1 (isPropLeast pP)
LPm LPn (Least-unique m n LPm LPn)
Decidable→Collapsible
: (∀ m → isProp (P m)) → (∀ m → Dec (P m)) → Collapsible (Σ ℕ P)
Decidable→Collapsible pP dP = λ where
.fst → Least→ ∘ →Least dP
.snd x y → cong Least→ (isPropΣLeast pP (→Least dP x) (→Least dP y))
open Minimal using (Decidable→Collapsible) public