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//
9/// \file mcrl2/pbes/structure_graph_builder.h
10/// \brief add your file description here.
11
12#ifndef MCRL2_PBES_STRUCTURE_GRAPH_BUILDER_H
13#define MCRL2_PBES_STRUCTURE_GRAPH_BUILDER_H
14
15#include <mcrl2/atermpp/standard_containers/unordered_map.h>
16#include "mcrl2/pbes/pbessolve_vertex_set.h"
17
18namespace mcrl2::pbes_system::detail {
19
21{
22 using index_type = structure_graph::index_type;
23
28 std::equal_to<>,
31 true>
33 pbes_expression m_initial_state; // The initial state.
34
37 {}
38
39 std::size_t extent() const
40 {
41 return m_graph.extent();
42 }
43
45 {
46 return m_graph.m_vertices;
47 }
48
50 {
51 return m_graph.m_vertices;
52 }
53
54 structure_graph::vertex& vertex(index_type u)
55 {
56 return m_graph.m_vertices[u];
57 }
58
59 const structure_graph::vertex& vertex(index_type u) const
60 {
61 return m_graph.m_vertices[u];
62 }
63
65 {
66 if (is_true(x))
67 {
69 }
70 else if (is_false(x))
71 {
73 }
75 {
77 }
78 else if (is_and(x))
79 {
81 }
82 else if (is_or(x))
83 {
85 }
86 throw std::runtime_error("structure_graph_builder: encountered unsupported pbes_expression " + pp(x));
87 }
88
89 index_type create_vertex(const pbes_expression& x)
90 {
91 assert(m_vertex_map.find(x) == m_vertex_map.end());
92
93 vertices().emplace_back(x, decoration(x));
94 index_type index = vertices().size() - 1;
95 m_vertex_map.insert({ x, index });
96 return index;
97 }
98
99 // insert the variable corresponding to the equation x = phi; overwrites existing value, but leaves pred/succ intact
100 index_type insert_variable(const pbes_expression& x, const pbes_expression& psi, std::size_t k)
101 {
102 auto i = m_vertex_map.find(x);
103 index_type ui = i == m_vertex_map.end() ? create_vertex(x) : static_cast<unsigned int>(i->second);
104 auto& u = vertex(ui);
106 u.rank = k;
107 return ui;
108 }
109
110 // insert the variable x; does not overwrite existing value
111 index_type insert_variable(const pbes_expression& x)
112 {
113 auto i = m_vertex_map.find(x);
114 if (i != m_vertex_map.end())
115 {
116 return i->second;
117 }
118 else
119 {
120 return create_vertex(x);
121 }
122 }
123
124 index_type insert_vertex(const pbes_expression& x)
125 {
126 // if the vertex already exists, return it
127 auto i = m_vertex_map.find(x);
128 if (i != m_vertex_map.end())
129 {
130 return i->second;
131 }
132
133 // create a new vertex, and return it
134 return create_vertex(x);
135 }
136
137 void insert_edge(index_type ui, index_type vi)
138 {
139 using utilities::detail::contains;
140 auto& u = vertex(ui);
141 auto& v = vertex(vi);
142 if (!contains(u.successors, vi))
143 {
144 u.successors.push_back(vi);
145 v.predecessors.push_back(ui);
146 }
147 }
148
150 {
152 }
153
154 structure_graph::index_type initial_vertex() const
155 {
156 auto i = m_vertex_map.find(m_initial_state);
157 assert (i != m_vertex_map.end());
158 return i->second;
159 }
160
161 // call at the end, to put the results into m_graph
162 void finalize()
163 {
165 m_graph.m_exclude = boost::dynamic_bitset<>(m_graph.extent());
166 }
167
168 index_type find_vertex(const pbes_expression& x) const
169 {
170 auto i = m_vertex_map.find(x);
171 if (i == m_vertex_map.end())
172 {
173 return undefined_vertex();
174 }
175 return i->second;
176 }
177
178 // Erases all vertices in the set U.
180 {
181
182 using utilities::detail::contains;
183
184 // compute new index for the vertices
185 std::vector<index_type> index;
186 structure_graph::index_type count = 0;
187 for (index_type u = 0; u != vertices().size(); u++)
188 {
189 index.push_back(U.contains(u) ? undefined_vertex() : count++);
190 }
191
192 // computes new predecessors / successors
193 auto update = [&](const std::vector<index_type>& V) {
194 std::vector<index_type> result;
195 for (auto v: V)
196 {
197 if (index[v] != undefined_vertex())
198 {
199 result.push_back(index[v]);
200 }
201 }
202 return result;
203 };
204
205 for (index_type u = 0; u != vertices().size(); u++)
206 {
207 if (index[u] != undefined_vertex())
208 {
209 structure_graph::vertex& u_ = vertex(u);
210 u_.predecessors = update(u_.predecessors);
211 u_.successors = update(u_.successors);
212 if (u_.strategy != undefined_vertex())
213 {
214 u_.strategy = index[u_.strategy];
215 }
216 if (index[u] != u)
217 {
218 std::swap(vertex(u), vertex(index[u]));
219 }
220 }
221 }
222
223 vertices().erase(vertices().begin() + static_cast<std::ptrdiff_t>(vertices().size() - U.size()), vertices().end());
224
225 // Recreate the index
226 m_vertex_map.clear();
227 for (std::size_t i = 0; i < vertices().size(); i++)
228 {
229 m_vertex_map.insert({vertex(i).formula(), i});
230 }
231 }
232};
233
235{
236 using index_type = structure_graph::index_type;
237
240 index_type m_initial_state = 0U; // The initial state.
241
243 : m_graph(G)
244 {}
245
246 /// \brief Create a vertex, returns the index of the new vertex
247 index_type insert_vertex(bool is_conjunctive, std::size_t rank)
248 {
249 m_vertices.emplace_back(pbes_expression(), is_conjunctive ? structure_graph::d_conjunction : structure_graph::d_disjunction, rank);
250 return m_vertices.size() - 1;
251 }
252
253 void insert_edge(index_type ui, index_type vi)
254 {
255 using utilities::detail::contains;
256 structure_graph::vertex& u = m_vertices[ui];
257 structure_graph::vertex& v = m_vertices[vi];
258 if (!contains(u.successors, vi))
259 {
260 u.successors.push_back(vi);
261 v.predecessors.push_back(ui);
262 }
263 }
264
265 void remove_edge(index_type ui, index_type vi)
266 {
267 structure_graph::vertex& u = m_vertices[ui];
268 structure_graph::vertex& v = m_vertices[vi];
271 }
272
273 void set_initial_state(const index_type i)
274 {
275 m_initial_state = i;
276 }
277
278 /// \brief call at the end, to put the results into m_graph
279 /// \details May be called more than once. Does not invalidate this builder.
280 void finalize()
281 {
282 m_graph.m_vertices = m_vertices;
284
285 std::size_t N = m_vertices.size();
286 m_graph.m_exclude = boost::dynamic_bitset<>(N);
287 }
288};
289
290} // namespace mcrl2::pbes_system::detail
291
292
293
294
295
296#endif // MCRL2_PBES_STRUCTURE_GRAPH_BUILDER_H
pbes_expression & operator=(const pbes_expression &) noexcept=default
pbes_expression(const data::data_expression &x)
\brief Constructor Z6.
\brief A propositional variable instantiation
const data::data_expression & undefined_data_expression()
Returns a data expression that corresponds to 'undefined'.
Definition undefined.h:58
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)
bool is_and(const atermpp::aterm &x)
bool is_true(const pbes_expression &t)
Test for the value true.
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)
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