packages feed

fitspec-0.2.0: bench/sieve.hs

-- Example benchmark that mutation tests properties over an infinite list of primes
import System.Console.CmdArgs hiding (args)
import 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<y && strictlyOrdered (y:xs)

elemO :: Ord a => 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