Ticket #7863: graphing.cpp

File graphing.cpp, 4.2 KB (added by anonymous, 10 years ago)
Line 
1
2#include <boost/graph/graph_traits.hpp>
3#include <boost/graph/adjacency_list.hpp>
4#include <boost/graph/topological_sort.hpp>
5
6
7class Op
8{
9 const char *mName;
10public:
11 Op( const char *s ) : mName(s) {}
12 const char* name() const { return mName; }
13};
14
15struct OpMapper
16{
17 Op *op;
18 OpMapper( Op *o = NULL ) : op(o) {}
19};
20
21namespace boost { namespace graph {
22
23 template <typename T>
24 struct vertex_name_extractor
25 {
26 typedef T type;
27 typedef Op* result_type;
28 const result_type operator() ( const T& v ) const
29 {
30 return v.me;
31 }
32 };
33
34 template<typename VertexProperty>
35 struct vertex_info_constructor
36 {
37 typedef VertexProperty return_type;
38 typedef typename vertex_name_extractor<VertexProperty>::result_type argument_type;
39 return_type operator()( argument_type n )
40 {
41 return VertexProperty(n);
42 }
43 };
44
45 template<> struct internal_vertex_name<OpMapper>
46 { typedef multi_index::member<OpMapper, Op*, &OpMapper::op> type; };
47
48 template<> struct internal_vertex_constructor<OpMapper>
49 { typedef vertex_info_constructor<OpMapper> type; };
50
51} }
52
53
54class BoostGraph
55{
56 typedef boost::adjacency_list<boost::setS, boost::vecS, boost::bidirectionalS, OpMapper> graph_t;
57 typedef boost::graph_traits<graph_t>::vertex_descriptor Vertex;
58 typedef boost::graph_traits<graph_t>::edge_descriptor Edge;
59 typedef boost::graph_traits<graph_t>::in_edge_iterator Iterator;
60
61 graph_t mGraph;
62
63 bool removeVertexIfEmpty( const Vertex &v )
64 {
65 if ( boost::degree(v, mGraph)==0 && boost::out_degree(v, mGraph)==0 )
66 {
67 OpMapper &op = mGraph[v];
68 printf("removeVert: %s (%p,%lu)\n", op.op->name(), op.op, v);
69 boost::clear_vertex(v, mGraph);
70 boost::remove_vertex(v, mGraph);
71 return true;
72 }
73 return false;
74 }
75
76 void _printInputs( const Vertex &v )
77 {
78 Op *dst = mGraph[v].op;
79 Iterator vi, ve;
80 for ( boost::tie(vi,ve) = boost::in_edges(v, mGraph); vi != ve; ++vi )
81 {
82 const Vertex dv = source(*vi, mGraph);
83 Op *src = mGraph[dv].op;
84 printf("inedge: %s (%p,%lu) -> %s (%p,%lu)\n", src->name(), src, size_t(v), dst?dst->name():"!NULL!", dst, size_t(dv));
85 }
86 }
87
88 void printInputs( const Vertex &v )
89 {
90 _printInputs(v);
91 printf("---------------------------------\n");
92 }
93
94public:
95 void connect( Op &from, Op &to )
96 {
97 const Vertex u = boost::graph::add_vertex(&from, mGraph), v = boost::graph::add_vertex(&to, mGraph);
98 if ( boost::edge(u, v, mGraph).second==false )
99 {
100 boost::add_edge(u, v, mGraph);
101 printInputs(v);
102 }
103 }
104
105 void disconnect( Op &from, Op &to )
106 {
107 boost::optional<Vertex> fv = boost::graph::find_vertex(&from, mGraph);
108 if ( fv )
109 {
110 const boost::optional<Vertex> tv = boost::graph::find_vertex(&to, mGraph);
111 if ( tv )
112 {
113 printf("disconnect: %s (%p,%lu) -> %s (%p,%lu)\n", from.name(), &from, *fv, to.name(), &to, *tv);
114 boost::remove_edge(*fv, *tv, mGraph);
115 if ( removeVertexIfEmpty(*tv) )
116 {
117 // fv invalid now ?
118 fv = boost::graph::find_vertex(&from, mGraph);
119 if ( fv ) removeVertexIfEmpty(*fv);
120
121 printInputs(*tv);
122 return;
123 }
124 printInputs(*tv);
125 }
126 removeVertexIfEmpty(*fv);
127 }
128 }
129
130 void dumpInputs( const Vertex &v )
131 {
132 Iterator vi, ve;
133 for ( boost::tie(vi,ve) = boost::in_edges(v, mGraph); vi != ve; ++vi )
134 dumpInputs( source(*vi, mGraph) );
135
136 _printInputs(v);
137 }
138
139 void printInputs( Op &op )
140 {
141 printf("-------------- tree -------------------\n");
142 dumpInputs( *boost::graph::find_vertex(&op, mGraph) );
143 }
144};
145
146extern "C" int main( int argc, const char **argv )
147{
148 Op a("a"), b("b"), c("c"), d("d");
149 BoostGraph bg;
150
151 bg.connect(c, d);
152
153 // Swapping these two lines should have no affect...but it does
154 // BoostGraph::connect calling boost::graph::add_vertex is giving bad vertex ids
155 bg.connect(a, b);
156 bg.disconnect(c, d);
157
158 bg.connect(c, b);
159 bg.connect(b, d);
160
161 bg.printInputs(d);
162
163 return 0;
164}