exp-pairs-0.2.1.0: tests/Instances.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Instances (Ratio01 (..), Positive (..), Sorted(..)) where
import Test.QuickCheck (Arbitrary(..), Gen, genericShrink, suchThat, vectorOf)
import Test.SmallCheck.Series
import Control.Applicative
import Control.Monad
import Data.List (sort)
import Data.Ratio
import GHC.Generics (Generic (..))
import Math.ExpPairs.LinearForm
import Math.ExpPairs.Process
import Math.ExpPairs.ProcessMatrix
import Math.ExpPairs.Pair (InitPair' (..))
import Math.ExpPairs.Matrix3 as M3 (Matrix3, fromList)
instance Arbitrary a => Arbitrary (LinearForm a) where
arbitrary = LinearForm <$> arbitrary <*> arbitrary <*> arbitrary
shrink = genericShrink
instance (Monad m, Serial m a) => Serial m (LinearForm a) where
series = cons3 LinearForm
instance Arbitrary a => Arbitrary (RationalForm a) where
arbitrary = (:/:) <$> arbitrary <*> arbitrary
shrink = genericShrink
instance (Monad m, Serial m a) => Serial m (RationalForm a) where
series = cons2 (:/:)
instance Arbitrary a => Arbitrary (Constraint a) where
arbitrary = Constraint <$> arbitrary <*> arbitrary
shrink = genericShrink
instance (Monad m, Serial m a) => Serial m (Constraint a) where
series = cons2 Constraint
instance Arbitrary IneqType where
arbitrary = f <$> arbitrary where
f x = if x then Strict else NonStrict
shrink = genericShrink
instance Monad m => Serial m IneqType where
series = cons0 Strict \/ cons0 NonStrict
instance Arbitrary Process where
arbitrary = f <$> arbitrary where
f x = if x then A else BA
shrink = genericShrink
instance Monad m => Serial m Process where
series = cons0 A \/ cons0 BA
-- | Does not have a 'Num' instance!
newtype Ratio01 t = Ratio01 t
deriving (Eq, Ord, Generic)
instance (Ord t, Integral t, Arbitrary t) => Arbitrary (Ratio01 (Ratio t)) where
arbitrary = do
denom <- arbitrary `suchThat` (> 0)
numer <- arbitrary
pure $ Ratio01 $ (numer `mod` (denom + 1)) % denom
shrink (Ratio01 y) = Ratio01 <$> filter (\x -> 0 <= x && x <= 1) (shrink y)
instance (Ord t, Integral t, Serial m t) => Serial m (Ratio01 (Ratio t)) where
series = Ratio01 <$> (series `suchThatSerial` (\x -> 0 <= x && x <= 1))
instance Show t => Show (Ratio01 t) where
showsPrec n (Ratio01 x) = showsPrec n x
instance (Ord t, Integral t, Arbitrary t) => Arbitrary (InitPair' (Ratio t)) where
arbitrary = f <$> liftM2 (,) arbitrary arbitrary where
f :: (Ord t, Fractional t) => (Ratio01 t, Ratio01 t) -> InitPair' t
f (Ratio01 x, Ratio01 y)
| 100*x<5 = Corput01
| 100*x<10 = Corput12
| otherwise = Mix x' y' where
x' = x*10/9
y' = y*(1-x)
shrink = genericShrink
instance (Ord t, Integral t, Serial m t) => Serial m (InitPair' (Ratio t)) where
series = cons0 Corput01 \/ cons0 Corput12 \/ mseries
where
mseries = do
(Ratio01 x) <- series
(Ratio01 y) <- series
return $ Mix x (y * (1-x))
instance (Num a, Ord a, Arbitrary a) => Arbitrary (Positive a) where
arbitrary = Positive <$> (arbitrary `suchThat` (> 0))
shrink (Positive x) = Positive <$> filter (> 0) (shrink x)
instance (Arbitrary a) => Arbitrary (M3.Matrix3 a) where
arbitrary = M3.fromList <$> vectorOf 9 arbitrary
shrink = genericShrink
suchThatSerial :: Series m a -> (a -> Bool) -> Series m a
suchThatSerial s p = s >>= \x -> if p x then pure x else empty
newtype Sorted t = Sorted t
deriving (Show, Generic)
instance (Ord t, Arbitrary t) => Arbitrary (Sorted (t, t)) where
arbitrary = Sorted <$> (arbitrary `suchThat` uncurry (<=))
instance (Ord t, Serial m t) => Serial m (Sorted (t, t)) where
series = Sorted <$> (series `suchThatSerial` uncurry (<=))
instance (Num t, Ord t, Arbitrary t) => Arbitrary (Sorted (t, t, t)) where
arbitrary = do
a <- arbitrary
ab <- arbitrary `suchThat` (>= 0)
bc <- arbitrary `suchThat` (>= 0)
let b = a + ab; c = b + bc
pure $ Sorted (a, b, c)
instance (Num t, Ord t, Serial m t) => Serial m (Sorted (t, t, t)) where
series = do
a <- series
ab <- series `suchThatSerial` (>= 0)
bc <- series `suchThatSerial` (>= 0)
let b = a + ab; c = b + bc
pure $ Sorted (a, b, c)
instance (Num t, Ord t, Arbitrary t) => Arbitrary (Sorted (t, t, t, t)) where
arbitrary = do
a <- arbitrary
ab <- arbitrary `suchThat` (>= 0)
bc <- arbitrary `suchThat` (>= 0)
cd <- arbitrary `suchThat` (>= 0)
let b = a + ab; c = b + bc; d = c + cd
pure $ Sorted (a, b, c, d)
shrink (Sorted (aa, bb, cc, dd))
= map ((\[a, b, c, d] -> Sorted (a, b, c, d)) . sort)
$ filter ((== 4) . length)
$ shrink [aa, bb, cc, dd]
instance (Num t, Ord t, Serial m t) => Serial m (Sorted (t, t, t, t)) where
series = do
a <- series
ab <- series `suchThatSerial` (>= 0)
bc <- series `suchThatSerial` (>= 0)
cd <- series `suchThatSerial` (>= 0)
let b = a + ab; c = b + bc; d = c + cd
pure $ Sorted (a, b, c, d)
instance (Num t, Ord t, Arbitrary t) => Arbitrary (Sorted (t, t, t, t, t, t)) where
arbitrary = do
a <- arbitrary
ab <- arbitrary `suchThat` (>= 0)
bc <- arbitrary `suchThat` (>= 0)
cd <- arbitrary `suchThat` (>= 0)
de <- arbitrary `suchThat` (>= 0)
ef <- arbitrary `suchThat` (>= 0)
let b = a + ab; c = b + bc; d = c + cd; e = d + de; f = e + ef
pure $ Sorted (a, b, c, d, e, f)
instance (Num t, Ord t, Serial m t) => Serial m (Sorted (t, t, t, t, t, t)) where
series = do
a <- series
ab <- series `suchThatSerial` (>= 0)
bc <- series `suchThatSerial` (>= 0)
cd <- series `suchThatSerial` (>= 0)
de <- series `suchThatSerial` (>= 0)
ef <- series `suchThatSerial` (>= 0)
let b = a + ab; c = b + bc; d = c + cd; e = d + de; f = e + ef
pure $ Sorted (a, b, c, d, e, f)
instance (Num t, Ord t, Arbitrary t) => Arbitrary (Sorted (t, t, t, t, t, t, t, t)) where
arbitrary = do
a <- arbitrary
ab <- arbitrary `suchThat` (>= 0)
bc <- arbitrary `suchThat` (>= 0)
cd <- arbitrary `suchThat` (>= 0)
de <- arbitrary `suchThat` (>= 0)
ef <- arbitrary `suchThat` (>= 0)
fg <- arbitrary `suchThat` (>= 0)
gh <- arbitrary `suchThat` (>= 0)
let b = a + ab; c = b + bc; d = c + cd; e = d + de; f = e + ef; g = f + fg; h = g + gh
pure $ Sorted (a, b, c, d, e, f, g, h)
shrink (Sorted (aa, bb, cc, dd, ee, ff, gg, hh))
= map ((\[a, b, c, d, e, f, g, h] -> Sorted (a, b, c, d, e, f, g, h)) . sort)
$ filter ((== 8) . length)
$ shrink [aa, bb, cc, dd, ee, ff, gg, hh]
instance Arbitrary Path where
arbitrary = foldMap (\x -> if x then aPath else baPath) <$> (arbitrary :: Gen [Bool])
instance Monad m => Serial m Path where
series = foldMap (\x -> if x then aPath else baPath) <$> (series :: Monad m => Series m [Bool])