12#ifndef MCRL2_PBES_PBESINST_STRUCTURE_GRAPH2_H
13#define MCRL2_PBES_PBESINST_STRUCTURE_GRAPH2_H
15#include "mcrl2/atermpp/standard_containers/deque.h"
16#include "mcrl2/atermpp/standard_containers/indexed_set.h"
17#include "mcrl2/atermpp/standard_containers/vector.h"
18#include "mcrl2/pbes/pbesinst_fatal_attractors.h"
19#include "mcrl2/pbes/pbesinst_find_loops.h"
20#include "mcrl2/pbes/pbesinst_partial_solve.h"
21#include "mcrl2/pbes/pbesinst_structure_graph.h"
22#include "mcrl2/utilities/stopwatch.h"
135 stack.push_back(elem);
140 auto result = stack.back();
167 stack.emplace_back(x, x, true_(), false_());
181 stack.emplace_back(data::undefined_data_expression(), x, true_(), false_());
183 else if (S[0].contains(u))
185 stack.emplace_back(true_(), x, x, false_());
187 else if (S[1].contains(u))
189 stack.emplace_back(false_(), x, true_(), x);
193 stack.emplace_back(data::undefined_data_expression(), x, true_(), false_());
202 auto& f1_prime = elem1.f;
203 auto& g0_1 = elem1.g0;
204 auto& g1_1 = elem1.g1;
206 auto& f2_prime = elem2.f;
207 auto& g0_2 = elem2.g0;
208 auto& g1_2 = elem2.g1;
211 if (is_true(b_1) && is_true(b_2))
214 f1_prime = and_(f1_prime, f2_prime);
215 g0_1 = and_(g0_1, g0_2);
218 else if (is_false(b_1) && !is_false(b_2))
225 else if (!is_false(b_1) && is_false(b_2))
232 else if (is_false(b_1) && is_false(b_2))
234 if (less(f1_prime, f2_prime))
251 b_1 = data::undefined_data_expression();
252 f1_prime = and_(f1_prime, f2_prime);
263 auto& f1_prime = elem1.f;
264 auto& g0_1 = elem1.g0;
265 auto& g1_1 = elem1.g1;
267 auto& f2_prime = elem2.f;
268 auto& g0_2 = elem2.g0;
269 auto& g1_2 = elem2.g1;
272 if (is_false(b_1) && is_false(b_2))
275 f1_prime = or_(f1_prime, f2_prime);
277 g1_1 = or_(g1_1, g1_2);
279 else if (is_true(b_1) && !is_true(b_2))
286 else if (!is_true(b_1) && is_true(b_2))
293 else if (is_true(b_1) && is_true(b_2))
295 if (less(f1_prime, f2_prime))
312 b_1 = data::undefined_data_expression();
313 f1_prime = or_(f1_prime, f2_prime);
321 throw mcrl2::
runtime_error(
"Fail to evaluate the expression " +
pbes_system::pp(x
) +
" as the routine Rplus does not expect an implication, which is an internal error.");
360 return S[0].contains(u) || S[1].contains(u);
367
368
369
370
371
372
373
374
375 for (
const propositional_variable_instantiation& X: todo.elements())
377 structure_graph::index_type u = m_graph_builder.find_vertex(X);
378 const structure_graph::vertex& u_ = m_graph_builder.vertex(u);
384 for (
const propositional_variable_instantiation& X: todo.irrelevant_elements())
386 structure_graph::index_type u = m_graph_builder.find_vertex(X);
387 const structure_graph::vertex& u_ = m_graph_builder.vertex(u);
399 std::size_t regeneration_period
410 atermpp::deque<pbes_expression> todo1{init};
411 atermpp::indexed_set<pbes_expression> done1;
412 atermpp::indexed_set<propositional_variable_instantiation> new_todo;
415 while (!todo1.empty())
417 using utilities::detail::contains;
422 auto u = m_graph_builder.find_vertex(X);
423 const auto& u_ = m_graph_builder.vertex(u);
425 if (u_.decoration == structure_graph::d_none && u_.successors.empty())
427 assert(is_propositional_variable_instantiation(u_.formula()));
428 new_todo.insert(atermpp::down_cast<propositional_variable_instantiation>(u_.formula()));
432 if (!S[0].contains(u) && !S[1].contains(u))
435 for (
auto v: G.successors(u))
437 const auto& v_ = m_graph_builder.vertex(v);
438 const auto& Y = v_.formula();
439 if (contains(done1, Y))
452 atermpp::deque<propositional_variable_instantiation> new_todo_list;
453 for (
const propositional_variable_instantiation& X: todo.irrelevant_elements())
455 if (contains(new_todo, X))
457 new_todo_list.push_back(X);
460 for (
const propositional_variable_instantiation& X: todo.elements())
462 if (contains(new_todo, X))
464 new_todo_list.push_back(X);
467 todo.set_todo(new_todo_list);
474 for (structure_graph::index_type u: S[0].vertices())
477 if (G.decoration(u) == structure_graph::d_disjunction && tau[0][u] == undefined_vertex())
479 mCRL2log(log::debug) <<
"Error: no strategy has been set for disjunctive node " << u <<
" in S0." << std::endl;
480 mCRL2log(log::debug) << G << std::endl;
481 mCRL2log(log::debug) <<
"S0 = " << S[0] << std::endl;
482 mCRL2log(log::debug) <<
"S1 = " << S[1] << std::endl;
486 for (structure_graph::index_type u: S[1].vertices())
489 if (G.decoration(u) == structure_graph::d_conjunction && tau[1][u] == undefined_vertex())
491 mCRL2log(log::debug) <<
"Error: no strategy has been set for conjunctive node " << u <<
" in S1." << std::endl;
492 mCRL2log(log::debug) << G << std::endl;
493 mCRL2log(log::debug) <<
"S0 = " << S[0] << std::endl;
494 mCRL2log(log::debug) <<
"S1 = " << S[1] << std::endl;
522 auto rplus_result =
Rplus(result
);
523 b[thread_index] = rplus_result.b;
524 if (is_true(rplus_result.b))
526 result = rplus_result.g0;
529 else if (is_false(rplus_result.b))
531 result = rplus_result.g1;
534 result = rplus_result.f;
545 S[0].resize(m_graph_builder.extent());
546 S[1].resize(m_graph_builder.extent());
549 if (is_true(b[thread_index]))
553 else if (is_false(b[thread_index]))
568 if (S_guard[0](S[0].size()))
571 S[0] = attr_default_with_tau(G, S[0], 0, tau);
573 if (S_guard[1](S[1].size()))
576 S[1] = attr_default_with_tau(G, S[1], 1, tau);
585 detail::find_loops2(G, S, tau, m_iteration_count);
596 detail::fatal_attractors(G, S, tau, m_iteration_count);
601 detail::fatal_attractors_original(G, S, tau, m_iteration_count);
607 detail::partial_solve(m_graph_builder.m_graph, todo, S, tau, m_iteration_count, m_graph_builder);
616 detail::find_loops(G, discovered, todo, S, tau, m_iteration_count, m_graph_builder);
622 mCRL2log(log::verbose) <<
"found solution for" << std::setw(12) << S[0].size() + S[1].size() <<
" BES equations" << std::endl;
628 for (
const propositional_variable_instantiation& e: elements)
630 todo.irrelevant_elements().erase(e);
632 prune_todo_list(init, todo, (discovered.size() - todo.size()) / 2);
645 std::set<structure_graph::index_type> V = extract_minimal_structure_graph(G, u, S[0], S[1], tau[0], tau[1]);
649 for (
std::size_t v = 0; v < n; v++)
logger(const log_level_t l)
Default constructor.
\brief The and operator for pbes expressions
computation_guard(std::size_t initial_count=64)
bool operator()(std::size_t count)
std::size_t regeneration_period
bool operator()(std::size_t period)
\brief The existential quantification operator for pbes expressions
\brief The universal quantification operator for pbes expressions
\brief The implication operator for pbes expressions
\brief The or operator for pbes expressions
parameterized boolean equation system
const pbessolve_options & m_options
Algorithm options.
virtual void rewrite_psi(const std::size_t, pbes_expression &result, const fixpoint_symbol &symbol, const propositional_variable_instantiation &X, const pbes_expression &psi)
propositional_variable_instantiation init
The initial value (after rewriting).
std::size_t m_iteration_count
Adds an optimization to pbesinst_structure_graph.
void on_discovered_elements(const std::set< propositional_variable_instantiation > &elements) override
This function is called when new elements are added to discovered.
detail::computation_guard fatal_attractors_guard
void rewrite_psi(const std::size_t thread_index, pbes_expression &result, const fixpoint_symbol &symbol, const propositional_variable_instantiation &X, const pbes_expression &psi) override
Rplus_traverser::stack_element Rplus(const pbes_expression &x)
bool todo_has_only_undefined_nodes() const
pbesinst_structure_graph_algorithm2(const pbessolve_options &options, const pbes &p, structure_graph &G)
void prune_todo_list(const propositional_variable_instantiation &init, pbesinst_lazy_todo &todo, std::size_t regeneration_period)
detail::computation_guard find_loops_guard
std::array< strategy_vector, 2 > tau
atermpp::vector< pbes_expression > b
std::array< vertex_set, 2 > S
detail::periodic_guard reset_guard
bool strategies_are_set_in_solved_nodes() const
pbes_expression expr(const T &x) const
pbesinst_structure_graph_algorithm super
bool solution_found(const propositional_variable_instantiation &init) const override
void on_report_equation(const std::size_t thread_index, const propositional_variable_instantiation &X, const pbes_expression &psi, std::size_t k) override
Reports BES equations that are produced by the algorithm. This function is called for every BES equat...
void on_end_while_loop() override
This function is called right after the while loop is finished.
std::array< detail::computation_guard, 2 > S_guard
Variant of pbesinst that will compute a structure graph for a PBES. The result will be put in the str...
detail::structure_graph_builder m_graph_builder
void on_report_equation(const std::size_t, const propositional_variable_instantiation &X, const pbes_expression &psi, std::size_t k) override
Reports BES equations that are produced by the algorithm. This function is called for every BES equat...
pbesinst_structure_graph_algorithm(const pbessolve_options &options, const pbes &p, structure_graph &G)
\brief A propositional variable instantiation
Standard exception class for reporting runtime errors.
Implements a simple stopwatch that starts on construction.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
The main namespace for the aterm++ library.
std::stack< std::reference_wrapper< detail::_aterm > > term_mark_stack
Namespace for all data library functionality.
bool is_false(const data_expression &x)
Test if x is false.
bool is_true(const data_expression &x)
Test if x is true.
The main namespace for the PBES library.
std::string pp(const pbes_system::forall &x)
constexpr unsigned int undefined_vertex()
std::string pp(const pbes_system::pbes_expression &x)
std::string pp(const pbes_system::imp &x)
std::string pp(const pbes_system::exists &x)
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
void erase_vertices(const vertex_set &U)
index_type find_vertex(const pbes_expression &x) const
std::size_t extent() const
atermpp::detail::reference_aterm< pbes_expression > f
stack_element(pbes_expression b_, pbes_expression f_, pbes_expression g0_, pbes_expression g1_)
atermpp::detail::reference_aterm< pbes_expression > g1
void mark(atermpp::term_mark_stack &todo) const
atermpp::detail::reference_aterm< pbes_expression > g0
atermpp::detail::reference_aterm< pbes_expression > b
void enter(const forall &x)
atermpp::vector< stack_element > stack
void leave(const exists &x)
detail::structure_graph_builder & graph_builder
const stack_element & top() const
void push(const stack_element &elem)
void leave(const data::data_expression &x)
pbes_expression_traverser< Rplus_traverser > super
std::array< vertex_set, 2 > & S
void enter(const exists &x)
static bool less(const pbes_expression &, const pbes_expression &)
Rplus_traverser(std::array< vertex_set, 2 > &S_, detail::structure_graph_builder &graph_builder_)
void leave(const forall &x)
void leave(const propositional_variable_instantiation &x)
vertex_set(std::size_t N)
void insert(structure_graph::index_type u)
std::size_t operator()(const atermpp::detail::reference_aterm< T > &t) const