mCRL2
Loading...
Searching...
No Matches
stategraph_pbes.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_pbes.h
10/// \brief add your file description here.
11
12#ifndef MCRL2_PBES_DETAIL_STATEGRAPH_PBES_H
13#define MCRL2_PBES_DETAIL_STATEGRAPH_PBES_H
14
15#include "mcrl2/core/detail/print_utility.h"
16#include "mcrl2/pbes/detail/guard_traverser.h"
17#include "mcrl2/pbes/detail/stategraph_simplify_rewriter.h"
18#include "mcrl2/pbes/detail/stategraph_utility.h"
19
20
21
22
23
24namespace mcrl2::pbes_system::detail {
25
27{
28 friend class stategraph_equation;
29
30 protected:
34 std::map<std::size_t, data::data_expression> m_source; // source[j] = e <=> source(X, i, j) = e
35 std::map<std::size_t, data::data_expression> m_target; // target[j] = c <=> target(X, i, j) = c
36 std::map<std::size_t, std::size_t> m_copy; // copy[j] = k <=> copy(X, i, j) = k
37 std::set<std::size_t> m_used; // j \in used <=> used(X, i, j)
38 std::set<std::size_t> m_changed; // j \in changed <=> changed(X, i, j)
39
40 public:
41
43 : X(X_), m_guard(guard_)
44 {}
45
47 {
48 return X;
49 }
50
51 const pbes_expression& guard() const
52 {
53 return m_guard;
54 }
55
56 const core::identifier_string& name() const
57 {
58 return X.name();
59 }
60
62 {
63 return m_sigma;
64 }
65
66 const data::data_expression_list& parameters() const
67 {
68 return X.parameters();
69 }
70
72 {
73 return m_source;
74 }
75
76 // Returns source(k), or data::undefined_data_expression() if source(k) does not exist.
77 data::data_expression source(std::size_t k) const
78 {
79 using utilities::detail::mapped_value;
80 return mapped_value(m_source, k, data::undefined_data_expression());
81 }
82
84 {
85 return m_target;
86 }
87
88 // Returns target(k), or data::undefined_data_expression() if target(k) does not exist.
89 data::data_expression target(std::size_t k) const
90 {
91 using utilities::detail::mapped_value;
92 return mapped_value(m_target, k, data::undefined_data_expression());
93 }
94
95 const std::map<std::size_t, std::size_t>& copy() const
96 {
97 return m_copy;
98 }
99
100 // Returns copy(k), or data::undefined_index() if copy(k) does not exist.
102 {
103 using utilities::detail::mapped_value;
104 return mapped_value(m_copy, k, data::undefined_index());
105 }
106
107 const std::set<std::size_t>& used() const
108 {
109 return m_used;
110 }
111
112 const std::set<std::size_t>& changed() const
113 {
114 return m_changed;
115 }
116
118 {
121 m_guard = R(m_guard);
122 }
123
124 std::string print() const
125 {
126 std::ostringstream out;
127 out << "predicate variable X = " << X << std::endl;
128 out << "guard = " << m_guard << std::endl;
129 out << "sigma = " << m_sigma << std::endl;
130 out << "source = " << core::detail::print_map(m_source) << std::endl;
131 out << "target = " << core::detail::print_map(m_target) << std::endl;
132 out << "copy = " << core::detail::print_map(m_copy) << std::endl;
133 out << "used = " << core::detail::print_set(m_used) << std::endl;
134 out << "changed = " << core::detail::print_set(m_changed) << std::endl;
135 return out.str();
136 }
137};
138
139inline
141{
142 return out << x.variable();
143}
144
146{
147 protected:
155
156 // Extracts all conjuncts d[i] == e from the pbes expression x, for some i in 0 ... d.size(), and with e a constant.
157 void find_equality_conjuncts(const pbes_expression& x, const std::vector<data::variable>& d, std::map<data::variable, data::data_expression>& result) const
158 {
159 std::vector<pbes_expression> conjuncts;
160 detail::stategraph_split_and(x, conjuncts);
161 for (const pbes_expression& expr: conjuncts)
162 {
163 if (data::is_data_expression(expr))
164 {
165 const auto& v_i = atermpp::down_cast<const data::data_expression>(expr);
166 if (data::is_equal_to_application(v_i))
167 {
168 const data::data_expression& left = data::binary_left1(v_i);
169 const data::data_expression& right = data::binary_right1(v_i);
170 if (data::is_variable(left) && std::find(d.begin(), d.end(), data::variable(left)) != d.end() && data::is_constant(right))
171 {
172 const auto& vleft = atermpp::down_cast<data::variable>(left);
173 result[vleft] = right;
174 }
175 else if (data::is_variable(right) && std::find(d.begin(), d.end(), data::variable(right)) != d.end() && data::is_constant(left))
176 {
177 const auto& vright = atermpp::down_cast<data::variable>(right);
178 result[vright] = left;
179 }
180 }
181 // handle conjuncts b and !b, with b a variable with sort Bool
182 else if (data::is_variable(v_i) && data::is_bool(v_i.sort()) && std::find(d.begin(), d.end(), data::variable(v_i)) != d.end())
183 {
184 const auto& v = atermpp::down_cast<data::variable>(v_i);
185 result[v] = data::true_();
186 }
187 else if (data::is_not(v_i))
188 {
189 const data::data_expression& narg = data::sort_bool::arg(v_i);
190 if (data::is_variable(narg) && data::is_bool(v_i.sort()) && std::find(d.begin(), d.end(), data::variable(narg)) != d.end())
191 {
192 const auto& v = atermpp::down_cast<data::variable>(narg);
193 result[v] = data::false_();
194 }
195 }
196 }
197 }
198 mCRL2log(log::log_level_t::trace) << " computing source: expression = " << x << ", d_X = " << core::detail::print_list(d) << ", result = " << core::detail::print_map(result) << std::endl;
199 }
200
202 {
203 auto j = is_control_flow.find(X);
204 assert(j != is_control_flow.end());
205 const std::vector<bool>& cf = j->second;
206 assert(i < cf.size());
207 return cf[i];
208 }
209
210 // computes the source function for a pbes equation
212 {
213 for (predicate_variable& predvar: m_predvars)
214 {
215 std::map<data::variable, data::data_expression> sigma;
216 find_equality_conjuncts(predvar.m_guard, m_parameters, sigma);
217
218 // convert sigma to source
219 for (std::size_t j = 0; j < m_parameters.size(); j++)
220 {
221 data::variable d_j = m_parameters[j];
222 auto k = sigma.find(d_j);
223 if (k != sigma.end())
224 {
225 data::data_expression e = k->second;
226 predvar.m_source[j] = e;
227 predvar.m_sigma[d_j] = e;
228 }
229 }
230 }
231 }
232
234 {
235 for (predicate_variable& Ye: m_predvars)
236 {
237 auto const& e = Ye.parameters();
238 std::size_t j_index = 0;
239 for (auto j = e.begin(); j != e.end(); ++j, ++j_index)
240 {
241 data::data_expression c = R(*j, Ye.sigma());
242 if (data::is_constant(c))
243 {
244 Ye.m_target[j_index] = c;
245 }
246 }
247 }
248 }
249
251 {
252 for (predicate_variable& predvar: m_predvars)
253 {
254 auto const& e = predvar.X.parameters();
255 for (std::size_t j = 0; j < m_parameters.size(); j++)
256 {
257 std::size_t k_index = 0;
258 for (auto k = e.begin(); k != e.end(); ++k, ++k_index)
259 {
260 if (m_parameters[j] == *k)
261 {
262 predvar.m_copy[j] = k_index;
263 }
264 }
265 }
266 }
267 }
268
270 {
271 using utilities::detail::contains;
272
273 auto const& d_X = m_parameters;
274 for (predicate_variable& Ye : m_predvars)
275 {
276 auto v = pbes_system::find_free_variables(Ye.guard());
277 for (std::size_t j = 0; j < d_X.size(); j++)
278 {
279 if (contains(v, d_X[j]))
280 {
281 Ye.m_used.insert(j);
282 }
283 std::size_t p_index = 0;
284 auto const& e = Ye.parameters();
285 for (auto p = e.begin(); p != e.end(); ++p, ++p_index)
286 {
287 auto freevars = data::find_free_variables(*p);
288 if (contains(freevars, d_X[j]))
289 {
290 if ( (Ye.name() != variable().name()) || p_index != j )
291 {
292 Ye.m_used.insert(j);
293 }
294 }
295 }
296 }
297 }
298 }
299
301 {
302 auto const& d_X = m_parameters;
303 for (predicate_variable& Ye: m_predvars)
304 {
305 if (Ye.name() != variable().name())
306 {
307 continue;
308 }
309 std::size_t j_index = 0;
310 auto const& e = Ye.parameters();
311 for (auto j = e.begin(); j != e.end(); ++j, ++j_index)
312 {
313 if (*j != d_X[j_index])
314 {
315 Ye.m_changed.insert(j_index);
316 }
317 }
318 }
319 }
320
321 public:
323 : pbes_equation(eqn)
324 {
326 f.apply(eqn.formula());
327 const std::vector<std::pair<propositional_variable_instantiation, pbes_expression>>& guards = f.expression_stack.back().guards;
328 for (const auto& guard: guards)
329 {
330 m_predvars.emplace_back(guard.first, guard.second);
331 }
332 m_condition = f.expression_stack.back().condition;
333 data::variable_list params = variable().parameters();
334 m_parameters = std::vector<data::variable>(params.begin(), params.end());
335 }
336
338 {
344 }
345
346 /// \brief Sets the control flow parameters of this equation
347 /// \param CFP contains the indices of the control flow parameters of this equation
348 void set_control_flow_parameters(const std::set<std::size_t>& CFP) const
349 {
350 m_control_flow_parameter_indices = std::vector<std::size_t>(CFP.begin(), CFP.end());
351 for (std::size_t i: m_control_flow_parameter_indices)
352 {
353 m_control_flow_parameters.push_back(m_parameters[i]);
354 }
355 }
356
357 /// \brief Sets the data parameters of this equation
358 /// \param DP contains the indices of the control flow parameters of this equation
359 void set_data_parameters(const std::set<std::size_t>& DP) const
360 {
361 m_data_parameter_indices = std::vector<std::size_t>(DP.begin(), DP.end());
362 for (std::size_t i: m_data_parameter_indices)
363 {
364 m_data_parameters.push_back(m_parameters[i]);
365 }
366 }
367
369 {
370 return m_control_flow_parameters;
371 }
372
374 {
375 return m_control_flow_parameter_indices;
376 }
377
379 {
380 return m_data_parameters;
381 }
382
384 {
385 return m_data_parameter_indices;
386 }
387
388 bool is_simple() const
389 {
390 for (const predicate_variable& predvar: m_predvars)
391 {
392 // TODO check this
393 if (!pbes_system::is_false(predvar.guard()))
394 {
395 return false;
396 }
397 }
398 return true;
399 }
400
402 {
403 return m_condition;
404 }
405
407 {
408 return m_parameters;
409 }
410
412 {
413 return m_predvars;
414 }
415
417 {
418 return m_predvars;
419 }
420
421 std::string print() const
422 {
423 std::ostringstream out;
424 out << "equation = " << print_equation(*this) << std::endl;
425 out << "guards:" << std::endl;
426 for (const predicate_variable& predvar: m_predvars)
427 {
428 out << "variable = " << predvar.variable() << " guard = " << predvar.guard() << std::endl;
429 }
430 out << "simple = " << std::boolalpha << is_simple() << std::endl;
431 return out.str();
432 }
433
435 {
436 std::ostringstream out;
437 std::string X(variable().name());
438 for (std::size_t i = 0; i < m_predvars.size(); i++)
439 {
440 out << " predvar[" << i << "] = " << m_predvars[i] << " guard = " << m_predvars[i].guard() << std::endl;
441
442 // source
443 auto const& source = m_predvars[i].source();
444 for (const auto& j: source)
445 {
446 out << " source(" << X << ", " << i << ", " << j.first << ") = " << j.second << std::endl;
447 }
448
449 // sigma
450 out << " sigma = " << m_predvars[i].sigma() << std::endl;
451
452 // target
453 const std::map<std::size_t, data::data_expression>& target = m_predvars[i].target();
454 for (const auto& j: target)
455 {
456 out << " target(" << X << ", " << i << ", " << j.first << ") = " << j.second << std::endl;
457 }
458
459 // copy
460 auto const& copy = m_predvars[i].copy();
461 for (const auto& j: copy)
462 {
463 out << " copy(" << X << ", " << i << ", " << j.first << ") = " << j.second << std::endl;
464 }
465 out << " used = " << core::detail::print_set(m_predvars[i].used()) << std::endl;
466 out << " changed = " << core::detail::print_set(m_predvars[i].changed()) << std::endl;
467 }
468 return out.str();
469 }
470
471 // Removes the values from e that correspond to a data parameter
472 data::data_expression_list project(const data::data_expression_list& e) const
473 {
474 assert(e.size() == m_parameters.size());
475 data::data_expression_vector result;
476 for (std::size_t i: m_control_flow_parameter_indices)
477 {
478 result.push_back(nth_element(e, i));
479 }
480 return data::data_expression_list(result.begin(), result.end());
481 }
482};
483
484// explicit representation of a pbes in STATEGRAPH format
486{
487 protected:
492
493 public:
494 stategraph_pbes() = default;
495
496 /// \brief Constructor
497 /// \pre The pbes p must be in STATEGRAPH format
498 stategraph_pbes(const pbes& p, const data::rewriter& rewr)
500 {
501 const std::vector<pbes_equation>& equations = p.equations();
502 for (const pbes_equation& equation: equations)
503 {
504 m_equations.emplace_back(equation, rewr);
505 }
506 }
507
509 {
510 return m_equations;
511 }
512
514 {
515 return m_equations;
516 }
517
519 {
520 return m_global_variables;
521 }
522
524 {
525 return m_global_variables;
526 }
527
529 {
530 return m_initial_state;
531 }
532
533 const data::data_specification& data() const
534 {
535 return m_data;
536 }
537
538 data::data_expression source(std::size_t k, std::size_t i, std::size_t n) const
539 {
540 auto const& eqn = equations()[k];
541 auto const& sigma = eqn.predicate_variables()[i].sigma();
542 data::variable d_n = eqn.parameters()[n];
543 data::data_expression x = sigma(d_n);
544 if (x == d_n)
545 {
547 }
548 else
549 {
550 return x;
551 }
552 }
553
555 {
556 data::rewriter R(m_data);
557 for (stategraph_equation& eqn: equations())
558 {
559 eqn.compute_source_target_copy(R);
560 }
561 }
562
564 {
565 std::ostringstream out;
566 for (const stategraph_equation& eqn: equations())
567 {
568 out << "equation = " << print_equation(eqn) << std::endl;
569 out << eqn.print_source_target_copy() << std::endl;
570 }
571 return out.str();
572 }
573};
574
575inline
576std::vector<stategraph_equation>::const_iterator find_equation(const stategraph_pbes& p, const core::identifier_string& X, bool warn = true)
577{
578 auto const& equations = p.equations();
579 for (auto i = equations.begin(); i != equations.end(); ++i)
580 {
581 if (i->variable().name() == X)
582 {
583 return i;
584 }
585 }
586 if (warn)
587 {
588 mCRL2log(log::log_level_t::debug) << "find_equation: could not find predicate variable " << X << std::endl;
589 }
590 return equations.end();
591}
592
593} // namespace mcrl2::pbes_system::detail
594
595
596
597
598
599#endif // MCRL2_PBES_DETAIL_STATEGRAPH_PBES_H
Rewriter that operates on data expressions.
Definition rewriter.h:84
\brief A data variable
Definition variable.h:25
std::map< std::size_t, data::data_expression > m_source
const propositional_variable_instantiation & variable() const
const std::set< std::size_t > & used() const
data::data_expression source(std::size_t k) const
std::map< std::size_t, data::data_expression > m_target
predicate_variable(const propositional_variable_instantiation &X_, const pbes_expression &guard_)
const std::set< std::size_t > & changed() const
data::rewriter::substitution_type m_sigma
const std::map< std::size_t, data::data_expression > & target() const
const data::data_expression_list & parameters() const
const data::rewriter::substitution_type & sigma() const
data::data_expression target(std::size_t k) const
const std::map< std::size_t, data::data_expression > & source() const
const core::identifier_string & name() const
propositional_variable_instantiation X
const std::map< std::size_t, std::size_t > & copy() const
std::map< std::size_t, std::size_t > m_copy
const std::vector< std::size_t > & control_flow_parameter_indices() const
data::data_expression_list project(const data::data_expression_list &e) const
const data::variable_vector & data_parameters() const
const std::vector< data::variable > & parameters() const
void find_equality_conjuncts(const pbes_expression &x, const std::vector< data::variable > &d, std::map< data::variable, data::data_expression > &result) const
void set_data_parameters(const std::set< std::size_t > &DP) const
Sets the data parameters of this equation.
std::vector< predicate_variable > & predicate_variables()
stategraph_equation(const pbes_equation &eqn, const data::rewriter &rewr)
const std::vector< predicate_variable > & predicate_variables() const
const pbes_expression & simple_guard() const
void set_control_flow_parameters(const std::set< std::size_t > &CFP) const
Sets the control flow parameters of this equation.
std::vector< predicate_variable > m_predvars
bool is_cf(const std::map< core::identifier_string, std::vector< bool > > &is_control_flow, const core::identifier_string &X, std::size_t i) const
std::vector< std::size_t > m_control_flow_parameter_indices
const data::variable_vector & control_flow_parameters() const
const std::vector< std::size_t > & data_parameter_indices() const
propositional_variable_instantiation m_initial_state
std::set< data::variable > m_global_variables
const std::set< data::variable > & global_variables() const
const propositional_variable_instantiation & initial_state() const
const std::vector< stategraph_equation > & equations() const
data::data_expression source(std::size_t k, std::size_t i, std::size_t n) const
std::vector< stategraph_equation > & equations()
std::set< data::variable > & global_variables()
std::vector< stategraph_equation > m_equations
stategraph_pbes(const pbes &p, const data::rewriter &rewr)
Constructor.
A rewriter that simplifies expressions that simplifies quantifiers.
const pbes_expression & formula() const
Returns the predicate formula on the right hand side of the equation.
pbes_expression(const pbes_expression &) noexcept=default
Move semantics.
parameterized boolean equation system
Definition pbes.h:54
const propositional_variable_instantiation & initial_state() const
Returns the initial state.
Definition pbes.h:187
\brief A propositional variable instantiation
const data::data_expression_list & parameters() const
propositional_variable_instantiation(const propositional_variable_instantiation &) noexcept=default
Move semantics.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:435
const data::data_expression & undefined_data_expression()
Returns a data expression that corresponds to 'undefined'.
Definition undefined.h:58
std::ostream & operator<<(std::ostream &out, const predicate_variable &x)
Computes a multimap of propositional variable instantiations and the corresponding guards from a PBES...