math-programming-0.3.0: test/Math/Programming/TestLinearExpression.hs
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE FlexibleInstances #-}
module Math.Programming.TestLinearExpression where
import Control.Monad
import Data.Ratio
import Test.Tasty
import Test.Tasty.QuickCheck
import Math.Programming
test_tree :: TestTree
test_tree = testGroup "LinearExpression tests"
[ testProperty "Additive commutativity" commutativityProp
, testProperty "Additive associativity" additiveAssociativityProp
, testProperty "Coefficient commutativity" coefficientCommutativityProp
, testProperty "Simplification" simplifyProp
]
type ExactExpr = LinearExpression (Ratio Integer) (Ratio Integer)
instance Arbitrary ExactExpr where
arbitrary = LinearExpression <$> arbitrary <*> arbitrary
-- | A pair of linear expressions, differing only by the ordering of
-- the summands.
newtype ShuffledAndUnshuffled
= ShuffledAndUnshuffled (ExactExpr, ExactExpr)
deriving
( Show
)
instance Arbitrary ShuffledAndUnshuffled where
arbitrary = do
unshuffled@(LinearExpression terms constant) <- arbitrary
shuffledTerms <- shuffle terms
let shuffled = LinearExpression shuffledTerms constant
return $ ShuffledAndUnshuffled (unshuffled, shuffled)
-- | Addition should be commutative.
commutativityProp :: ShuffledAndUnshuffled -> Bool
commutativityProp (ShuffledAndUnshuffled (shuffled, unshuffled))
= eval shuffled == eval unshuffled
-- | A pair of linear expressions, differing only by the ordering of
-- the coefficients of the summands.
newtype ShuffledCoefficients
= ShuffledCoefficients (ExactExpr, ExactExpr)
deriving
( Show
)
instance Arbitrary ShuffledCoefficients where
arbitrary = do
unshuffled@(LinearExpression terms constant) <- arbitrary
terms' <- forM terms $ \(x, y) -> do
flipped <- arbitrary
return $ if flipped
then (y, x)
else (x, y)
let shuffled = LinearExpression terms' constant
return $ ShuffledCoefficients (shuffled, unshuffled)
coefficientCommutativityProp :: ShuffledCoefficients -> Bool
coefficientCommutativityProp (ShuffledCoefficients (shuffled, unshuffled))
= eval shuffled == eval unshuffled
additiveAssociativityProp :: ExactExpr -> ExactExpr -> ExactExpr -> Bool
additiveAssociativityProp x y z
= eval ((x .+. y) .+. z) == eval (x .+. (y .+. z))
simplifyProp :: ExactExpr -> Bool
simplifyProp x = eval x == eval (simplify x)