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]) -- (ws,rs) Schreibende >> Leseende {--------------------------------------------------------------------- Invarianten: ------------ (1) fuer alle (ws,rs): rs = [] -> ws = [] (2) (ws1,rs1) == (ws2,rs2) -> rs1 ++ (reverse ws1) = rs2 ++ (reverse ws2) ----------------------------------------------------------------------} infix 2 === (ws1,rs1) === (ws2,rs2) = rs1 ++ (reverse ws1) == rs2 ++ (reverse ws2) inv_1 :: Queue Int -> Bool inv_1 (ws,rs) = 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) emptyQueue :: Queue a emptyQueue = ([],[]) enqueue :: Queue a -> a -> Queue a enqueue (ws,[]) x = (ws,[x]) -- hier gilt: ws = [] enqueue (ws,rs@(r:rs')) x = (x:ws,rs) dequeue :: Queue a -> Queue a dequeue (ws, x:r:rs) = (ws, r:rs) dequeue (ws, [x]) = ([], reverse ws) firstQueue :: Queue a -> a firstQueue (ws, r:rs) = r isEmptyQueue :: Queue a -> Bool isEmptyQueue (ws, rs) = null rs -- dann gilt auch ws = []