mCRL2
Loading...
Searching...
No Matches
stategraph_global_reset_variables.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/detail/stategraph_global_reset_variables.h
10/// \brief add your file description here.
11
12#ifndef MCRL2_PBES_DETAIL_STATEGRAPH_GLOBAL_RESET_VARIABLES_H
13#define MCRL2_PBES_DETAIL_STATEGRAPH_GLOBAL_RESET_VARIABLES_H
14
15#include "mcrl2/pbes/detail/stategraph_global_algorithm.h"
16#include "mcrl2/pbes/detail/stategraph_reset_variables.h"
17
18namespace mcrl2::pbes_system::detail {
19
22
23/// \brief Adds the reset variables procedure to the stategraph algorithm
25{
26 public:
28
29 protected:
31 pbes m_transformed_pbes; // will contain the result of the computation
32
33 // if true, the resulting PBES is simplified
35
37 {
38 // TODO: make this an attribute
39 data::representative_generator f(m_pbes.data());
40 return f(x);
41 }
42
43 // returns the parameters of the propositional variable with name X
45 {
46 auto const& eq_X = *find_equation(m_pbes, X);
47 auto const& d_X = eq_X.parameters();
48 return std::set<data::variable>(d_X.begin(), d_X.end());
49 }
50
51 template <typename Graph>
53 {
54 using utilities::detail::pick_element;
55
56 mCRL2log(log::log_level_t::debug) << "--- compute initial marking ---" << std::endl;
57
58 // initialization
59 for (auto i = G.begin(); i != G.end(); ++i)
60 {
61 auto const& v = *i;
62 std::set<data::variable> dx = propvar_parameters(v.name());
63 v.set_marking(utilities::detail::set_intersection(v.sig(), dx));
64 mCRL2log(log::log_level_t::debug) << "vertex " << v << " sig = " << core::detail::print_set(v.sig()) << " dx = " << core::detail::print_set(dx) << "\n";
65 }
66 mCRL2log(log::log_level_t::debug) << "--- initial control flow marking ---\n" << G.print_marking();
67
68 // backwards reachability algorithm
69 std::set<const typename Graph::vertex_type*> todo;
70 for (auto i = G.begin(); i != G.end(); ++i)
71 {
72 auto const& v = *i;
73 todo.insert(&v);
74 }
75 mCRL2log(log::log_level_t::debug) << "--- update marking ---" << std::endl;
76 while (!todo.empty())
77 {
78 auto const& v = *pick_element(todo);
79 mCRL2log(log::log_level_t::debug) << "selected marking todo element " << v << std::endl;
80 std::set<std::size_t> I = v.marking_variable_indices(m_pbes);
81
82 auto const& incoming_edges = v.incoming_edges();
83 for (auto ei = incoming_edges.begin(); ei != incoming_edges.end(); ++ei)
84 {
85 auto const& u = *ei->first;
86 const std::set<std::size_t>& labels = ei->second;
87 for (std::size_t i: labels)
88 {
89 std::size_t last_size = u.marking().size();
90 const stategraph_equation& eq_X = *find_equation(m_pbes, u.name());
91 const propositional_variable_instantiation& Y = eq_X.predicate_variables()[i].variable();
92 std::set<data::variable> dx = propvar_parameters(u.name());
93 mCRL2log(log::log_level_t::debug) << " vertex u = " << v << " label = " << i << " I = " << print_set(I) << " u.marking = " << core::detail::print_set(u.marking()) << std::endl;
94 for (std::size_t m: I)
95 {
96 const data::data_expression_list& e = Y.parameters();
97 const data::data_expression& e_m = nth_element(e, m);
98 std::set<data::variable> fv = data::find_free_variables(e_m);
99 u.set_marking(utilities::detail::set_union(utilities::detail::set_intersection(fv, dx), u.marking()));
100 mCRL2log(log::log_level_t::debug) << " m = " << m << " freevars = " << core::detail::print_set(fv) << " dx = " << core::detail::print_set(dx) << "\n";
101 }
102 if (u.marking().size() > last_size)
103 {
104 todo.insert(&u);
105 mCRL2log(log::log_level_t::debug) << "updated marking " << u.print_marking() << " using edge " << pbes_system::pp(Y) << "\n";
106 }
107 }
108 }
109 }
110
111 // set the marking_parameters attributes
112 for (auto i = G.begin(); i != G.end(); ++i)
113 {
114 auto const& v = *i;
115 const stategraph_equation& eqn = *find_equation(m_pbes, v.name());
116 for (const data::variable& w: eqn.parameters())
117 {
118 v.add_marked_parameter(v.marking().find(w) != v.marking().end());
119 }
120 }
121 }
122
123 // First determine whether this location should be considered
124 template <typename Vertex>
125 bool location_possibly_reachable(const core::identifier_string& Y, const Vertex& u, const std::vector<data::data_expression>& e_X, const stategraph_equation& eq_X,std::size_t i)
126 {
127 std::size_t N = e_X.size();
128 data::data_expression_list::const_iterator k = u.values().begin();
129 for (std::size_t j = 0; j < N; ++j)
130 {
131 if (is_global_control_flow_parameter(Y, j))
132 {
133 const predicate_variable& X_i = eq_X.predicate_variables()[i];
134 auto target_j = X_i.target().find(j);
135 if (target_j != X_i.target().end())
136 {
137 data::data_expression f_k = *k;
138 if(f_k != target_j->second)
139 {
140 return false;
141 }
142 }
143 ++k;
144 }
145 }
146 return true;
147 }
148
149 public:
150 // expands a propositional variable instantiation using the control flow graph
151 // x = Y(e)
152 // Y(e) = PVI(phi_X, i)
154 {
155 mCRL2log(log::log_level_t::debug) << "--- resetting variable Y(e) = " << pbes_system::pp(x) << " with index " << i << std::endl;
156 assert(eq_X.predicate_variables()[i].variable() == x);
157
158 std::vector<pbes_expression> phi;
159 const core::identifier_string& Y = x.name();
160 std::vector<data::data_expression> e(x.parameters().begin(),x.parameters().end());
161
162 // iterate over the alternatives as defined by the control flow graph
163 auto inst = m_control_flow_graph.index(Y);
164 if (inst.empty())
165 {
166 mCRL2log(log::log_level_t::verbose) << "Equation " << Y << " is not reachable!" << std::endl;
167 }
168 for (auto q: inst)
169 {
170 auto& u = *q;
171 mCRL2log(log::log_level_t::debug) << " vertex u = " << u << std::endl;
172
173 if(!location_possibly_reachable(Y, u, e, eq_X, i))
174 {
175 continue;
176 }
177
178 // Now build the actual formula
179 std::vector<data::data_expression> r;
180 std::size_t N = u.marked_parameters().size();
181 assert(e.size() == u.marked_parameters().size());
182 auto k = u.values().begin();
183 data::data_expression condition = data::true_();
184 for (std::size_t j = 0; j < N; ++j)
185 {
186 mCRL2log(log::log_level_t::debug) << " j = " << j;
187 if (is_global_control_flow_parameter(Y, j))
188 {
189 mCRL2log(log::log_level_t::debug) << " CFP(Y, j) = true";
190 const data::data_expression& f_k = *k++;
191 const predicate_variable& X_i = eq_X.predicate_variables()[i];
192 if (X_i.target().find(j) == X_i.target().end() || !m_simplify)
193 {
194 condition = data::lazy::and_(condition, data::equal_to(e[j], f_k));
195 r.push_back(e[j]);
196 mCRL2log(log::log_level_t::debug) << " target(X, i, j) = false";
197 mCRL2log(log::log_level_t::debug) << " c := c && " << data::pp(data::equal_to(e[j], f_k));
198 }
199 else
200 {
201 r.push_back(X_i.target().find(j)->second);
202 }
203 mCRL2log(log::log_level_t::debug) << " r := r <| " << data::pp(r.back());
204
205 }
206 else if (u.is_marked_parameter(j))
207 {
208 mCRL2log(log::log_level_t::debug) << " e[j] is in marking(u)";
209 mCRL2log(log::log_level_t::debug) << " r := r <| " << data::pp(e[j]);
210 r.push_back(e[j]);
211 }
212 else
213 {
214 mCRL2log(log::log_level_t::debug) << " default parameter ";
215 mCRL2log(log::log_level_t::debug) << " r := r <| " << data::pp(default_value(e[j].sort()));
216 r.push_back(default_value(e[j].sort()));
217 }
218 mCRL2log(log::log_level_t::debug) << std::endl;
219 }
220 propositional_variable_instantiation Yr(Y, data::data_expression_list(r.begin(),r.end()));
221 if (m_simplify)
222 {
223 condition = m_datar(condition);
224 if (condition != data::false_())
225 {
226 phi.push_back(imp(atermpp::down_cast<pbes_expression>(condition), Yr));
227 }
228 }
229 else
230 {
231 phi.push_back(imp(atermpp::down_cast<pbes_expression>(condition), Yr));
232 }
233 }
234 return join_and(phi.begin(), phi.end());
235 }
236
237 // Applies resetting of variables to the original PBES p.
239 {
240 mCRL2log(log::log_level_t::debug) << "--- resetting variables to the original PBES ---" << std::endl;
241
242 // apply the reset variable procedure to all propositional variable instantiations
243 std::vector<pbes_equation>& p_eqn = p.equations();
244 const std::vector<stategraph_equation>& s_eqn = m_pbes.equations();
245
246 for (std::size_t k = 0; k < p_eqn.size(); k++)
247 {
248
249 p_eqn[k].formula() = reset_variables(*this, p_eqn[k].formula(), s_eqn[k]);
250 }
251
252 // TODO: merge the two rewriters?
253 if (m_simplify)
254 {
256 pbes_system::pbes_rewrite(p, pbesr);
257 }
258 }
259
263 m_simplify(options.simplify)
264 {}
265
267 {
268 start_timer("compute_global_control_flow_marking");
269 compute_global_control_flow_marking(m_control_flow_graph);
270 finish_timer("compute_global_control_flow_marking");
271 mCRL2log(log::log_level_t::verbose) << "Computed control flow marking" << std::endl;
272 mCRL2log(log::log_level_t::debug) << "--- control flow marking ---\n" << m_control_flow_graph.print_marking();
273 m_transformed_pbes = m_original_pbes;
274 reset_variables_to_original(m_transformed_pbes);
275 }
276
277 const pbes& result() const
278 {
279 return m_transformed_pbes;
280 }
281};
282
283/// \brief reset propositional variables
284/// N.B. It is essential that this traverser uses the same traversal order as the guard_traverser.
286{
288 using super::enter;
289 using super::leave;
290 using super::apply;
291
295
296 reset_traverser(global_reset_variables_algorithm& algorithm_, const stategraph_equation& eq_X_, std::size_t& i_)
297 : algorithm(algorithm_),
298 eq_X(eq_X_),
299 i(i_)
300 {}
301
303
304 void push(const pbes_expression& x)
305 {
306 mCRL2log(log::log_level_t::trace) << "<push>" << "\n" << x << std::endl;
307 expression_stack.push_back(x);
308 }
309
311 {
312 return expression_stack.back();
313 }
314
315 const pbes_expression& top() const
316 {
317 return expression_stack.back();
318 }
319
321 {
322 pbes_expression result = top();
323 expression_stack.pop_back();
324 return result;
325 }
326
327 void leave(const data::data_expression& x)
328 {
329 push(atermpp::down_cast<pbes_expression>(x));
330 }
331
333 {
334 pbes_expression result = algorithm.reset_variable(x, eq_X, i);
335 mCRL2log(log::log_level_t::debug) << "reset variable " << pbes_system::pp(x) << " with index " << i << " to " << pbes_system::pp(result) << std::endl;
336 i++;
337 push(result);
338 }
339
340 void leave(const pbes_system::not_& /* x */)
341 {
342 pbes_expression operand = pop();
343 push(not_(static_cast<atermpp::aterm>(operand)));
344 }
345
346 void leave(const pbes_system::and_& /* x */)
347 {
348 pbes_expression right = pop();
349 pbes_expression left = pop();
350 push(and_(left, right));
351 }
352
353 void leave(const pbes_system::or_& /* x */)
354 {
355 pbes_expression right = pop();
356 pbes_expression left = pop();
357 push(or_(left, right));
358 }
359
360 void leave(const pbes_system::imp& /* x */)
361 {
362 pbes_expression right = pop();
363 pbes_expression left = pop();
364 push(imp(left, right));
365 }
366
367 void leave(const pbes_system::forall& x)
368 {
369 pbes_expression operand = pop();
371 }
372
373 void leave(const pbes_system::exists& x)
374 {
375 pbes_expression operand = pop();
377 }
378};
379
380inline
382{
383 std::size_t i = 0;
384 reset_traverser f(algorithm, eq_X, i);
385 f.apply(x);
386 return f.top();
387}
388
389} // namespace mcrl2::pbes_system::detail
390
391#endif // MCRL2_PBES_DETAIL_STATEGRAPH_GLOBAL_RESET_VARIABLES_H
aterm(const aterm &other) noexcept=default
This class has user-declared copy constructor so declare default copy and move operators.
A unordered_map class in which aterms can be stored.
Components for generating an arbitrary element of a sort.
data_expression operator()(const sort_expression &sort)
Returns a representative of a sort.
Rewriter that operates on data expressions.
Definition rewriter.h:84
\brief A sort expression
\brief The and operator for pbes expressions
and_(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
Adds the reset variables procedure to the stategraph algorithm.
global_reset_variables_algorithm(const pbes &p, const pbesstategraph_options &options)
pbes_expression reset_variable(const propositional_variable_instantiation &x, const stategraph_equation &eq_X, std::size_t i)
bool location_possibly_reachable(const core::identifier_string &Y, const Vertex &u, const std::vector< data::data_expression > &e_X, const stategraph_equation &eq_X, std::size_t i)
std::set< data::variable > propvar_parameters(const core::identifier_string &X) const
data::data_expression default_value(const data::sort_expression &x)
Algorithm class for the global variant of the stategraph algorithm.
stategraph_global_algorithm(const pbes &p, const pbesstategraph_options &options)
\brief The existential quantification operator for pbes expressions
exists(const data::variable_list &variables, const pbes_expression &body)
\brief Constructor Z14.
const data::variable_list & variables() const
\brief The universal quantification operator for pbes expressions
forall(const data::variable_list &variables, const pbes_expression &body)
\brief Constructor Z14.
const data::variable_list & variables() const
\brief The implication operator for pbes expressions
imp(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
\brief The not operator for pbes expressions
not_(const atermpp::aterm &term)
\brief The or operator for pbes expressions
or_(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
parameterized boolean equation system
Definition pbes.h:54
\brief A propositional variable instantiation
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:435
pbes_expression reset_variables(global_reset_variables_algorithm &algorithm, const pbes_expression &x, const stategraph_equation &eq_X)
reset propositional variables N.B. It is essential that this traverser uses the same traversal order ...
void leave(const pbes_system::propositional_variable_instantiation &x)
reset_traverser(global_reset_variables_algorithm &algorithm_, const stategraph_equation &eq_X_, std::size_t &i_)
A rewriter that simplifies boolean expressions in a term, and rewrites data expressions using DataRew...