19
19
#include < list>
20
20
#include < map>
21
21
#include < queue>
22
+ #include < sstream>
22
23
#include < stack>
23
24
#include < vector>
24
25
@@ -60,6 +61,39 @@ class graph_nodet
60
61
{
61
62
out.erase (n);
62
63
}
64
+
65
+ private:
66
+ // / \brief Node with attributes suitable for Graphviz DOT format
67
+ // /
68
+ // / Derived types may override this function to produce more informative DOT
69
+ // / diagrams than the default implementation, which displays only the node
70
+ // / index. The return value should be a list of node attributes within square
71
+ // / brackets that can be parsed by `dot`. Here is a sample implementation for
72
+ // / a fictional node type with `is_evil()` and `is_pink()` functions:
73
+ // /
74
+ // / std::stringstream ss;
75
+ // / ss << "[shape=\"" << is_evil() ? "box" : "diamond"
76
+ // / << "\", color=\"" << is_pink() ? "#e91e63" : "#9c27b0"
77
+ // / << "\", label=\"this is node " << std::to_string(idx)
78
+ // / << "\"]";
79
+ // / return ss.str();
80
+ // /
81
+ virtual std::string dot_attributes (const node_indext &idx) const
82
+ {
83
+ return " " ;
84
+ }
85
+
86
+ public:
87
+ std::string pretty (const node_indext &idx) const
88
+ {
89
+ std::stringstream ss;
90
+ ss << std::to_string (idx) << " " << dot_attributes (idx);
91
+ return ss.str ();
92
+ }
93
+
94
+ virtual ~graph_nodet ()
95
+ {
96
+ }
63
97
};
64
98
65
99
// / A node type with an extra bit
@@ -877,9 +911,11 @@ void output_dot_generic(
877
911
const std::function<
878
912
void(const node_index_type &, std::function<void (const node_index_type &)>)>
879
913
&for_each_succ,
880
- const std::function<std::string(const node_index_type &)> node_to_string)
914
+ const std::function<std::string(const node_index_type &)> node_to_string,
915
+ const std::function<std::string(const node_index_type &)> node_to_pretty)
881
916
{
882
917
for_each_node ([&](const node_index_type &i) {
918
+ out << node_to_pretty (i) << " ;\n " ;
883
919
for_each_succ (i, [&](const node_index_type &n) {
884
920
out << node_to_string (i) << " -> " << node_to_string (n) << ' \n ' ;
885
921
});
@@ -914,7 +950,7 @@ template <class N>
914
950
void grapht<N>::output_dot(std::ostream &out) const
915
951
{
916
952
const auto for_each_node =
917
- [& ](const std::function<void (const node_indext &)> &f) {
953
+ [this ](const std::function<void (const node_indext &)> &f) {
918
954
for (node_indext i = 0 ; i < nodes.size (); ++i)
919
955
f (i);
920
956
};
@@ -925,7 +961,11 @@ void grapht<N>::output_dot(std::ostream &out) const
925
961
};
926
962
927
963
const auto to_string = [](const node_indext &i) { return std::to_string (i); };
928
- output_dot_generic<node_indext>(out, for_each_node, for_each_succ, to_string);
964
+ const auto to_pretty_string = [this ](const node_indext &i) {
965
+ return nodes[i].pretty (i);
966
+ };
967
+ output_dot_generic<node_indext>(
968
+ out, for_each_node, for_each_succ, to_string, to_pretty_string);
929
969
}
930
970
931
971
#endif // CPROVER_UTIL_GRAPH_H
0 commit comments