|
Packit |
785658 |
-- |
|
|
Packit |
785658 |
-- Module: Math.NumberTheory.TestUtils
|
|
Packit |
785658 |
-- Copyright: (c) 2016 Andrew Lelechenko
|
|
Packit |
785658 |
-- Licence: MIT
|
|
Packit |
785658 |
-- Maintainer: Andrew Lelechenko <andrew.lelechenko@gmail.com>
|
|
Packit |
785658 |
-- Stability: Provisional
|
|
Packit |
785658 |
-- Portability: Non-portable (GHC extensions)
|
|
Packit |
785658 |
--
|
|
Packit |
785658 |
|
|
Packit |
785658 |
{-# LANGUAGE FlexibleContexts #-}
|
|
Packit |
785658 |
{-# LANGUAGE FlexibleInstances #-}
|
|
Packit |
785658 |
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
|
Packit |
785658 |
{-# LANGUAGE MultiParamTypeClasses #-}
|
|
Packit |
785658 |
{-# LANGUAGE StandaloneDeriving #-}
|
|
Packit |
785658 |
|
|
Packit |
785658 |
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
|
Packit |
785658 |
|
|
Packit |
785658 |
module Math.NumberTheory.TestUtils
|
|
Packit |
785658 |
( module Test.SmallCheck.Series
|
|
Packit |
785658 |
, Power (..)
|
|
Packit |
785658 |
, Huge (..)
|
|
Packit |
785658 |
, testSmallAndQuick
|
|
Packit |
785658 |
) where
|
|
Packit |
785658 |
|
|
Packit |
785658 |
import Test.SmallCheck.Series (cons2)
|
|
Packit |
785658 |
import Test.Tasty
|
|
Packit |
785658 |
import Test.Tasty.SmallCheck as SC
|
|
Packit |
785658 |
import Test.Tasty.QuickCheck as QC hiding (Positive, NonNegative, generate, getNonNegative)
|
|
Packit |
785658 |
import Test.SmallCheck.Series (Positive(..), NonNegative(..), Serial(..), Series, generate)
|
|
Packit |
785658 |
|
|
Packit |
785658 |
import Control.Applicative
|
|
Packit |
785658 |
import Data.Word
|
|
Packit |
785658 |
import Numeric.Natural
|
|
Packit |
785658 |
|
|
Packit |
785658 |
testSmallAndQuick
|
|
Packit |
785658 |
:: SC.Testable IO a
|
|
Packit |
785658 |
=> QC.Testable a
|
|
Packit |
785658 |
=> String -> a -> TestTree
|
|
Packit |
785658 |
testSmallAndQuick name f = testGroup name
|
|
Packit |
785658 |
[ SC.testProperty "smallcheck" f
|
|
Packit |
785658 |
, QC.testProperty "quickcheck" f
|
|
Packit |
785658 |
]
|
|
Packit |
785658 |
|
|
Packit |
785658 |
-------------------------------------------------------------------------------
|
|
Packit |
785658 |
-- Serial monadic actions
|
|
Packit |
785658 |
|
|
Packit |
785658 |
instance Monad m => Serial m Word where
|
|
Packit |
785658 |
series =
|
|
Packit |
785658 |
generate (\d -> if d >= 0 then pure 0 else empty) <|> nats
|
|
Packit |
785658 |
where
|
|
Packit |
785658 |
nats = generate $ \d -> if d > 0 then [1 .. fromInteger (toInteger d)] else empty
|
|
Packit |
785658 |
|
|
Packit |
785658 |
instance Monad m => Serial m Natural where
|
|
Packit |
785658 |
series =
|
|
Packit |
785658 |
generate (\d -> if d >= 0 then pure 0 else empty) <|> nats
|
|
Packit |
785658 |
where
|
|
Packit |
785658 |
nats = generate $ \d -> if d > 0 then [1 .. fromInteger (toInteger d)] else empty
|
|
Packit |
785658 |
|
|
Packit |
785658 |
-------------------------------------------------------------------------------
|
|
Packit |
785658 |
-- Power
|
|
Packit |
785658 |
|
|
Packit |
785658 |
newtype Power a = Power { getPower :: a }
|
|
Packit |
785658 |
deriving (Eq, Ord, Read, Show, Num, Enum, Bounded, Integral, Real)
|
|
Packit |
785658 |
|
|
Packit |
785658 |
instance (Monad m, Num a, Ord a, Serial m a) => Serial m (Power a) where
|
|
Packit |
785658 |
series = Power <$> series `suchThatSerial` (> 0)
|
|
Packit |
785658 |
|
|
Packit |
785658 |
instance (Num a, Ord a, Integral a, Arbitrary a) => Arbitrary (Power a) where
|
|
Packit |
785658 |
arbitrary = Power <$> (getSmall <$> arbitrary) `suchThat` (> 0)
|
|
Packit |
785658 |
shrink (Power x) = Power <$> filter (> 0) (shrink x)
|
|
Packit |
785658 |
|
|
Packit |
785658 |
suchThatSerial :: Series m a -> (a -> Bool) -> Series m a
|
|
Packit |
785658 |
suchThatSerial s p = s >>= \x -> if p x then pure x else empty
|
|
Packit |
785658 |
|
|
Packit |
785658 |
-------------------------------------------------------------------------------
|
|
Packit |
785658 |
-- Huge
|
|
Packit |
785658 |
|
|
Packit |
785658 |
newtype Huge a = Huge { getHuge :: a }
|
|
Packit |
785658 |
deriving (Eq, Ord, Read, Show, Num, Enum, Bounded, Integral, Real)
|
|
Packit |
785658 |
|
|
Packit |
785658 |
instance (Num a, Arbitrary a) => Arbitrary (Huge a) where
|
|
Packit |
785658 |
arbitrary = do
|
|
Packit |
785658 |
Positive l <- arbitrary
|
|
Packit |
785658 |
ds <- vector (l :: Int)
|
|
Packit |
785658 |
return $ Huge $ foldl1 (\acc n -> acc * 2^(63 :: Int) + n) ds
|
|
Packit |
785658 |
|
|
Packit |
785658 |
-- | maps 'Huge' constructor over series
|
|
Packit |
785658 |
instance Serial m a => Serial m (Huge a) where
|
|
Packit |
785658 |
series = fmap Huge series
|
|
Packit |
785658 |
|
|
Packit |
785658 |
-------------------------------------------------------------------------------
|
|
Packit |
785658 |
-- Positive from smallcheck
|
|
Packit |
785658 |
|
|
Packit |
785658 |
instance (Num a, Ord a, Arbitrary a) => Arbitrary (Positive a) where
|
|
Packit |
785658 |
arbitrary = Positive <$> (arbitrary `suchThat` (> 0))
|
|
Packit |
785658 |
shrink (Positive x) = Positive <$> filter (> 0) (shrink x)
|