10#ifndef MCRL2_PBES_EQELM_H
11#define MCRL2_PBES_EQELM_H
13#include "mcrl2/pbes/algorithms.h"
14#include "mcrl2/pbes/pbes_rewriter_type.h"
15#include "mcrl2/pbes/print.h"
16#include "mcrl2/pbes/replace.h"
17#include "mcrl2/pbes/rewriters/enumerate_quantifiers_rewriter.h"
23template <
typename Term,
typename DataRewriter,
typename PbesRewriter>
54 std::map< data::sort_expression, equivalence_class> m;
55 for (
const auto & i : X.parameters())
57 m[i.sort()].insert(i);
59 std::vector<equivalence_class> result;
62 if (i.second.size() > 1)
64 result.push_back(i.second);
73 std::ostringstream out;
74 for (
const auto& vertex: m_vertices)
76 out << vertex.first <<
" -> [ ";
77 const std::vector<equivalence_class>& v = vertex.second;
78 for (
auto j = v.begin(); j != v.end(); ++j)
84 out << core::detail::print_set(*j);
86 out <<
" ]" << std::endl;
94 std::ostringstream out;
95 for (
const auto& edge: m_edges)
97 out << edge.first <<
" -> " << core::detail::print_set(edge.second) << std::endl;
105 std::ostringstream out;
106 for (
const auto& vertex: m_vertices)
108 out <<
" vertex " << vertex.first <<
": ";
109 for (
const auto& j: vertex.second)
111 out << core::detail::print_set(j) <<
" ";
119 void log_todo_list(
const std::set<core::identifier_string>& todo,
const std::string& msg =
"")
const
122 mCRL2log(log::debug) << core::detail::print_set(todo) <<
"\n";
132 template <
typename VariableContainer>
135 return static_cast<std::size_t>(std::find(v.begin(), v.end(), x) - v.begin());
139 template <
typename Substitution>
141 const Substitution& vX,
142 std::set<core::identifier_string>& todo
146 std::vector<data::data_expression> e(Ye.parameters().begin(), Ye.parameters().end());
148 std::vector<equivalence_class>& cY = m_vertices[Y];
149 std::vector<equivalence_class> cY1;
150 for (
auto & equiv : cY)
152 std::map<data::data_expression, equivalence_class> w;
153 for (
const auto & k : equiv)
155 std::size_t p = index_of(k, m_parameters[Y]);
156 pbes_system::data_rewriter<DataRewriter> rewr(m_data_rewriter);
157 pbes_system::pbes_expression e_p = rewr(atermpp::down_cast<pbes_expression>(e[p]), vX);
158 w[atermpp::down_cast<
const data::data_expression>(e_p)].insert(k);
162 if (i.second.size() > 1)
164 cY1.push_back(i.second);
171 m_discovered[Y] =
true;
174 else if (!m_discovered[Y])
177 m_discovered[Y] =
true;
184 data::mutable_map_substitution<> result;
185 const std::vector<equivalence_class>& cX = m_vertices[X];
186 for (
const auto & s : cX)
188 for (
auto j = ++s.begin(); j != s.end(); ++j)
190 result[*j] = *s.begin();
203 for (pbes_equation& eqn: p.equations())
205 core::identifier_string X = eqn.variable().name();
206 data::mutable_map_substitution<> sigma = compute_substitution(X);
210 eqn.formula() = pbes_system::replace_variables_capture_avoiding(eqn.formula(), sigma);
215 std::map<core::identifier_string, std::vector<std::size_t> > to_be_removed;
216 for (pbes_equation& eqn: p.equations())
218 core::identifier_string X = eqn.variable().name();
219 const std::vector<equivalence_class>& eq = m_vertices[X];
220 for (
const auto & j : eq)
222 for (
auto k = ++j.begin(); k != j.end(); ++k)
224 to_be_removed[X].push_back(index_of(*k, m_parameters[X]));
226 std::sort(to_be_removed[X].begin(), to_be_removed[X].end());
230 pbes_system::algorithms::remove_parameters(p, to_be_removed);
245 void run(
pbes& p,
bool ignore_initial_state =
false)
249 std::set<core::identifier_string> todo;
252 for (pbes_equation& eqn: p.equations())
254 core::identifier_string name = eqn.variable().name();
255 m_edges[name] = find_propositional_variable_instantiations(eqn.formula());
256 m_vertices[name] = compute_equivalence_sets(eqn.variable());
257 const data::variable_list& param = eqn.variable().parameters();
258 m_parameters[name] = std::vector<data::variable>(param.begin(), param.end());
260 m_discovered[name] = ignore_initial_state;
263 if (!ignore_initial_state)
268 data::mutable_map_substitution<> vX = compute_substitution(X);
274 m_discovered[X] =
true;
275 update_equivalence_classes(kappa, vX, todo);
276 mCRL2log(log::debug) <<
"updated equivalence classes using initial state " << kappa <<
"\n" << print_equivalence_classes();
280 mCRL2log(log::verbose) <<
"--- vertices ---\n" << print_vertices();
281 mCRL2log(log::verbose) <<
"\n--- edges ---\n" << print_edges();
282 mCRL2log(log::debug) <<
"computed initial equivalence classes\n" << print_equivalence_classes();
285 while (!todo.empty())
287 mCRL2log(log::debug) <<
"todo list = " << core::detail::print_set(todo) <<
"\n";
288 mCRL2log(log::verbose) <<
"--- vertices ---\n" << print_vertices();
290 core::identifier_string X = *todo.begin();
292 mCRL2log(log::debug) <<
"choose todo element " << X <<
"\n";
295 data::mutable_map_substitution<> vX = compute_substitution(X);
296 const std::set<propositional_variable_instantiation>& edges = m_edges[X];
297 for (
const auto& Ye : edges)
300 if (evaluate_guard(X, Ye))
302 update_equivalence_classes(Ye, vX, todo);
303 mCRL2log(log::debug) <<
"updated equivalence classes using edge " << Ye <<
"\n" << print_equivalence_classes();
308 mCRL2log(log::verbose) <<
"\n--- result ---\n" << print_vertices();
319 data::rewrite_strategy rewrite_strategy,
320 pbes_rewriter_type rewriter_type,
321 bool ignore_initial_state =
false
328 switch (rewriter_type)
330 case pbes_rewriter_type::simplify:
333 pbes_rewriter pbesr(datar);
335 algorithm.run(p, ignore_initial_state);
338 case pbes_rewriter_type::quantifier_all:
339 case pbes_rewriter_type::quantifier_finite:
341 const enumerate_quantifiers_mode enum_mode = (rewriter_type == pbes_rewriter_type::quantifier_all?
342 expand_infinite_sorts_and_use_data_rewriter:
343 expand_finite_sorts);
346 algorithm.run(p, ignore_initial_state);
Rewriter that operates on data expressions.
Algorithm class for the eqelm algorithm.
void log_todo_list(const std::set< core::identifier_string > &todo, const std::string &msg="") const
Prints the todo list.
pbes_eqelm_algorithm(const DataRewriter &datar, const PbesRewriter &pbesr)
Constructor.
bool evaluate_guard(const core::identifier_string &, const propositional_variable_instantiation &)
Returns true if the vertex X should propagate its values to Y.
std::string print_edges() const
Prints the edges of the dependency graph.
data::mutable_map_substitution compute_substitution(const core::identifier_string &X)
Computes a substitution that corresponds to the equivalence relations in X.
const DataRewriter & m_data_rewriter
Compares data expressions for equality.
const PbesRewriter & m_pbes_rewriter
Compares data expressions for equality.
std::map< core::identifier_string, bool > m_discovered
Used for determining if a vertex has been visited before.
std::string print_equivalence_classes() const
Prints the equivalence classes.
std::string print_vertices() const
Prints the vertices of the dependency graph.
void update_equivalence_classes(const propositional_variable_instantiation &Ye, const Substitution &vX, std::set< core::identifier_string > &todo)
Propagate the equivalence relations given by the substitution vX over the edge Ye.
void apply_equivalence_relations(pbes &p)
Chooses one parameter for every equivalence class, and removes the others. All occurrences of the rem...
std::vector< equivalence_class > compute_equivalence_sets(const propositional_variable &X) const
Puts all parameters of the same sort in the same equivalence set.
std::size_t index_of(const data::variable &x, const VariableContainer &v)
Returns the index of the element x in the sequence v.
void run(pbes &p, bool ignore_initial_state=false)
Runs the eqelm algorithm.
parameterized boolean equation system
propositional_variable_instantiation & initial_state()
Returns the initial state.
\brief A propositional variable instantiation
const core::identifier_string & name() const
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
void eqelm(pbes &p, data::rewrite_strategy rewrite_strategy, pbes_rewriter_type rewriter_type, bool ignore_initial_state=false)
Apply the eqelm algorithm.
An attempt for improving the efficiency.
enumerate_quantifiers_rewriter(const data::rewriter &R, const data::data_specification &dataspec, const enumerate_quantifiers_mode enum_mode=expand_infinite_sorts_and_use_data_rewriter)
A rewriter that simplifies boolean expressions in a term, and rewrites data expressions using DataRew...