ideas-math-1.0: src/Domain/Math/Numeric/Tests.hs
-----------------------------------------------------------------------------
-- Copyright 2013, Open Universiteit Nederland. This file is distributed
-- under the terms of the GNU General Public License. For more information,
-- see the file "LICENSE.txt", which is included in the distribution.
-----------------------------------------------------------------------------
-- |
-- Maintainer : bastiaan.heeren@ou.nl
-- Stability : provisional
-- Portability : portable (depends on ghc)
--
-----------------------------------------------------------------------------
module Domain.Math.Numeric.Tests (main) where
import Control.Monad
import Data.Maybe
import Data.Monoid
import Domain.Math.Expr
import Domain.Math.Numeric.Generators
import Domain.Math.Numeric.Strategies
import Domain.Math.Numeric.Views
import Ideas.Common.Classes
import Ideas.Common.Context
import Ideas.Common.Utils.TestSuite
import Ideas.Common.View
import Test.QuickCheck
main :: TestSuite
main = suite "Numeric tests" $ do
suite "Correctness numeric views" $ do
let f s v = forM_ numGenerators $ \g -> do
addProperty ("idempotence " ++ s) $ propIdempotence g v
addProperty ("soundness " ++ s) $ propSoundness semEqDouble g v
f "integer view" integerView
f "rational view" rationalView
f "integer normal form" integerNF
f "rational normal form" rationalNF
f "rational relaxed form" rationalRelaxedForm
suite "Normal forms" $ do
let f s v = forM_ numGenerators $ \g ->
addProperty s $ propNormalForm g v
f "integer normal form" integerNF
-- f rationalNF -- no longer a normal form
suite "Correctness generators" $ do
let f s g v = addProperty s $ forAll (sized g) (`belongsTo` v)
f "integer" integerGenerator integerView
f "rational" rationalGenerator rationalView
f "ratio expr" ratioExprGen rationalNF
f "ratio expr nonzero" ratioExprGenNonZero rationalNF
suite "View relations" $ do
let va .>. vb = forM_ numGenerators $ \g ->
addProperty "" $ forAll g $ \a ->
not (a `belongsTo` va) || a `belongsTo` vb
integerNF .>. integerView
rationalNF .>. rationalRelaxedForm
rationalRelaxedForm .>. rationalView
integerNF .>. rationalNF
integerView .>. rationalView
suite "Pre/post conditions strategies" $ do
let f l s pre post = forM_ numGenerators $ \g ->
addProperty l $ forAll g $ \a ->
let run = fromMaybe a . fromContext . applyD s
. newContext mempty . termNavigator
in not (a `belongsTo` pre) || run a `belongsTo` post
f "natural" naturalStrategy integerView integerNF
f "integer" integerStrategy integerView integerNF
f "rational" rationalStrategy rationalView rationalNF
f "fraction" fractionStrategy rationalView rationalNF
numGenerators :: [Gen Expr]
numGenerators = map sized
[ integerGenerator, rationalGenerator
, ratioExprGen, ratioExprGenNonZero, numGenerator
]
semEqDouble :: Expr -> Expr -> Bool
semEqDouble a b =
case (match doubleView a, match doubleView b) of
(Just x, Just y) -> x ~= y
(Nothing, Nothing) -> True
_ -> False
where
delta = 0.0001
(~=) :: Double -> Double -> Bool
x ~= y = abs x < delta || abs y < delta || abs (1 - (x/y)) < delta