{-# OPTIONS -XFlexibleInstances #-}
import Test.QuickCheck
import Data.List
rev :: [a] -> [a]
rev [] = []
rev (h:t) = rev t ++ [h]
prop_rev_unit :: Int -> Bool
prop_rev_unit x = rev [x] == [x]
prop_rev_plus :: [Int] -> [Int] -> Bool
prop_rev_plus xs ys = rev (xs ++ ys) == rev ys ++ rev xs
prop_rev_rev :: [Int] -> Bool
prop_rev_rev xs = rev (rev xs) == xs
frev :: [a] -> [a]
frev l = aux l []
where aux :: [a] -> [a] -> [a]
aux [] a = a
aux (h:t) a = aux t (h:a)
prop_frev :: [Int] -> Bool
prop_frev l = frev l == rev l
filtra :: (a -> Bool) -> [a] -> [a]
filtra p [] = []
filtra p (h:t) | p h = h : filtra p t
| otherwise = filtra p t
prop_filtra_false :: [Int] -> Bool
prop_filtra_false xs = null (filtra (\_ -> False) xs)
instance Show (Int -> Bool) where
show f = concat $ intersperse "\n" $ map (\n -> show n ++ " -> " ++ show (f n)) [-5 .. 5]
prop_filtra :: (Int -> Bool) -> [Int] -> Bool
prop_filtra p xs = all p (filtra p xs)
prop_filtra_todos :: (Int -> Bool) -> Property
prop_filtra_todos p = forAll notnull $ \xs -> forAll (elements xs) $ \x -> p x ==> x `elem` filtra p xs
notnull :: Arbitrary a => Gen [a]
notnull = do xs <- arbitrary
x <- arbitrary
return (x:xs)
insere :: Ord a => a -> [a] -> [a]
insere x [] = [x]
insere x (y:ys) | x <= y = x : y : ys
| otherwise = y : insere x ys
ordenada :: Ord a => [a] -> Bool
ordenada [] = True
ordenada [_] = True
ordenada (x:y:ys) = x <= y && ordenada (y:ys)
prop_insere :: Int -> Property
prop_insere x = forAll lista_ordenada $ \xs -> collect (length xs) $ ordenada (insere x xs)
lista_ordenada :: (Arbitrary a, Ord a) => Gen [a]
lista_ordenada = do l <- arbitrary
return (sort l)
data Set a = Set [a]
deriving Show
instance (Eq a, Arbitrary a) => Arbitrary (Set a) where
arbitrary = do l <- arbitrary
return (Set (nub l))
member :: Eq a => a -> Set a -> Bool
member x (Set xs) = x `elem` xs
(./\.) :: Eq a => Set a -> Set a -> Set a
Set xs ./\. Set ys = Set (filter (\x -> x `elem` ys) xs)
prop_intersect :: Int -> Set Int -> Set Int -> Property
prop_intersect x xs ys = x `member` xs && x `member` ys ==> x `member` (xs ./\. ys)
data Tree a = Leaf a | Fork (Tree a) (Tree a)
deriving Show
instance Arbitrary a => Arbitrary (Tree a) where
arbitrary = sized gerador
gerador :: Arbitrary a => Int -> Gen (Tree a)
gerador 0 = do x <- arbitrary
return (Leaf x)
gerador n = frequency [(1, do {x <- arbitrary; return (Leaf x)}),
(4, do {l <- gerador (n `div` 2);
r <- gerador (n `div` 2);
return (Fork l r)})]
instance CoArbitrary a => CoArbitrary (Tree a) where
coarbitrary (Leaf x) = variant 0 . coarbitrary x
coarbitrary (Fork l r) = variant 1 . coarbitrary l . coarbitrary r
folhas :: Tree a -> [a]
folhas (Leaf x) = [x]
folhas (Fork l r) = folhas l ++ folhas r
mirror :: Tree a -> Tree a
mirror (Leaf x) = Leaf x
mirror (Fork l r) = Fork (mirror r) (mirror l)
size :: Tree a -> Int
size t = length (folhas t)
prop_mirror :: Tree Int -> Property
prop_mirror t = collect (size t) $ folhas t == reverse (folhas (mirror t))