module QCUtils where
import Prelude hiding (catch)
import Test.QuickCheck
import Control.Exception
import Foreign (unsafePerformIO)
import System.Random
propertyDefined :: a -> Property
propertyDefined exp = unsafePerformIO $
catch (do x <- evaluate exp
return $ property True)
(\(exc::SomeException) -> return $ property False)
excAsFalse :: Testable a => a -> Property
excAsFalse exp = unsafePerformIO $
catch (do x <- evaluate exp
return $ property x)
(\(exc::SomeException) -> return $ property False)
excAsNothing :: a -> Maybe a
excAsNothing exp = unsafePerformIO $
catch (do x <- evaluate exp
return $ Just x)
(\(exc::SomeException) -> return Nothing)
throws :: a -> Bool
throws exp = unsafePerformIO $
catch (do !x <- evaluate exp
return $ False)
(\(exc::SomeException) -> return True)
f_equal x f g = (excAsNothing $ f x) == (excAsNothing $ g x)
arbChar :: Gen Char
arbChar = elements $ ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ ['_', ' ', '!']
arbLetter :: Gen Char
arbLetter = elements $ ['a'..'z'] ++ ['A'..'Z']
arbWordChar :: Gen Char
arbWordChar = frequency [(1, elements $ ['a'..'z'] ++ ['A'..'Z']),
(1, elements ['_'])]
arbStringLen :: Gen Char -> Int -> Gen String
arbStringLen charGen 0 = return ""
arbStringLen charGen n = do str <- arbStringLen charGen (n1)
ch <- charGen
return $ ch : str
arbString charGen = frequency [(1, arbStringLen charGen len)| len <- [0..6]]
arbStringSized charGen = sized (\n -> arbStringLen charGen n)
genIntLt n = elements [0..n1]
vecTor :: Int -> Gen a -> Gen [a]
vecTor n _ | n < 0 = error "vector with negative # of elements"
vecTor 0 gen = return []
vecTor n gen = do x <- gen; xs <- vecTor (n1) gen; return $ x : xs
posInt :: (Num a, Arbitrary a) => Gen a
posInt = fmap ((+1) . abs) arbitrary
nonNegInt :: (Num a, Arbitrary a) => Gen a
nonNegInt = fmap abs arbitrary
expIntGen n = frequency [(1, return n), (1, expIntGen (n+1))]
whens p e = if p then e else []
small = stdArgs
big = Args {
maxSuccess = 1000,
maxDiscard = 1000,
maxSize = 12,
replay = Nothing,
chatty = False
}
huge = Args {
maxSuccess = 10000,
maxDiscard = 5000,
maxSize = 20,
replay = Nothing,
chatty = False
}
histogram [] result = result
histogram (x : xs) result =
histogram xs (incLookup x result)
where incLookup x [] = [(x, 1)]
incLookup x ((y, yN):ys) | x == y = (y,yN+1) : ys
| otherwise = (y,yN) : (incLookup x ys)
subsets [] = [[]]
subsets (x:xs) =
let xsSubsets = subsets xs in
map (x:) xsSubsets ++ xsSubsets
chooseSubset [] n = []
chooseSubset (x:xs) 0 = []
chooseSubset (x:xs) n = if n `mod` 2 == 1 then x : chooseSubset xs (n `div` 2)
else chooseSubset xs (n `div` 2)
arbSubset xs = do n <- posInt :: Gen Int
return $ chooseSubset xs n
genEnv :: (Arbitrary a, Num a, Enum a, Arbitrary b) => a -> Gen [(a, b)]
genEnv min =
do n <- arbitrary
sequence [do ty <- arbitrary; return (i, ty)
| i <- [min..min+pred(abs n)]]
failProp = property False
ignore = False ==> (undefined::Bool)
tinyArgs :: Args
tinyArgs = Args {
maxSuccess = 100,
maxDiscard = 100,
maxSize = 8,
replay = Nothing,
chatty = False
}
verySmallArgs :: Args
verySmallArgs = Args {
maxSuccess = 1000,
maxDiscard = 1000,
maxSize = 12,
replay = Nothing,
chatty = False
}
smallArgs :: Args
smallArgs = Args {
maxSuccess = 10000,
maxDiscard = 10000,
maxSize = 16,
replay = Nothing,
chatty = False
}
mediumArgs :: Args
mediumArgs = Args {
maxSuccess = 100,
maxDiscard = 100,
maxSize = 100,
replay = Nothing,
chatty = False
}
bigArgs :: Args
bigArgs = Args {
maxSuccess = 1000,
maxDiscard = 1000,
maxSize = 500,
replay = Nothing,
chatty = False
}