Skip to content

Commit b3ee761

Browse files
committed
Use new Tree functions internally
1 parent 85a1ab5 commit b3ee761

2 files changed

Lines changed: 16 additions & 32 deletions

File tree

containers-tests/tests/graph-properties.hs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import qualified Data.Foldable as F
77
import qualified Data.Graph as G
88
import qualified Data.List as L
99
import qualified Data.Set as S
10+
import qualified Data.Tree as Tree
1011

1112
default (Int)
1213

@@ -128,14 +129,14 @@ prop_dfs (Graph g) =
128129
in forAll vsgen $ \vs ->
129130
let ts = G.dfs g vs
130131
in S.fromList (concatMap F.toList ts) `S.isSubsetOf` S.fromList (G.vertices g) .&&.
131-
S.fromList (concatMap treeEdges ts) `S.isSubsetOf` S.fromList (G.edges g)
132+
S.fromList (concatMap Tree.edges ts) `S.isSubsetOf` S.fromList (G.edges g)
132133

133134
-- Note: This tests some simple properties but not complete correctness
134135
prop_dff :: Graph -> Property
135136
prop_dff (Graph g) =
136137
let ts = G.dff g
137138
in L.sort (concatMap F.toList ts) === G.vertices g .&&.
138-
S.fromList (concatMap treeEdges ts) `S.isSubsetOf` S.fromList (G.edges g)
139+
S.fromList (concatMap Tree.edges ts) `S.isSubsetOf` S.fromList (G.edges g)
139140

140141
prop_topSort :: DAG -> Property
141142
prop_topSort (DAG g) =
@@ -147,7 +148,7 @@ prop_scc :: Graph -> Property
147148
prop_scc (Graph g) =
148149
let ts = G.scc g
149150
in L.sort (concatMap F.toList ts) === G.vertices g .&&.
150-
S.fromList (concatMap treeEdges ts) `S.isSubsetOf` S.fromList (G.edges g) .&&.
151+
S.fromList (concatMap Tree.edges ts) `S.isSubsetOf` S.fromList (G.edges g) .&&.
151152
-- vertices in a component are mutually reachable
152153
and [G.path g u v | t <- ts, u <- F.toList t, v <- F.toList t] .&&.
153154
-- vertices in later components are not reachable from earlier components, due to reverse
@@ -160,7 +161,7 @@ prop_bcc (UndirectedG g) =
160161
comps = concatMap F.toList ts :: [[G.Vertex]]
161162
in S.fromList (concat comps) `S.isSubsetOf` S.fromList (G.vertices g) .&&.
162163
all testBCC comps .&&.
163-
all (uncurry testBCCs) (concatMap treeEdges ts)
164+
all (uncurry testBCCs) (concatMap Tree.edges ts)
164165
where
165166
-- a biconnected component remains connected even if any single vertex is removed
166167
testBCC c = and [subsetComponents (L.delete x c) == 1 | x <- c]
@@ -194,7 +195,3 @@ prop_stronglyConnCompR (AdjList adj) =
194195
testSCC (G.AcyclicSCC (_, k, ks)) = k `notElem` ks
195196
testSCC (G.CyclicSCC [(_, k, ks)]) = k `elem` ks
196197
testSCC (G.CyclicSCC xs) = and [G.path g (getv k) (getv k') | (_,k,_) <- xs , (_,k',_) <- xs]
197-
198-
treeEdges :: G.Tree a -> [(a, a)]
199-
treeEdges t = go t []
200-
where go (G.Node x ts) acc = [(x,y) | G.Node y _ <- ts] ++ foldr go acc ts

containers/src/Data/Graph.hs

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ import Data.IntSet (IntSet)
119119
import qualified Data.IntSet as Set
120120
#endif
121121
import Data.Tree (Tree(..), Forest)
122+
import qualified Data.Tree as Tree
122123

123124
-- std interfaces
124125
import Data.Foldable as F
@@ -647,15 +648,6 @@ run _ f = fst (runSetM (f contains include) Set.empty)
647648
-- Algorithm 1: depth first search numbering
648649
------------------------------------------------------------
649650

