mCRL2
Loading...
Searching...
No Matches
stategraph_local_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_local_reset_variables.h
10/// \brief add your file description here.
11
12#ifndef MCRL2_PBES_DETAIL_STATEGRAPH_LOCAL_RESET_VARIABLES_H
13#define MCRL2_PBES_DETAIL_STATEGRAPH_LOCAL_RESET_VARIABLES_H
14
15#include "mcrl2/pbes/detail/stategraph_local_algorithm.h"
16#include "mcrl2/pbes/detail/stategraph_reset_variables.h"
17
18namespace mcrl2::pbes_system::detail {
19
20template <typename Container>
22{
23 std::ostringstream os;
24 for (auto i = v.begin(); i != v.end(); ++i)
25 {
26 if(i != v.begin())
27 {
28 os << delim;
29 }
30 os << *i;
31 }
32 return os.str();
33}
34
37
38/// \brief Adds the reset variables procedure to the stategraph algorithm
40{
41 public:
43
44 protected:
45 const pbes m_original_pbes; // TODO: make this a const reference again
46 pbes m_transformed_pbes; // will contain the result of the computation
47
48 // if true, the resulting PBES is simplified
50
51 // m_occurring_data_parameters[X] contains the indices of data parameters that occur in at least one local control flow graph
53
54 // returns a default value for the given sort, that corresponds to parameter d_X[j]
55 data::data_expression default_value(const core::identifier_string& X, std::size_t j, const data::sort_expression& x)
56 {
57 auto const& Xinit = m_pbes.initial_state();
58 if (X == Xinit.name())
59 {
60 return nth_element(Xinit.parameters(), j);
61 }
62
63 // TODO: make this an attribute
64 data::representative_generator f(m_pbes.data());
65 return f(x);
66 }
67
69 {
70 m_occurring_data_parameters.clear();
71
72 // first collect all parameters (X, p) that are being used in a local control flow graph
73 for (auto& G: m_local_control_flow_graphs)
74 {
75 auto const& V = G.vertices;
76 for (const auto& u: V)
77 {
78 auto const& X = u.name();
79 auto p = u.index();
80 m_occurring_data_parameters[X].insert(p);
81 }
82 }
83
84 // then intersect them with the data parameter indices
85 for (auto& i: m_occurring_data_parameters)
86 {
87 auto const& X = i.first;
88 auto const& eq_X = *find_equation(m_pbes, X);
89 auto const& dp_X = eq_X.data_parameter_indices();
90 i.second = utilities::detail::set_intersection(i.second, std::set<std::size_t>(dp_X.begin(), dp_X.end()));
91 }
92 }
93
95 const stategraph_equation& eq_X, std::size_t i);
96
97 public:
98
99 // expands a propositional variable instantiation using the control flow graph
100 // x = Y(e)
101 // Y(e) = PVI(phi_X, i)
103 {
104 const predicate_variable& Ye = eq_X.predicate_variables()[i];
105 data::data_expression_list e = reset_variable_parameters(x, eq_X, i);
106 return propositional_variable_instantiation(Ye.name(), e);
107 }
108
109 // Applies resetting of variables to the original PBES p.
111 {
112 mCRL2log(log::log_level_t::debug) << "=== resetting variables to the original PBES ---" << std::endl;
113
114 // apply the reset variable procedure to all propositional variable instantiations
115 std::vector<pbes_equation>& p_eqn = p.equations();
116 const std::vector<stategraph_equation>& s_eqn = m_pbes.equations();
117
118 for (std::size_t k = 0; k < p_eqn.size(); k++)
119 {
120 mCRL2log(log::log_level_t::trace) << "--- resetting equation " << p_eqn[k] << std::endl;
121 p_eqn[k].formula() = local_reset_variables(*this, p_eqn[k].formula(), s_eqn[k]);
122 }
123
124 }
125
129 m_simplify(options.simplify)
130 {}
131
133 {
134 m_transformed_pbes = m_original_pbes;
136 start_timer("reset_variables_to_original");
137 reset_variables_to_original(m_transformed_pbes);
138 finish_timer("reset_variables_to_original");
139 }
140
141 const pbes& result() const
142 {
143 return m_transformed_pbes;
144 }
145};
146
147/// N.B. It is essential that this traverser uses the same traversal order as the guard_traverser.
149{
151 using super::enter;
152 using super::leave;
153 using super::apply;
154
158
160 : algorithm(algorithm_),
161 eq_X(eq_X_),
162 i(i_)
163 {}
164
166
167 void push(const pbes_expression& x)
168 {
169 mCRL2log(log::log_level_t::trace) << "<push>" << "\n" << x << std::endl;
170 expression_stack.push_back(x);
171 }
172
174 {
175 return expression_stack.back();
176 }
177
178 const pbes_expression& top() const
179 {
180 return expression_stack.back();
181 }
182
184 {
185 pbes_expression result = top();
186 expression_stack.pop_back();
187 return result;
188 }
189
190 void leave(const data::data_expression& x)
191 {
192 push(atermpp::down_cast<pbes_expression>(x));
193 }
194
196 {
197 pbes_expression result = algorithm.reset_variable(x, eq_X, i);
198 mCRL2log(log::log_level_t::trace) << "reset variable " << x << " with index " << i << " to " << result << std::endl;
199 i++;
200 push(result);
201 }
202
203 void leave(const pbes_system::not_& /* x */)
204 {
205 pbes_expression operand = pop();
206 push(not_(static_cast<atermpp::aterm>(operand)));
207 }
208
209 void leave(const pbes_system::and_& /* x */)
210 {
211 pbes_expression right = pop();
212 pbes_expression left = pop();
213 push(and_(left, right));
214 }
215
216 void leave(const pbes_system::or_& /* x */)
217 {
218 pbes_expression right = pop();
219 pbes_expression left = pop();
220 push(or_(left, right));
221 }
222
223 void leave(const pbes_system::imp& /* x */)
224 {
225 pbes_expression right = pop();
226 pbes_expression left = pop();
227 push(imp(left, right));
228 }
229
230 void leave(const pbes_system::forall& x)
231 {
232 pbes_expression operand = pop();
234 }
235
236 void leave(const pbes_system::exists& x)
237 {
238 pbes_expression operand = pop();
240 }
241};
242
243inline
245{
246 std::size_t i = 0;
247 local_reset_traverser f(algorithm, eq_X, i);
248 f.apply(x);
249 return f.top();
250}
251
254 const stategraph_equation& eq_X,
255 std::size_t i)
256{
257 using utilities::detail::contains;
258
259 assert(i < eq_X.predicate_variables().size());
260 const predicate_variable& Ye = eq_X.predicate_variables()[i];
261 assert(Ye.variable() == x);
262
263 const core::identifier_string& X = eq_X.variable().name();
264 const core::identifier_string& Y = Ye.name();
265 const stategraph_equation& eq_Y = *find_equation(m_pbes, Y);
266 const data::data_expression_list& e = x.parameters();
267 std::vector<data::data_expression> e1(e.begin(), e.end());
268 const std::vector<data::variable>& d_Y = eq_Y.parameters();
269 assert(d_Y.size() == Ye.parameters().size());
270 const std::size_t J = m_local_control_flow_graphs.size();
271
272 auto const& dp_Y = eq_Y.data_parameter_indices();
273 for (std::size_t k: dp_Y)
274 {
275 bool relevant = true;
276 std::set<data::data_expression> condition;
277 for (std::size_t j = 0; j < J; j++)
278 {
279 auto const& Vj = m_local_control_flow_graphs[j];
280 auto& Bj = m_belongs[j];
281 default_rules_predicate rules(Vj);
282 if (rules(X, i))
283 {
284 auto const& v = Vj.find_vertex(Y); // v = (Y, p, q)
285 std::size_t p = v.index();
286 auto di = Ye.target().find(p);
287 if (di != Ye.target().end())
288 {
289 auto const& q1 = di->second; // q1 = target(X, i, p)
290 auto const& u = Vj.find_vertex(local_control_flow_graph_vertex(Y, p, data::undefined_variable(), q1));
291 if (contains(Bj[Y], d_Y[k]) && !contains(u.marking(), d_Y[k]))
292 {
293 relevant = false;
294 break;
295 }
296 }
297 else if(!v.has_variable())
298 {
299 if (contains(Bj[Y], d_Y[k]) && !contains(v.marking(), d_Y[k]))
300 {
301 relevant = false;
302 break;
303 }
304 }
305 else
306 {
307 // update relevant and condition
308 if (contains(Bj[Y], d_Y[k]))
309 {
310 bool found = false;
311 for (const auto& w: Vj.vertices)
312 {
313 if (w.name() == Y && w.index() == p) // w = (Y, p, d_Y[p]=r)
314 {
315 if (contains(w.marking(), d_Y[k]))
316 {
317 found = true;
318 }
319 else
320 {
321 if (w.has_variable())
322 {
323 auto const& r = w.value();
324 condition.insert(data::equal_to(nth_element(e, p), r));
325 }
326 }
327 }
328 }
329 if (!found)
330 {
331 relevant = false;
332 break;
333 }
334 }
335 }
336 }
337 }
338 if (!relevant)
339 {
340 e1[k] = default_value(Y, k, e1[k].sort());
341 }
342 else
343 {
344 if (!condition.empty())
345 {
346 e1[k] = data::if_(data::lazy::join_or(condition.begin(), condition.end()), default_value(Y, k, e1[k].sort()), nth_element(e, k));
347 mCRL2log(log::log_level_t::trace) << " reset copy Y = " << Y << " k = " << k << " e'[k] = " << e1[k] << std::endl;
348 }
349 }
350 }
351 return data::data_expression_list(e1.begin(), e1.end());
352}
353
354} // namespace mcrl2::pbes_system::detail
355
356#endif // MCRL2_PBES_DETAIL_STATEGRAPH_LOCAL_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.
\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.
local_reset_variables_algorithm(const pbes &p, const pbesstategraph_options &options)
data::data_expression default_value(const core::identifier_string &X, std::size_t j, const data::sort_expression &x)
pbes_expression reset_variable(const propositional_variable_instantiation &x, const stategraph_equation &eq_X, std::size_t i)
data::data_expression_list reset_variable_parameters(const propositional_variable_instantiation &x, const stategraph_equation &eq_X, std::size_t i)
const propositional_variable_instantiation & variable() const
const core::identifier_string & name() const
Algorithm class for the local variant of the stategraph algorithm.
stategraph_local_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
const data::data_expression_list & parameters() const
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:435
std::string print_vector(const Container &v, const std::string &delim)
pbes_expression local_reset_variables(local_reset_variables_algorithm &algorithm, const pbes_expression &x, const stategraph_equation &eq_X)
N.B. It is essential that this traverser uses the same traversal order as the guard_traverser.
void leave(const pbes_system::propositional_variable_instantiation &x)
local_reset_traverser(local_reset_variables_algorithm &algorithm_, const stategraph_equation &eq_X_, std::size_t &i_)