module Quipper.Libraries.ClassicalOptim.QuickCheckAlgExp where import qualified Test.QuickCheck as Test import qualified Data.Map as M import qualified Data.List as L import qualified Data.Set as S import qualified Data.IntSet as IS import qualified Data.IntMap.Strict as IM {- containers-0.5.2.1 -} import Quipper.Utils.Auxiliary (bool_xor) import Quipper.Libraries.ClassicalOptim.Circuit import Quipper.Libraries.ClassicalOptim.AlgExp -- ---------------------------------------------------------------------- -- ** Quick-checking -- | Compute 2[sup /n/]. twoExp :: (Integral a) => a -> Int twoExp 0 = 1 twoExp n | mod n 2 == 0 = let a = twoExp (div n 2) in a * a | otherwise = 2 * (twoExp (n-1)) -- | Generate a list of 'Bool'. genBoolList :: Integral a => a -> Test.Gen [Bool] genBoolList n = Test.vectorOf (twoExp n) $ Test.oneof [return True, return False] -- | Arguments for QuickCheck. test_args :: Test.Args test_args = Test.stdArgs { Test.maxSize = 100, Test.maxSuccess = 100, Test.maxDiscardRatio = 20 } -- | First test: truth table to expression to truth table is the identity. test_truth1 :: Int -> IO () test_truth1 n = Test.quickCheckWith test_args $ aux where aux = Test.forAll (genBoolList n) $ \x -> x == (truth_table_of_exp [1..n] $ exp_of_truth_table 1 x) -- | Generate a random list of @Int@s. genIntList :: [Int] -> Int -> Test.Gen [Int] genIntList vars size = do s <- Test.choose (0,size) Test.vectorOf s $ Test.elements vars -- | Generate a random expression out of the given variables. genExp :: [Int] -> Test.Gen Exp genExp vars = do nber <- Test.choose (0, twoExp (length vars)) v <- Test.vectorOf nber $ Test.sized $ genIntList vars return $ expOfList v -- | Second test: expression to truth table to expression is the -- identity. test_truth2 :: Int -> IO Test.Result test_truth2 n = Test.quickCheckWithResult test_args $ aux where aux = Test.forAll (genExp [1..n]) $ \x -> x == (exp_of_truth_table 1 $ truth_table_of_exp [1..n] x)