From 8119d0e1690c286b2a7194f146f09e3a9869e171 Mon Sep 17 00:00:00 2001 From: Pavel Samolysov Date: Sat, 21 Dec 2024 07:43:50 +0300 Subject: [PATCH 1/8] Use vector-of-structs of preds/semi for Lengauer-Tarjan Closes #383 --- include/boost/graph/dominator_tree.hpp | 75 ++++++++++++++++++-------- 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/include/boost/graph/dominator_tree.hpp b/include/boost/graph/dominator_tree.hpp index 8a9e7afd..cd7e7f9e 100644 --- a/include/boost/graph/dominator_tree.hpp +++ b/include/boost/graph/dominator_tree.hpp @@ -62,6 +62,33 @@ namespace detail Tag >(timeMap, v, t); } + // Auxiliary structure of different kinds of predecessors are used to + // calculate the semidominators: ancestor, semidominator, and the ancestor + // with the lowest semidominator (`best`). Placing these predecessors in a + // structure let us organize a "vector of structs" what improves cache + // efficiency. + template < class Graph > struct preds + { + preds() + : semi(graph_traits< Graph >::null_vertex()) + , ancestor(graph_traits< Graph >::null_vertex()) + , best(graph_traits< Graph >::null_vertex()) + { + } + + typedef typename graph_traits< Graph >::vertex_descriptor Vertex; + + void set_ancestor(const preds& pr) { ancestor = pr.ancestor; } + + void set_ancestor(const Vertex& v) { ancestor = v; } + + void set_best(const Vertex& v) { best = v; } + + void set_semi(const Vertex& v) { semi = v; } + + Vertex semi, ancestor, best; + }; + template < class Graph, class IndexMap, class TimeMap, class PredMap, class DomTreePredMap > class dominator_visitor @@ -80,13 +107,9 @@ namespace detail */ dominator_visitor(const Graph& g, const Vertex& entry, const IndexMap& indexMap, DomTreePredMap domTreePredMap) - : semi_(num_vertices(g)) - , ancestor_(num_vertices(g), graph_traits< Graph >::null_vertex()) - , samedom_(ancestor_) - , best_(semi_) - , semiMap_(make_iterator_property_map(semi_.begin(), indexMap)) - , ancestorMap_(make_iterator_property_map(ancestor_.begin(), indexMap)) - , bestMap_(make_iterator_property_map(best_.begin(), indexMap)) + : preds_(num_vertices(g)) + , predsMap_(make_iterator_property_map(preds_.begin(), indexMap)) + , samedom_(num_vertices(g), graph_traits< Graph >::null_vertex()) , buckets_(num_vertices(g)) , bucketMap_(make_iterator_property_map(buckets_.begin(), indexMap)) , entry_(entry) @@ -132,18 +155,20 @@ namespace detail if (get(dfnumMap, v) <= get(dfnumMap, n)) s2 = v; else - s2 = get(semiMap_, ancestor_with_lowest_semi_(v, dfnumMap)); + s2 = get(predsMap_, ancestor_with_lowest_semi_(v, dfnumMap)) + .semi; if (get(dfnumMap, s2) < get(dfnumMap, s)) s = s2; } - put(semiMap_, n, s); + preds< Graph >& preds_of_n = get(predsMap_, n); + preds_of_n.set_semi(s); // 2. Calculation of n's dominator is deferred until // the path from s to n has been linked into the forest get(bucketMap_, s).push_back(n); - get(ancestorMap_, n) = p; - get(bestMap_, n) = n; + preds_of_n.set_ancestor(p); + preds_of_n.set_best(n); // 3. Now that the path from p to v has been linked into // the spanning forest, these lines calculate the dominator of v, @@ -161,7 +186,7 @@ namespace detail { const Vertex v(*buckItr); const Vertex y(ancestor_with_lowest_semi_(v, dfnumMap)); - if (get(semiMap_, y) == get(semiMap_, v)) + if (get(predsMap_, y).semi == get(predsMap_, v).semi) put(domTreePredMap_, v, p); else put(samedomMap, v, y); @@ -177,24 +202,32 @@ namespace detail const Vertex ancestor_with_lowest_semi_( const Vertex& v, const TimeMap& dfnumMap) { - const Vertex a(get(ancestorMap_, v)); + const Vertex a(get(predsMap_, v).ancestor); + const preds< Graph >& preds_of_a = get(predsMap_, a); - if (get(ancestorMap_, a) != graph_traits< Graph >::null_vertex()) + preds< Graph >& preds_of_v = get(predsMap_, v); + + if (preds_of_a.ancestor != graph_traits< Graph >::null_vertex()) { const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap)); + const preds< Graph >& preds_of_b = get(predsMap_, b); - put(ancestorMap_, v, get(ancestorMap_, a)); + preds_of_v.set_ancestor(preds_of_a); - if (get(dfnumMap, get(semiMap_, b)) - < get(dfnumMap, get(semiMap_, get(bestMap_, v)))) - put(bestMap_, v, b); + if (get(dfnumMap, preds_of_b.semi) + < get(dfnumMap, get(predsMap_, preds_of_v.best).semi)) + preds_of_v.set_best(b); } - return get(bestMap_, v); + return preds_of_v.best; } - std::vector< Vertex > semi_, ancestor_, samedom_, best_; - PredMap semiMap_, ancestorMap_, bestMap_; + std::vector< preds< Graph > > preds_; + iterator_property_map< typename std::vector< preds< Graph > >::iterator, + IndexMap > + predsMap_; + + std::vector< Vertex > samedom_; std::vector< std::vector< Vertex > > buckets_; iterator_property_map< From 3de9380d4851413da3f329263f87bc0619684945 Mon Sep 17 00:00:00 2001 From: Pavel Samolysov Date: Sun, 29 Dec 2024 12:57:14 +0300 Subject: [PATCH 2/8] Remove the 'set_' members from 'preds' struct --- include/boost/graph/dominator_tree.hpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/include/boost/graph/dominator_tree.hpp b/include/boost/graph/dominator_tree.hpp index cd7e7f9e..8f9b048c 100644 --- a/include/boost/graph/dominator_tree.hpp +++ b/include/boost/graph/dominator_tree.hpp @@ -78,14 +78,6 @@ namespace detail typedef typename graph_traits< Graph >::vertex_descriptor Vertex; - void set_ancestor(const preds& pr) { ancestor = pr.ancestor; } - - void set_ancestor(const Vertex& v) { ancestor = v; } - - void set_best(const Vertex& v) { best = v; } - - void set_semi(const Vertex& v) { semi = v; } - Vertex semi, ancestor, best; }; @@ -162,13 +154,13 @@ namespace detail s = s2; } preds< Graph >& preds_of_n = get(predsMap_, n); - preds_of_n.set_semi(s); + preds_of_n.semi = s; // 2. Calculation of n's dominator is deferred until // the path from s to n has been linked into the forest get(bucketMap_, s).push_back(n); - preds_of_n.set_ancestor(p); - preds_of_n.set_best(n); + preds_of_n.ancestor = p; + preds_of_n.best = n; // 3. Now that the path from p to v has been linked into // the spanning forest, these lines calculate the dominator of v, @@ -212,11 +204,11 @@ namespace detail const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap)); const preds< Graph >& preds_of_b = get(predsMap_, b); - preds_of_v.set_ancestor(preds_of_a); + preds_of_v.ancestor = preds_of_a.ancestor; if (get(dfnumMap, preds_of_b.semi) < get(dfnumMap, get(predsMap_, preds_of_v.best).semi)) - preds_of_v.set_best(b); + preds_of_v.best = b; } return preds_of_v.best; From e121340571cc771747238a4e3412403754639e28 Mon Sep 17 00:00:00 2001 From: Pavel Samolysov Date: Thu, 27 Feb 2025 14:14:40 +0300 Subject: [PATCH 3/8] Address the comments from @jeremy-murphy Closes #383 --- include/boost/graph/dominator_tree.hpp | 28 +++++++++++--------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/include/boost/graph/dominator_tree.hpp b/include/boost/graph/dominator_tree.hpp index 8f9b048c..d78e0e0c 100644 --- a/include/boost/graph/dominator_tree.hpp +++ b/include/boost/graph/dominator_tree.hpp @@ -67,18 +67,14 @@ namespace detail // with the lowest semidominator (`best`). Placing these predecessors in a // structure let us organize a "vector of structs" what improves cache // efficiency. - template < class Graph > struct preds + template < class Graph > + struct vertex_triple { - preds() - : semi(graph_traits< Graph >::null_vertex()) - , ancestor(graph_traits< Graph >::null_vertex()) - , best(graph_traits< Graph >::null_vertex()) - { - } + using Vertex = typename graph_traits< Graph >::vertex_descriptor; - typedef typename graph_traits< Graph >::vertex_descriptor Vertex; - - Vertex semi, ancestor, best; + Vertex semi { graph_traits< Graph >::null_vertex() }; + Vertex ancestor { graph_traits< Graph >::null_vertex() }; + Vertex best { graph_traits< Graph >::null_vertex() }; }; template < class Graph, class IndexMap, class TimeMap, class PredMap, @@ -153,7 +149,7 @@ namespace detail if (get(dfnumMap, s2) < get(dfnumMap, s)) s = s2; } - preds< Graph >& preds_of_n = get(predsMap_, n); + auto& preds_of_n = get(predsMap_, n); preds_of_n.semi = s; // 2. Calculation of n's dominator is deferred until @@ -195,14 +191,14 @@ namespace detail const Vertex& v, const TimeMap& dfnumMap) { const Vertex a(get(predsMap_, v).ancestor); - const preds< Graph >& preds_of_a = get(predsMap_, a); + const auto& preds_of_a = get(predsMap_, a); - preds< Graph >& preds_of_v = get(predsMap_, v); + auto& preds_of_v = get(predsMap_, v); if (preds_of_a.ancestor != graph_traits< Graph >::null_vertex()) { const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap)); - const preds< Graph >& preds_of_b = get(predsMap_, b); + const auto& preds_of_b = get(predsMap_, b); preds_of_v.ancestor = preds_of_a.ancestor; @@ -214,8 +210,8 @@ namespace detail return preds_of_v.best; } - std::vector< preds< Graph > > preds_; - iterator_property_map< typename std::vector< preds< Graph > >::iterator, + std::vector< vertex_triple< Graph > > preds_; + iterator_property_map< typename std::vector< vertex_triple< Graph > >::iterator, IndexMap > predsMap_; From 561e3771992fe36aab515dd4c72264bd4abed38d Mon Sep 17 00:00:00 2001 From: Pavel Samolysov Date: Thu, 27 Feb 2025 14:44:16 +0300 Subject: [PATCH 4/8] .clang-format Enable adding a blank line between template and class name --- .clang-format | 1 + 1 file changed, 1 insertion(+) diff --git a/.clang-format b/.clang-format index e73f6d56..81a8918f 100644 --- a/.clang-format +++ b/.clang-format @@ -5,6 +5,7 @@ AlignEscapedNewlinesLeft: true AlwaysBreakAfterDefinitionReturnType: None BreakBeforeBraces: Allman BreakConstructorInitializersBeforeComma: false +BreakTemplateDeclarations: Yes ColumnLimit: 80 ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 0 From 38b4f317a8f2cbf61ca16f389aa549cee1022de8 Mon Sep 17 00:00:00 2001 From: Pavel Samolysov Date: Thu, 27 Feb 2025 14:46:06 +0300 Subject: [PATCH 5/8] Add a test case for adjacency_list< listS, vecS, bidirectionalS > This specialization of the adjacency_list class uses different value for `graph_traits< G >::null_vertex()`. --- test/dominator_tree_test.cpp | 87 +++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 21 deletions(-) diff --git a/test/dominator_tree_test.cpp b/test/dominator_tree_test.cpp index 86835cf0..bc17a9f8 100644 --- a/test/dominator_tree_test.cpp +++ b/test/dominator_tree_test.cpp @@ -24,13 +24,48 @@ struct DominatorCorrectnessTestSet using namespace boost; -typedef adjacency_list< listS, listS, bidirectionalS, - property< vertex_index_t, std::size_t >, no_property > - G; +// a workaround for the C++ standard before C++17, after switching to C++17, +// the method may be just inlined into the run_test() with constexpr if. +namespace detail { -int main(int, char*[]) +template < bool IsRandomAccessAdjacentList = true> +struct GraphIndexer { + template + static void index_graph(Graph &g) { + // nothing to do for already indexed adjacent list + } +}; + +template <> +struct GraphIndexer { + template + static void index_graph(Graph &g) { + using IndexMap = typename property_map< Graph, vertex_index_t >::type; + IndexMap indexMap(get(vertex_index, g)); + typename graph_traits< Graph >::vertex_iterator uItr, uEnd; + int j = 0; + for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr, ++j) + { + put(indexMap, *uItr, j); + } + } +}; + +} // namespace detail + +template < typename Graph > +void index_graph(Graph &g) { + using Traits = adjacency_list_traits< typename Graph::out_edge_list_selector, + typename Graph::vertex_list_selector, + typename Graph::directed_selector, + typename Graph::edge_list_selector >; + ::detail::GraphIndexer< Traits::is_rand_access::value >::index_graph(g); +} + +template < typename Graph > +void run_test() { - typedef DominatorCorrectnessTestSet::edge edge; + using edge = DominatorCorrectnessTestSet::edge; DominatorCorrectnessTestSet testSet[7]; @@ -217,34 +252,32 @@ int main(int, char*[]) { const int numOfVertices = testSet[i].numOfVertices; - G g(testSet[i].edges.begin(), testSet[i].edges.end(), numOfVertices); + Graph g(testSet[i].edges.begin(), testSet[i].edges.end(), numOfVertices); - typedef graph_traits< G >::vertex_descriptor Vertex; - typedef property_map< G, vertex_index_t >::type IndexMap; - typedef iterator_property_map< vector< Vertex >::iterator, IndexMap > - PredMap; + using Vertex = typename graph_traits< Graph >::vertex_descriptor; + using IndexMap = typename property_map< Graph, vertex_index_t >::type; + IndexMap indexMap(get(vertex_index, g)); + using PredMap + = iterator_property_map< typename vector< Vertex >::iterator, IndexMap >; + + index_graph(g); vector< Vertex > domTreePredVector, domTreePredVector2; - IndexMap indexMap(get(vertex_index, g)); - graph_traits< G >::vertex_iterator uItr, uEnd; - int j = 0; - for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr, ++j) - { - put(indexMap, *uItr, j); - } // Lengauer-Tarjan dominator tree algorithm domTreePredVector = vector< Vertex >( - num_vertices(g), graph_traits< G >::null_vertex()); + num_vertices(g), graph_traits< Graph >::null_vertex()); PredMap domTreePredMap = make_iterator_property_map(domTreePredVector.begin(), indexMap); lengauer_tarjan_dominator_tree(g, vertex(0, g), domTreePredMap); vector< int > idom(num_vertices(g)); + typename graph_traits< Graph >::vertex_iterator uItr, uEnd; for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr) { - if (get(domTreePredMap, *uItr) != graph_traits< G >::null_vertex()) + if (get(domTreePredMap, *uItr) + != graph_traits< Graph >::null_vertex()) idom[get(indexMap, *uItr)] = get(indexMap, get(domTreePredMap, *uItr)); else @@ -260,7 +293,7 @@ int main(int, char*[]) // compare results of fast version and slow version of dominator tree domTreePredVector2 = vector< Vertex >( - num_vertices(g), graph_traits< G >::null_vertex()); + num_vertices(g), graph_traits< Graph >::null_vertex()); domTreePredMap = make_iterator_property_map(domTreePredVector2.begin(), indexMap); @@ -269,7 +302,8 @@ int main(int, char*[]) vector< int > idom2(num_vertices(g)); for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr) { - if (get(domTreePredMap, *uItr) != graph_traits< G >::null_vertex()) + if (get(domTreePredMap, *uItr) + != graph_traits< Graph >::null_vertex()) idom2[get(indexMap, *uItr)] = get(indexMap, get(domTreePredMap, *uItr)); else @@ -283,6 +317,17 @@ int main(int, char*[]) for (k = 0; k < num_vertices(g); ++k) BOOST_TEST(domTreePredVector[k] == domTreePredVector2[k]); } +} + +int main(int, char*[]) +{ + using AdjacencyListList = adjacency_list< listS, listS, bidirectionalS, + property< vertex_index_t, std::size_t >, no_property >; + + using AdjacencyListVec = adjacency_list< listS, vecS, bidirectionalS >; + + run_test< AdjacencyListList >(); + run_test< AdjacencyListVec >(); return boost::report_errors(); } From e936b093409593473a636632123462d6512aceb8 Mon Sep 17 00:00:00 2001 From: Pavel Samolysov Date: Sat, 1 Mar 2025 16:29:06 +0300 Subject: [PATCH 6/8] Add a test case for adjacency_matrix --- test/dominator_tree_test.cpp | 64 ++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/test/dominator_tree_test.cpp b/test/dominator_tree_test.cpp index bc17a9f8..2b53b948 100644 --- a/test/dominator_tree_test.cpp +++ b/test/dominator_tree_test.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include using namespace std; @@ -26,40 +27,43 @@ using namespace boost; // a workaround for the C++ standard before C++17, after switching to C++17, // the method may be just inlined into the run_test() with constexpr if. -namespace detail { +namespace detail +{ -template < bool IsRandomAccessAdjacentList = true> -struct GraphIndexer { - template - static void index_graph(Graph &g) { - // nothing to do for already indexed adjacent list - } -}; +template < typename Graph > +void index_graph(Graph&, std::true_type /*IsRandomAccessAdjacentList*/) +{ + // nothing to do for already indexed adjacent list +} -template <> -struct GraphIndexer { - template - static void index_graph(Graph &g) { - using IndexMap = typename property_map< Graph, vertex_index_t >::type; - IndexMap indexMap(get(vertex_index, g)); - typename graph_traits< Graph >::vertex_iterator uItr, uEnd; - int j = 0; - for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr, ++j) - { - put(indexMap, *uItr, j); - } +template < typename Graph > +void index_graph(Graph& g, std::false_type /*IsRandomAccessAdjacentList*/) +{ + using IndexMap = typename property_map< Graph, vertex_index_t >::type; + IndexMap indexMap(get(vertex_index, g)); + typename graph_traits< Graph >::vertex_iterator uItr, uEnd; + int j = 0; + for (boost::tie(uItr, uEnd) = vertices(g); uItr != uEnd; ++uItr, ++j) + { + put(indexMap, *uItr, j); } -}; +} } // namespace detail -template < typename Graph > -void index_graph(Graph &g) { - using Traits = adjacency_list_traits< typename Graph::out_edge_list_selector, - typename Graph::vertex_list_selector, - typename Graph::directed_selector, - typename Graph::edge_list_selector >; - ::detail::GraphIndexer< Traits::is_rand_access::value >::index_graph(g); +template < typename OEL, typename VL, typename D, typename VP, typename EP, + typename GP, typename EL > +void index_graph(adjacency_list< OEL, VL, D, VP, EP, GP, EL >& g) +{ + using Traits = adjacency_list_traits< OEL, VL, D, EL >; + ::detail::index_graph( + g, std::integral_constant< bool, Traits::is_rand_access::value > {}); +} + +template < typename D, typename VP, typename EP, typename GP, typename A > +void index_graph(adjacency_matrix&) +{ + // nothing to do for already indexed adjacent matrix } template < typename Graph > @@ -317,6 +321,7 @@ void run_test() for (k = 0; k < num_vertices(g); ++k) BOOST_TEST(domTreePredVector[k] == domTreePredVector2[k]); } + cout << endl; } int main(int, char*[]) @@ -326,8 +331,11 @@ int main(int, char*[]) using AdjacencyListVec = adjacency_list< listS, vecS, bidirectionalS >; + using AdjacencyMatrix = adjacency_matrix< directedS >; + run_test< AdjacencyListList >(); run_test< AdjacencyListVec >(); + run_test< AdjacencyMatrix >(); return boost::report_errors(); } From 57058f091aa02c4c5ee179e905c2a6ddccac85b5 Mon Sep 17 00:00:00 2001 From: Pavel Samolysov Date: Sat, 1 Mar 2025 17:05:04 +0300 Subject: [PATCH 7/8] Combine the preds_of_n's components update into a whole --- include/boost/graph/dominator_tree.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/boost/graph/dominator_tree.hpp b/include/boost/graph/dominator_tree.hpp index d78e0e0c..d89d6bbe 100644 --- a/include/boost/graph/dominator_tree.hpp +++ b/include/boost/graph/dominator_tree.hpp @@ -150,13 +150,11 @@ namespace detail s = s2; } auto& preds_of_n = get(predsMap_, n); - preds_of_n.semi = s; + preds_of_n = {s, p, n}; // 2. Calculation of n's dominator is deferred until // the path from s to n has been linked into the forest get(bucketMap_, s).push_back(n); - preds_of_n.ancestor = p; - preds_of_n.best = n; // 3. Now that the path from p to v has been linked into // the spanning forest, these lines calculate the dominator of v, From 7b04334601349805f3ea6881f3f872a742c58c4a Mon Sep 17 00:00:00 2001 From: Pavel Samolysov Date: Tue, 4 Mar 2025 13:43:27 +0300 Subject: [PATCH 8/8] Rename preds -> pred --- include/boost/graph/dominator_tree.hpp | 36 +++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/include/boost/graph/dominator_tree.hpp b/include/boost/graph/dominator_tree.hpp index d89d6bbe..afe741fc 100644 --- a/include/boost/graph/dominator_tree.hpp +++ b/include/boost/graph/dominator_tree.hpp @@ -95,8 +95,8 @@ namespace detail */ dominator_visitor(const Graph& g, const Vertex& entry, const IndexMap& indexMap, DomTreePredMap domTreePredMap) - : preds_(num_vertices(g)) - , predsMap_(make_iterator_property_map(preds_.begin(), indexMap)) + : pred_(num_vertices(g)) + , predMap_(make_iterator_property_map(pred_.begin(), indexMap)) , samedom_(num_vertices(g), graph_traits< Graph >::null_vertex()) , buckets_(num_vertices(g)) , bucketMap_(make_iterator_property_map(buckets_.begin(), indexMap)) @@ -143,14 +143,14 @@ namespace detail if (get(dfnumMap, v) <= get(dfnumMap, n)) s2 = v; else - s2 = get(predsMap_, ancestor_with_lowest_semi_(v, dfnumMap)) + s2 = get(predMap_, ancestor_with_lowest_semi_(v, dfnumMap)) .semi; if (get(dfnumMap, s2) < get(dfnumMap, s)) s = s2; } - auto& preds_of_n = get(predsMap_, n); - preds_of_n = {s, p, n}; + auto& pred_of_n = get(predMap_, n); + pred_of_n = {s, p, n}; // 2. Calculation of n's dominator is deferred until // the path from s to n has been linked into the forest @@ -172,7 +172,7 @@ namespace detail { const Vertex v(*buckItr); const Vertex y(ancestor_with_lowest_semi_(v, dfnumMap)); - if (get(predsMap_, y).semi == get(predsMap_, v).semi) + if (get(predMap_, y).semi == get(predMap_, v).semi) put(domTreePredMap_, v, p); else put(samedomMap, v, y); @@ -188,30 +188,30 @@ namespace detail const Vertex ancestor_with_lowest_semi_( const Vertex& v, const TimeMap& dfnumMap) { - const Vertex a(get(predsMap_, v).ancestor); - const auto& preds_of_a = get(predsMap_, a); + const Vertex a(get(predMap_, v).ancestor); + const auto& pred_of_a = get(predMap_, a); - auto& preds_of_v = get(predsMap_, v); + auto& pred_of_v = get(predMap_, v); - if (preds_of_a.ancestor != graph_traits< Graph >::null_vertex()) + if (pred_of_a.ancestor != graph_traits< Graph >::null_vertex()) { const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap)); - const auto& preds_of_b = get(predsMap_, b); + const auto& pred_of_b = get(predMap_, b); - preds_of_v.ancestor = preds_of_a.ancestor; + pred_of_v.ancestor = pred_of_a.ancestor; - if (get(dfnumMap, preds_of_b.semi) - < get(dfnumMap, get(predsMap_, preds_of_v.best).semi)) - preds_of_v.best = b; + if (get(dfnumMap, pred_of_b.semi) + < get(dfnumMap, get(predMap_, pred_of_v.best).semi)) + pred_of_v.best = b; } - return preds_of_v.best; + return pred_of_v.best; } - std::vector< vertex_triple< Graph > > preds_; + std::vector< vertex_triple< Graph > > pred_; iterator_property_map< typename std::vector< vertex_triple< Graph > >::iterator, IndexMap > - predsMap_; + predMap_; std::vector< Vertex > samedom_; std::vector< std::vector< Vertex > > buckets_;