-- Example benchmark that mutation tests properties over an infinite list of primes import Test.FitSpec import Data.Maybe -- The code under test primes :: [Int] primes = sieve [2..] where sieve (p:ns) = p : sieve [n | n <- ns, n `mod` p /= 0] -- Some auxiliary functions strictlyOrdered [] = True strictlyOrdered [x] = True strictlyOrdered (x:y:xs) = x a -> [a] -> Bool x `elemO` [] = False x `elemO` (x':xs) = case x `compare` x' of LT -> False -- would already have appeared int the list EQ -> True GT -> x `elemO` xs infix 4 `elemO` notElemO :: Ord a => a -> [a] -> Bool notElemO = (not .) . elemO infix 4 `notElemO` -- The property map properties :: [Int] -> [Property] properties primes = [ property $ listToMaybe primes == Just 2 -- start with two --, property $ length (take n primes) == n -- infinite --, property $ allUnique (take n primes) --, property $ strictlyOrdered (take n primes) , property $ \x -> x `elemO` primes ==> x*x `notElemO` primes , property $ \x y -> x `elemO` primes && y `elemO` primes ==> x*y `notElemO` primes --, property $ \i' -> let i = fromIntegral (i'::Nat) -- p = primes !! i -- ps = drop (i+1) primes -- in p > 1 ==> all (\p' -> p' `mod` p /= 0) (take n ps) , property $ \x y -> x `elemO` primes && y `elemO` primes && x /= y ==> x `mod` y /= 0 --, all prime (take n primes) -- sound --, all (`elemO` primes) [ x | x <- [1..n], prime x ] -- complete ] where prime x = x > 1 && all (\p -> p > 0 && x `mod` p /= 0) (takeWhile (\p -> p*p <= x) primes) prime x = x > 1 && all (\p -> p `mod` x /= 0) (takeWhile (\p -> p*p <= x) primes) sargs :: Args sargs = args { nMutants = 20000 , nTests = 100 , timeout = 0 } --, showMutantN = \_ _ -> showInfinite --where showInfinite xs | not . null $ drop 10 xs = (init . show $ take 10 xs) ++ "..." -- | otherwise = show xs main :: IO () main = mainWith sargs primes properties allUnique :: Ord a => [a] -> Bool allUnique [] = True allUnique (x:xs) = x `notElem` xs && allUnique lesser && allUnique greater where lesser = filter (< x) xs greater = filter (> x) xs