650-
preorder' :: Tree a -> [a] -> [a]
651-
preorder' (Node a ts) = (a :) . preorderF' ts
652-
653-
preorderF' :: [Tree a] -> [a] -> [a]
654-
preorderF' ts = foldr (.) id $ map preorder' ts
655-
656-
preorderF :: [Tree a] -> [a]
657-
preorderF ts = preorderF' ts []
658-
659651
tabulate :: Bounds -> [Vertex] -> UArray Vertex Int
660652
tabulate bnds vs = UA.array bnds (zipWith (flip (,)) [1..] vs)
661653
-- Why zipWith (flip (,)) instead of just using zip with the
@@ -664,38 +656,33 @@ tabulate bnds vs = UA.array bnds (zipWith (flip (,)) [1..] vs)
664656
-- list argument.
665657

666658
preArr :: Bounds -> [Tree Vertex] -> UArray Vertex Int
667-
preArr bnds = tabulate bnds . preorderF
659+
preArr bnds = tabulate bnds . concatMap Tree.flatten
668660

669661
------------------------------------------------------------
670662
-- Algorithm 2: topological sorting
671663
------------------------------------------------------------
672664

673-
postorder :: Tree a -> [a] -> [a]
674-
postorder (Node a ts) = postorderF ts . (a :)
675-
676-
postorderF :: [Tree a] -> [a] -> [a]
677-
postorderF ts = foldr (.) id $ map postorder ts
678-
679-
postOrd :: Graph -> [Vertex]
680-
postOrd g = postorderF (dff g) []
681-
682665
-- | \(O(V+E)\). A topological sort of the graph.
683666
-- The order is partially specified by the condition that a vertex /i/
684667
-- precedes /j/ whenever /j/ is reachable from /i/ but not vice versa.
685668
--
686669
-- Note: A topological sort exists only when there are no cycles in the graph.
687670
-- If the graph has cycles, the output of this function will not be a
688671
-- topological sort. In such a case consider using 'scc'.
689-
topSort :: Graph -> [Vertex]
690-
topSort = reverse . postOrd
672+
topSort :: Graph -> [Vertex]
673+
topSort = reversePostOrder . dff
674+
where
675+
reversePostOrder :: [Tree a] -> [a]
676+
reversePostOrder =
677+
F.foldl' (\vs t -> F.foldl' (flip (:)) vs (Tree.PostOrder t)) []
691678

692679
-- | \(O(V+E)\). Reverse ordering of `topSort`.
693680
--
694681
-- See note in 'topSort'.
695682
--
696683
-- @since 0.6.4
697684
reverseTopSort :: Graph -> [Vertex]
698-
reverseTopSort = postOrd
685+
reverseTopSort = concatMap (F.toList . Tree.PostOrder) . dff
699686

700687
------------------------------------------------------------
701688
-- Algorithm 3: connected components
@@ -722,7 +709,7 @@ undirected g = buildG (bounds g) (edges g ++ reverseE g)
722709
-- > ,Node {rootLabel = 3, subForest = []}]
723710

724711
scc :: Graph -> [Tree Vertex]
725-
scc g = dfs g (reverse (postOrd (transposeG g)))
712+
scc g = dfs g (topSort (transposeG g))
726713

727714
------------------------------------------------------------
728715
-- Algorithm 5: Classifying edges
@@ -764,7 +751,7 @@ mapT f t = array (bounds t) [ (,) v (f v (t!v)) | v <- indices t ]
764751
--
765752
-- > reachable (buildG (0,2) [(0,1), (1,2)]) 0 == [0,1,2]
766753
reachable :: Graph -> Vertex -> [Vertex]
767-
reachable g v = preorderF (dfs g [v])
754+
reachable g v = concatMap Tree.flatten (dfs g [v])
768755

769756
-- | \(O(V+E)\). Returns @True@ if the second vertex reachable from the first.
770757
--

0 commit comments

Comments
 (0)