11#ifndef MCRL2_PBES_QUANTIFIER_PROPAGATE_H
12#define MCRL2_PBES_QUANTIFIER_PROPAGATE_H
14#include "mcrl2/data/rewriter.h"
15#include "mcrl2/pbes/replace.h"
122 std::list<quantifier> result;
123 for(
const pbes_expression& pe: ctx)
125 assert(is_forall(pe) || is_exists(pe));
127 data::variable_list vars(is_forall(pe) ? atermpp::down_cast<forall>(pe).variables() : atermpp::down_cast<exists>(pe).variables());
129 if(result.empty() || result.back().is_forall() != is_forall(pe))
131 result.emplace_back(is_forall(pe), vars);
135 result.back().add_variables(vars);
143 return m_eqn_map.at(X_e.name());
158 quantified_context.push_back(x);
163 if(quantified_context.empty())
167 return make_quantifier(is_forall, vars, result);
172 quantified_context.pop_back();
201 quantified_context.clear();
206 quantified_context.clear();
211 quantified_context.clear();
216 quantified_context.clear();
227 std::list<quantifier> qvars = make_quantifier_list(quantified_context);
234 const std::vector<data::variable> parameters(find_equation(X_e).variable().parameters().begin(), find_equation(X_e).variable().parameters().end());
235 const std::vector<data::data_expression> updates(X_e.parameters().begin(), X_e.parameters().end());
237 std::list<std::size_t> independent_pars;
238 std::set<data::variable> quantified_variables;
239 for(
const quantifier& qv: qvars)
241 quantified_variables.insert(qv.variables().begin(), qv.variables().end());
245 std::set<data::variable> seen;
247 for(
const data::data_expression& up: updates)
249 std::set<data::variable> fv = find_free_variables(up);
250 if(set_includes(quantified_variables, fv))
252 independent_pars.push_back(i);
256 seen.insert(fv.begin(), fv.end());
260 std::queue<data::variable> todo(std::deque<data::variable>(seen.begin(), seen.end()));
266 data::variable elem = todo.front();
271 for(std::list<std::size_t>::const_iterator ip = independent_pars.begin(); ip != independent_pars.end(); )
273 std::set<data::variable> fv = find_free_variables(updates[*ip]);
274 if(contains(fv, elem))
276 for(
const data::variable& var: set_difference(fv, seen))
281 ip = independent_pars.erase(ip);
291 bool add_rest =
false;
292 for (
auto& qvar: std::ranges::reverse_view(qvars))
294 const std::set<data::variable>& vars = qvar.variables();
297 for(
const data::variable& var: set_difference(vars, seen))
303 else if(contains(vars, elem))
312 if(independent_pars.empty() ||
313 set_difference(qvars.back().variables(), seen).empty())
320 data::variable_list new_parameter_list;
321 data::data_expression_list new_update_list;
323 auto ip = independent_pars.begin();
324 data::rewriter::substitution_type sigma;
326 for(
const data::variable& par: parameters)
328 if(ip != independent_pars.end() && *ip == i)
330 sigma[par] = updates[i];
335 new_parameter_list.push_front(par);
336 new_update_list.push_front(updates[i]);
340 new_parameter_list = reverse(new_parameter_list);
341 new_update_list = reverse(new_update_list);
345 pbes_expression new_rhs_X = pbes_system::replace_free_variables(find_equation(X_e).formula(), sigma);
348 for (
auto& qvar: std::ranges::reverse_view(qvars))
350 new_Q_X_e = qvar.make_expr_include_only(seen, new_Q_X_e);
351 new_rhs_X = qvar.make_expr_exclude(seen, new_rhs_X);
353 pbes_equation new_eqn(find_equation(X_e).symbol(), propositional_variable(new_name, new_parameter_list), new_rhs_X);
354 m_new_equations.emplace_back(X_e.name(), new_eqn);
376 std::list<std::pair<core::identifier_string, pbes_equation>> new_equations;
377 detail::quantifier_propagate_builder::equation_map_t m_eqn_map;
379 for(
const pbes_equation& eq: p.equations())
381 id_gen.add_identifier(eq.variable().name());
382 m_eqn_map[eq.variable().name()] = eq;
385 for(pbes_equation& eqn: p.equations())
387 detail::quantifier_propagate(new_equations, id_gen, m_eqn_map, eqn.formula());
391 for(
const auto& [target, eqn]: new_equations)
394 p.equations().insert(
395 std::find_if(p.equations().begin(), p.equations().end(),
396 [t = target](
const pbes_equation& eq){
return eq.variable().name() == t; }),
Identifier generator that stores the identifiers of the context in a set. Using the operator()() and ...
\brief The and operator for pbes expressions
\brief The existential quantification operator for pbes expressions
const data::variable_list & variables() const
const pbes_expression & body() const
\brief The universal quantification operator for pbes expressions
const pbes_expression & body() const
const data::variable_list & variables() const
\brief The implication operator for pbes expressions
\brief The not operator for pbes expressions
\brief The or operator for pbes expressions
parameterized boolean equation system
\brief A propositional variable instantiation
const core::identifier_string & name() const
void quantifier_propagate(std::list< std::pair< core::identifier_string, pbes_equation > > &new_equations, data::set_identifier_generator &id_gen, const quantifier_propagate_builder::equation_map_t eqn_map, pbes_expression &x)
pbes_expression make_exists_(std::set< data::variable > vars, const pbes_expression &expr)
pbes_expression quantifier_propagate(const pbes_expression &x)
void quantifier_propagate(pbes &p)
pbes quantifier_propagate(const pbes &p)
quantifier_propagate_builder(std::list< std::pair< core::identifier_string, pbes_equation > > &new_eqns, data::set_identifier_generator &ig, const equation_map_t &eq_idx)
pbes_equation find_equation(const propositional_variable_instantiation &X_e)
void apply(T &result, const exists &x)
data::set_identifier_generator & id_gen
void apply(T &result, const forall &x)
void apply(T &result, const propositional_variable_instantiation &X_e)
pbes_expression apply_quantifier(bool is_forall, const data::variable_list &vars, const pbes_expression &body)
std::list< quantifier > make_quantifier_list(const std::list< pbes_expression > &ctx) const
const equation_map_t & m_eqn_map
std::list< pbes_expression > quantified_context