{-# LANGUAGE CPP, TemplateHaskell, ScopedTypeVariables #-} module TestIntegerInterval (integerIntervalTestGroup) where #ifdef MIN_VERSION_lattices import qualified Algebra.Lattice as L #endif import Control.DeepSeq import Control.Monad import Data.Generics.Schemes import Data.Hashable import Data.Maybe import Data.Ratio import Data.Typeable import Test.Tasty import Test.Tasty.QuickCheck import Test.Tasty.HUnit import Test.Tasty.TH import Data.IntegerInterval ( IntegerInterval, Extended (..), (<=..<=), (<=..<), (<..<=), (<..<) , (=!), (>!), (/=!) , (=?), (>?), (/=?) , (=??), (>??), (/=??) ) import qualified Data.IntegerInterval as IntegerInterval import Data.Interval (Interval) import qualified Data.Interval as Interval import Data.IntervalRelation {-------------------------------------------------------------------- empty --------------------------------------------------------------------} prop_empty_is_bottom = forAll integerIntervals $ \a -> IntegerInterval.isSubsetOf IntegerInterval.empty a prop_null_empty = forAll integerIntervals $ \a -> IntegerInterval.null a == (a == IntegerInterval.empty) case_null_empty = IntegerInterval.null (IntegerInterval.empty :: IntegerInterval) @?= True {-------------------------------------------------------------------- whole --------------------------------------------------------------------} prop_whole_is_top = forAll integerIntervals $ \a -> IntegerInterval.isSubsetOf a IntegerInterval.whole case_nonnull_top = IntegerInterval.null (IntegerInterval.whole :: IntegerInterval) @?= False {-------------------------------------------------------------------- singleton --------------------------------------------------------------------} -- prop_singleton_isSingleton = -- forAll arbitrary $ \x -> -- IntegerInterval.isSingleton (IntegerInterval.singleton x) prop_singleton_member = forAll arbitrary $ \r -> IntegerInterval.member (r::Integer) (IntegerInterval.singleton r) prop_singleton_member_intersection = forAll integerIntervals $ \a -> forAll arbitrary $ \r -> let b = IntegerInterval.singleton r in IntegerInterval.member (r::Integer) a ==> IntegerInterval.intersection a b == b prop_singleton_nonnull = forAll arbitrary $ \r1 -> not $ IntegerInterval.null $ IntegerInterval.singleton (r1::Integer) prop_distinct_singleton_intersection = forAll arbitrary $ \r1 -> forAll arbitrary $ \r2 -> (r1::Integer) /= r2 ==> IntegerInterval.intersection (IntegerInterval.singleton r1) (IntegerInterval.singleton r2) == IntegerInterval.empty {-------------------------------------------------------------------- Intersection --------------------------------------------------------------------} prop_intersection_comm = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> IntegerInterval.intersection a b == IntegerInterval.intersection b a prop_intersection_assoc = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> forAll integerIntervals $ \c -> IntegerInterval.intersection a (IntegerInterval.intersection b c) == IntegerInterval.intersection (IntegerInterval.intersection a b) c prop_intersection_unitL = forAll integerIntervals $ \a -> IntegerInterval.intersection IntegerInterval.whole a == a prop_intersection_unitR = forAll integerIntervals $ \a -> IntegerInterval.intersection a IntegerInterval.whole == a prop_intersection_empty = forAll integerIntervals $ \a -> IntegerInterval.intersection a IntegerInterval.empty == IntegerInterval.empty prop_intersection_isSubsetOf = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> IntegerInterval.isSubsetOf (IntegerInterval.intersection a b) a prop_intersection_isSubsetOf_equiv = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> (IntegerInterval.intersection a b == a) == IntegerInterval.isSubsetOf a b case_intersections_empty_list = IntegerInterval.intersections [] @?= (IntegerInterval.whole :: IntegerInterval) prop_intersections_singleton_list = forAll integerIntervals $ \a -> IntegerInterval.intersections [a] == a prop_intersections_two_elems = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> IntegerInterval.intersections [a,b] == IntegerInterval.intersection a b {-------------------------------------------------------------------- Hull --------------------------------------------------------------------} prop_hull_comm = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> IntegerInterval.hull a b == IntegerInterval.hull b a prop_hull_assoc = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> forAll integerIntervals $ \c -> IntegerInterval.hull a (IntegerInterval.hull b c) == IntegerInterval.hull (IntegerInterval.hull a b) c prop_hull_unitL = forAll integerIntervals $ \a -> IntegerInterval.hull IntegerInterval.empty a == a prop_hull_unitR = forAll integerIntervals $ \a -> IntegerInterval.hull a IntegerInterval.empty == a prop_hull_whole = forAll integerIntervals $ \a -> IntegerInterval.hull a IntegerInterval.whole == IntegerInterval.whole prop_hull_isSubsetOf = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> IntegerInterval.isSubsetOf a (IntegerInterval.hull a b) prop_hull_isSubsetOf_equiv = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> (IntegerInterval.hull a b == b) == IntegerInterval.isSubsetOf a b case_hulls_empty_list = IntegerInterval.hulls [] @?= (IntegerInterval.empty :: IntegerInterval) prop_hulls_singleton_list = forAll integerIntervals $ \a -> IntegerInterval.hulls [a] == a prop_hulls_two_elems = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> IntegerInterval.hulls [a,b] == IntegerInterval.hull a b {-------------------------------------------------------------------- member --------------------------------------------------------------------} prop_member_isSubsetOf = forAll arbitrary $ \r -> forAll integerIntervals $ \a -> IntegerInterval.member r a == IntegerInterval.isSubsetOf (IntegerInterval.singleton r) a prop_notMember_empty = forAll arbitrary $ \r -> r `IntegerInterval.notMember` IntegerInterval.empty {-------------------------------------------------------------------- isSubsetOf, isProperSubsetOf --------------------------------------------------------------------} prop_isSubsetOf_refl = forAll integerIntervals $ \a -> IntegerInterval.isSubsetOf a a prop_isSubsetOf_trans = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> forAll integerIntervals $ \c -> IntegerInterval.isSubsetOf a b && IntegerInterval.isSubsetOf b c ==> IntegerInterval.isSubsetOf a c -- prop_isSubsetOf_antisym = -- forAll integerIntervals $ \a -> -- forAll integerIntervals $ \b -> -- IntegerInterval.isSubsetOf a b && IntegerInterval.isSubsetOf b a -- ==> a == b prop_isProperSubsetOf_not_refl = forAll integerIntervals $ \a -> not (a `IntegerInterval.isProperSubsetOf` a) -- too slow -- prop_isProperSubsetOf_trans = -- forAll integerIntervals $ \a -> -- forAll (liftM (IntegerInterval.intersection a) integerIntervals) $ \b -> -- forAll (liftM (IntegerInterval.intersection b) integerIntervals) $ \c -> -- IntegerInterval.isProperSubsetOf c b && IntegerInterval.isProperSubsetOf b a -- ==> IntegerInterval.isProperSubsetOf c a case_isProperSubsetOf = (0 <=..<= 1) `IntegerInterval.isProperSubsetOf` (0 <=..<= 2) @?= True {-- ----------------------------------------------------------------- isConnected ----------------------------------------------------------------- --} prop_isConnected_reflexive = forAll integerIntervals $ \a -> a `IntegerInterval.isConnected` a prop_isConnected_symmetric = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> (a `IntegerInterval.isConnected` b) == (b `IntegerInterval.isConnected` a) {-------------------------------------------------------------------- simplestIntegerWithin --------------------------------------------------------------------} prop_simplestIntegerWithin_member = forAll integerIntervals $ \a -> case IntegerInterval.simplestIntegerWithin a of Nothing -> True Just x -> x `IntegerInterval.member` a prop_simplestIntegerWithin_singleton = forAll arbitrary $ \x -> IntegerInterval.simplestIntegerWithin (IntegerInterval.singleton x) == Just x case_simplestIntegerWithin_empty = IntegerInterval.simplestIntegerWithin IntegerInterval.empty @?= Nothing {-------------------------------------------------------------------- width --------------------------------------------------------------------} case_width_null = IntegerInterval.width IntegerInterval.empty @?= 0 prop_width_singleton = forAll arbitrary $ \x -> IntegerInterval.width (IntegerInterval.singleton x) == 0 {-------------------------------------------------------------------- map --------------------------------------------------------------------} case_mapMonotonic = IntegerInterval.mapMonotonic (+1) (0 <=..< 10) @?= ((1 <=..<11) :: IntegerInterval) {-------------------------------------------------------------------- pickup --------------------------------------------------------------------} prop_pickup_member_null = forAll integerIntervals $ \a -> case IntegerInterval.pickup a of Nothing -> IntegerInterval.null a Just x -> IntegerInterval.member x a case_pickup_empty = IntegerInterval.pickup (IntegerInterval.empty :: IntegerInterval) @?= Nothing case_pickup_whole = isJust (IntegerInterval.pickup (IntegerInterval.whole :: IntegerInterval)) @?= True prop_pickup_singleton = forAll arbitrary $ \x -> IntegerInterval.pickup (IntegerInterval.singleton x) == Just x {-------------------------------------------------------------------- relate --------------------------------------------------------------------} prop_relate_equals = forAll integerIntervals $ \a -> IntegerInterval.relate a a == Equal prop_relate_empty_contained_in_non_empty = forAll (integerIntervals `suchThat` (not . IntegerInterval.null)) $ \a -> IntegerInterval.relate a IntegerInterval.empty == Contains prop_relate_detects_before = forAll (nonEmptyIntegerIntervalPairs (\_ ub1 lb2 _ -> ub1 < lb2 - 1)) $ \(a, b) -> IntegerInterval.relate a b == Before prop_relate_detects_just_before = forAll (arbitrary `suchThat` \(b1, b2, i) -> b1 <= Finite i && Finite (i + 1) <= b2) $ \(b1, b2, i) -> IntegerInterval.relate (b1 <=..<= Finite i) (Finite (i + 1) <=..<= b2) == JustBefore prop_relate_two_intervals_overlap = forAll (nonEmptyIntegerIntervalPairs (\lb1 ub1 lb2 ub2 -> lb1 < lb2 && lb2 < ub1 && ub1 < ub2)) $ \(a, b) -> IntegerInterval.relate a b == Overlaps prop_relate_interval_starts_another = forAll (nonEmptyIntegerIntervalPairs (\lb1 ub1 lb2 ub2 -> lb1 == lb2 && ub1 < ub2)) $ \(a, b) -> IntegerInterval.relate a b == Starts prop_relate_interval_finishes_another = forAll (nonEmptyIntegerIntervalPairs (\lb1 ub1 lb2 ub2 -> lb1 > lb2 && ub1 == ub2)) $ \(a, b) -> IntegerInterval.relate a b == Finishes prop_relate_interval_contains_another = forAll (nonEmptyIntegerIntervalPairs (\lb1 ub1 lb2 ub2 -> lb1 < lb2 && ub1 > ub2)) $ \(a, b) -> IntegerInterval.relate a b == Contains {-------------------------------------------------------------------- Comparison --------------------------------------------------------------------} case_lt_all_1 = (a not (IntegerInterval.null a) ==> not (a not (IntegerInterval.null a) ==> a <=? a prop_ne_all_not_refl = forAll integerIntervals $ \a -> not (IntegerInterval.null a) ==> not (a /=! a) prop_lt_all_singleton = forAll arbitrary $ \a -> forAll arbitrary $ \b -> (a::Integer) < b ==> IntegerInterval.singleton a not $ IntegerInterval.singleton (a::Integer) forAll arbitrary $ \b -> (a::Integer) <= b ==> IntegerInterval.singleton a <=! IntegerInterval.singleton b prop_le_all_singleton_2 = forAll arbitrary $ \a -> IntegerInterval.singleton (a::Integer) <=! IntegerInterval.singleton a prop_eq_all_singleton = forAll arbitrary $ \a -> IntegerInterval.singleton (a::Integer) ==! IntegerInterval.singleton a prop_ne_all_singleton = forAll arbitrary $ \a -> forAll arbitrary $ \b -> (a::Integer) /= b ==> IntegerInterval.singleton a /=! IntegerInterval.singleton b prop_ne_all_singleton_2 = forAll arbitrary $ \a -> not $ IntegerInterval.singleton (a::Integer) /=! IntegerInterval.singleton a prop_lt_some_singleton = forAll arbitrary $ \a -> forAll arbitrary $ \b -> (a::Integer) < b ==> IntegerInterval.singleton a not $ IntegerInterval.singleton (a::Integer) forAll arbitrary $ \b -> (a::Integer) <= b ==> IntegerInterval.singleton a <=? IntegerInterval.singleton b prop_le_some_singleton_2 = forAll arbitrary $ \a -> IntegerInterval.singleton (a::Integer) <=? IntegerInterval.singleton a prop_eq_some_singleton = forAll arbitrary $ \a -> IntegerInterval.singleton (a::Integer) ==? IntegerInterval.singleton a prop_lt_all_empty = forAll integerIntervals $ \a -> a IntegerInterval.empty a <=! IntegerInterval.empty prop_le_all_empty_2 = forAll integerIntervals $ \a -> IntegerInterval.empty <=! a prop_eq_all_empty = forAll integerIntervals $ \a -> a ==! IntegerInterval.empty prop_ne_all_empty = forAll integerIntervals $ \a -> a /=! IntegerInterval.empty prop_lt_some_empty = forAll integerIntervals $ \a -> not (a not (IntegerInterval.empty not (a <=? IntegerInterval.empty) prop_le_some_empty_2 = forAll integerIntervals $ \a -> not (IntegerInterval.empty <=? a) prop_eq_some_empty = forAll integerIntervals $ \a -> not (a ==? IntegerInterval.empty) prop_intersect_le_some = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> not (IntegerInterval.null (IntegerInterval.intersection a b)) ==> a <=? b prop_intersect_eq_some = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> not (IntegerInterval.null (IntegerInterval.intersection a b)) ==> a ==? b prop_le_some_witness = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> case a <=?? b of Nothing -> forAll arbitrary $ \(x,y) -> not (IntegerInterval.member x a && IntegerInterval.member y b && x <= y) Just (x,y) -> IntegerInterval.member x a .&&. IntegerInterval.member y b .&&. x <= y prop_lt_some_witness = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> case a forAll arbitrary $ \(x,y) -> not (IntegerInterval.member x a && IntegerInterval.member y b && x < y) Just (x,y) -> IntegerInterval.member x a .&&. IntegerInterval.member y b .&&. x < y prop_eq_some_witness = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> case a ==?? b of Nothing -> forAll arbitrary $ \x -> not (IntegerInterval.member x a && IntegerInterval.member x b) Just (x,y) -> IntegerInterval.member x a .&&. IntegerInterval.member y b .&&. x == y prop_ne_some_witness = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> case a /=?? b of Nothing -> forAll arbitrary $ \x -> forAll arbitrary $ \y -> not (IntegerInterval.member x a && IntegerInterval.member y b && x /= y) Just (x,y) -> IntegerInterval.member x a .&&. IntegerInterval.member y b .&&. x /= y case_ne_some_witness_test1 = do let i1 = 0 i2 = 0 <=..<= 1 case i1 /=?? i2 of Nothing -> assertFailure "should not be Nothing" Just (a,b) -> do unless (a `IntegerInterval.member` i1) $ assertFailure (show a ++ "is not a member of " ++ show i1) unless (b `IntegerInterval.member` i2) $ assertFailure (show b ++ "is not a member of " ++ show i2) unless (a /= b) $ assertFailure (show a ++ " /= " ++ show b ++ " failed") case_ne_some_witness_test2 = do let i1 = 0 <=..<= 1 i2 = 1 case i1 /=?? i2 of Nothing -> assertFailure "should not be Nothing" Just (a,b) -> do unless (a `IntegerInterval.member` i1) $ assertFailure (show a ++ "is not a member of " ++ show i1) unless (b `IntegerInterval.member` i2) $ assertFailure (show b ++ "is not a member of " ++ show i2) unless (a /= b) $ assertFailure (show a ++ " /= " ++ show b ++ " failed") prop_le_some_witness_forget = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> isJust (a <=?? b) == (a <=? b) prop_lt_some_witness_forget = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> isJust (a forAll integerIntervals $ \b -> isJust (a ==?? b) == (a ==? b) prop_ne_some_witness_forget = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> isJust (a /=?? b) == (a /=? b) {-------------------------------------------------------------------- Num --------------------------------------------------------------------} prop_scale_empty = forAll arbitrary $ \r -> IntegerInterval.singleton (r::Integer) * IntegerInterval.empty == IntegerInterval.empty prop_add_comm = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> a + b == b + a prop_add_assoc = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> forAll integerIntervals $ \c -> a + (b + c) == (a + b) + c prop_add_unitL = forAll integerIntervals $ \a -> IntegerInterval.singleton 0 + a == a prop_add_unitR = forAll integerIntervals $ \a -> a + IntegerInterval.singleton 0 == a prop_add_member = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> and [ (x+y) `IntegerInterval.member` (a+b) | x <- maybeToList $ IntegerInterval.pickup a , y <- maybeToList $ IntegerInterval.pickup b ] prop_mult_comm = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> a * b == b * a prop_mult_assoc = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> forAll integerIntervals $ \c -> a * (b * c) == (a * b) * c prop_mult_unitL = forAll integerIntervals $ \a -> IntegerInterval.singleton 1 * a == a prop_mult_unitR = forAll integerIntervals $ \a -> a * IntegerInterval.singleton 1 == a prop_mult_dist = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> forAll integerIntervals $ \c -> (a * (b + c)) `IntegerInterval.isSubsetOf` (a * b + a * c) prop_mult_empty = forAll integerIntervals $ \a -> IntegerInterval.empty * a == IntegerInterval.empty prop_mult_zero = forAll integerIntervals $ \a -> not (IntegerInterval.null a) ==> IntegerInterval.singleton 0 * a == IntegerInterval.singleton 0 prop_mult_member = forAll integerIntervals $ \a -> forAll integerIntervals $ \b -> and [ (x*y) `IntegerInterval.member` (a*b) | x <- maybeToList $ IntegerInterval.pickup a , y <- maybeToList $ IntegerInterval.pickup b ] case_mult_test1 = ival1 * ival2 @?= ival3 where ival1 :: IntegerInterval ival1 = 1 <=..<= 2 ival2 = 1 <=..<= 2 ival3 = 1 <=..<= 4 case_mult_test2 = ival1 * ival2 @?= ival3 where ival1 :: IntegerInterval ival1 = 1 <=..<= 2 ival2 = 1 <..< 2 ival3 = IntegerInterval.empty -- * case_mult_test3 = ival1 * ival2 @?= ival3 where ival1 :: IntegerInterval ival1 = 1 <..< 2 ival2 = 1 <..< 2 ival3 = IntegerInterval.empty -- * case_mult_test4 = ival1 * ival2 @?= ival3 where ival1 :: IntegerInterval ival1 = 2 <..< PosInf ival2 = 3 <..< PosInf ival3 = 11 <..< PosInf -- * case_mult_test5 = ival1 * ival2 @?= ival3 where ival1 :: IntegerInterval ival1 = NegInf <..< (-3) ival2 = NegInf <..< (-2) ival3 = 11 <..< PosInf -- * case_mult_test6 = ival1 * ival2 @?= ival3 where ival1 :: IntegerInterval ival1 = 2 <..< PosInf ival2 = NegInf <..< (-2) ival3 = NegInf <..< (-8) -- * prop_abs_signum = forAll integerIntervals $ \a -> abs (signum a) `IntegerInterval.isSubsetOf` (0 <=..<= 1) prop_negate_negate = forAll integerIntervals $ \a -> negate (negate a) == a {-------------------------------------------------------------------- Lattice --------------------------------------------------------------------} #ifdef MIN_VERSION_lattices prop_Lattice_Leq_welldefined = forAll integerIntervals $ \a b -> a `L.meetLeq` b == a `L.joinLeq` b prop_top = forAll integerIntervals $ \a -> a `L.joinLeq` L.top prop_bottom = forAll integerIntervals $ \a -> L.bottom `L.joinLeq` a #else prop_Lattice_Leq_welldefined = True prop_top = True prop_bottom = True #endif {-------------------------------------------------------------------- Read --------------------------------------------------------------------} prop_show_read_invariance = forAll integerIntervals $ \i -> do i == read (show i) case_read_old = read "interval (Finite 0, Closed) (PosInf, Open)" @?= IntegerInterval.interval (Finite 0, Interval.Closed) (PosInf, Interval.Open) {-------------------------------------------------------------------- NFData --------------------------------------------------------------------} prop_rnf = forAll integerIntervals $ \a -> rnf a == () {-------------------------------------------------------------------- Hashable --------------------------------------------------------------------} prop_hash = forAll integerIntervals $ \i -> hash i `seq` True {- ------------------------------------------------------------------ Data ------------------------------------------------------------------ -} case_Data = everywhere f i @?= (1 <=..<= 2 :: IntegerInterval) where i :: IntegerInterval i = 0 <=..<= 1 f x | Just (y :: Integer) <- cast x = fromJust $ cast (y + 1) | otherwise = x {-------------------------------------------------------------------- Conversion between Interval and IntegerInterval --------------------------------------------------------------------} prop_fromInterval_toInterval = forAll integerIntervals $ \i -> IntegerInterval.fromInterval (IntegerInterval.toInterval i) == i prop_fromIntervalOver_toInterval = forAll integerIntervals $ \i -> IntegerInterval.fromIntervalOver (IntegerInterval.toInterval i :: Interval Rational) == i prop_fromIntervalUnder_toInterval = forAll integerIntervals $ \i -> IntegerInterval.fromIntervalUnder (IntegerInterval.toInterval i :: Interval Rational) == i prop_fromIntervalOver_toInterval_adjoint = forAll intervals $ \a -> forAll integerIntervals $ \b -> IntegerInterval.fromIntervalOver a `IntegerInterval.isSubsetOf` b == a `Interval.isSubsetOf` IntegerInterval.toInterval b prop_toInterval_fromIntervalUnder_adjoint = forAll integerIntervals $ \a -> forAll intervals $ \b -> IntegerInterval.toInterval a `Interval.isSubsetOf` b == a `IntegerInterval.isSubsetOf` IntegerInterval.fromIntervalUnder b prop_toInterval_fromInterval = forAll arbitrary $ \(i :: Interval Integer) -> IntegerInterval.toInterval (IntegerInterval.fromInterval i) `Interval.isSubsetOf` i case_fromIntervalUnder_test1 = IntegerInterval.fromIntervalUnder ((0.5::Extended Rational) Interval.<=..<= 1.5) @?= IntegerInterval.singleton 1 case_fromIntervalUnder_test2 = IntegerInterval.fromIntervalUnder ((0::Extended Rational) Interval.<..< 2) @?= IntegerInterval.singleton 1 {-------------------------------------------------------------------- Generators --------------------------------------------------------------------} instance Arbitrary Interval.Boundary where arbitrary = arbitraryBoundedEnum instance Arbitrary r => Arbitrary (Extended r) where arbitrary = oneof [ return NegInf , return PosInf , liftM Finite arbitrary ] instance (Arbitrary r, Ord r) => Arbitrary (Interval.Interval r) where arbitrary = do lb <- arbitrary ub <- arbitrary return $ Interval.interval lb ub instance Arbitrary IntegerInterval where arbitrary = do lb <- arbitrary ub <- arbitrary return $ IntegerInterval.interval lb ub integerIntervals :: Gen IntegerInterval integerIntervals = arbitrary nonEmptyIntegerIntervalPairs :: ( Extended Integer -> Extended Integer -> Extended Integer -> Extended Integer -> Bool) -> Gen (IntegerInterval, IntegerInterval) nonEmptyIntegerIntervalPairs boundariesComparer = ap (fmap (,) integerIntervals) integerIntervals `suchThat` (\(i1, i2) -> (not . IntegerInterval.null $ i1) && (not . IntegerInterval.null $ i2) && boundariesComparer (IntegerInterval.lowerBound i1) (IntegerInterval.upperBound i1) (IntegerInterval.lowerBound i2) (IntegerInterval.upperBound i2) ) intervals :: Gen (Interval.Interval Rational) intervals = arbitrary pos :: IntegerInterval pos = 0 <..< PosInf neg :: IntegerInterval neg = NegInf <..< 0 nonpos :: IntegerInterval nonpos = NegInf <..<= 0 nonneg :: IntegerInterval nonneg = 0 <=..< PosInf ------------------------------------------------------------------------ -- Test harness integerIntervalTestGroup = $(testGroupGenerator)