packages feed

MiniAgda-0.2014.1.9: test/succeed/qsapp.ma

-- 2010-06-21 Andreas Abel  
-- Quicksort (implementation using partition) in MiniAgda

-- Booleans

data Bool : Set
{ true : Bool
; false : Bool
}

fun if : [A : Set] -> Bool -> A -> A -> A
{ if A true  t e = t
; if A false t e = e
}

-- Natural numbers

data Nat : Set
{ zero : Nat
; succ : Nat -> Nat
}

fun leq : Nat -> Nat -> Bool 
{ leq  zero     n       = true
; leq (succ m)  zero    = false
; leq (succ m) (succ n) = leq m n
}

-- Lists over natural numbers as a sized inductive type

sized data List : Size -> Set
{ nil  : [i : Size] -> List ($ i) 
; cons : [i : Size] -> Nat -> List i -> List ($ i)
}

-- Partition a list, continuation-style
-- the lists passed to the continuation k are at most as big as the input list

fun partition : (Nat -> Bool) -> [i : Size] -> List i -> 
  [A : Set] -> (List i -> List i -> A) -> A
{ partition p i (nil  (i > j))     A k = k (nil j) (nil j)
; partition p i (cons (i > j) n l) A k = if A (p n)
   (partition p j l A (\ l1 -> \ l2 -> k (cons j n l1) l2)) -- then 
   (partition p j l A (\ l1 -> \ l2 -> k l1 (cons j n l2))) -- else
}

-- Quicksort-append
-- qsapp i l1 l2 = append (sort l1) l2

fun qsapp : [i : Size] -> List i -> List # -> List #
{ qsapp i (nil (i > j))      acc = acc
; qsapp i (cons (i > j) n l) acc = partition (\ m -> leq m n) j l (List #)
    (\ l1 -> \ l2 -> qsapp j l1 (cons # n (qsapp j l2 acc)))
}

-- Quicksort 

let quicksort : List # -> List # = \ l -> qsapp # l (nil #)

-- Testing

let n0 : Nat = zero
let n1 : Nat = succ n0
let n2 : Nat = succ n1
let n3 : Nat = succ n2
let n4 : Nat = succ n3
let n5 : Nat = succ n4
let n6 : Nat = succ n5
let n7 : Nat = succ n6
let n8 : Nat = succ n7
let n9 : Nat = succ n8

-- qsapp is fast enough even with MiniAgda CBN
let l : List # = 
  (cons # n4 (cons # n9 (cons # n1 (cons # n7 (cons # n6 
  (cons # n4 (cons # n0 (cons # n0 
  (cons # n3 (cons # n3 (cons # n3 (cons # n2 (cons # n3 (nil #))))))))))))))
-- eval  -- 2012-02-25 NO LONGER 
let l' : List # = quicksort l