-- | Generic properties of functions
module Test.QuickCheck.Property.Generic (
module Test.QuickCheck.Property.Common
-- * General
, prop_Reflexive
-- * Monoids & group
, prop_Associative
, prop_Commutative
, prop_LeftIdentity
, prop_RightIdentity
, prop_Identity
, prop_GroupInverse
-- ** General
, prop_GenMonoid
, prop_Group
) where
import Test.QuickCheck.Property.Common
import Test.QuickCheck.Property.Common.Internal
-- | Test that relation is reflective.
--
-- > f x x = True
prop_Reflexive :: (a -> a -> Bool) -> T a -> a -> Bool
prop_Reflexive f T x = f x x
----------------------------------------------------------------
-- Monoids & Co
----------------------------------------------------------------
-- | Test that function is commutative
prop_Commutative :: (a -> a -> b) -> T (a,b) -> a -> a -> Equal b
prop_Commutative f T x y = f x y .==. f y x
-- | Test that function is associative
prop_Associative :: (a -> a -> a) -> T a -> a -> a -> a -> Equal a
prop_Associative (<>) T a b c = ((a <> b) <> c) .==. (a <> (b <> c))
-- | Test that value is a left identity
prop_LeftIdentity :: a -- ^ Left identity
-> (a -> a -> a) -- ^ Associative operation
-> T a -> a -> Equal a
prop_LeftIdentity e (<>) T x = (e <> x) .==. x
-- | Test that value is a left identity
prop_RightIdentity :: a -- ^ Right identity
-> (a -> a -> a) -- ^ Associative operation
-> T a -> a -> Equal a
prop_RightIdentity e (<>) T x = (x <> e) .==. x
-- | Test that value is both right and left identity
prop_Identity :: a -- ^ Identity element
-> (a -> a -> a) -- ^ Associative operation
-> T a -> a -> Equal a
prop_Identity = prop_LeftIdentity .&&. prop_RightIdentity
-- | Test that inverse operation is correct.
prop_GroupInverse :: a -- ^ Identity element
-> (a -> a -> a) -- ^ Group operation
-> (a -> a) -- ^ Find inverse
-> T a -> a -> Equal a
prop_GroupInverse e (<>) inv T x = ((x <> inv x) .==. e)
.&&. ((inv x <> x) .==. e)
-- | Test that identity and associative operation satisfy monoid laws.
prop_GenMonoid :: a -- ^ Identity element
-> (a -> a -> a) -- ^ Associative operation
-> T a -> a -> a -> a -> Equal a
prop_GenMonoid e (<>) T x y z = prop_Associative (<>) T x y z
.&&. prop_Identity e (<>) T x
-- | Test that identity, associative operation and inverse satisfy group laws
prop_Group :: a -- ^ Identity element
-> (a -> a -> a) -- ^ Associative operation
-> (a -> a) -- ^ Find inverse element
-> T a -> a -> a -> a -> Equal a
prop_Group e (<>) inv T x y z = prop_Identity e (<>) T x
.&&. prop_Associative (<>) T x y z
.&&. prop_GroupInverse e (<>) inv T x