mCRL2
Loading...
Searching...
No Matches
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//
9/// \file mcrl2/pbes/structure_graph.h
10/// \brief add your file description here.
11
12#ifndef MCRL2_PBES_STRUCTURE_GRAPH_H
13#define MCRL2_PBES_STRUCTURE_GRAPH_H
14
15#include <iomanip>
16#include <boost/dynamic_bitset.hpp>
17#include <boost/range/adaptor/filtered.hpp>
18
19#include "mcrl2/atermpp/standard_containers/vector.h"
20#include "mcrl2/core/detail/print_utility.h"
21#include "mcrl2/pbes/pbes.h"
22
23namespace mcrl2::pbes_system {
24
25namespace detail {
26
29
30} // namespace detail
31
32constexpr inline
33unsigned int undefined_vertex()
34{
35 return std::numeric_limits<unsigned int>::max();
36}
37
38// A structure graph with a facility to exclude a subset of the vertices.
39// It has the same interface as simple_structure_graph.
41{
44
45
46 public:
48 {
53 d_none
54 };
55
56 using index_type = unsigned int;
57
58 struct vertex
59 {
65 mutable index_type strategy;
66
67 explicit vertex(pbes_expression formula_,
69 std::size_t rank_ = data::undefined_index(),
70 std::vector<index_type> pred_ = std::vector<index_type>(),
71 std::vector<index_type> succ_ = std::vector<index_type>(),
72 index_type strategy_ = undefined_vertex()
73 )
75 decoration(decoration_),
76 rank(rank_),
79 strategy(strategy_)
80 {}
81
82 void remove_predecessor(index_type u)
83 {
84 predecessors.erase(std::remove(predecessors.begin(), predecessors.end(), u), predecessors.end());
85 }
86
87 // Downcast reference aterm
88 inline const pbes_expression& formula() const
89 {
90 return m_formula;
91 }
92
93 void remove_successor(index_type u)
94 {
95 successors.erase(std::remove(successors.begin(), successors.end(), u), successors.end());
96 }
97
98 bool is_defined() const
99 {
100 return ((decoration != structure_graph::d_none) || (rank != data::undefined_index()))
101 && (!successors.empty() || (decoration == d_true || decoration == d_false));
102 }
103
104 void inline mark(atermpp::term_mark_stack& todo) const
105 {
106 mark_term(m_formula, todo);
107 }
108 };
109
111
112 protected:
114 index_type m_initial_vertex = 0;
116
118 {
120
121 explicit integers_not_contained_in(const boost::dynamic_bitset<>& subset_)
122 : subset(subset_)
123 {}
124
125 bool operator()(index_type i) const
126 {
127 return !subset[i];
128 }
129 };
130
132 {
135
136 vertices_not_contained_in(const vertex_vector& vertices_, const boost::dynamic_bitset<>& subset_)
139 {}
140
141 bool operator()(const vertex& v) const
142 {
143 std::size_t i = &v - &static_cast<const vertex&>(vertices.front());
144 return !subset[i];
145 }
146 };
147
148 public:
149 structure_graph() = default;
150
151 structure_graph(vertex_vector vertices, index_type initial_vertex, boost::dynamic_bitset<> exclude)
153 m_initial_vertex(initial_vertex),
155 {}
156
157 index_type initial_vertex() const
158 {
159 return m_initial_vertex;
160 }
161
163 {
164 return m_vertices.size();
165 }
166
167 decoration_type decoration(index_type u) const
168 {
170 }
171
173 {
174 return find_vertex(u).rank;
175 }
176
178 {
179 return m_vertices;
180 }
181
183 {
184 return find_vertex(u).predecessors;
185 }
186
188 {
189 return find_vertex(u).successors;
190 }
191
193 {
194 return all_vertices() | boost::adaptors::filtered(vertices_not_contained_in(m_vertices, m_exclude));
195 }
196
198 {
199 return all_predecessors(u) | boost::adaptors::filtered(integers_not_contained_in(m_exclude));
200 }
201
203 {
204 return all_successors(u) | boost::adaptors::filtered(integers_not_contained_in(m_exclude));
205 }
206
207 index_type strategy(index_type u) const
208 {
210 }
211
212 vertex& find_vertex(index_type u)
213 {
214 return m_vertices[u];
215 }
216
217 const vertex& find_vertex(index_type u) const
218 {
219 return m_vertices[u];
220 }
221
222 const boost::dynamic_bitset<>& exclude() const
223 {
224 return m_exclude;
225 }
226
228 {
229 return m_exclude;
230 }
231
232 bool contains(index_type u) const
233 {
234 return !m_exclude[u];
235 }
236
237 // TODO: avoid this linear time check
238 bool is_empty() const
239 {
240 return m_exclude.all();
241 }
242
243 // Returns true if all vertices have a rank and a decoration
244 bool is_defined() const
245 {
246 return std::all_of(m_vertices.begin(), m_vertices.end(), [](const vertex& u) { return u.is_defined(); });
247 }
248};
249
250template <typename StructureGraph>
252{
253 std::vector<typename StructureGraph::index_type> result;
254 for (auto v: G.predecessors(u))
255 {
256 result.push_back(v);
257 }
258 return result;
259}
260
261template <typename StructureGraph>
263{
264 std::vector<typename StructureGraph::index_type> result;
265 for (auto v: G.successors(u))
266 {
267 result.push_back(v);
268 }
269 return result;
270}
271
272inline
274{
275 switch (decoration)
276 {
277 case structure_graph::d_conjunction : { out << "conjunction"; break; }
278 case structure_graph::d_disjunction : { out << "disjunction"; break; }
279 case structure_graph::d_true : { out << "true"; break; }
280 case structure_graph::d_false : { out << "false"; break; }
281 default : { out << "none"; break; }
282 }
283 return out;
284}
285
286inline
288{
289 out << "vertex(formula = " << u.formula()
290 << ", decoration = " << u.decoration
291 << ", rank = " << (u.rank == data::undefined_index() ? std::string("undefined") : std::to_string(u.rank))
292 << ", predecessors = " << core::detail::print_list(u.predecessors)
293 << ", successors = " << core::detail::print_list(u.successors)
294 << ", strategy = " << (u.strategy == undefined_vertex() ? std::string("undefined") : std::to_string(u.strategy))
295 << ")";
296 return out;
297}
298
299template <typename StructureGraph>
301{
302 auto N = G.all_vertices().size();
303 for (std::size_t i = 0; i < N; i++)
304 {
305 if (G.contains(i))
306 {
307 const structure_graph::vertex& u = G.find_vertex(i);
308 out << std::setw(4) << i << " "
309 << "vertex(formula = " << u.formula()
310 << ", decoration = " << u.decoration
311 << ", rank = " << (u.rank == data::undefined_index() ? std::string("undefined") : std::to_string(u.rank))
312 << ", predecessors = " << core::detail::print_list(structure_graph_predecessors(G, i))
313 << ", successors = " << core::detail::print_list(structure_graph_successors(G, i))
314 << ", strategy = " << (u.strategy == undefined_vertex() ? std::string("undefined") : std::to_string(u.strategy))
315 << ")"
316 << std::endl;
317 }
318 }
319 if (G.is_empty())
320 {
321 out << " empty" << std::endl;
322 }
323 return out;
324}
325
326inline
328{
329 return print_structure_graph(out, G);
330}
331
332} // namespace mcrl2::pbes_system
333
334
335
336#endif // MCRL2_PBES_STRUCTURE_GRAPH_H
boost::dynamic_bitset & exclude()
boost::filtered_range< vertices_not_contained_in, const vertex_vector > vertices() const
structure_graph(vertex_vector vertices, index_type initial_vertex, boost::dynamic_bitset<> exclude)
boost::filtered_range< integers_not_contained_in, const std::vector< index_type > > predecessors(index_type u) const
const std::vector< index_type > & all_successors(index_type u) const
const std::vector< index_type > & all_predecessors(index_type u) const
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
const vertex & find_vertex(index_type u) const
bool contains(index_type u) const
std::size_t rank(index_type u) const
index_type strategy(index_type u) const
decoration_type decoration(index_type u) const
std::vector< typename StructureGraph::index_type > structure_graph_successors(const StructureGraph &G, typename StructureGraph::index_type u)
std::ostream & operator<<(std::ostream &out, const structure_graph::decoration_type &decoration)
std::ostream & operator<<(std::ostream &out, const structure_graph::vertex &u)
constexpr unsigned int undefined_vertex()
std::vector< typename StructureGraph::index_type > structure_graph_predecessors(const StructureGraph &G, typename StructureGraph::index_type u)
std::ostream & print_structure_graph(std::ostream &out, const StructureGraph &G)
std::ostream & operator<<(std::ostream &out, const structure_graph &G)
integers_not_contained_in(const boost::dynamic_bitset<> &subset_)
atermpp::detail::reference_aterm< pbes_expression > m_formula
vertex(pbes_expression formula_, decoration_type decoration_=structure_graph::d_none, std::size_t rank_=data::undefined_index(), std::vector< index_type > pred_=std::vector< index_type >(), std::vector< index_type > succ_=std::vector< index_type >(), index_type strategy_=undefined_vertex())
const pbes_expression & formula() const
void mark(atermpp::term_mark_stack &todo) const
vertices_not_contained_in(const vertex_vector &vertices_, const boost::dynamic_bitset<> &subset_)