12#ifndef MCRL2_PBES_PBESINST_FINITE_ALGORITHM_H
13#define MCRL2_PBES_PBESINST_FINITE_ALGORITHM_H
15#include "mcrl2/atermpp/aterm.h"
16#include "mcrl2/data/consistency.h"
17#include "mcrl2/data/data_expression.h"
18#include "mcrl2/data/enumerator.h"
19#include "mcrl2/data/replace.h"
20#include "mcrl2/pbes/algorithms.h"
21#include "mcrl2/pbes/detail/pbes_parameter_map.h"
22#include "mcrl2/pbes/join.h"
23#include "mcrl2/pbes/rewriters/data_rewriter.h"
41 core::identifier_string
rename(
const core::identifier_string& name,
const data::data_expression_list& parameters)
const
43 std::ostringstream out;
44 out << std::string(name);
45 for (
const data::data_expression& param: parameters)
47 out <<
"_" << data::pp(param);
49 return core::identifier_string(out.str());
54 core::identifier_string
operator()(
const core::identifier_string& name,
const data::data_expression_list& parameters)
const
61 if (id_generator.has_identifier(dest))
63 dest = id_generator(dest);
67 id_generator.add_identifier(dest);
96template <
typename PropositionalVariable,
typename Parameter>
98 const pbesinst_index_map& index_map,
99 std::vector<Parameter>& finite,
100 std::vector<Parameter>& infinite
103 auto pi = index_map.find(X.name());
104 assert(pi != index_map.end());
105 const std::vector<std::size_t>& v = pi->second;
106 auto i = X.parameters().begin();
107 std::size_t index = 0;
109 for (; i != X.parameters().end(); ++i, ++index)
111 if (j != v.end() && index == *j)
113 finite.push_back(*i);
118 infinite.push_back(*i);
124template <
typename DataRewriter,
typename SubstitutionFunction>
137 SubstitutionFunction& sigma,
140 const pbesinst_index_map& index_map,
141 const pbesinst_variable_map& variable_map
154 std::ostringstream out;
156 for (
const data::data_expression& e: finite_parameters)
161 for (
const data::data_expression& e: infinite_parameters)
170 template <
typename VariableContainer,
typename ExpressionContainer>
173 assert(variables.size() == expressions.size());
174 if (variables.empty())
178 auto vi = variables.begin();
179 auto ei = expressions.begin();
183 for (; vi != variables.end(); ++vi, ++ei)
190 template <
typename DataExpressionContainer>
193 return data::data_expression_list(v.begin(), v.end(), [&](
const data::data_expression& x) {
return rewr(x); });
196 template <
typename DataExpressionContainer>
199 return data::data_expression_list(v.begin(), v.end(), [&](
const data::data_expression& x) {
return rewr(x, sigma); });
205 using enumerator_element = data::enumerator_list_element_with_substitution<>;
208 std::vector<data::data_expression> finite_parameters;
209 std::vector<data::data_expression> infinite_parameters;
210 split_parameters(x, m_index_map, finite_parameters, infinite_parameters);
211 mCRL2log(log::debug) << print_parameters(finite_parameters, infinite_parameters);
212 data::data_expression_list d(finite_parameters.begin(), finite_parameters.end());
213 data::data_expression_list e(infinite_parameters.begin(), infinite_parameters.end());
217 auto vi = m_variable_map.find(Xi);
218 std::vector<data::variable> di;
219 if (vi != m_variable_map.end())
224 std::set<pbes_expression> result_set;
225 bool accept_solutions_with_variables =
false;
227 data::enumerator_algorithm<> E(super::R, m_data_spec, super::R, id_generator, accept_solutions_with_variables);
228 const data::variable_list di_list(di.begin(), di.end());
229 data::mutable_indexed_substitution<> local_sigma;
230 E.enumerate(enumerator_element(di_list, data::true_()),
232 [&](
const enumerator_element& p) {
233 data::mutable_indexed_substitution<> sigma_i;
234 p.add_assignments(di_list, sigma_i, super::R);
235 data::data_expression_list d_copy = rewrite_container(d, super::R, sigma);
236 data::data_expression_list e_copy = rewrite_container(e, super::R, sigma);
237 data::data_expression_list di_copy(di_list);
238 di_copy = data::replace_free_variables(di_copy, sigma_i);
239 data::data_expression c = make_condition(di_copy, d_copy);
240 core::identifier_string Y = m_rename(Xi, di_copy);
241 result_set.insert(and_(atermpp::down_cast<pbes_expression>(c), propositional_variable_instantiation(Y, e_copy)));
245 result = join_or(result_set.begin(), result_set.end());
251 std::vector<data::data_expression> finite_parameters_vector;
252 std::vector<data::data_expression> infinite_parameters_vector;
253 split_parameters(init, m_index_map, finite_parameters_vector, infinite_parameters_vector);
255 data::data_expression_list finite_parameters = rewrite_container(finite_parameters_vector, super::R);
256 data::data_expression_list infinite_parameters = rewrite_container(infinite_parameters_vector, super::R);
257 core::identifier_string X = m_rename(init.name(), finite_parameters);
258 return propositional_variable_instantiation(X, infinite_parameters);
279 const pbesinst_variable_map& variable_map,
280 pbesinst_index_map& index_map)
283 for (
const pbes_equation& eqn: equations)
285 const core::identifier_string& name = eqn.variable().name();
286 const data::variable_list& parameters = eqn.variable().parameters();
288 std::vector<std::size_t> v;
289 auto j = variable_map.find(name);
290 if (j != variable_map.end())
292 std::size_t index = 0;
293 for (
auto k = parameters.begin(); k != parameters.end(); ++k, ++index)
295 if (contains(j->second, *k))
308 if (size > 0 && size % 1000 == 0)
310 std::ostringstream out;
311 out <<
"Generated " << size <<
" BES equations" << std::endl;
328 void run(
pbes& pbesspec,
const pbesinst_variable_map& variable_map)
332 m_equation_count = 0;
335 pbesinst_index_map index_map;
336 compute_index_map(pbesspec.equations(), variable_map, index_map);
338 data::
rewriter rewr(pbesspec.data(), m_rewriter_strategy);
341 std::vector<pbes_equation> equations;
342 for (
const pbes_equation& eqn: pbesspec.equations())
344 std::vector<data::variable> finite_parameters;
345 std::vector<data::variable> infinite_parameters;
346 detail::split_parameters(eqn.variable(), index_map, finite_parameters, infinite_parameters);
347 data::variable_list infinite(infinite_parameters.begin(), infinite_parameters.end());
349 using enumerator_element = data::enumerator_list_element_with_substitution<>;
350 bool accept_solutions_with_variables =
false;
351 data::enumerator_algorithm<> E(rewr, pbesspec.data(), rewr, m_id_generator, accept_solutions_with_variables);
352 data::variable_list finite_parameter_list(finite_parameters.begin(), finite_parameters.end());
353 data::mutable_indexed_substitution<> sigma;
354 E.enumerate(enumerator_element(finite_parameter_list, data::true_()),
356 [&](
const enumerator_element& p) {
357 data::mutable_indexed_substitution<> sigma_j;
358 p.add_assignments(finite_parameter_list, sigma_j, rewr);
359 std::vector<data::data_expression> finite;
360 for (
const data::variable& v: finite_parameters)
362 finite.push_back(sigma_j(v));
364 core::identifier_string name = rename(eqn.variable().name(), data::data_expression_list(finite.begin(), finite.end()));
365 propositional_variable X(name, infinite);
366 detail::pbesinst_finite_builder<data::rewriter, data::mutable_indexed_substitution<>> visitor(rewr, sigma_j, rename, pbesspec.data(), index_map, variable_map);
367 pbes_expression formula;
368 visitor.apply(formula, eqn.formula());
369 equations.emplace_back(eqn.symbol(), X, formula);
370 mCRL2log(log::debug) << print_equation_count(++m_equation_count);
371 mCRL2log(log::debug) <<
"Added equation " << pbes_system::pp(eqn) <<
"\n";
383 pbesspec.equations() = equations;
392 pbesinst_variable_map variable_map;
393 for (
const pbes_equation& eqn: p.equations())
395 for (
const data::variable& v: eqn.variable().parameters())
397 if (p.data().is_certainly_finite(v.sort()))
399 variable_map[eqn.variable().name()].push_back(v);
404 run(p, variable_map);
411 if (finite_parameter_selection.empty())
413 throw empty_parameter_selection(
"no finite parameters were selected!");
416 pbes_system::detail::pbes_parameter_map parameter_map = pbes_system::detail::parse_pbes_parameter_map(p, finite_parameter_selection);
418 bool is_empty =
true;
419 for (
auto& i: parameter_map)
421 if (!((i.second).empty()))
429 mCRL2log(log::verbose) <<
"Warning: no parameters were found that match the string \"" + finite_parameter_selection +
"\"" << std::endl;
433 algorithm.run(p, parameter_map);
Rewriter that operates on data expressions.
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
\brief The universal quantification operator for pbes expressions
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
propositional_variable_instantiation & initial_state()
Returns the initial state.
Algorithm class for the finite pbesinst algorithm.
data::enumerator_identifier_generator m_id_generator
Identifier generator for the enumerator.
std::size_t m_equation_count
The number of generated equations.
void run(pbes &p)
Runs the algorithm.
void run(pbes &pbesspec, const pbesinst_variable_map &variable_map)
Runs the algorithm.
std::string print_equation_count(std::size_t size) const
Prints a message for every 1000-th equation.
data::rewriter::strategy m_rewriter_strategy
The strategy of the data rewriter.
void compute_index_map(const std::vector< pbes_equation > &equations, const pbesinst_variable_map &variable_map, pbesinst_index_map &index_map)
Returns true if the container contains the given element.
pbesinst_finite_algorithm(data::rewriter::strategy rewriter_strategy=data::jitty)
Constructor.
\brief A propositional variable instantiation
propositional_variable_instantiation(const core::identifier_string &name, const data::data_expression_list ¶meters)
Constructor.
const core::identifier_string & name() const
propositional_variable_instantiation & operator=(const propositional_variable_instantiation &) noexcept=default
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
data_expression and_(const data_expression &x, const data_expression &y)
const data_expression & true_()
std::set< data::variable > significant_variables(const pbes_expression &x)
Returns the significant variables of a pbes expression.
void remove_parameters(pbes &x, const std::set< data::variable > &to_be_removed)
Removes parameters from propositional variable instantiations in a pbes expression.
void remove_parameters(pbes &x, const std::map< core::identifier_string, std::vector< std::size_t > > &to_be_removed)
Removes parameters from propositional variable instantiations in a pbes expression.
void pbesinst_finite(pbes &p, data::rewrite_strategy rewrite_strategy, const std::string &finite_parameter_selection)
Apply finite instantiation to the given PBES.
void instantiate_global_variables(pbes &p)
Attempts to eliminate the free variables of a PBES, by substituting a constant value for them....
bool is_normalized(const pbes &x)
Checks if a PBEs is normalized.
std::vector< propositional_variable > remove_unreachable_variables(pbes &p)
Removes equations that are not (syntactically) reachable from the initial state of a PBES.
std::string print_removed_equations(const std::vector< propositional_variable > &removed)
Print removed equations.
void normalize(pbes &x)
The function normalize brings (embedded) pbes expressions into positive normal form,...
void split_parameters(const PropositionalVariable &X, const pbesinst_index_map &index_map, std::vector< Parameter > &finite, std::vector< Parameter > &infinite)
Computes the subset with variables of finite sort and infinite.
The main namespace for the PBES library.
pbes_expression make_exists_(const data::variable_list &l, const pbes_expression &p)
Make an existential quantification. It checks for an empty variable list, which is not allowed.
void pbesinst_finite(pbes &p, data::rewrite_strategy rewrite_strategy, const std::string &finite_parameter_selection)
pbes_expression make_forall_(const data::variable_list &l, const pbes_expression &p)
Make a universal quantification. It checks for an empty variable list, which is not allowed.
bool is_normalized(const T &x)
Checks if a pbes expression is normalized.
An empty struct that is used to denote the absence of a substitution. Used for rewriters.
Visitor that applies a propositional variable substitution to a pbes expression.
const pbesinst_finite_rename & m_rename
data::data_expression make_condition(const VariableContainer &variables, const ExpressionContainer &expressions) const
Computes the condition 'for all i: variables[i] == expressions[i]'.
void apply(T &result, const propositional_variable_instantiation &x)
const pbesinst_index_map & m_index_map
data::data_expression_list rewrite_container(const DataExpressionContainer &v, const data::rewriter &rewr, const data::mutable_indexed_substitution<> &sigma)
const pbesinst_variable_map & m_variable_map
std::string print_parameters(const std::vector< data::data_expression > &finite_parameters, const std::vector< data::data_expression > &infinite_parameters) const
propositional_variable_instantiation visit_initial_state(const propositional_variable_instantiation &init)
const data::data_specification & m_data_spec
data::data_expression_list rewrite_container(const DataExpressionContainer &v, const data::rewriter &rewr)
pbesinst_finite_builder(const DataRewriter &R, SubstitutionFunction &sigma, const pbesinst_finite_rename &rho, const data::data_specification &data_spec, const pbesinst_index_map &index_map, const pbesinst_variable_map &variable_map)
Exception that is used to signal an empty parameter selection.
empty_parameter_selection(const std::string &msg)
Function object for renaming a propositional variable instantiation.
core::identifier_string operator()(const core::identifier_string &name, const data::data_expression_list ¶meters) const
Renames the propositional variable x.
std::unordered_map< propositional_variable_instantiation, core::identifier_string > m
data::set_identifier_generator id_generator
core::identifier_string rename(const core::identifier_string &name, const data::data_expression_list ¶meters) const