packages feed

fitspec-0.2.0: bench/sorting.hs

import Data.List
import FitSpec


ordered :: Ord a => [a] -> Bool
ordered [] = True
ordered [_] = True
ordered (x:y:xs) = x <= y && ordered (y:xs)

permutation :: Eq a => [a] -> [a] -> Bool
[]     `permutation` []    = True
(_:_)  `permutation` []    = False
[]     `permutation` (_:_) = False
(x:xs) `permutation` ys    = x `elem` ys  &&  xs `permutation` delete x ys

count :: Eq a => a -> [a] -> Int
count x = length . filter (==x)


properties :: (Ord a, Show a, Listable a)
           => ([a] -> [a]) -> [Property]
properties sort =
  [ property $ \xs ->          ordered (sort xs)
  , property $ \xs ->           length (sort xs) == length xs
  , property $ \x xs ->         elem x (sort xs) == elem x xs
  , property $ \x xs ->        count x (sort xs) == count x xs
  , property $ \xs ->   permutation xs (sort xs)
  , property $ \x xs ->       insert x (sort xs) == sort (x:xs)
  ]


sargs :: Args
sargs = args
  { names = ["sort xs"]
  , timeout  =    0
  , nMutants = 1000
  , nTests   = 1000
  }
--, extraMutants = take 0
--               . concat
--               . lsmap (. sort)
--               $ cons2 (\y ys -> (++ (y:ys))) -- prepend non-empty list
--            \++/ cons2 (\y ys -> ((y:ys) ++)) -- append non-empty list

type Ty a = [a] -> [a]

main :: IO ()
main = do
  as <- getArgsWith sargs
  let run f = reportWith as f properties
  case concat $ extra as of
    "bool"  -> run (sort :: Ty Bool)
    "bools" -> run (sort :: Ty [Bool])
    "int"   -> run (sort :: Ty Int)
    "i1"    -> run (sort :: Ty Int1)
    "i2"    -> run (sort :: Ty Int2)
    "i3"    -> run (sort :: Ty Int3)
    "w1"    -> run (sort :: Ty Word1)
    "w2"    -> run (sort :: Ty Word2)
    "w3"    -> run (sort :: Ty Word3)
    "unit"  -> run (sort :: Ty ())
    ""      -> run (sort :: Ty Word2)
    t       -> putStrLn $ "unknown type " ++ t

-- This hack is only necessary when using sortCounter as a manual mutant
instance Bounded a => Bounded [a] where
  minBound = []
  maxBound = repeat maxBound -- non terminating upper bound

sortCounter :: (Bounded a, Ord a) => [a] -> [a]
sortCounter = (++ [maxBound]) . sort