module Examples.Nat.TotalOrdering where
open import Description
open import Ornament
open import Examples.Nat
open import Function using (_∘_; _∋_)
open import Data.Empty using (⊥; ⊥-elim)
open import Data.Unit using (⊤; tt)
open import Data.List using (List; []; _∷_)
open import Data.Product using (Σ; Σ-syntax; _,_; _×_) renaming (map to _**_)
open import Relation.Nullary using (¬_; Dec; yes; no)
open import Relation.Binary.PropositionalEquality using (_≡_; refl; _≢_; cong; sym; trans)
LeD : Desc (Nat × Nat)
LeD = wrap λ { (x , y) →
σ ListTag λ { `nil → σ[ _ ∈ x ≡ zero ] ṿ []
; `cons → σ[ x' ∈ Nat ] σ[ y' ∈ Nat ] σ[ _ ∈ (suc x' , suc y') ≡ (Nat × Nat ∋ x , y) ] ṿ ((x' , y') ∷ []) } }
_≤_ : Nat → Nat → Set
x ≤ y = μ LeD (x , y)
_≰_ : Nat → Nat → Set
x ≰ y = ¬ (x ≤ y)
infix 3 _≤_ _≰_
≤-base : {y : Nat} → zero ≤ y
≤-base = con (`nil , refl , tt)
≤-step : {x y : Nat} → x ≤ y → suc x ≤ suc y
≤-step le = con (`cons , _ , _ , refl , le , tt)
≤-squeeze : {x : Nat} → x ≤ zero → x ≡ zero
≤-squeeze (con (`nil , refl , _)) = refl
≤-squeeze (con (`cons , _ , _ , () , _))
≤-step⁻¹ : {x y : Nat} → suc x ≤ suc y → x ≤ y
≤-step⁻¹ (con (`nil , () , _))
≤-step⁻¹ (con (`cons , _ , _ , refl , le , _)) = le
≤-refl : {x : Nat} → x ≤ x
≤-refl {con (`nil , _)} = ≤-base
≤-refl {con (`cons , x , _)} = ≤-step (≤-refl {x})
≤-trans : {x y z : Nat} → x ≤ y → y ≤ z → x ≤ z
≤-trans (con (`nil , refl , _)) y≤z = ≤-base
≤-trans (con (`cons , _ , _ , refl , x≤y , _)) (con (`nil , () , _))
≤-trans (con (`cons , _ , _ , refl , x≤y , _)) (con (`cons , ._ , _ , refl , y≤z , _)) = ≤-step (≤-trans x≤y y≤z)
≰-invert : {x y : Nat} → x ≰ y → y ≤ x
≰-invert {x} {con (`nil , _)} nle = ≤-base
≰-invert {con (`nil , _)} {con (`cons , y , _)} nle = ⊥-elim (nle ≤-base)
≰-invert {con (`cons , x , _)} {con (`cons , y , _)} nle = ≤-step (≰-invert (nle ∘ ≤-step))
mutual
_≤?_ : (x y : Nat) → Dec (x ≤ y)
con (`nil , _) ≤? y = yes ≤-base
con (`cons , x , _) ≤? con (`nil , _) = no (suc≢zero ∘ ≤-squeeze)
con (`cons , x , _) ≤? con (`cons , y , _) = ≤?-with x y (x ≤? y)
≤?-with : (x y : Nat) → Dec (x ≤ y) → Dec (suc x ≤ suc y)
≤?-with x y (yes x≤y) = yes (≤-step x≤y)
≤?-with x y (no x≰y) = no (x≰y ∘ ≤-step⁻¹)