mCRL2
Loading...
Searching...
No Matches
structure_graph_builder.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_STRUCTURE_GRAPH_BUILDER_H
13#define MCRL2_PBES_STRUCTURE_GRAPH_BUILDER_H
14
17
18namespace mcrl2 {
19
20namespace pbes_system {
21
22namespace detail {
23
25{
27
31 std::hash<atermpp::detail::reference_aterm<pbes_expression> >,
32 std::equal_to<atermpp::detail::reference_aterm<pbes_expression> >,
33 std::allocator< std::pair<const atermpp::detail::reference_aterm<pbes_expression>, atermpp::detail::reference_aterm<index_type> > >,
35 pbes_expression m_initial_state; // The initial state.
36
38 : m_graph(G), m_initial_state(data::undefined_data_expression())
39 {}
40
41 std::size_t extent() const
42 {
43 return m_graph.extent();
44 }
45
47 {
48 return m_graph.m_vertices;
49 }
50
52 {
53 return m_graph.m_vertices;
54 }
55
57 {
58 return m_graph.m_vertices[u];
59 }
60
62 {
63 return m_graph.m_vertices[u];
64 }
65
67 {
68 if (is_true(x))
69 {
71 }
72 else if (is_false(x))
73 {
75 }
77 {
79 }
80 else if (is_and(x))
81 {
83 }
84 else if (is_or(x))
85 {
87 }
88 throw std::runtime_error("structure_graph_builder: encountered unsupported pbes_expression " + pp(x));
89 }
90
92 {
93 assert(m_vertex_map.find(x) == m_vertex_map.end());
94
96 index_type index = vertices().size() - 1;
97 m_vertex_map.insert({ x, index });
98 return index;
99 }
100
101 // insert the variable corresponding to the equation x = phi; overwrites existing value, but leaves pred/succ intact
102 index_type insert_variable(const pbes_expression& x, const pbes_expression& psi, std::size_t k)
103 {
104 auto i = m_vertex_map.find(x);
105 index_type ui = i == m_vertex_map.end() ? create_vertex(x) : static_cast<unsigned int>(i->second);
106 auto& u = vertex(ui);
107 u.decoration = decoration(psi);
108 u.rank = k;
109 return ui;
110 }
111
112 // insert the variable x; does not overwrite existing value
114 {
115 auto i = m_vertex_map.find(x);
116 if (i != m_vertex_map.end())
117 {
118 return i->second;
119 }
120 else
121 {
122 return create_vertex(x);
123 }
124 }
125
127 {
128 // if the vertex already exists, return it
129 auto i = m_vertex_map.find(x);
130 if (i != m_vertex_map.end())
131 {
132 return i->second;
133 }
134
135 // create a new vertex, and return it
136 return create_vertex(x);
137 }
138
140 {
142 auto& u = vertex(ui);
143 auto& v = vertex(vi);
144 if (!contains(u.successors, vi))
145 {
146 u.successors.push_back(vi);
147 v.predecessors.push_back(ui);
148 }
149 }
150
152 {
153 m_initial_state = x;
154 }
155
157 {
158 auto i = m_vertex_map.find(m_initial_state);
159 assert (i != m_vertex_map.end());
160 return i->second;
161 }
162
163 // call at the end, to put the results into m_graph
164 void finalize()
165 {
167 m_graph.m_exclude = boost::dynamic_bitset<>(m_graph.extent());
168 }
169
171 {
172 auto i = m_vertex_map.find(x);
173 if (i == m_vertex_map.end())
174 {
175 return undefined_vertex();
176 }
177 return i->second;
178 }
179
180 // Erases all vertices in the set U.
182 {
183 // mCRL2log(log::debug) << "erasing nodes " << U << std::endl;
184
186
187 // compute new index for the vertices
188 std::vector<index_type> index;
190 for (index_type u = 0; u != vertices().size(); u++)
191 {
192 index.push_back(U.contains(u) ? undefined_vertex() : count++);
193 }
194
195 // computes new predecessors / successors
196 auto update = [&](const std::vector<index_type>& V) {
197 std::vector<index_type> result;
198 for (auto v: V)
199 {
200 if (index[v] != undefined_vertex())
201 {
202 result.push_back(index[v]);
203 }
204 }
205 return result;
206 };
207
208 for (index_type u = 0; u != vertices().size(); u++)
209 {
210 if (index[u] != undefined_vertex())
211 {
213 u_.predecessors = update(u_.predecessors);
214 u_.successors = update(u_.successors);
215 if (u_.strategy != undefined_vertex())
216 {
217 u_.strategy = index[u_.strategy];
218 }
219 if (index[u] != u)
220 {
221 std::swap(vertex(u), vertex(index[u]));
222 }
223 }
224 }
225
226 vertices().erase(vertices().begin() + vertices().size() - U.size(), vertices().end());
227
228 // Recreate the index
229 m_vertex_map.clear();
230 for (std::size_t i = 0; i < vertices().size(); i++)
231 {
232 m_vertex_map.insert({vertex(i).formula(), i});
233 }
234 }
235};
236
238{
240
243 index_type m_initial_state; // The initial state.
244
246 : m_graph(G)
247 {}
248
251 {
253 return m_vertices.size() - 1;
254 }
255
257 {
261 if (!contains(u.successors, vi))
262 {
263 u.successors.push_back(vi);
264 v.predecessors.push_back(ui);
265 }
266 }
267
269 {
272 u.remove_successor(vi);
273 v.remove_predecessor(ui);
274 }
275
277 {
278 m_initial_state = i;
279 }
280
283 void finalize()
284 {
287
288 std::size_t N = m_vertices.size();
289 m_graph.m_exclude = boost::dynamic_bitset<>(N);
290 }
291};
292
293} // namespace detail
294
295} // namespace pbes_system
296
297} // namespace mcrl2
298
299#endif // MCRL2_PBES_STRUCTURE_GRAPH_BUILDER_H
Base class that should not be used.
A unordered_map class in which aterms can be stored.
std::size_t size() const
Definition vector.h:329
iterator erase(const_iterator pos)
Definition vector.h:211
reference emplace_back(Args &&... args)
Definition vector.h:262
\brief A propositional variable instantiation
bool is_conjunctive(const pbes_expression &phi)
Definition srf_pbes.h:523
constexpr unsigned int undefined_vertex()
bool is_or(const atermpp::aterm &x)
bool is_false(const pbes_expression &t)
Test for the value false.
bool is_propositional_variable_instantiation(const atermpp::aterm &x)
std::string pp(const fixpoint_symbol &x)
Definition pbes.cpp:37
bool is_and(const atermpp::aterm &x)
bool is_true(const pbes_expression &t)
Test for the value true.
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.
void finalize()
call at the end, to put the results into m_graph
index_type insert_vertex(bool is_conjunctive, std::size_t rank)
Create a vertex, returns the index of the new vertex.
index_type insert_variable(const pbes_expression &x, const pbes_expression &psi, std::size_t k)
void set_initial_state(const propositional_variable_instantiation &x)
atermpp::utilities::unordered_map< pbes_expression, index_type, std::hash< atermpp::detail::reference_aterm< pbes_expression > >, std::equal_to< atermpp::detail::reference_aterm< pbes_expression > >, std::allocator< std::pair< const atermpp::detail::reference_aterm< pbes_expression >, atermpp::detail::reference_aterm< index_type > > >, true > m_vertex_map
const structure_graph::vertex & vertex(index_type u) const
structure_graph::decoration_type decoration(const pbes_expression &x) const
const structure_graph::vertex_vector & vertices() const
index_type find_vertex(const pbes_expression &x) const
const pbes_expression & formula() const
bool contains(structure_graph::index_type u) const