arithmoi-0.11.0.0: test-suite/Math/NumberTheory/Primes/SequenceTests.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Math.NumberTheory.Primes.SequenceTests
( testSuite
) where
import Test.Tasty
import Test.Tasty.HUnit
import Data.Bits
import Data.Maybe
import Data.Proxy
import Numeric.Natural
import Math.NumberTheory.Primes
import Math.NumberTheory.Primes.Counting (nthPrime, primeCount)
import Math.NumberTheory.TestUtils
nextPrimeProperty
:: (Bits a, Integral a, UniqueFactorisation a)
=> AnySign a
-> Bool
nextPrimeProperty (AnySign n) = unPrime (nextPrime n) >= n
precPrimeProperty
:: (Bits a, Integral a, UniqueFactorisation a)
=> Positive a
-> Bool
precPrimeProperty (Positive n) = n <= 2 || unPrime (precPrime n) <= n
toEnumProperty
:: forall a.
(Enum (Prime a), Integral a)
=> Proxy a
-> Int
-> Bool
toEnumProperty _ n = n <= 0 || unPrime (toEnum n :: Prime a) == fromInteger (unPrime (nthPrime n))
fromEnumProperty
:: (Enum (Prime a), Integral a)
=> Prime a
-> Bool
fromEnumProperty p = fromEnum p == fromInteger (primeCount (toInteger (unPrime p)))
succProperty
:: (Enum a, Enum (Prime a), Num a, UniqueFactorisation a)
=> Prime a
-> Bool
succProperty p = all (isNothing . isPrime) [unPrime p + 1 .. unPrime (succ p) - 1]
predProperty
:: (Enum a, Enum (Prime a), Ord a, Num a, UniqueFactorisation a)
=> Prime a
-> Bool
predProperty p = unPrime p <= 2 || all (isNothing . isPrime) [unPrime (pred p) + 1 .. unPrime p - 1]
enumFrom2To2 :: Assertion
enumFrom2To2 = assertEqual "should be equal"
[two]
[two..two]
where
two = minBound :: Prime Word
enumFrom65500To65600 :: Assertion
enumFrom65500To65600 = assertEqual "should be equal"
[65519, 65521, 65537, 65539, 65543, 65551, 65557, 65563, 65579, 65581, 65587, 65599]
(map unPrime [low..high])
where
low = nextPrime (65500 :: Word)
high = precPrime (65600 :: Word)
enumFrom2To100000 :: Assertion
enumFrom2To100000 = assertEqual "should be equal"
(takeWhile (<= high) [low..])
[low..high]
where
low = minBound :: Prime Word
high = precPrime (100000 :: Word)
enumFromProperty
:: (Ord a, Enum (Prime a))
=> Prime a
-> Prime a
-> Bool
enumFromProperty p q = [p..q] == takeWhile (<= q) [p..]
enumFromToProperty
:: (Eq a, Enum a, Enum (Prime a), UniqueFactorisation a)
=> Prime a
-> Prime a
-> Bool
enumFromToProperty p q = [p..q] == mapMaybe isPrime [unPrime p .. unPrime q]
enumFromThenProperty
:: (Show a, Ord a, Enum (Prime a))
=> Prime a
-> Prime a
-> Prime a
-> Bool
enumFromThenProperty p q r = case p `compare` q of
LT -> enumFromThenTo p q r == takeWhile (<= r) (enumFromThen p q)
EQ -> True
GT -> enumFromThenTo p q r == takeWhile (>= r) (enumFromThen p q)
enumFromThenToProperty
:: (Ord a, Enum a, Enum (Prime a), UniqueFactorisation a, Show a)
=> Prime a
-> Prime a
-> Prime a
-> Bool
enumFromThenToProperty p q r
| p == q && q <= r = True
| otherwise
= [p, q .. r] == mapMaybe isPrime [unPrime p, unPrime q .. unPrime r]
testSuite :: TestTree
testSuite = testGroup "Sequence"
[ testIntegralPropertyNoLarge "nextPrime" nextPrimeProperty
, testIntegralPropertyNoLarge "precPrime" precPrimeProperty
, testGroup "toEnum"
[ testSmallAndQuick "Int" (toEnumProperty (Proxy @Int))
, testSmallAndQuick "Word" (toEnumProperty (Proxy @Word))
, testSmallAndQuick "Integer" (toEnumProperty (Proxy @Integer))
, testSmallAndQuick "Natural" (toEnumProperty (Proxy @Natural))
]
, testGroup "fromEnum"
[ testSmallAndQuick "Int" (fromEnumProperty @Int)
, testSmallAndQuick "Word" (fromEnumProperty @Word)
, testSmallAndQuick "Integer" (fromEnumProperty @Integer)
, testSmallAndQuick "Natural" (fromEnumProperty @Natural)
]
, testGroup "succ"
[ testSmallAndQuick "Int" (succProperty @Int)
, testSmallAndQuick "Word" (succProperty @Word)
, testSmallAndQuick "Integer" (succProperty @Integer)
, testSmallAndQuick "Natural" (succProperty @Natural)
]
, testGroup "pred"
[ testSmallAndQuick "Int" (predProperty @Int)
, testSmallAndQuick "Word" (predProperty @Word)
, testSmallAndQuick "Integer" (predProperty @Integer)
, testSmallAndQuick "Natural" (predProperty @Natural)
]
, testCase "[2..2] == [2]" enumFrom2To2
, testCase "[65500..65600]" enumFrom65500To65600
, testCase "[2..100000]" enumFrom2To100000
, testGroup "enumFrom"
[ testSmallAndQuick "Int" (enumFromProperty @Int)
, testSmallAndQuick "Word" (enumFromProperty @Word)
, testSmallAndQuick "Integer" (enumFromProperty @Integer)
, testSmallAndQuick "Natural" (enumFromProperty @Natural)
]
, testGroup "enumFromTo"
[ testSmallAndQuick "Int" (enumFromToProperty @Int)
, testSmallAndQuick "Word" (enumFromToProperty @Word)
, testSmallAndQuick "Integer" (enumFromToProperty @Integer)
, testSmallAndQuick "Natural" (enumFromToProperty @Natural)
]
, testGroup "enumFromThen"
[ testSmallAndQuick "Int" (enumFromThenProperty @Int)
, testSmallAndQuick "Word" (enumFromThenProperty @Word)
, testSmallAndQuick "Integer" (enumFromThenProperty @Integer)
, testSmallAndQuick "Natural" (enumFromThenProperty @Natural)
]
, testGroup "enumFromThenTo"
[ testSmallAndQuick "Int" (enumFromThenToProperty @Int)
, testSmallAndQuick "Word" (enumFromThenToProperty @Word)
, testSmallAndQuick "Integer" (enumFromThenToProperty @Integer)
, testSmallAndQuick "Natural" (enumFromThenToProperty @Natural)
]
]