module TestQueue where import Test.QuickCheck {--------------------------------------------------------------------- Interface: ---------- emptyQueue :: Queue a enqueue :: Queue a -> a -> Queue a dequeue :: Queue a -> Queue a firstQueue :: Queue a -> a isEmptyQueue :: Queue a -> Bool -} {- Gleichungsspezifikation: ----------------------- -} prop_1 :: Int -> Bool prop_1 x = dequeue (enqueue emptyQueue x) === emptyQueue prop_2 :: Queue Int -> Int -> Property prop_2 q x = isEmptyQueue q == False ==> dequeue (enqueue q x) === enqueue (dequeue q) x prop_3 :: Int -> Bool prop_3 x = firstQueue (enqueue emptyQueue x) == x prop_4 :: Queue Int -> Int -> Property prop_4 q x = isEmptyQueue q == False ==> firstQueue (enqueue q x) == firstQueue q prop_5 :: Queue Int -> Int -> Bool prop_5 q x = (isEmptyQueue emptyQueue) && (isEmptyQueue (enqueue q x) == False) {----------------------------------------------------------------------} type Queue a = ([a],[a]) -- (rs,ws) Leseende << Schreibende {--------------------------------------------------------------------- Invarianten: ------------ (1) fuer alle (rs,ws): rs = [] -> ws = [] (2) (rs1,ws1) == (rs2,ws2) -> rs1 ++ (reverse ws1) = rs2 ++ (reverse ws2) ----------------------------------------------------------------------} infix 2 === (rs1,ws1) === (rs2,ws2) = rs1 ++ (reverse ws1) == rs2 ++ (reverse ws2) inv_1 :: Queue Int -> Bool inv_1 (rs,ws) = not( null rs) || null ws prop_6 :: Queue Int -> Property prop_6 q = (inv_1 q && not (isEmptyQueue q)) ==> inv_1 (dequeue q) prop_7 :: Queue Int -> Int -> Property prop_7 q x = inv_1 q ==> inv_1 (enqueue q x) -- Testkontrolle prop_8 :: Queue Int -> Property prop_8 q@(rs,ws) = inv_1 q ==> classify (null rs) "empty" $ classify (length (rs++ws) == 1) "unit" $ True prop_9 :: Queue Int -> Property prop_9 q@(rs,ws) = inv_1 q ==> collect (length (rs++ws)) $ True emptyQueue :: Queue a emptyQueue = ([],[]) enqueue :: Queue a -> a -> Queue a enqueue ([], ws) x = ([x], ws) -- hier gilt: ws = [] enqueue (rs@(r:rs'), ws) x = (rs, x:ws) dequeue :: Queue a -> Queue a dequeue (x:r:rs, ws) = (r:rs, ws) dequeue ([x], ws) = (reverse ws, []) firstQueue :: Queue a -> a firstQueue (r:rs, ws) = r isEmptyQueue :: Queue a -> Bool isEmptyQueue (rs, ws) = null rs -- dann gilt auch ws = []