intset-0.1.0.0: tests/Main.hs
{-# OPTIONS -fno-warn-orphans #-}
module Main (main) where
import Control.Applicative hiding (empty)
import Test.QuickCheck hiding ((.&.))
import Test.Framework
import Test.Framework.Providers.QuickCheck2
import Data.List as L (sort, nub, map, filter, minimum, intersect)
import Data.IntervalSet as S
import Data.IntervalSet.ByteString as S
import Data.Monoid
instance Arbitrary IntSet where
arbitrary = oneof [fromList <$> arbitrary, buddy <$> arbitrary]
where
buddy :: [Int] -> IntSet
buddy = fromList . concatMap mk
where
mk i = [i * 64 .. i * 64 + 64]
shrink (Bin _ _ l r) = [l, r]
shrink (Fin p m) = [splitFin p m]
shrink _ = []
prop_empty :: [Int] -> Bool
prop_empty xs = (not . (`member` empty)) `all` xs
prop_singleton :: Int -> [Int] -> Bool
prop_singleton e = all check
where
check x | x == e = member x (singleton e)
| otherwise = notMember x (singleton e)
prop_insertLookup :: IntSet -> Int -> Bool
prop_insertLookup s i = member i (insert i s )
prop_unionLookup :: [Int] -> [Int] -> Bool
prop_unionLookup a b = all (`member` u) a && all (`member` u) b
where
u = fromList a `union` fromList b
prop_sorted :: IntSet -> Bool
prop_sorted xs = toList xs == L.nub (L.sort (toList xs))
prop_valid :: IntSet -> Bool
prop_valid = isValid
prop_unionSize :: IntSet -> IntSet -> Bool
prop_unionSize a b = size u >= size a
&& size u >= size b
&& size u <= size a + size b
where
u = a `union` b
prop_unionComm :: IntSet -> IntSet -> Bool
prop_unionComm a b = a <> b == b <> a
prop_unionAssoc :: IntSet -> IntSet -> IntSet -> Bool
prop_unionAssoc a b c = a <> (b <> c) == (a <> b) <> c
prop_unionLeftId :: IntSet -> Bool
prop_unionLeftId a = mempty <> a == a
prop_unionRightId :: IntSet -> Bool
prop_unionRightId a = mempty <> a == a
prop_unionTop :: IntSet -> Bool
prop_unionTop a = a <> a == a
prop_unionIdemp :: IntSet -> IntSet -> Bool
prop_unionIdemp a b = ((a <> b) <> b) == a <> b
prop_intersectionSize :: IntSet -> IntSet -> Bool
prop_intersectionSize a b = size i <= size a && size i <= size b
where
i = intersection a b
prop_intersection :: [Int] -> [Int] -> Bool
prop_intersection a b =
fromList a `intersection` fromList b
== fromList (a `L.intersect` b)
prop_intersectComm :: IntSet -> IntSet -> Bool
prop_intersectComm a b = (a `intersection` b) == (b `intersection` a)
prop_intersectAssoc :: IntSet -> IntSet -> IntSet -> Bool
prop_intersectAssoc a b c =
((a `intersection` b) `intersection` c)
== (a `intersection` (b `intersection` c))
prop_intersectLeft :: IntSet -> Bool
prop_intersectLeft a = intersection empty a == empty
prop_intersectRight :: IntSet -> Bool
prop_intersectRight a = intersection a empty == empty
prop_intersectBot :: IntSet -> Bool
prop_intersectBot a = (a `intersection` a) == a
prop_intersectIdemp :: IntSet -> IntSet -> Bool
prop_intersectIdemp a b = ((a `intersection` b) `intersection` b)
== intersection a b
prop_showRead :: IntSet -> Bool
prop_showRead a = read (show a) == a
prop_eq :: [Int] -> [Int] -> Bool
prop_eq a b
| a' == b' = fromList a' == fromList b'
| a' /= b' = fromList a' /= fromList b'
| otherwise = error "prop_eq: impossible"
where
a' = nub (sort a)
b' = nub (sort b)
prop_eqRefl :: IntSet -> Bool
prop_eqRefl a = a == a
prop_eqSym :: IntSet -> IntSet -> Bool
prop_eqSym a b = (a == b) == (b == a)
prop_eqTrans :: IntSet -> IntSet -> IntSet -> Bool
prop_eqTrans a b c
| (a == b) && (b == c) = a == c
| otherwise = True
prop_size :: [Int] -> Bool
prop_size xs = length (nub (sort xs)) == size (fromList xs)
prop_insertDelete :: Int -> IntSet -> Bool
prop_insertDelete i = notMember i . delete i . insert i
prop_mapPresSize :: IntSet -> Bool
prop_mapPresSize s = size (S.map (*2) s) == size s
prop_mapLessSize :: IntSet -> Bool
prop_mapLessSize s = size (S.map (`div` 2) s) <= size s
prop_mapping :: [Int] -> Bool
prop_mapping xs = toList (S.map (*2) (fromList xs)) == L.map (*2) (nub (sort xs))
prop_filterSize :: IntSet -> Bool
prop_filterSize s = size (S.filter even s) <= size s
prop_filtering :: [Int] -> Bool
prop_filtering xs = S.filter even (fromList xs) == fromList (L.filter even xs)
prop_min :: [Int] -> Bool
prop_min [] = True
prop_min xs = findMin (fromList xs) == L.minimum xs
{-
prop_universeMember :: [Int] -> Bool
prop_universeMember = all (`member` universe)
prop_universeDelete :: Int -> Bool
prop_universeDelete i = notMember i (delete i universe)
prop_universeInsert :: Int -> Bool
prop_universeInsert i = insert i universe == universe
prop_universeNatNeg :: Bool
prop_universeNatNeg = naturals <> negatives == universe
prop_naturals :: [Int] -> Bool
prop_naturals = all check
where
check x | x >= 0 = member x naturals
| otherwise = True
prop_negatives :: [Int] -> Bool
prop_negatives = all check
where
check x | x < 0 = member x negatives
| otherwise = True
-}
prop_minInSet :: IntSet -> Bool
prop_minInSet s
| S.null s = True
| otherwise = member (findMin s) s
prop_minIsTheLess :: IntSet -> Bool
prop_minIsTheLess s
| S.null s = True
| otherwise = all (findMin s <=) (toList s)
prop_maxInSet :: IntSet -> Bool
prop_maxInSet s
| S.null s = True
| otherwise = member (findMax s) s
prop_maxIsTheGreatest :: IntSet -> Bool
prop_maxIsTheGreatest s
| S.null s = True
| otherwise = all (<= findMax s) (toList s)
prop_differenceMember :: IntSet -> IntSet -> Bool
prop_differenceMember a b = all (`notMember` difference a b) (toList b)
prop_differenceIntersection :: IntSet -> IntSet -> Bool
prop_differenceIntersection a b = (difference a b `intersection` b) == empty
prop_differenceSize :: IntSet -> IntSet -> Bool
prop_differenceSize a b = size (difference a b) <= size a
prop_differenceSubset :: IntSet -> IntSet -> Bool
prop_differenceSubset a b = (a `difference` b) `isSubsetOf` a
prop_differenceDeMorgan1 :: IntSet -> IntSet -> IntSet -> Bool
prop_differenceDeMorgan1 a b c = a - b * c == (a - b) + (a - c)
prop_differenceDeMorgan2 :: IntSet -> IntSet -> IntSet -> Bool
prop_differenceDeMorgan2 a b c = a - (b + c) == (a - b) * (a - c)
prop_differenceDistributive :: IntSet -> IntSet -> IntSet -> Bool
prop_differenceDistributive a b c = (a + b) - c == (a - c) + (b - c)
prop_splitPivot :: IntSet -> Key -> Bool
prop_splitPivot s k = all (< k) (toList lt) && all (k <) (toList gt)
where
(lt, gt) = split k s
prop_splitIntersect :: IntSet -> Key -> Bool
prop_splitIntersect s k = lt * gt == empty
where
(lt, gt) = split k s
prop_splitGT :: IntSet -> Key -> Bool
prop_splitGT s k = all (k <) (toList (splitGT k s))
prop_splitLT :: IntSet -> Key -> Bool
prop_splitLT s k = all (< k) (toList (splitLT k s))
prop_interval :: Int -> Int -> Bool
prop_interval a s = interval l r == fromList [l..r]
where
l = a
r = l + min 10000 s
prop_cmp :: IntSet -> IntSet -> Bool
prop_cmp a b = compare a b == compare (toList a) (toList b)
prop_numInst :: Int -> Bool
prop_numInst i = fromIntegral i == singleton i
prop_deleteEmpty :: Int -> Bool
prop_deleteEmpty k = delete k empty == empty
prop_elems :: IntSet -> Bool
prop_elems s = toList s == elems s
prop_combine :: [IntSet] -> Bool
prop_combine xs = all check xs
where
check x = us <> x == us && is * x == is
us = mconcat xs
is = intersections xs
prop_sortIdemp :: [Int] -> Bool
prop_sortIdemp xs = let a = ssort xs in ssort a == a
where
ssort = toList . fromList
prop_bitmapEncode :: IntSet -> Bool
prop_bitmapEncode xs = fromByteString (toByteString xs') == xs'
where -- we should restrict upper bound otherwise we might have out of memory
xs' = splitGT (-1) $ splitLT 1000000 xs
prop_partition :: IntSet -> Bool
prop_partition s = fst (S.partition even s) == S.filter even s
&& snd (S.partition even s) == S.filter odd s
prop_subsetSize :: IntSet -> IntSet -> Bool
prop_subsetSize a b
| a `isSubsetOf` b = size a <= size b
| otherwise = True
prop_supersetSize :: IntSet -> IntSet -> Bool
prop_supersetSize a b
| a `isSupersetOf` b = size a >= size b
| otherwise = True
prop_subsetSuperset :: IntSet -> IntSet -> Bool
prop_subsetSuperset a b = (a `isSubsetOf` b) || (b `isSubsetOf` a)
|| not (S.null (symDiff a b))
prop_subsetIntersection :: IntSet -> IntSet -> Bool
prop_subsetIntersection a b = (i `isSubsetOf` a) && (i `isSubsetOf` b)
where
i = a * b
prop_subsetUnion :: IntSet -> IntSet -> Bool
prop_subsetUnion a b = (a `isSubsetOf` u) && (b `isSubsetOf` u)
where
u = a + b
prop_symDiffLeftNeutral :: IntSet -> Bool
prop_symDiffLeftNeutral a = symDiff empty a == a
prop_symDiffRightNeutral :: IntSet -> Bool
prop_symDiffRightNeutral a = symDiff a empty == a
prop_symDiffCommutative :: IntSet -> IntSet -> Bool
prop_symDiffCommutative a b = (a `symDiff` b) == b `symDiff` a
prop_symDiffAssociative :: IntSet -> IntSet -> IntSet -> Bool
prop_symDiffAssociative a b c = ((a `symDiff` b) `symDiff` c)
== (a `symDiff` (b `symDiff` c))
prop_symDiffDistr :: IntSet -> IntSet -> IntSet -> Bool
prop_symDiffDistr a b c = (a `intersection` (b `symDiff` c))
== ((a `intersection` b) `symDiff` (a `intersection` c))
prop_symDiffUnion :: IntSet -> IntSet -> Bool
prop_symDiffUnion a b = (a `difference` b) `union` (b `difference` a)
== symDiff a b
prop_symDiffInter :: IntSet -> IntSet -> Bool
prop_symDiffInter a b = (a `union` b) `difference` (a `intersection` b)
== symDiff a b
prop_symDiffSizeBound :: IntSet -> IntSet -> Bool
prop_symDiffSizeBound a b = size s <= size a + size b
where
s = symDiff a b
main :: IO ()
main = defaultMain
[ testProperty "empty" prop_empty
, testProperty "singleton" prop_singleton
, testProperty "insertLookup" prop_insertLookup
, testProperty "insert delete" prop_insertDelete
, testProperty "compare" prop_cmp
, testProperty "interval" prop_interval
, testProperty "subset size" prop_subsetSize
, testProperty "superset size" prop_supersetSize
, testProperty "subset superset exclusion" prop_subsetSuperset
, testProperty "subset of intersection" prop_subsetIntersection
, testProperty "subset of union" prop_subsetUnion
, testProperty "bitmap_encode" prop_bitmapEncode
, testProperty "symmetric difference left neutral" prop_symDiffLeftNeutral
, testProperty "symmetric difference right neutral" prop_symDiffRightNeutral
, testProperty "symmetric difference commutative" prop_symDiffCommutative
, testProperty "symmetric difference associative" prop_symDiffAssociative
, testProperty "symmetric difference distributive" prop_symDiffDistr
, testProperty "symmetric difference union" prop_symDiffUnion
, testProperty "symmetric difference intersection" prop_symDiffInter
, testProperty "symmetric difference size upper bound" prop_symDiffSizeBound
{-
, testProperty "universe member" prop_universeMember
, testProperty "universe delete" prop_universeDelete
, testProperty "universe insert" prop_universeInsert
, testProperty "universe nat neg" prop_universeNatNeg
, testProperty "naturals" prop_naturals
, testProperty "negatives" prop_negatives
-}
, testProperty "size" prop_size
, testProperty "sort" prop_sorted
, testProperty "sort idempotent" prop_sortIdemp
, testProperty "read . show == id" prop_showRead
, testProperty "equality" prop_eq
, testProperty "equality reflexivity" prop_eqRefl
, testProperty "equality symmetry" prop_eqSym
, testProperty "equality transitivity" prop_eqTrans
, testProperty "map preserve size" prop_mapPresSize
, testProperty "map not preserve siz" prop_mapLessSize
, testProperty "mapping" prop_mapping
, testProperty "filter size" prop_filterSize
, testProperty "filtering" prop_filtering
, testProperty "union size" prop_unionSize
, testProperty "unionLookup" prop_unionLookup
, testProperty "union commutative" prop_unionComm
, testProperty "union associative" prop_unionAssoc
, testProperty "union left identity" prop_unionLeftId
, testProperty "union right identity" prop_unionRightId
, testProperty "union top" prop_unionTop
, testProperty "union idemp" prop_unionIdemp
, testProperty "minimal in set" prop_minInSet
, testProperty "maximal in set" prop_maxInSet
, testProperty "minimal is the less" prop_minIsTheLess
, testProperty "maximal is the greatest" prop_maxIsTheGreatest
, testProperty "intersection size" prop_intersectionSize
, testProperty "intersection lists" prop_intersection
, testProperty "intersection commutative" prop_intersectComm
, testProperty "intersection associative" prop_intersectAssoc
, testProperty "intersection idemp" prop_intersectIdemp
, testProperty "intersection left empty" prop_intersectLeft
, testProperty "intersection right empty" prop_intersectRight
, testProperty "intersection bot" prop_intersectBot
, testProperty "difference member" prop_differenceMember
, testProperty "difference intersection" prop_differenceIntersection
, testProperty "difference size" prop_differenceSize
, testProperty "difference de morgan1" prop_differenceDeMorgan1
, testProperty "difference de morgan2" prop_differenceDeMorgan2
, testProperty "difference distributive" prop_differenceDistributive
, testProperty "difference subset" prop_differenceSubset
, testProperty "split pivot" prop_splitPivot
, testProperty "split intersection" prop_splitIntersect
, testProperty "split greater than" prop_splitGT
, testProperty "split lesser than" prop_splitLT
, testProperty "partition filter" prop_partition
, testProperty "min" prop_min
, testProperty "valid" prop_valid
-- for coverage mostly
, testProperty "delete from empty" prop_deleteEmpty
, testProperty "combine" prop_combine
, testProperty "num instance" prop_numInst
, testProperty "elems" prop_elems
]