@ 131018.10
current
module QC.HeapProps where

import Data.List (sort)
import Control.Monad (liftM)
import Test.QuickCheck

-- import QC.Heap 
import QC.SkewHeap

instance (Arbitrary a, Ord a) => Arbitrary (Heap a) where
  arbitrary = liftM heapify arbitrary

  shrink Nil = []
  shrink h = [delete h]

-- peek (insert empty x) == x
prop_single :: Int -> Bool
prop_single x = peek (insert empty x) == x

-- peek (heapify xs) == minimum xs
prop_heapify :: [Int] -> Property
prop_heapify xs = not (null xs) ==> peek (heapify xs) == minimum xs

-- peek (delete (heapify xs)) == head (tail (sort xs))
prop_delete :: [Int] -> Property
prop_delete xs =
  length xs >= 2 ==> peek (delete (heapify xs)) == head (tail (sort xs))

-- peek (foldl merge empty heaps) == minimum (map peek heaps)
prop_merge :: [Heap Int] -> Property
prop_merge heaps =
  not (null heaps) && all (not . isEmpty) heaps
  ==> peek (foldl merge empty heaps) == minimum (map peek heaps)

-- forall n . n <= left n && n <= right n
prop_heap :: Heap Int -> Bool
prop_heap Nil = True
prop_heap (Node Nil Nil _) = True
prop_heap (Node (Node _ _ lv) Nil v) = v <= lv
prop_heap (Node Nil (Node _ _ rv) v) = v <= rv
prop_heap (Node (Node _ _ lv) (Node _ _ rv) v) = v <= lv && v <= rv

tests :: [(String, Property)]
tests = [ ("peek (insert empty x) == x", property prop_single)
        , ("peek (heapify xs) == minimum xs", property prop_heapify)
        , ( "peek (delete (heapify xs)) == head (tail (sort xs))"
          , property prop_delete
          )
        , ( "peek (foldl merge empty heaps) == minimum (map peek heaps)"
          , property prop_merge
          )
        , ("forall n . n <= left n && n <= right n", property prop_heap)
        ]

main :: IO ()
main = mapM_ (\(s, p) -> do { putStrLn s; quickCheck p}) tests