diff --git a/src/util/graph.h b/src/util/graph.h index 6ef7976ad0a..11b7b98af2f 100644 --- a/src/util/graph.h +++ b/src/util/graph.h @@ -19,6 +19,9 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include + +#include "invariant.h" class empty_edget { @@ -226,6 +229,13 @@ class grapht // return value: number of SCCs std::size_t SCCs(std::vector &subgraph_nr); + bool is_dag() const + { + return empty() || !topsort().empty(); + } + + std::list topsort() const; + void output_dot(std::ostream &out) const; void output_dot_node(std::ostream &out, node_indext n) const; @@ -570,6 +580,52 @@ void grapht::make_chordal() } } +/// Find a topological order of the nodes if graph is DAG, return empty list for +/// non-DAG or empty graph. Uses Kahn's algorithm running in O(#edges+#nodes). +template +std::list::node_indext> grapht::topsort() const +{ + // list of topologically sorted nodes + std::list nodelist; + // queue of working set nodes with in-degree zero + std::queue indeg0_nodes; + // in-degree for each node + std::vector in_deg(nodes.size(), 0); + + // abstract graph as in-degree of each node + for(node_indext idx=0; idx void grapht::output_dot(std::ostream &out) const {