finite-field-0.4.0: test/TestPrimeField.hs
{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}
import Test.QuickCheck
import Test.Framework.TH
import Test.Framework.Providers.QuickCheck2
import Control.Monad
import Data.Numbers.Primes (primes)
import Data.FiniteField.PrimeField (PrimeField)
import qualified Data.FiniteField.PrimeField as PrimeField
import Data.FiniteField.SomeNat (SomeNat (..))
import qualified Data.FiniteField.SomeNat as SomeNat
import TypeLevel.Number.Nat
-- ----------------------------------------------------------------------
-- addition
prop_add_comm =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
forAll arbitrary $ \b ->
a + b == b + a
prop_add_assoc =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
forAll arbitrary $ \b ->
forAll arbitrary $ \c ->
(a + b) + c == a + (b + c)
prop_add_unitl =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
0 + a == a
prop_add_unitr =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
a + 0 == a
prop_negate =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
a + negate a == 0
-- ----------------------------------------------------------------------
-- multiplication
prop_mult_comm =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
forAll arbitrary $ \b ->
a * b == b * a
prop_mult_assoc =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
forAll arbitrary $ \b ->
forAll arbitrary $ \c ->
(a * b) * c == a * (b * c)
prop_mult_unitl =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
1 * a == a
prop_mult_unitr =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
a * 1 == a
prop_mult_zero_l =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
0*a == 0
prop_mult_zero_r =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
a*0 == 0
-- ----------------------------------------------------------------------
-- distributivity
prop_distl =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
forAll arbitrary $ \b ->
forAll arbitrary $ \c ->
a * (b + c) == a*b + a*c
prop_distr =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
forAll arbitrary $ \b ->
forAll arbitrary $ \c ->
(b + c) * a == b*a + c*a
-- ----------------------------------------------------------------------
-- recip
prop_recip =
forAll smallPrimes $ \(SomeNat (_ :: p)) ->
forAll arbitrary $ \(a :: PrimeField p) ->
a /= 0 ==> a * (recip a) == 1
-- ----------------------------------------------------------------------
prop_intToSomeNat = do
forAll arbitrary $ \n ->
case SomeNat.fromInteger (abs n) of
SomeNat m -> abs n == toInt m
------------------------------------------------------------------------
smallPrimes :: Gen SomeNat
smallPrimes = do
i <- choose (0, 2^(16::Int))
return $ SomeNat.fromInteger $ primes !! i
instance Nat p => Arbitrary (PrimeField p) where
arbitrary = liftM fromInteger arbitrary
------------------------------------------------------------------------
-- Test harness
main :: IO ()
main = $(defaultMainGenerator)