mCRL2
Loading...
Searching...
No Matches
solve_structure_graph.h
Go to the documentation of this file.
1// Author(s): Wieger Wesselink
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
11
12#ifndef MCRL2_PBES_SOLVE_STRUCTURE_GRAPH_H
13#define MCRL2_PBES_SOLVE_STRUCTURE_GRAPH_H
14
16#include "mcrl2/data/join.h"
20
21namespace mcrl2 {
22
23namespace pbes_system {
24
25inline
26std::tuple<std::size_t, std::size_t, vertex_set> get_minmax_rank(const structure_graph& G)
27{
28 std::size_t min_rank = (std::numeric_limits<std::size_t>::max)();
29 std::size_t max_rank = 0;
30 std::vector<structure_graph::index_type> M; // vertices with minimal rank
31 std::size_t N = G.all_vertices().size();
32
33 for (std::size_t vi = 0; vi < N; vi++)
34 {
35 if (!G.contains(vi))
36 {
37 continue;
38 }
39 const auto& v = G.find_vertex(vi);
40 if (v.rank <= min_rank)
41 {
42 if (v.rank < min_rank)
43 {
44 M.clear();
45 min_rank = v.rank;
46 }
47 M.push_back(vi);
48 }
49 if (v.rank > max_rank)
50 {
51 max_rank = v.rank;
52 }
53 }
54 return std::make_tuple(min_rank, max_rank, vertex_set(N, M.begin(), M.end()));
55}
56
58inline
60{
61 std::regex re("Z(neg|pos)_(\\d+)_.*");
62 std::smatch match;
63 for (const pbes_equation& eqn: pbesspec.equations())
64 {
65 std::string X = eqn.variable().name();
66 if (std::regex_match(X, match, re))
67 {
68 return true;
69 }
70 }
71 return false;
72}
73
75{
76 protected:
77 // do a sanity check on the computed strategy
78 bool check_strategy = false;
79
81
82 // find a successor of u
84 {
86 {
87 return v;
88 }
89 return undefined_vertex();
90 }
91
92 // find a successor of u in U, or a random one if no successor in U exists
93 static inline
95 {
96 auto result = undefined_vertex();
98 {
99 if (U.contains(v))
100 {
101 return v;
102 }
103 result = v;
104 }
105 return result;
106 }
107
108 public:
109 // computes solve_recursive(G \ A)
110 inline
111 std::pair<vertex_set, vertex_set> solve_recursive(structure_graph& G, const vertex_set& A)
112 {
113 auto exclude = G.exclude() | A.include();
114 std::swap(G.exclude(), exclude);
115 auto result = solve_recursive(G);
116 std::swap(G.exclude(), exclude);
117 return result;
118 }
119
120 protected:
121 // pre: G does not contain nodes with decoration true or false.
122 //
123 // N.B. If use_toms_optimization is true, then the oomputed strategy may be incorrect.
124 // So this flag should only be used to compute the solution.
125 inline
126 std::pair<vertex_set, vertex_set> solve_recursive(structure_graph& G)
127 {
128 mCRL2log(log::debug) << "\n --- solve_recursive input ---\n" << G << std::endl;
129 std::size_t N = G.extent();
130
131 if (G.is_empty())
132 {
133 return { vertex_set(N), vertex_set(N) };
134 }
135
136 auto q = get_minmax_rank(G);
137 std::size_t m = std::get<0>(q);
138 const vertex_set& U = std::get<2>(q);
139
140 std::size_t alpha = m % 2; // 0 = disjunctive, 1 = conjunctive
141
142 // set strategy
144 {
145 const auto& u = G.find_vertex(ui);
146 if (u.decoration == alpha)
147 {
148 // auto v = succ(G, ui); // N.B. this may lead to a wrong strategy!
149 auto v = succ(G, ui, U);
150 if (v != undefined_vertex())
151 {
153// mCRL2log(log::debug) << "set initial strategy for node " << ui << " to " << v << std::endl;
154 }
155 }
156 }
157
158 // // optimization
159 // std::size_t h = std::get<1>(q);
160 // if (h == m)
161 // {
162 // if (m % 2 == 0)
163 // {
164 // return { make_vertex_set(G), vertex_set(N) };
165 // }
166 // else
167 // {
168 // return { vertex_set(N), make_vertex_set(G) };
169 // }
170 // }
171
172 vertex_set W[2] = { vertex_set(N), vertex_set(N) };
173 vertex_set W_1[2];
174
175 vertex_set A = attr_default(G, U, alpha);
176 std::tie(W_1[0], W_1[1]) = solve_recursive(G, A);
177
179 {
180 // More efficient than Zielonka, because some recursive calls are skipped.
181 // As a consequence, the computed strategy may be wrong.
182 vertex_set B = attr_default(G, W_1[1 - alpha], 1 - alpha);
183 if (W_1[1 - alpha].size() == B.size())
184 {
185 W[alpha] = set_union(A, W_1[alpha]);
186 W[1 - alpha] = B;
187 }
188 else
189 {
190 std::tie(W[0], W[1]) = solve_recursive(G, B);
191 W[1 - alpha] = set_union(W[1 - alpha], B);
192 }
193 }
194 else
195 {
196 // Original Zielonka version
197 if (W_1[1 - alpha].is_empty())
198 {
199 W[alpha] = set_union(A, W_1[alpha]);
200 W[1 - alpha].clear();
201 }
202 else
203 {
204 vertex_set B = attr_default(G, W_1[1 - alpha], 1 - alpha);
205 std::tie(W[0], W[1]) = solve_recursive(G, B);
206 W[1 - alpha] = set_union(W[1 - alpha], B);
207 }
208 }
209
210 mCRL2log(log::debug) << "\n --- solution for solve_recursive input ---\n" << G;
211 mCRL2log(log::debug) << " W0 = " << W[0] << std::endl;
212 mCRL2log(log::debug) << " W1 = " << W[1] << std::endl;
213 assert(W[0].size() + W[1].size() + G.exclude().count() == N);
214 return { W[0], W[1] };
215 }
216
217 // Handles nodes with decoration true or false.
218 inline
219 std::pair<vertex_set, vertex_set> solve_recursive_extended(structure_graph& G)
220 {
221 mCRL2log(log::debug) << "\n --- solve_recursive_extended input ---\n" << G << std::endl;
222
223 std::size_t N = G.extent();
224 vertex_set Vconj(N);
225 vertex_set Vdisj(N);
226
227 // find vertices Vconj with decoration false and Vdisj with decoration true
228 for (std::size_t vi = 0; vi < N; vi++)
229 {
230 if (!G.contains(vi))
231 {
232 continue;
233 }
234 const auto& v = G.find_vertex(vi);
235 if (v.decoration == structure_graph::d_false)
236 {
237 Vconj.insert(vi);
238 }
239 else if (v.decoration == structure_graph::d_true)
240 {
241 Vdisj.insert(vi);
242 }
243 }
244
245 // extend Vconj and Vdisj
246 if (!Vconj.is_empty())
247 {
248 Vconj = attr_default(G, Vconj, 1);
249 }
250 if (!Vdisj.is_empty())
251 {
252 Vdisj = attr_default(G, Vdisj, 0);
253 }
254
255 // default case
256 if (Vconj.is_empty() && Vdisj.is_empty())
257 {
258 return solve_recursive(G);
259 }
260 else
261 {
262 vertex_set Wconj(N);
263 vertex_set Wdisj(N);
264 vertex_set Vunion = set_union(Vconj, Vdisj);
265 std::tie(Wdisj, Wconj) = solve_recursive(G, Vunion);
266 return std::make_pair(set_union(Wdisj, Vdisj), set_union(Wconj, Vconj));
267 }
268 }
269
271 {
273 structure_graph::vertex& u = V[ui];
274 structure_graph::vertex& v = V[vi];
275 if (!contains(u.successors, vi))
276 {
277 u.successors.push_back(vi);
278 v.predecessors.push_back(ui);
279 }
280 }
281
283 {
285
286 mCRL2log(log::debug) << "\n--- CHECK STRATEGY ---" << std::endl;
287 log_vertex_set(G, Wconj, "Wconj");
288 log_vertex_set(G, Wdisj, "Wdisj");
289
290 typedef structure_graph::vertex vertex;
292
293 // V contains the vertices of G, but not the edges
295 for (vertex& v: V)
296 {
297 v.successors.clear();
298 v.predecessors.clear();
299 }
300
301 std::set<structure_graph::index_type> todo = { init };
302 std::set<structure_graph::index_type> done;
303
304 while (!todo.empty())
305 {
306 structure_graph::index_type u = *todo.begin();
307 todo.erase(todo.begin());
308 done.insert(u);
310 {
311 // explore only the strategy edge
313 insert_edge(V, u, v);
314 if (v != undefined_vertex() && !contains(done, v))
315 {
316 todo.insert(v);
317 }
318 }
319 else
320 {
321 // explore all outgoing edges
323 {
324 insert_edge(V, u, v);
325 if (!contains(done, v))
326 {
327 todo.insert(v);
328 }
329 }
330 }
331 }
332
333 vertex_set Wconj1;
334 vertex_set Wdisj1;
335
336 structure_graph Gcopy(V, G.initial_vertex(), G.exclude());
337 std::tie(Wdisj1, Wconj1) = solve_recursive_extended(Gcopy);
338 bool is_disjunctive1;
339 if (Wdisj1.contains(G.initial_vertex()))
340 {
341 is_disjunctive1 = true;
342 }
343 else if (Wconj1.contains(G.initial_vertex()))
344 {
345 is_disjunctive1 = false;
346 }
347 else
348 {
349 throw mcrl2::runtime_error("No solution found!!!");
350 }
351 if (is_disjunctive != is_disjunctive1)
352 {
353 log_vertex_set(Gcopy, Wconj1, "Wconj1");
354 log_vertex_set(Gcopy, Wdisj1, "Wdisj1");
355 throw mcrl2::runtime_error("check_solve_recursive_solution failed!");
356 }
357 }
358
359 public:
360 explicit solve_structure_graph_algorithm(bool check_strategy_ = false, bool use_toms_optimization_ = false)
361 : check_strategy(check_strategy_),
362 use_toms_optimization(use_toms_optimization_)
363 {}
364
365 inline
367 {
368 mCRL2log(log::verbose) << "Solving parity game..." << std::endl;
369 mCRL2log(log::debug) << G << std::endl;
370 assert(G.extent() > 0);
371 assert(G.is_defined());
372 auto W = solve_recursive_extended(G);
373 bool is_disjunctive;
374 if (W.first.contains(G.initial_vertex()))
375 {
376 is_disjunctive = true;
377 }
378 else if (W.second.contains(G.initial_vertex()))
379 {
380 is_disjunctive = false;
381 }
382 else
383 {
384 throw mcrl2::runtime_error("No solution found!!!");
385 }
386 if (check_strategy)
387 {
388 check_solve_recursive_solution(G, is_disjunctive, W.first, W.second);
389 }
390 return is_disjunctive;
391 }
392};
393
395{
396 protected:
397 static lps::specification create_counter_example_lps(structure_graph& G, const std::set<structure_graph::index_type>& V, const lps::specification& lpsspec, const pbes& p, const pbes_equation_index& p_index)
398 {
399 lps::specification result = lpsspec;
400 result.process().action_summands().clear();
401 result.process().deadlock_summands().clear();
402 auto& action_summands = result.process().action_summands();
403 std::regex re("Z(neg|pos)_(\\d+)_.*");
404 std::size_t n = lpsspec.process().process_parameters().size();
405
407 {
408 const auto& v = G.find_vertex(vi);
410 {
411 // The variable Z below should be a reference, but this leads to crashes with the GCC compiler (March 2022).
412 // JFG: I think this is a GCC problem, which may resolve itself in due time.
413 const auto Z = atermpp::down_cast<propositional_variable_instantiation>(v.formula());
414 std::string Zname = Z.name();
415 std::smatch match;
416 if (std::regex_match(Zname, match, re))
417 {
418 std::size_t summand_index = std::stoul(match[2]);
419 if (summand_index >= lpsspec.process().action_summands().size())
420 {
421 throw mcrl2::runtime_error("Counter-example cannot be reconstructed from this LPS. Did you supply the correct file?");
422 }
423 lps::action_summand summand = lpsspec.process().action_summands()[summand_index];
424 std::size_t equation_index = p_index.index(Z.name());
425 const pbes_equation& eqn = p.equations()[equation_index];
426 const data::variable_list& d = eqn.variable().parameters();
427 data::variable_vector d1(d.begin(), d.end());
428
429 const data::data_expression_list& e = Z.parameters();
431
433 data::assignment_vector next_state_assignments;
434 std::size_t m = d.size() - 2 * n;
435
436 for (std::size_t i = 0; i < n; i++)
437 {
438 condition.push_back(data::equal_to(d1[i], e1[i]));
439 next_state_assignments.emplace_back(d1[i], e1[n + m + i]);
440 }
441
443 std::size_t index = 0;
444 for (const process::action& a: summand.multi_action().actions())
445 {
446 process::action a1(a.label(), data::data_expression_list(e1.begin() + n + index, e1.begin() + n + index + a.arguments().size()));
447 actions.push_back(a1);
448 index = index + a.arguments().size();
449 }
450
452 summand.condition() = data::join_and(condition.begin(), condition.end());
453 summand.multi_action() = lps::multi_action(process::action_list(actions.begin(), actions.end()),summand.multi_action().time());
454 summand.assignments() = data::assignment_list(next_state_assignments.begin(), next_state_assignments.end());
455
456 action_summands.push_back(summand);
457 }
458 }
459 }
460 return result;
461 }
462
463 public:
465
472 std::pair<bool, lps::specification> solve_with_counter_example(structure_graph& G, const lps::specification& lpsspec, const pbes& p, const pbes_equation_index& p_index)
473 {
474 if (!lpsspec.global_variables().empty())
475 {
476 throw mcrl2::runtime_error("solve_with_counter_example requires an LPS without global variables.");
477 }
478 if (!p.global_variables().empty())
479 {
480 throw mcrl2::runtime_error("solve_with_counter_example requires a PBES without global variables.");
481 }
482
483 mCRL2log(log::verbose) << "Solving parity game..." << std::endl;
484 vertex_set Wconj;
485 vertex_set Wdisj;
486 std::tie(Wdisj, Wconj) = solve_recursive_extended(G);
488
489 mCRL2log(log::verbose) << "Extracting evidence..." << std::endl;
490 std::set<structure_graph::index_type> W = extract_minimal_structure_graph(G, init, Wdisj, Wconj);
491 return { Wdisj.contains(init), create_counter_example_lps(G, W, lpsspec, p, p_index) };
492 }
493};
494
496{
497 protected:
498 // Removes all transitions from ltsspec, except the ones in transition_indices.
499 // After that, the unreachable parts of the LTS are removed.
500 static inline
501 void filter_transitions(lts::lts_lts_t& ltsspec, const std::set<std::size_t>& transition_indices)
502 {
503 // remove transitions
504 const auto& lts_transitions = ltsspec.get_transitions();
505 std::vector<lts::transition> transitions;
506 for (std::size_t i: transition_indices)
507 {
508 if (i >= lts_transitions.size())
509 {
510 throw mcrl2::runtime_error("Counter-example cannot be reconstructed from this LTS. Did you supply the correct file?");
511 }
512 transitions.push_back(lts_transitions[i]);
513 }
514 ltsspec.get_transitions() = transitions;
515
516 // remove unreachable states
517 lts::reachability_check(ltsspec, true);
518 }
519
520 // modifies ltsspec
521 static inline
522 void create_counter_example_lts(structure_graph& G, const std::set<structure_graph::index_type>& V, lts::lts_lts_t& ltsspec)
523 {
524 std::regex re("Z(neg|pos)_(\\d+)_.*");
525
526 std::set<std::size_t> transition_indices;
528 {
529 const auto& v = G.find_vertex(vi);
531 {
532 const propositional_variable_instantiation& Z = atermpp::down_cast<propositional_variable_instantiation>(v.formula());
533 std::string Zname = Z.name();
534 std::smatch match;
535 if (std::regex_match(Zname, match, re))
536 {
537 std::size_t transition_index = std::stoul(match[2]);
538 transition_indices.insert(transition_index);
539 }
540 }
541 }
542 filter_transitions(ltsspec, transition_indices);
543 }
544
545 public:
547
551 inline
553 {
554 mCRL2log(log::verbose) << "Solving parity game..." << std::endl;
555 vertex_set Wconj;
556 vertex_set Wdisj;
557 std::tie(Wdisj, Wconj) = solve_recursive_extended(G);
559
560 mCRL2log(log::verbose) << "Extracting evidence..." << std::endl;
561 std::set<structure_graph::index_type> W = extract_minimal_structure_graph(G, init, Wdisj, Wconj);
562 create_counter_example_lts(G, W, ltsspec);
563 return Wdisj.contains(init);
564 }
565};
566
567inline
568bool solve_structure_graph(structure_graph& G, bool check_strategy = false)
569{
570 bool use_toms_optimization = !check_strategy;
571 solve_structure_graph_algorithm algorithm(check_strategy, use_toms_optimization);
572 return algorithm.solve(G);
573}
574
575inline
576std::pair<bool, lps::specification> solve_structure_graph_with_counter_example(structure_graph& G, const lps::specification& lpsspec, const pbes& p, const pbes_equation_index& p_index)
577{
579 return algorithm.solve_with_counter_example(G, lpsspec, p, p_index);
580}
581
585inline
587{
589 return algorithm.solve_with_counter_example(G, ltsspec);
590}
591
592} // namespace pbes_system
593
594} // namespace mcrl2
595
596#endif // MCRL2_PBES_SOLVE_STRUCTURE_GRAPH_H
size_type size() const
Returns the size of the term_list.
Definition aterm_list.h:256
const_iterator end() const
Returns a const_iterator pointing to the end of the term_list.
Definition aterm_list.h:282
const_iterator begin() const
Returns a const_iterator pointing to the beginning of the term_list.
Definition aterm_list.h:275
std::size_t size() const
Definition vector.h:329
void clear() noexcept
Definition vector.h:129
LPS summand containing a multi-action.
const lps::multi_action & multi_action() const
Returns the multi-action of this summand.
const data::assignment_list & assignments() const
Returns the sequence of assignments.
const std::vector< ActionSummand > & action_summands() const
Returns the sequence of action summands.
const deadlock_summand_vector & deadlock_summands() const
Returns the sequence of deadlock summands.
const data::variable_list & process_parameters() const
Returns the sequence of process parameters.
\brief A timed multi-action
const process::action_list & actions() const
const data::data_expression & time() const
const std::set< data::variable > & global_variables() const
Returns the declared free variables of the LPS.
const LinearProcess & process() const
Returns the linear process of the specification.
Linear process specification.
const data::data_expression & condition() const
Returns the condition expression.
Definition summand.h:60
data::variable_list & summation_variables()
Returns the sequence of summation variables.
Definition summand.h:46
This class contains labelled transition systems in .lts format.
Definition lts_lts.h:385
const std::vector< transition > & get_transitions() const
Gets a const reference to the vector of transitions of the current lts.
Definition lts.h:545
Maps variables to their corresponding equations in a boolean_equation_system or PBES.
std::pair< bool, lps::specification > solve_with_counter_example(structure_graph &G, const lps::specification &lpsspec, const pbes &p, const pbes_equation_index &p_index)
Solve a pbes for some equation, while constructing a counter example or wittness based on the accompa...
static lps::specification create_counter_example_lps(structure_graph &G, const std::set< structure_graph::index_type > &V, const lps::specification &lpsspec, const pbes &p, const pbes_equation_index &p_index)
static void filter_transitions(lts::lts_lts_t &ltsspec, const std::set< std::size_t > &transition_indices)
bool solve_with_counter_example(structure_graph &G, lts::lts_lts_t &ltsspec)
Solve a boolean equation system while generating a counter example.
static void create_counter_example_lts(structure_graph &G, const std::set< structure_graph::index_type > &V, lts::lts_lts_t &ltsspec)
const propositional_variable & variable() const
Returns the pbes variable of the equation.
parameterized boolean equation system
Definition pbes.h:58
const std::set< data::variable > & global_variables() const
Returns the declared free variables of the pbes.
Definition pbes.h:178
const std::vector< pbes_equation > & equations() const
Returns the equations.
Definition pbes.h:164
\brief A propositional variable instantiation
const data::variable_list & parameters() const
std::pair< vertex_set, vertex_set > solve_recursive(structure_graph &G, const vertex_set &A)
static void insert_edge(structure_graph::vertex_vector &V, structure_graph::index_type ui, structure_graph::index_type vi)
solve_structure_graph_algorithm(bool check_strategy_=false, bool use_toms_optimization_=false)
static structure_graph::index_type succ(const structure_graph &G, structure_graph::index_type u)
void check_solve_recursive_solution(const structure_graph &G, bool is_disjunctive, const vertex_set &Wdisj, const vertex_set &Wconj)
std::pair< vertex_set, vertex_set > solve_recursive(structure_graph &G)
static structure_graph::index_type succ(const structure_graph &G, structure_graph::index_type u, const vertex_set &U)
std::pair< vertex_set, vertex_set > solve_recursive_extended(structure_graph &G)
const boost::dynamic_bitset & exclude() const
const vertex_vector & all_vertices() const
boost::filtered_range< integers_not_contained_in, const std::vector< index_type > > successors(index_type u) const
bool contains(index_type u) const
index_type strategy(index_type u) const
decoration_type decoration(index_type u) const
Standard exception class for reporting runtime errors.
Definition exception.h:27
Join and split functions for data expressions.
MCRL2_EXPORT bool init(rewriter_interface *i, RewriterCompilingJitty *this_rewriter)
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:391
Algorithms for LTS, such as equivalence reductions, determinisation, etc.
std::vector< assignment > assignment_vector
\brief vector of assignments
Definition assignment.h:149
std::vector< variable > variable_vector
\brief vector of variables
Definition variable.h:89
std::vector< data_expression > data_expression_vector
\brief vector of data_expressions
atermpp::term_list< variable > variable_list
\brief list of variables
atermpp::term_list< assignment > assignment_list
\brief list of assignments
Definition assignment.h:146
function_symbol equal_to(const sort_expression &s)
Constructor for function symbol ==.
Definition standard.h:126
data_expression join_and(FwdIt first, FwdIt last)
Returns and applied to the sequence of data expressions [first, last)
Definition join.h:40
@ verbose
Definition logger.h:37
bool reachability_check(lts< SL, AL, BASE > &l, bool remove_unreachable=false)
Checks whether all states in this LTS are reachable from the initial state and remove unreachable sta...
constexpr unsigned int undefined_vertex()
bool solve_structure_graph(structure_graph &G, bool check_strategy=false)
bool has_counter_example_information(const pbes &pbesspec)
Guesses if a pbes has counter example information.
vertex_set attr_default(const StructureGraph &G, vertex_set A, std::size_t alpha)
bool is_disjunctive(const pbes_expression &x)
vertex_set set_union(const vertex_set &V, const vertex_set &W)
std::pair< bool, lps::specification > solve_structure_graph_with_counter_example(structure_graph &G, const lps::specification &lpsspec, const pbes &p, const pbes_equation_index &p_index)
std::tuple< std::size_t, std::size_t, vertex_set > get_minmax_rank(const structure_graph &G)
std::set< structure_graph::index_type > extract_minimal_structure_graph(StructureGraph &G, typename StructureGraph::index_type init, const vertex_set &S0, const vertex_set &S1)
void log_vertex_set(const StructureGraph &G, const vertex_set &V, const std::string &name)
bool is_propositional_variable_instantiation(const atermpp::aterm &x)
std::vector< action > action_vector
\brief vector of actions
bool contains(const atermpp::indexed_set< Key, ThreadSafe, Hash, Equals, Allocator, KeyTable > &c, const typename atermpp::indexed_set< Key, ThreadSafe, Hash, Equals, Allocator, KeyTable >::key_type &v, const std::size_t thread_index=0)
Definition indexed_set.h:86
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
void swap(atermpp::unprotected_aterm_core &t1, atermpp::unprotected_aterm_core &t2) noexcept
Swaps two aterms.
Definition aterm.h:462
add your file description here.
add your file description here.
void set_strategy(structure_graph::index_type u, structure_graph::index_type v)
std::size_t index(const core::identifier_string &name) const
Returns the index of the equation of the variable with the given name.
void insert(structure_graph::index_type u)
bool contains(structure_graph::index_type u) const
const std::vector< structure_graph::index_type > & vertices() const
const boost::dynamic_bitset & include() const