--
-- This code written by James Hook -- This file should work with Omega version 1.1 -- released May 23, 2005 -- See http://www.cs.pdx.edu/~sheard/Omega/index.html {-- These are predefined by the compiler kind Nat = Z | S Nat data Nat' n = Z where n = Z | forall m . S (Nat' m) where n = S m -} data LE a b = LeBase where a = b | ex c . LeStep (LE a c) where b = S c reflLE :: LE a a reflLE = LeBase transLE :: (LE a b) -> (LE b c) -> (LE a c) transLE p LeBase = p transLE p (LeStep q) = LeStep (transLE p q) compare :: Nat' a -> Nat' b -> ((LE a b)+(LE b a)) compare Z Z = L LeBase compare Z (S x) = case compare Z x of L w -> L (LeStep w) compare (S x) Z = case compare Z x of L w -> R (LeStep w) compare (S x) (S y) = mapP g g (compare x y ) where mapP f g (L x) = L(f x) mapP f g (R x) = R(g x) g :: LE x y -> LE (S x) (S y) g LeBase = LeBase g (LeStep x) = LeStep (g x) data MonoList min max = MonoNil (LE min max) | forall n a . MonoCons (Nat' n) (LE a n) (LE n max) (MonoList min a) appMonoList :: MonoList b c -> MonoList a b -> MonoList a c appMonoList (MonoNil bc) (MonoNil ab) = MonoNil (transLE ab bc) appMonoList (MonoNil bc) (MonoCons n an nb xs) = MonoCons n an (transLE nb bc) xs appMonoList (MonoCons m dm mc ys) xs = MonoCons m dm mc (appMonoList ys xs) singletonMonoList :: Nat' n -> MonoList n n singletonMonoList n = MonoCons n reflLE reflLE (MonoNil reflLE) data IntervalList min max = ILNil (LE min max) | forall x . ILCons (Nat' x) (LE min x) (LE x max) (IntervalList min max) partition :: Nat' n -> LE a n -> LE n b -> IntervalList a b -> (IntervalList a n, IntervalList n b) partition x an nb xs = partitionAcc (ILNil an) (ILNil nb) xs where partitionAcc ls gs (ILNil ab) = (ls,gs) partitionAcc ls gs (ILCons y ay yb ys) = case compare y x of L yx -> partitionAcc (ILCons y ay yx ls) gs ys R xy -> partitionAcc ls (ILCons y xy yb gs) ys qsort :: IntervalList a b -> MonoList a b qsort (ILNil ab) = MonoNil ab qsort (ILCons x ax xb (ILNil ab)) = MonoCons x ax xb (MonoNil reflLE) qsort (ILCons x ax xb xs) = let (less,greater) = partition x ax xb xs sortedLess = qsort less sortedGreater = qsort greater in appMonoList sortedGreater (appMonoList (singletonMonoList x) sortedLess) --