17#ifndef MCRL2_PBES_DETAIL_BQNF2PPG_REWRITER_H
18#define MCRL2_PBES_DETAIL_BQNF2PPG_REWRITER_H
20#include "mcrl2/pbes/detail/bqnf_visitor.h"
46 for (
const auto & eqn : p.equations()) {
47 equation_type e = eqn;
48 propositional_variable var = e.variable();
49 variable_names.insert(core::pp(var.name()));
64 std::string base; std::string name;
67 while (variable_names.find(name)!=variable_names.end()) {
68 if (variable_name_suffix.find(base) != variable_name_suffix.end()) {
69 suffix = variable_name_suffix[base] + 1;
71 variable_name_suffix[base] = suffix;
73 ss << base <<
"_" << suffix;
76 variable_names.insert(name);
97 equation_type eqn = equation_type
(sigma
, var
, e
);
98 equations.push_back(eqn);
101 term_type psi = qexpr;
105 if (is_simple_expression(l,
false)) {
113 equation_type eqn = equation_type
(sigma
, var
, e
);
114 equations.push_back(eqn);
115 }
else if (!qvars.empty() || !(is_or(qexpr) ? is_true(phi) : is_false(phi))) {
116 std::string fresh_varname = fresh_variable_name(var.name());
118 data::variable_list variable_parameters = var.parameters() + qvars;
121 propositional_variable(fresh_varname, variable_parameters);
123 propositional_variable_instantiation(fresh_varname, data::data_expression_list(variable_parameters));
127 expr
= fresh_var_instantiation;
129 expr
= or_(phi
, fresh_var_instantiation
);
133 expr
= fresh_var_instantiation;
135 expr
= imp(phi
, fresh_var_instantiation
);
138 if (!qvars.empty()) {
143 equation_type eqn = equation_type
(sigma
, var
, expr
);
144 equations.push_back(eqn);
147 equation_type new_eqn = equation_type
(sigma
, fresh_var
, psi
);
172 data::variable_list qvars = atermpp::down_cast<forall>(e).variables();
175 qvars = qvars + atermpp::down_cast<forall>(qexpr).variables();
178 bool result = visit_inner_implies(sigma, var, e, qvars, qexpr);
180 std::clog <<
"Unexpected result: expression not in form phi => psi: " << pp(e) << std::endl;
181 throw(std::runtime_error(
"Unexpected result: expression not in form phi => psi."));
205 equation_type eqn = equation_type
(sigma
, var
, e
);
206 equations.push_back(eqn);
209 term_type psi = qexpr;
213 bool l_is_simple = is_simple_expression(l,
false);
222 equation_type eqn = equation_type
(sigma
, var
, e
);
223 equations.push_back(eqn);
224 }
else if (!qvars.empty() || !is_true(phi)) {
225 std::string fresh_varname = fresh_variable_name(var.name());
226 data::variable_list variable_parameters = var.parameters() + qvars;
229 propositional_variable(fresh_varname, variable_parameters);
231 propositional_variable_instantiation(fresh_varname, data::data_expression_list(variable_parameters));
234 expr
= fresh_var_instantiation;
236 expr
= and_(phi
, fresh_var_instantiation
);
238 if (!qvars.empty()) {
243 equation_type eqn = equation_type
(sigma
, var
, expr
);
244 equations.push_back(eqn);
247 equation_type new_eqn = equation_type
(sigma
, fresh_var
, psi
);
273 data::variable_list qvars = atermpp::down_cast<exists>(e).variables();
275 qvars = qvars + atermpp::down_cast<exists>(qexpr).variables();
278 bool result = visit_inner_and_quantified(sigma, var, e, qvars, qexpr);
280 std::clog <<
"Unexpected result: expression not in form phi /\\ psi: " << pp(e) << std::endl;
281 throw(std::runtime_error(
"Unexpected result: expression not in form phi /\\ psi."));
301 data::variable_list qvars;
303 qvars = qvars + atermpp::down_cast<forall>(qexpr).variables();
308 equation_type eqn = dummy;
315 term_type psi = qexpr;
319 if (is_simple_expression(l,
false)) {
328 std::string fresh_varname = fresh_variable_name(var.name());
329 data::variable_list variable_parameters = var.parameters() + qvars;
332 propositional_variable(fresh_varname, variable_parameters);
334 propositional_variable_instantiation(fresh_varname, data::data_expression_list(variable_parameters));
338 expr
= fresh_var_instantiation;
340 expr
= or_(phi
, fresh_var_instantiation
);
344 expr
= fresh_var_instantiation;
346 expr
= imp(phi
, fresh_var_instantiation
);
350 expr = optimized_forall(qvars, expr);
354 eqn = equation_type
(sigma
, fresh_var
, psi
);
358 return std::make_pair(expr, eqn);
371 term_type conjunction =
true_();
372 std::vector<equation_type> new_eqns;
373 std::vector<term_type> conjuncts = split_conjuncts(e);
374 for (
auto expr: conjuncts)
376 std::pair<term_type, equation_type> p = rewrite_inner_bounded_forall(sigma, var, expr, dummy);
377 if (is_true(conjunction)) {
378 conjunction = p.first;
380 conjunction = and_(conjunction, p.first);
382 if (p.second != dummy) {
383 new_eqns.push_back(p.second);
387 equation_type eqn = equation_type
(sigma
, var
, conjunction
);
388 equations.push_back(eqn);
389 for (
const auto& new_eqn: new_eqns)
392 visit_bqnf_equation(new_eqn);
412 data::variable_list qvars;
414 qvars = qvars + atermpp::down_cast<exists>(qexpr).variables();
419 equation_type eqn = dummy;
426 term_type psi = qexpr;
430 if (is_simple_expression(l,
false)) {
439 std::string fresh_varname = fresh_variable_name(var.name());
440 data::variable_list variable_parameters = var.parameters() + qvars;
443 propositional_variable(fresh_varname, variable_parameters);
445 propositional_variable_instantiation(fresh_varname, data::data_expression_list(variable_parameters));
448 expr
= fresh_var_instantiation;
450 expr
= and_(phi
, fresh_var_instantiation
);
453 expr = optimized_exists(qvars, expr);
457 eqn = equation_type
(sigma
, fresh_var
, psi
);
461 return std::make_pair(expr, eqn);
475 std::vector<equation_type> new_eqns;
476 std::vector<term_type> disjuncts = split_disjuncts(e);
477 for (
auto expr: disjuncts)
479 std::pair<term_type, equation_type> p = rewrite_inner_bounded_exists(sigma, var, expr, dummy);
480 if (is_false(disjunction)) {
481 disjunction = p.first;
483 disjunction = or_(disjunction, p.first);
485 if (p.second != dummy) {
486 new_eqns.push_back(p.second);
490 equation_type eqn = equation_type
(sigma
, var
, disjunction
);
491 equations.push_back(eqn);
492 for (
const auto& new_eqn: new_eqns)
495 visit_bqnf_equation(new_eqn);
514 equation_type eqn = equation_type
(sigma
, var
, e
);
515 equations.push_back(eqn);
519 data::variable_list empty_seq;
520 visit_inner_implies(sigma, var, e, empty_seq, e) || visit_or(sigma, var, e);
522 data::variable_list empty_seq;
523 visit_inner_and_quantified(sigma, var, e, empty_seq, e) || visit_and(sigma, var, e);
541 equations.push_back(eqn);
\brief The and operator for pbes expressions
and_(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
\brief The implication operator for pbes expressions
imp(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
\brief The or operator for pbes expressions
or_(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
const pbes_expression & formula() const
Returns the predicate formula on the right hand side of the equation.
pbes_equation(const fixpoint_symbol &symbol, const propositional_variable &variable, const pbes_expression &expr)
Constructor.
const fixpoint_symbol & symbol() const
Returns the fixpoint symbol of the equation.
const propositional_variable & variable() const
Returns the pbes variable of the equation.
pbes_expression & operator=(pbes_expression &&) noexcept=default
pbes_expression & operator=(const pbes_expression &) noexcept=default
parameterized boolean equation system
\brief A propositional variable instantiation
\brief A propositional variable declaration
The namespace for accessor functions on pbes expressions.
const pbes_expression & arg(const pbes_expression &t)
Returns the pbes expression argument of expressions of type not, exists and forall.
const pbes_expression & left(const pbes_expression &t)
Returns the left hand side of an expression of type and, or or imp.
const pbes_expression & right(const pbes_expression &t)
Returns the right hand side of an expression of type and, or or imp.
static void inc_indent()
Increases the current indent level.
static void dec_indent()
Decreases the current indent level.
const pbes_expression & true_()
bool is_exists(const atermpp::aterm &x)
bool is_or(const atermpp::aterm &x)
bool is_forall(const atermpp::aterm &x)
bool is_false(const pbes_expression &t)
Test for the value false.
pbes_expression optimized_exists(const data::variable_list &l, const pbes_expression &p, bool remove_variables=false)
Make an existential quantification If l is empty, p is returned.
bool is_propositional_variable_instantiation(const atermpp::aterm &x)
bool is_and(const atermpp::aterm &x)
bool is_imp(const atermpp::aterm &x)
pbes_expression optimized_forall(const data::variable_list &l, const pbes_expression &p, bool remove_variables=false)
Make a universal quantification If l is empty, p is returned.
bool is_true(const pbes_expression &t)
Test for the value true.
const pbes_expression & false_()
bool visit_bqnf_equation(const equation_type &eqn) override
Visits a BQNF equation. Rewrites the equation to a PPG equation. The resulting equations are added to...
virtual bool visit_inner_and_quantified(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e, const data::variable_list &qvars, const term_type &qexpr)
Visits a conjunctive expression qexpr within a bounded existential quantifier expression e....
bool visit_bounded_forall(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e) override
Visits a bounded universal quantifier expression. Rewrites the expression to PPG form by collecting q...
std::set< std::string > variable_names
The set of variable names already in use.
virtual std::vector< equation_type > result()
Returns the result of the transformation.
bool visit_bqnf_expression(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e) override
Visits a BQNF expression. Rewrites the expression to PPG form. The resulting equations are added to t...
bool visit_and(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e) override
Visits a conjunctive expression. Rewrites the expression to PPG form. The resulting equations are add...
virtual std::pair< term_type, equation_type > rewrite_inner_bounded_exists(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e, const equation_type &dummy)
Rewrites an inner bounded existential quantifier expression to PPG form. Returns the rewritten expres...
std::vector< equation_type > equations
The sequence of equations resulting from the transformation.
virtual bool visit_inner_implies(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e, const data::variable_list &qvars, const term_type &qexpr)
Visits a disjunctive expression qexpr within a bounded universal quantifier expression e....
std::map< std::string, int > variable_name_suffix
A map from variable name prefix to the last suffix that has been added.
virtual std::pair< term_type, equation_type > rewrite_inner_bounded_forall(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e, const equation_type &dummy)
Rewrites an inner bounded universal quantifier expression to PPG form. Returns the rewritten expressi...
bqnf2ppg_rewriter(const pbes &p)
Constructor.
bool visit_or(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e) override
Visits a disjunctive expression. Rewrites the expression to PPG form. The resulting equations are add...
bool visit_bounded_exists(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e) override
Visits a bounded existential quantifier expression. Rewrites the expression to PPG form by collecting...
virtual std::string fresh_variable_name(const std::string &s)
Generates a fresh variable name, based on s (extending s).
A visitor class for PBES equations in BQNF. There is a visit_<node> function for each type of node....
virtual bool visit_bounded_quantifier(const fixpoint_symbol &sigma, const propositional_variable &var, const pbes_expression &e)
Visits a bounded quantifier expression.
static bool is_inner_implies(const pbes_expression &e)
Determines if an expression if of the form phi => psi or of the form phi \/ psi where phi is a simple...
static bool is_inner_and(const pbes_expression &e)
Determines if an expression if of the form phi /\ psi where phi is a simple expression and psi is an ...