import Test.QuickCheck

-- einfache Eigenschaften
prop_PA :: Int -> Int -> Int -> Bool
prop_PA x y z = (x+y)+z == x+(y+z) 

prop_MC :: Int -> Int -> Bool
prop_MC x y = x-y == y-x 

prop_MCA :: Int -> Int -> Bool
prop_MCA x y = abs (x-y) == abs (y-x)

prop_reverse :: [Int] -> Bool
prop_reverse xs = reverse (reverse xs) == xs
------------------------------------------------------------
isort        :: Ord a => [a] -> [a]
isort []     =  []
isort (x:xs) =  insert x (isort xs)

insert :: Ord a => a -> [a] -> [a]
insert x [] = [x]
insert x l@(y:ys) | x <= y    = x:l
                  | otherwise = y:insert x ys
               
ordered :: Ord a => [a] -> Bool
ordered xs  = and (zipWith (<=) xs (tail xs))
-- 

prop_IS :: [Int] -> Bool
prop_IS xs = ordered (isort xs)

prop_I0 :: Int -> [Int] -> Bool
prop_I0 x xs = ordered (insert x xs) 

prop_I1 :: Int -> [Int] -> Property 
prop_I1 x xs = ordered xs ==> 
               ordered (insert x xs)                


-- Testkontrolle

prop_O :: [Int] -> Property
prop_O xs = classify (ordered xs) "ordered" $ 
            classify (null xs) "empty" $
            classify (length xs == 1) "unit" $
            classify (length xs < 5) "less 5" $
            classify (length xs >= 5 && length xs <= 10) "between 5 and 10" $
            classify (length xs > 10) "more than 10" $
            True


prop_InsertOrdered3 :: Int -> [Int] -> Property 
prop_InsertOrdered3 x xs = ordered xs ==> 
                           ordered (insert x xs) 

prop_InsertOrdered3a :: Int -> [Int] -> Property 
prop_InsertOrdered3a x xs = ordered xs ==> 
                           classify (length xs <= 2) "trivial" $
                           ordered (insert x xs) 



prop_InsertOrdered4 :: Int -> [Int] -> Property 
prop_InsertOrdered4 x xs 
        = ordered xs ==> 
           classify (null xs) "empty" $
           classify (length xs == 1) "unit" $
                    ordered(insert x xs)

prop_InsertOrdered5 :: Int -> [Int] -> Property 
prop_InsertOrdered5 x xs 
        = ordered xs ==> 
           collect (length xs) $
                    ordered(insert x xs)
