mCRL2
Loading...
Searching...
No Matches
pbesinst_alternative_lazy_algorithm.h
Go to the documentation of this file.
1// Author(s): Xiao Qi
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/pbesinst_alternative_lazy_algorithm.h
10/// \brief An alternative lazy algorithm for instantiating a PBES, ported from
11/// bes_deprecated.h.
12
13#ifndef MCRL2_PBES_PBESINST_ALTERNATIVE_LAZY_ALGORITHM_H
14#define MCRL2_PBES_PBESINST_ALTERNATIVE_LAZY_ALGORITHM_H
15
16#include "mcrl2/pbes/remove_level.h"
17#include "mcrl2/pbes/detail/check_well_formed_bes.h"
18#include "mcrl2/pbes/pbesinst_algorithm.h"
19#include "mcrl2/pbes/search_strategy.h"
20#include "mcrl2/pbes/transformation_strategy.h"
21
22
23
24namespace mcrl2::pbes_system
25{
26
27namespace detail
28{
29 // The following function is a helper function to allow to create m_pv_renaming outside
30 // the class such that the class becomes a lightweight object.
31
35{
36 std::size_t index = 0;
39 {
41 {
43 {
45 ss << "X" << index;
47 }
48 else
49 {
51 }
52 index++;
53 }
54 }
55 return pv_renaming;
56 }
57
59 {
60 protected:
62
63 public:
66 {}
67
68
70 {
71 assert(m_pv_renaming.count(v)>0);
72 return m_pv_renaming.at(v);
73 }
74 };
75} // end namespace detail
76
77
79 const mcrl2::pbes_system::pbes_expression& p, const mcrl2::data::data_specification& data_spec)
80{
81 using namespace mcrl2;
82 using namespace mcrl2::pbes_system;
83
84 if (is_pbes_and(p))
85 {
86 const and_& pa=atermpp::down_cast<and_>(p);
89 }
90 else if (is_pbes_or(p))
91 {
92 const or_& po=atermpp::down_cast<or_>(p);
95 }
96 else if (is_pbes_imp(p))
97 {
98 const imp& pi=atermpp::down_cast<imp>(p);
101 }
102 else if (is_pbes_not(p))
103 {
104 return not_(pbes_expression_order_quantified_variables(atermpp::down_cast<not_>(p).operand(),data_spec));
105 }
106 else if (is_pbes_forall(p))
107 {
108 const forall& pf=atermpp::down_cast<forall>(p);
110 return make_forall_(mcrl2::data::order_variables_to_optimise_enumeration(pf.variables(),data_spec),expr);
111 }
112 else if (is_pbes_exists(p))
113 {
114 const exists& pe=atermpp::down_cast<exists>(p);
116 return make_exists_(mcrl2::data::order_variables_to_optimise_enumeration(pe.variables(),data_spec),expr);
117 }
118 else
119 {
120 return p;
121 }
122}
123
124/// \brief An alternative lazy algorithm for instantiating a PBES, ported from
125/// bes_deprecated.h.
127{
128 protected:
130
131 /// \brief Data rewriter.
133
134 /// \brief The rewriter.
136
137 /// \brief Initial value for regeneration_period.
138 static const std::size_t regeneration_count_init = 100;
139
140 /// The maximum size that the todo buffer is allowed to have.
142
143 /// The variable m_approximimate_true indicates whether
144 /// boolean variables that cannot be dealt with as the todo buffer
145 /// would otherwise exceeds m_maximum_todo_size are set to true or
146 /// to false
148
149 /// When the todo buffer is limited, due to m_maximum_todo_size, then the variable below counts how
150 /// many elements are dropped out of the todo buffer.
152
153 /// Indicate to which extent explored bes equations that turn out not to reachable can be thrown away.
154 /// Values are: none, some or all.
156
157 /// \brief Propositional variable instantiations that need to be handled.
159
160 /// \brief The content of todo as a set.
162
163 /// \brief Map a variable instantiation to a set of other variable
164 /// instantiations on whose right hand sides it appears.
166
167 /// \brief Map a variable instantiation to its right hand side.
169
170 /// \brief Map a variable instantiations to its right hand side
171 /// when the latter is trivial (either true or false).
173
174 /// \brief instantiations[i] contains all instantiations of the variable
175 /// of the i-th equation in the PBES.
177
178 /// \brief symbols[i] contains the fixedpoint symbol of the i-th equation
179 /// in the PBES.
181
182 /// \brief ranks[i] contains the rank of the i-th equation in the PBES.
184
185 /// \brief The initial value.
187
188 /// \brief A lookup map for PBES equations.
190
191 /// \brief The search strategy to use when exploring the state space.
192 search_strategy m_search_strategy;
193
194 /// \brief Transformation strategy.
195 transformation_strategy m_transformation_strategy;
196
197 /// \brief Prints a log message for every 1000-th equation
198 void print_equation_count(const std::size_t nr_of_processed_variables,
199 const std::size_t nr_of_generated_variables,
200 const std::size_t todo_size) const
201 {
202 static time_t last_log_time = time(nullptr) - 1;
203 time_t new_log_time=0;
204 if (time(&new_log_time) > last_log_time)
205 {
206 last_log_time = new_log_time;
207 mCRL2log(mcrl2::log::status) << "Processed " << nr_of_processed_variables <<
208 " and generated " << nr_of_generated_variables <<
209 " boolean variables";
210 if (m_maximum_todo_size != std::numeric_limits<std::size_t>::max())
211 {
212 mCRL2log(mcrl2::log::status) << " with a todo buffer of size " << todo_size << ". \n";
213 }
214 else
215 {
216 mCRL2log(mcrl2::log::status) << ". \n"; // Extra spaces, as the log messages are shown repeatedly on top of each other and can shorten, leaving residual letter on the output.
217 }
218 }
219 }
220
221 public:
222
223 /// \brief Constructor.
224 /// \param data_spec A data specification.
225 /// \param datar A data rewriter.
226 /// \param search_strategy A search strategy (e.g. breadth_first).
227 /// \param transformation_strategy A strategy to transform the PBES into a BES.
228 /// \param erase_unused_bes_variables An indicator how often unreachable variables must be garbage collected.
229 /// \param maximum_todo_size An indication of the maximal size of the stack with explorable
230 /// BES variables. If the stack exceeds this size, the ignored variable is set to
231 /// true or false, depending on the parameter \p approximate_true.
232 /// \param approximate_true If true BES variables that are not investigated are set to false. If false
233 /// these variables are set to true.
235 const data::rewriter& datar,
236 search_strategy search_strategy = breadth_first,
237 transformation_strategy transformation_strategy = lazy,
238 const mcrl2::pbes_system::remove_level erase_unused_bes_variables = mcrl2::pbes_system::none,
239 const std::size_t maximum_todo_size = std::numeric_limits<std::size_t>::max(),
240 const bool approximate_true = true)
241 : m_data_spec(data_spec),
242 m_datar(datar),
243 R(datar, data_spec),
245 m_approximate_true(approximate_true),
246
248 m_search_strategy(search_strategy),
249 m_transformation_strategy(transformation_strategy)
250 {
251 // Initialize the random generator, with an arbitrary seed, depending on a new time.
252 time_t t=time(nullptr);
253 for (; t == time(nullptr);)
254 {
255 ; // Wait until time changes.
256 }
257 srand((unsigned)time(nullptr));
258
259 if (m_search_strategy == breadth_first_short)
260 {
261 m_search_strategy = breadth_first;
262 }
263 else if (m_search_strategy == depth_first_short)
264 {
265 m_search_strategy = depth_first;
266 }
267 }
268
270 {
271 assert(todo.size()==todo_set.size());
272 if (m_search_strategy == breadth_first)
273 {
274 const propositional_variable_instantiation X_e = todo.front();
275 todo.pop_front();
276 todo_set.erase(X_e);
277 return X_e;
278 }
279 else
280 {
281 const propositional_variable_instantiation X_e = todo.back();
282 todo.pop_back();
283 todo_set.erase(X_e);
284 return X_e;
285 }
286 }
287
289 {
290 if (todo.size()<m_maximum_todo_size) // If there is no limit on todo, m_maximimum_todo_size is equal to npos.
291 {
292 todo.push_back(X);
293 todo_set.insert(X); // XXXXX
294 }
295 else
296 {
297 ++m_elements_not_stored_in_todo_buffer;
298 if ((rand() % (todo.size() + m_elements_not_stored_in_todo_buffer)) < todo.size())
299 {
300 std::size_t index = rand() % (todo.size());
301 const propositional_variable_instantiation Y=todo[index];
302 equation[Y]=(m_approximate_true?false_():true_());
303 trivial[Y]=equation[Y];
304 instantiations[equation_index[Y.name()]].push_back(Y);
305
306 todo_set.erase(Y);
307 todo[index]=X;
308 todo_set.insert(X);
309 }
310 else
311 {
312 equation[X]=(m_approximate_true?false_():true_());
313 instantiations[equation_index[X.name()]].push_back(X);
314 trivial[X]=equation[X];
315 }
316 }
317 }
318
320 {
321 return ranks[equation_index[X.name()]];
322 }
323
324 template <bool is_mu>
326 const pbes_expression& expr,
328 std::size_t rank,
329 std::unordered_map<propositional_variable_instantiation, bool>& visited)
330 {
331 if (is_false(expr) || is_true(expr))
332 {
333 return false;
334 }
336 {
337 const propositional_variable_instantiation& Y = atermpp::vertical_cast<propositional_variable_instantiation>(expr);
338 if (Y == X)
339 {
340 return true;
341 }
342 else if (get_rank(Y) != rank)
343 {
344 return false;
345 }
346 if (visited.count(Y))
347 {
348 return visited[Y];
349 }
350 if (equation.count(Y) == 0)
351 {
352 return false;
353 }
354 visited[Y] = false;
355 bool b = find_loop_rec<is_mu>(equation[Y], X, rank, visited);
356 visited[Y] = b;
357 return b;
358 }
359
360 if (is_mu)
361 {
362 if (is_and(expr))
363 {
364 const and_& expra=atermpp::down_cast<and_>(expr);
365 return find_loop_rec<is_mu>(expra.left(), X, rank, visited) ||
366 find_loop_rec<is_mu>(expra.right(), X, rank, visited);
367 }
368 if (is_or(expr))
369 {
370 const or_& expro=atermpp::down_cast<or_>(expr);
371 return find_loop_rec<is_mu>(expro.left(), X, rank, visited) &&
372 find_loop_rec<is_mu>(expro.right(), X, rank, visited);
373 }
374 }
375 else
376 {
377 if (is_and(expr))
378 {
379 const and_& expra=atermpp::down_cast<and_>(expr);
380 return find_loop_rec<is_mu>(expra.left(), X, rank, visited) &&
381 find_loop_rec<is_mu>(expra.right(), X, rank, visited);
382 }
383 if (is_or(expr))
384 {
385 const or_& expro=atermpp::down_cast<or_>(expr);
386 return find_loop_rec<is_mu>(expro.left(), X, rank, visited) ||
387 find_loop_rec<is_mu>(expro.right(), X, rank, visited);
388 }
389 }
390 return false;
391 }
392
393 template <bool is_mu>
395 {
396 std::unordered_map<propositional_variable_instantiation, bool> visited;
397 return find_loop_rec<is_mu>(expr, X, get_rank(X), visited);
398 }
399
401 {
402 if (m_erase_unused_bes_variables==pbes_system::none)
403 {
404 // Nothing will be thrown away. Therefore, it makes no sense to rebuild
405 // the data structures on the basis of reachable bes variables.
406 return;
407 }
408
409 // Create a set of reachable propositional_variable_instantiations
410 // and use that to clean up the set of equations.
411 std::unordered_set<propositional_variable_instantiation> reachable;
412
413 todo.clear();
414 todo_set.clear();
415 occurrence.clear();
416 for(std::vector<propositional_variable_instantiation>& vec: instantiations)
417 {
418 vec.clear();
419 }
420 assert(instantiations.size()==0 || instantiations[0].size()==0);
421
422
423 std::stack<pbes_expression> stack;
424 stack.push(init);
425
426 while (!stack.empty())
427 {
428 const pbes_expression expr = stack.top();
429 stack.pop();
430
431 if (is_propositional_variable_instantiation(expr))
432 {
433 const propositional_variable_instantiation& X = atermpp::vertical_cast<propositional_variable_instantiation>(expr);
434 if (reachable.count(X) == 0)
435 {
436 if (equation.count(X)>0)
437 {
438 stack.push(equation[X]);
439 reachable.insert(X);
440 }
441 else
442 {
443 add_todo(X);
444 }
445 }
446 }
447 else if (is_and(expr))
448 {
449 const and_& expra=atermpp::down_cast<and_>(expr);
450 stack.push(expra.left());
451 stack.push(expra.right());
452 }
453 else if (is_or(expr))
454 {
455 const or_& expro=atermpp::down_cast<or_>(expr);
456 stack.push(expro.left());
457 stack.push(expro.right());
458 }
459 }
460 // erase non reachable equations.
461 std::unordered_map<propositional_variable_instantiation, pbes_expression> new_equations;
462 for (const auto& i: equation)
463 {
464 // Insert the new equation if it is reachable, or if it equal to true or false and m_erase_unused_bes_variables is set to some.
465 if (reachable.count(i.first) > 0
466 || (m_erase_unused_bes_variables == pbes_system::some && (is_true(i.second) || is_false(i.second))))
467 {
468 new_equations.insert(i);
469 std::size_t index = equation_index[i.first.name()];
470 instantiations[index].push_back(i.first);
471 std::set<propositional_variable_instantiation> rhs_variables
472 = find_propositional_variable_instantiations(i.second);
473 for (const propositional_variable_instantiation& v: rhs_variables)
474 {
475 occurrence[v].insert(i.first);
476 }
477
478 }
479 }
480 equation.swap(new_equations);
481 }
482
483 // The function below simplifies a boolean_expression, given the knowledge that some propositional variables in trivial
484 // are known to be true or false. The idea is that variables that are redundant can be removed. If p = p1 && p2, and p1 is
485 // false, then p2 can be removed, as its value does not influence the rewrite system.
486 // The result of the function is a pair, with the simplified expression as first term, and the expression that is rewritten under the
487 // simplifications in trivial as the second term.
490 {
492 {
493 const std::unordered_map<propositional_variable_instantiation, pbes_expression>::const_iterator i=
494 trivial.find(atermpp::down_cast<propositional_variable_instantiation>(p));
495 if (i!=trivial.end() && (is_true(i->second) || is_false(i->second)))
496 {
497 return pbes_expression_pair(p,i->second);
498 }
499 return pbes_expression_pair(p,p);
500 }
501 else if (is_true(p)||is_false(p))
502 {
503 return pbes_expression_pair(p,p);
504 }
505 else if (is_and(p))
506 {
507 const and_& pa=atermpp::down_cast<and_>(p);
508 const pbes_expression_pair lhs=simplify_pbes_expression(pa.left(),trivial);
509 const pbes_expression_pair rhs=simplify_pbes_expression(pa.right(),trivial);
510 if (is_false(lhs.second))
511 {
512 return lhs;
513 }
514 if (is_false(rhs.second))
515 {
516 return rhs;
517 }
518 if (is_true(lhs.second))
519 {
520 return pbes_expression_pair(and_(lhs.first,rhs.first),rhs.second);
521 }
522 if (is_true(rhs.second))
523 {
524 return pbes_expression_pair(and_(lhs.first,rhs.first),lhs.second);
525 }
526 return pbes_expression_pair(and_(lhs.first,rhs.first),and_(lhs.first,rhs.first));
527 }
528 assert(is_or(p));
529 const or_& po=atermpp::down_cast<or_>(p);
530 const pbes_expression_pair lhs=simplify_pbes_expression(po.left(),trivial);
531 const pbes_expression_pair rhs=simplify_pbes_expression(po.right(),trivial);
532 if (is_true(lhs.second))
533 {
534 return lhs;
535 }
536 if (is_true(rhs.second))
537 {
538 return rhs;
539 }
540 if (is_false(lhs.second))
541 {
542 return pbes_expression_pair(or_(lhs.first,rhs.first),rhs.second);
543 }
544 if (is_false(rhs.second))
545 {
546 return pbes_expression_pair(or_(lhs.first,rhs.first),lhs.second);;
547 }
548 return pbes_expression_pair(or_(lhs.first,rhs.first),or_(lhs.first,rhs.first));
549 }
550
551
552
553 /// \brief Runs the algorithm. The result is obtained by calling the function \p get_result.
554 /// \param p A PBES
555 void run(pbes& p)
556 {
557 using utilities::detail::pick_element;
558 using utilities::detail::contains;
559
560 std::size_t regeneration_count=regeneration_count_init;
561 pbes_system::detail::instantiate_global_variables(p);
562
563 std::vector<pbes_equation>& pbes_equations = p.equations();
564
565 // simplify all right hand sides of p
566 //
567 // NOTE: This is not just an optimization. There are certain PBES
568 // equations for which applying enumerate_quantifiers_rewriter directly
569 // won't terminate, like:
570 //
571 // forall m: Nat . exists k: Nat . val(m == k)
572 pbes_system::one_point_rule_rewriter one_point_rule_rewriter;
573 pbes_system::simplify_quantifiers_data_rewriter<mcrl2::data::rewriter> simplify_rewriter(m_datar);
574 for (pbes_equation& eq: pbes_equations) // & is important as we change the equation.
575 {
576 eq.formula() = pbes_expression_order_quantified_variables(one_point_rule_rewriter(simplify_rewriter(eq.formula())), m_data_spec);
577 }
578
579 // initialize equation_index, instantiations, symbols and ranks
580 std::size_t eqn_index = 0;
581 ranks.resize(pbes_equations.size());
582 instantiations.resize(pbes_equations.size());
583 for (const pbes_equation& eqn: pbes_equations)
584 {
585 equation_index[eqn.variable().name()] = eqn_index;
586 symbols.push_back(eqn.symbol());
587 if (eqn_index > 0)
588 {
589 ranks[eqn_index] = ranks[eqn_index-1] + (symbols[eqn_index] == symbols[eqn_index-1] ? 0 : 1);
590 }
591 ++eqn_index;
592 }
593
594 init = atermpp::down_cast<propositional_variable_instantiation>(R(p.initial_state()));
596 while (!todo.empty())
597 {
598 const propositional_variable_instantiation X_e = next_todo();
599 std::size_t index = equation_index[X_e.name()];
600 instantiations[index].push_back(X_e);
601
602 const pbes_equation& eqn = pbes_equations[index];
603 data::rewriter::substitution_type sigma;
604 make_pbesinst_substitution(eqn.variable().parameters(), X_e.parameters(), sigma);
605 const pbes_expression& phi = eqn.formula();
606 pbes_expression psi_e = R(phi, sigma);
607 R.clear_identifier_generator();
608 try
609 {
610 check_whether_argument_is_a_well_formed_bes(psi_e);
611 }
612 catch (mcrl2::runtime_error& e)
613 {
614 throw mcrl2::runtime_error("Generated boolean equation system is not well formed.\n" + std::string(e.what()));
615 }
616 pbes_expression rewritten_psi_e;
617
618 if (m_transformation_strategy >= optimize)
619 {
620 // Substitute all trivial variable instantiations by their values
621 pbes_expression_pair p=simplify_pbes_expression(psi_e,trivial);
622 psi_e=p.first;
623 rewritten_psi_e=p.second;
624 }
625 else
626 {
627 rewritten_psi_e=psi_e;
628 }
629 // Store the result
630 equation[X_e] = psi_e;
631
632 if (m_transformation_strategy >= on_the_fly_with_fixed_points)
633 {
634 // Find mu or nu loop
635 if (eqn.symbol() == fixpoint_symbol::mu())
636 {
637 if (find_loop<true>(psi_e, X_e))
638 {
639 rewritten_psi_e = false_();
640 }
641 }
642 else
643 {
644 if (find_loop<false>(psi_e, X_e))
645 {
646 rewritten_psi_e = true_();
647 }
648 }
649 }
650
651
652 // Add all variable instantiations in psi_e to todo and generated,
653 // and augment the occurrence sets
654 std::set<propositional_variable_instantiation> psi_variables = find_propositional_variable_instantiations(psi_e);
655 for (const propositional_variable_instantiation& v: psi_variables)
656 {
657 if (todo_set.count(v) == 0 && equation.count(v) == 0)
658 {
659 add_todo(v);
660 }
661 occurrence[v].insert(X_e);
662 }
663
664 if (m_transformation_strategy >= optimize && (is_true(rewritten_psi_e) || is_false(rewritten_psi_e)))
665 {
666 trivial[X_e] = rewritten_psi_e;
667 if (m_transformation_strategy >= on_the_fly)
668 {
669 // Substitute X_e to its value in all its occurrences, and
670 // substitute all other variables to their values that are found
671 // to be either true or false in all their occurrences.
672 std::stack<propositional_variable_instantiation> new_trivials;
673 new_trivials.push(X_e);
674 while (!new_trivials.empty())
675 {
676 const propositional_variable_instantiation X = new_trivials.top();
677 new_trivials.pop();
678
679 const std::unordered_set<propositional_variable_instantiation> oc = occurrence[X];
680 std::unordered_map<propositional_variable_instantiation, pbes_expression> trivial_X;
681 trivial_X[X] = psi_e;
682 for (const propositional_variable_instantiation& Y: oc)
683 {
684 pbes_expression_pair p=simplify_pbes_expression(equation[Y],trivial);
685 equation[Y]=p.first;
686 const pbes_expression f=p.second;
687 if (is_true(f) || is_false(f))
688 {
689 trivial[Y] = f;
690 new_trivials.push(Y);
691 }
692 }
693 occurrence.erase(X);
694 }
695 }
696 }
697
698 if (m_transformation_strategy >= on_the_fly)
699 {
700 if (--regeneration_count == 0 || trivial.count(init)>0 )
701 {
702 regeneration_count = equation.size() / 2;
703 regenerate_states();
704 }
705 }
706
707 print_equation_count(equation.size(), equation.size()+todo.size(), todo.size()); // Print the number of equations every second in verbose mode.
708 detail::check_bes_equation_limit(equation.size());
709 }
710 // Remove unnessary equations.
712 }
713
714 /// \brief Returns the computed bes in pbes format
715 /// \return The computed bes in pbes format
716 pbes get_result(bool short_rename_scheme=true)
717 {
718 mCRL2log(log::verbose) << "Generated " << equation.size() << " BES equations in total, generating BES" << std::endl;
719 pbes result;
720 std::size_t index = 0;
721 const std::unordered_map<propositional_variable_instantiation,propositional_variable_instantiation>
722 pv_renaming = detail::create_pv_renaming(instantiations,short_rename_scheme);
723 detail::rename_pbesinst_consecutively renamer(pv_renaming);
724 for (const std::vector<propositional_variable_instantiation>& vec: instantiations)
725 {
726 const fixpoint_symbol symbol = symbols[index++];
727 for (const propositional_variable_instantiation& X_e: vec)
728 {
729 const propositional_variable lhs = propositional_variable(renamer(X_e).name(), data::variable_list());
730 const pbes_expression rhs = replace_propositional_variables(equation[X_e], renamer);
731 result.equations().emplace_back(symbol, lhs, rhs);
732 mCRL2log(log::debug) << "BESEquation: " << atermpp::aterm(symbol) << " " << lhs << " = " << rhs << std::endl;
733
734 }
735 }
736
737 result.initial_state() = renamer(init);
738 return result;
739 }
740
742 {
743 return R;
744 }
745};
746
747} // namespace mcrl2::pbes_system
748
749
750
751#endif // MCRL2_PBES_PBESINST_ALTERNATIVE_LAZY_ALGORITHM_H
Rewriter that operates on data expressions.
Definition rewriter.h:84
\brief The and operator for pbes expressions
and_(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
const pbes_expression & left() const
const pbes_expression & right() const
\brief The existential quantification operator for pbes expressions
const pbes_expression & body() const
\brief The universal quantification operator for pbes expressions
const pbes_expression & body() const
\brief The implication operator for pbes expressions
const pbes_expression & left() const
imp(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
const pbes_expression & right() const
A rewriter that applies one point rule quantifier elimination to a PBES.
\brief The or operator for pbes expressions
const pbes_expression & left() const
or_(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
const pbes_expression & right() const
parameterized boolean equation system
Definition pbes.h:54
propositional_variable_instantiation & initial_state()
Returns the initial state.
Definition pbes.h:195
An alternative lazy algorithm for instantiating a PBES, ported from bes_deprecated....
pbes_expression_pair simplify_pbes_expression(const pbes_expression &p, const std::unordered_map< propositional_variable_instantiation, pbes_expression > &trivial)
bool find_loop_rec(const pbes_expression &expr, propositional_variable_instantiation X, std::size_t rank, std::unordered_map< propositional_variable_instantiation, bool > &visited)
void add_todo(const propositional_variable_instantiation &X)
propositional_variable_instantiation init
The initial value.
static const std::size_t regeneration_count_init
Initial value for regeneration_period.
std::vector< fixpoint_symbol > symbols
symbols[i] contains the fixedpoint symbol of the i-th equation in the PBES.
std::unordered_map< core::identifier_string, std::size_t > equation_index
A lookup map for PBES equations.
void run(pbes &p)
Runs the algorithm. The result is obtained by calling the function get_result.
bool find_loop(pbes_expression expr, propositional_variable_instantiation X)
search_strategy m_search_strategy
The search strategy to use when exploring the state space.
transformation_strategy m_transformation_strategy
Transformation strategy.
pbesinst_alternative_lazy_algorithm(const data::data_specification &data_spec, const data::rewriter &datar, search_strategy search_strategy=breadth_first, transformation_strategy transformation_strategy=lazy, const mcrl2::pbes_system::remove_level erase_unused_bes_variables=mcrl2::pbes_system::none, const std::size_t maximum_todo_size=std::numeric_limits< std::size_t >::max(), const bool approximate_true=true)
Constructor.
void print_equation_count(const std::size_t nr_of_processed_variables, const std::size_t nr_of_generated_variables, const std::size_t todo_size) const
Prints a log message for every 1000-th equation.
std::unordered_map< propositional_variable_instantiation, pbes_expression > trivial
Map a variable instantiations to its right hand side when the latter is trivial (either true or false...
std::deque< propositional_variable_instantiation > todo
Propositional variable instantiations that need to be handled.
const std::size_t m_maximum_todo_size
The maximum size that the todo buffer is allowed to have.
std::size_t get_rank(const propositional_variable_instantiation &X)
std::unordered_set< propositional_variable_instantiation > todo_set
The content of todo as a set.
std::unordered_map< propositional_variable_instantiation, pbes_expression > equation
Map a variable instantiation to its right hand side.
pbes get_result(bool short_rename_scheme=true)
Returns the computed bes in pbes format.
std::unordered_map< propositional_variable_instantiation, std::unordered_set< propositional_variable_instantiation > > occurrence
Map a variable instantiation to a set of other variable instantiations on whose right hand sides it a...
std::vector< std::size_t > ranks
ranks[i] contains the rank of the i-th equation in the PBES.
\brief A propositional variable instantiation
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:393
std::unordered_map< propositional_variable_instantiation, propositional_variable_instantiation > create_pv_renaming(std::vector< std::vector< propositional_variable_instantiation > > &instantiations, bool short_renaming_scheme)
bool is_pbes_exists(const pbes_expression &t)
Returns true if the term t is an existential quantification.
bool is_pbes_not(const pbes_expression &t)
Returns true if the term t is a not expression.
bool is_pbes_forall(const pbes_expression &t)
Returns true if the term t is a universal quantification.
bool is_or(const atermpp::aterm &x)
bool is_pbes_or(const pbes_expression &t)
Returns true if the term t is an or expression.
bool is_false(const pbes_expression &t)
Test for the value false.
bool is_pbes_imp(const pbes_expression &t)
Returns true if the term t is an imp expression.
bool is_pbes_and(const pbes_expression &t)
Returns true if the term t is an and expression.
bool is_propositional_variable_instantiation(const atermpp::aterm &x)
mcrl2::pbes_system::pbes_expression pbes_expression_order_quantified_variables(const mcrl2::pbes_system::pbes_expression &p, const mcrl2::data::data_specification &data_spec)
bool is_and(const atermpp::aterm &x)
bool is_true(const pbes_expression &t)
Test for the value true.
A rewriter that simplifies boolean expressions and quantifiers, and rewrites data expressions.