ac-library-hs-1.1.0.0: test/Tests/Extra/Graph.hs
module Tests.Extra.Graph where
import AtCoder.Extra.Graph qualified as Gr
import AtCoder.Internal.Buffer qualified as B
import Control.Monad (unless)
import Control.Monad.Fix (fix)
import Control.Monad.ST (runST)
import Data.List qualified as L
import Data.Vector.Generic qualified as VG
import Data.Vector.Unboxed qualified as VU
import Data.Vector.Unboxed.Mutable qualified as VUM
import Test.Tasty
import Test.Tasty.QuickCheck as QC
genDag :: Int -> QC.Gen (Gr.Csr ())
genDag n = do
edges <- VU.fromList <$> QC.sublistOf [(u, v) | u <- [0 .. n - 1], v <- [u + 1 .. n - 1]]
verts <- VU.fromList <$> QC.shuffle [0 .. n - 1]
pure $ Gr.build n $ VU.map (\(!u, !v) -> (verts VG.! u, verts VG.! v, ())) edges
dfs :: Int -> (Int -> VU.Vector Int) -> Int -> VU.Vector Int
dfs n gr u0 = runST $ do
buf <- B.new n
vis <- VUM.replicate n False
flip fix u0 $ \loop u -> do
VU.forM_ (gr u) $ \v -> do
b <- VUM.read vis v
unless b $ do
B.pushBack buf v
loop v
B.unsafeFreeze buf
testTopSort :: Int -> Gr.Csr () -> VU.Vector Int -> Bool
testTopSort n gr vs = and
[ VU.notElem v (dfs n (gr `Gr.adj`) u)
| u <- (vs VG.!) <$> [0 .. n - 1],
v <- (vs VG.!) <$> [u + 1 .. n - 1]
]
-- | Tests lexicographically smallest topological ordering.
prop_topSort :: QC.Gen QC.Property
prop_topSort = do
n <- QC.chooseInt (1, 8)
dag <- genDag n
let vs = Gr.topSort n (dag `Gr.adj`)
let perms = map (VU.fromListN n) $ L.permutations [0 .. n - 1]
pure $ vs QC.=== head (filter (testTopSort n dag) perms)
tests :: [TestTree]
tests =
[ QC.testProperty "topSort" prop_topSort
]