-
Notifications
You must be signed in to change notification settings - Fork 10
subgraph of an transitive closure fails #39
Description
Description:
I am trying to extract a subgraph from the non-reflexive transitive closure of a directed graph.
This subgraph is defined by a set of vertices with a specific attribute.
No other modifications will be made afterwards – I am only extracting the subgraph.
Issue:
The function transitive_closure returns a Graph::TransitiveClosure object. The subgraph function calls the constructor of the graph with no parameters. The constructor of Graph::TransitiveClosure requires a graph object and fails because no parameters are passed.
I can work around this by blessing the Graph::TransitiveClosure object to a Graph before calling the subgraph function.
However, this feels like a hack, so I am asking for your help to find a better way of doing this. Would you consider supporting subgraphs of transitive closures?
How to reproduce:
perl -e 'use Graph; use Graph::TransitiveClosure; Graph->new->transitive_closure->subgraph([]);'
Use of uninitialized value $g in concatenation (.) or string at /usr/share/perl5/Graph/TransitiveClosure.pm line 17.
Graph::TransitiveClosure->new given non-Graph '' at /usr/share/perl5/Graph.pm line 7.
Graph::__carp_confess("Graph::TransitiveClosure->new given non-Graph ''") called at /usr/share/perl5/Graph/TransitiveClosure.pm line 17
Graph::TransitiveClosure::new(Graph::TransitiveClosure=ARRAY(0x56fd51a3ee78)) called at /usr/share/perl5/Graph.pm line 1223
Graph::subgraph(Graph::TransitiveClosure=ARRAY(0x56fd51a3ee78), ARRAY(0x56fd515fe3e8)) called at -e line 1
A simple example script:
#!/usr/bin/perl
use strict;
use warnings;
use Graph;
my $g = Graph->new(directed => 1);
$g->add_vertex('A');
$g->add_vertex('B');
$g->add_vertex('C');
$g->add_edge('A', 'B');
$g->add_edge('B', 'C');
$g->set_vertex_attribute('A', 'green', 1);
$g->set_vertex_attribute('B', 'green', 0);
$g->set_vertex_attribute('C', 'green', 1);
my $tc = $g->transitive_closure(reflexive => 0);
print "\n[Transitive Closure]\n";
for my $v (grep {$tc->successors($_)} $tc->vertices) {
print "$v -> ", join(', ', $tc->successors($v)), "\n";
}
my @vertices = grep { $g->get_vertex_attribute($_, 'green') } $g->vertices;
$tc = bless $tc, 'Graph'; #<-- this is the workaround i want to avoid
my $subg = $tc->subgraph(\@vertices);
print "\n[Subgraph]\n";
for my $v (grep {$subg->successors($_)} $subg->vertices) {
print "$v -> ", join(', ', $subg->successors($v)), "\n";
}
The expected output is:
[Transitive Closure]
A -> C, B
B -> C
[Subgraph]
A -> C