Skip to content

Instantly share code, notes, and snippets.

@VictorTaelin
Created March 30, 2025 19:07
Show Gist options
  • Save VictorTaelin/18045d28efead2fa65cfbc079ed07265 to your computer and use it in GitHub Desktop.
Save VictorTaelin/18045d28efead2fa65cfbc079ed07265 to your computer and use it in GitHub Desktop.
terminating sort in agda
data Uni : Set where
U : Uni
data : Set where
Z :
S :
data Vec (A : Set) : Set where
[] : {n} Vec A n
_::_ : {n} A Vec A n Vec A (S n)
Nat : s Set
Nat s = Vec Uni s
data _≡_ {A : Set} : A A Set where
refl : {x} x ≡ x
{-# BUILTIN EQUALITY _≡_ #-}
-- Equality
-- --------
subst : {A : Set} {x y : A} (P : A Set) x ≡ y P x P y
subst P refl px = px
sym : {A : Set} {x y : A} x ≡ y y ≡ x
sym refl = refl
cong : {A B : Set} {x y : A} (f : A B) x ≡ y f x ≡ f y
cong f refl = refl
-- ℕ
-- -
add :
add Z m = m
add (S n) m = S (add n m)
+zero : {m} add m Z ≡ m
+zero {Z} = refl
+zero {S m} = cong S +zero
+succ : {m n} add m (S n) ≡ S (add m n)
+succ {Z} = refl
+succ {S m} = cong S +succ
-- Vector
-- ------
map : {A B n} (A B) Vec A n Vec B n
map f [] = []
map f (x :: xs) = f x :: map f xs
-- The last argument is an accumulator (initially empty)
sort : {s n m} Vec (Nat (S s)) n Vec (Nat s) m Vec (Nat (S s)) (add n m)
sort {Z} {Z} {m} [] ys = map (λ x U :: x) ys
sort {Z} {(S n)} {m} ([] :: xs) ys = [] :: sort {Z} {n} {m} xs ys
sort {Z} {(S n)} {m} ((u :: x) :: xs) ys = subst (λ x Vec _ x) (+succ) (sort {Z} {n} {(S m)} xs (x :: ys))
sort {(S s)} {Z} {m} [] ys = subst (λ x Vec _ x) (+zero) (map (λ x U :: x) (sort {s} {m} {Z} ys []))
sort {(S s)} {(S n)} {m} ([] :: xs) ys = [] :: sort {(S s)} {n} {m} xs ys
sort {(S s)} {(S n)} {m} ((u :: x) :: xs) ys = subst (λ x Vec _ x) (+succ) (sort {(S s)} {n} {(S m)} xs (x :: ys))
sort {s} {n} {m} xs ys = []
-- Representation of numbers as vectors
n0 : {n} Nat n
n0 = []
n1 : {n} Nat (S n)
n1 = U :: []
n2 : {n} Nat (S (S n))
n2 = U :: (U :: [])
n3 : {n} Nat (S (S (S n)))
n3 = U :: (U :: (U :: []))
n4 : {n} Nat (S (S (S (S n))))
n4 = U :: (U :: (U :: (U :: [])))
vec : Vec (Nat (S (S (S Z)))) (S (S (S Z)))
vec = n3 :: (n1 :: (n2 :: []))
-- Example: sorting [3,1,2]
main : Vec (Nat (S (S (S Z)))) (S (S (S Z)))
main = sort {(S (S Z))} {(S (S (S Z)))} {Z} vec []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment