File 1911-digraph_utils-use-strong-components-for-roots-not-ju.patch of Package erlang
From 10fb9c5e74be5b7731d205af25220fe54d61cc6f Mon Sep 17 00:00:00 2001
From: Richard Carlsson <carlsson.richard@gmail.com>
Date: Mon, 5 Jan 2026 11:47:27 +0100
Subject: [PATCH] digraph_utils: use strong components for roots, not just
components
Selecting a random node of a component as root may start in a dead end,
so that the rest of the component is not traversed. The root selection
needs to use cyclic strong components.
---
lib/stdlib/src/digraph_utils.erl | 2 +-
lib/stdlib/test/digraph_utils_SUITE.erl | 14 ++++++++++++--
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/lib/stdlib/src/digraph_utils.erl b/lib/stdlib/src/digraph_utils.erl
index 935b3bae3e..57a0269cf8 100644
--- a/lib/stdlib/src/digraph_utils.erl
+++ b/lib/stdlib/src/digraph_utils.erl
@@ -419,7 +419,7 @@ postorder(G) ->
roots(G) ->
R1 = [V || V <- digraph:vertices(G), digraph:in_degree(G, V) =:= 0],
- R2 = [X || [X|_] <- components(G)],
+ R2 = [X || [X|_] <- cyclic_strong_components(G)],
R1 ++ R2.
forest(G, SF) ->
diff --git a/lib/stdlib/test/digraph_utils_SUITE.erl b/lib/stdlib/test/digraph_utils_SUITE.erl
index dbed1b9f17..d1961e809c 100644
--- a/lib/stdlib/test/digraph_utils_SUITE.erl
+++ b/lib/stdlib/test/digraph_utils_SUITE.erl
@@ -31,7 +31,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2]).
--export([simple/1, loop/1, isolated/1, topsort/1, subgraph/1,
+-export([simple/1, loop/1, roots/1, isolated/1, topsort/1, subgraph/1,
condensation/1, tree/1, traversals/1]).
@@ -40,7 +40,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [simple, loop, isolated, topsort, subgraph,
+ [simple, loop, roots, isolated, topsort, subgraph,
condensation, tree, traversals].
groups() ->
@@ -97,6 +97,15 @@ simple(Config) when is_list(Config) ->
true = digraph:delete(G),
ok.
+roots(Config) when is_list(Config) ->
+ G = digraph:new(),
+ add_vertices(G, [a]),
+ add_edges(G, [{a,b},{b,c},{c,a},{c,d},{j,j},{j,k},{j,l}]),
+ 7 = length(digraph_utils:postorder(G)),
+ 7 = length(digraph_utils:preorder(G)),
+ true = digraph:delete(G),
+ ok.
+
loop(Config) when is_list(Config) ->
G = digraph:new(),
add_vertices(G, [a,b]),
@@ -145,6 +154,7 @@ topsort(Config) when is_list(Config) ->
subgraph(Config) when is_list(Config) ->
G = digraph:new([acyclic]),
+ %% note: edges {g,e}, {h,h}, {i,i} get discarded due to acyclicity
add_edges(G, [{b,c},{b,d},{e,f},{f,fg,fgl,g},{f,fg2,fgl2,g},{g,e},
{h,h},{i,i},{i,j}]),
add_vertices(G, [{b,bl},{f,fl}]),
--
2.51.0