dynamic-graphs-0.1.0.1: tests/Data/Graph/Dynamic/Levels/Tests.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
module Data.Graph.Dynamic.Levels.Tests where
import Control.Monad (foldM, forM_)
import Control.Monad.ST
import Data.Graph.Dynamic.Action
import Data.Graph.Dynamic.Internal.Tree (Tree)
import qualified Data.Graph.Dynamic.Levels as Levels
import qualified Data.Graph.Dynamic.Program as Program
import qualified Data.Graph.Dynamic.Slow as Slow
import Data.Hashable (Hashable)
import Data.List (foldl', mapAccumL)
import Data.Maybe (catMaybes)
import Test.Framework
import Test.Framework.Providers.QuickCheck2
import Test.Framework.TH
import qualified Test.QuickCheck as QC
runGraphAction
:: (Eq v, Hashable v, Tree tree)
=> Levels.Graph tree s v -> [Bool] -> Action t v -> ST s [Bool]
runGraphAction levels xs (Cut x y) = do
Levels.cut_ levels x y
return xs
runGraphAction levels xs (Link x y) = do
Levels.link_ levels x y
return xs
runGraphAction levels xs (Toggle x y) = do
Levels.edge levels x y >>= \case
True -> Levels.cut_ levels x y
False -> Levels.link_ levels x y
return xs
runGraphAction levels xs (Query x y) =
Levels.connected levels x y >>= \q -> return (q:xs)
checkActions :: QC.Positive Int -> [Action t Int] -> QC.Property
checkActions (QC.Positive n) actions = slowResult QC.=== result
where
actions' = map (fmap (`mod` n)) actions
initialSlowGraph = Slow.edgeless [0..n-1]
slowResult = catMaybes $ snd $ mapAccumL runSlowGraphAction initialSlowGraph actions'
result :: [Bool]
result = runST $ do
initialGraph <- Levels.edgeless' [0..n-1]
results <- foldM (runGraphAction initialGraph) [] actions'
return $ reverse results
prop_graph_linkcut :: QC.Positive Int -> [Action 'LinkCut Int] -> QC.Property
prop_graph_linkcut = checkActions
prop_graph_toggle :: QC.Positive Int -> [Action 'Toggl Int] -> QC.Property
prop_graph_toggle = checkActions
prop_program :: Program.IntGraphProgram -> ()
prop_program (Program.IntGraphProgram p) = runST $ do
f <- Levels.empty'
Program.runProgram f p
prop_spanningTree :: QC.Positive Int -> [Action 'LinkCut Int] -> QC.Property
prop_spanningTree (QC.Positive n) actions =
Slow.isSpanningForest spanningForest slow QC.=== True
where
actions' = map (fmap (`mod` n)) actions
spanningForest = runST $ do
et <- Levels.edgeless' [0 .. n - 1]
forM_ actions' $ \action -> runGraphAction et [] action
Levels.spanningForest et
slow = foldl'
(\g a -> fst $ runSlowGraphAction g a)
(Slow.edgeless [0 .. n - 1])
actions'
tests :: Test
tests = $testGroupGenerator