--
-- This code written by Tim Sheard -- This file should work with Omega version 1.1 -- released May 23, 2005 -- See http://www.cs.pdx.edu/~sheard/Omega/index.html -- Existenial hiding and operators on anonymous sums data Covert t = exists x . Hide (t x) mapP :: (a -> b) -> (c -> d) -> (a+c) -> (b+d) mapP f g (L x) = L(f x) mapP f g (R x) = R(g x) unP :: (a+a) -> a unP (L x) = x unP (R x) = x map f [] = [] map f (x:xs) = f x : map f xs ----------------------------------------- -- singleton Nats and Less-than-equal (LE) {- Predefined by the compiler kind Nat = Z | S Nat data Nat' x = Z where x=Z | exist m . S (Nat' m) where x=S m -} data LE a b = LeBase where a=b | ex c . LeStep (LE a c) where b = S c g :: LE x y -> LE (S x) (S y) g LeBase = LeBase g (LeStep x) = LeStep(g x) trans :: LE a b -> LE b c -> LE a c trans LeBase LeBase = LeBase trans (x@(LeStep z)) LeBase = x trans LeBase (y@(LeStep z)) = y trans (a@(LeStep x)) (LeStep y) = LeStep(trans a y) magnitude :: Nat' a -> LE Z a magnitude Z = LeBase magnitude (S x) = LeStep(magnitude x) ------------------------------------------------- -- Sorted Sequence data data SSeq n = Snil where n = Z | ex m . Scons (Nat' n) (LE m n) (SSeq m) -------------------------------------------------- -- insertion sort 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 g :: LE x y -> LE (S x) (S y) g LeBase = LeBase g (LeStep x) = LeStep(g x) insert :: Nat' a -> SSeq b -> ((SSeq a)+(SSeq b)) insert z Snil = L(Scons z (magnitude z) Snil) insert x (xs@(Scons y p zs)) = case compare x y of R q -> L(Scons x q xs) L q -> case insert x zs of L (mm) -> R(Scons y q mm) R (mm) -> R(Scons y p mm) sort :: [Covert Nat'] -> Covert SSeq sort [] = Hide Snil sort ((Hide x):xs) = case insert x ys of {L w -> Hide w; R w -> Hide w} where (Hide ys) = sort xs toNat :: Int -> Covert Nat' toNat 0 = Hide Z toNat n = case toNat (n-1) of Hide b -> Hide(S b) test :: Nat' x -> Nat' y -> Maybe (Equal x y) test Z Z = Just Eq test (S x) (S y) = case (test x y) of { Just Eq -> Just Eq; Nothing -> Nothing} test _ _ = Nothing test2 :: [Int] -> Covert SSeq test2 xs = sort(map toNat xs) x23 = test2 [0,3,1] ---------------------------------------------------- -- merge sort merge :: SSeq n -> SSeq m -> (SSeq n + SSeq m) merge Snil ys = R ys merge xs Snil = L xs merge (a@(Scons x px xs)) (b@(Scons y py ys)) = case compare x y of L p -> case merge a ys of L ws -> R(Scons y p ws) R ws -> R(Scons y py ws) R p -> case merge b xs of L ws -> L(Scons x p ws) R ws -> L(Scons x px ws) merge2 :: SSeq u -> SSeq v -> Covert SSeq merge2 x y = unP (mapP Hide Hide (merge x y)) split [] pair = pair split [x] (xs,ys) = (x:xs,ys) split (x:y:zs) (xs,ys) = split zs (x:xs,y:ys) msort :: [Covert Nat'] -> Covert SSeq msort [] = Hide Snil msort [Hide x] = Hide(Scons x (magnitude x) Snil) msort xs = merge2 ys zs where (y,z) = split xs ([],[]) (Hide ys) = msort y (Hide zs) = msort z --