10#ifndef MCRL2_PBES_CONSTELM_H
11#define MCRL2_PBES_CONSTELM_H
31 for (
const auto& i : m)
33 result[i.first] = i.second;
66 return !(*
this == other);
81 std::ostringstream out;
90 std::list<quantified_variable>
Q;
95 return std::tie(
Q,
X_e) < std::tie(other.
Q, other.
X_e);
116 typedef std::multimap<QPVI, edge_details>
edge_map;
120 std::set<data::variable>
FV;
139 typedef std::list<detail::quantified_variable>
qvar_list;
172 for (
auto& i: ec1.
edges)
174 auto& [Q_X_e, details] = i;
175 details.conditions.insert(negate2 ? ec2.
Cneg : ec2.
Cpos);
176 (
is_conjunctive ? details.conjunctive_context_FV : details.disjunctive_context_FV)
177 .insert(ec2.
FV.begin(), ec2.
FV.end());
180 for (
auto& i: ec2.
edges)
182 auto& [Q_X_e, details] = i;
183 details.conditions.insert(negate1 ? ec1.
Cneg : ec1.
Cpos);
184 (
is_conjunctive ? details.conjunctive_context_FV : details.disjunctive_context_FV)
185 .insert(ec1.
FV.begin(), ec1.
FV.end());
286 for (
auto& [X_e, details]: ec.
edges)
288 auto& [cond_set, conj_FV, disj_FV] = details;
291 std::set<data::data_expression> new_conditions;
296 new_conditions.insert(t);
298 cond_set = std::move(new_conditions);
324 for (
auto& [X_e, details]: ec.
edges)
326 auto& [cond_set, conj_FV, disj_FV] = details;
329 std::set<data::data_expression> new_conditions;
334 new_conditions.insert(t);
336 cond_set = std::move(new_conditions);
365 data::variable_list vars(
is_forall(expr) ? atermpp::down_cast<forall>(expr).variables() : atermpp::down_cast<exists>(expr).variables());
371 QPVI Q_X_e{qvars, x};
375 ec.
edges.insert(std::make_pair(Q_X_e,
377 std::set<data::variable>{}, std::set<data::variable>{}}));
393template <
typename DataRewriter,
typename PbesRewriter>
399 typedef std::list<detail::quantified_variable>
qvar_list;
443 const std::set<data::variable>& conj_context,
444 const std::set<data::variable>& disj_context,
459 std::ostringstream out;
463 out << qv.to_string();
497 for (
auto it = Q.crbegin(); it != Q.crend(); ++it)
504 result.push_front(*it);
545 return std::all_of(free_vars.begin(), free_vars.end(), [&](
const data::variable& v)
547 return std::find_if(qvars.begin(), qvars.end(), [&](const detail::quantified_variable& qvar){ return qvar.variable() == v; }) != qvars.end();
556 while (!deleted_constraints.empty())
558 std::set<data::variable> vars_deleted;
563 deleted_constraints.clear();
567 return vars_deleted.find(qv.variable()) != vars_deleted.end();
570 m_qvars.erase(m_qvars.begin(), del_i.base());
574 auto k = m_constraints.find(par);
575 if(k == m_constraints.end())
579 if(!bound_in_quantifiers(m_qvars, k->second))
581 deleted_constraints.push_back(k->second);
582 m_constraints.erase(k);
613 return m_constraints;
620 std::vector<std::size_t> result;
621 std::size_t index = 0;
626 result.push_back(index);
637 std::ostringstream out;
638 out << m_variable <<
" assertions = ";
641 out << v.to_string();
643 for (
const auto& constraint: m_constraints)
645 out <<
"{" << constraint.first <<
" := " << constraint.second <<
"} ";
654 bool changed =
false;
668 std::vector<data::data_expression> deleted_constraints;
669 auto par = params.
begin();
670 for (
auto i = e.
begin(); i != e.
end(); ++i, ++par)
673 if (bound_in_quantifiers(m_qvars, e1))
675 m_constraints[*par] = e1;
679 deleted_constraints.push_back(e1);
682 fix_constraints(deleted_constraints);
687 auto mismatch_it = std::mismatch(m_qvars.rbegin(), m_qvars.rend(), qvars.rbegin(), qvars.rend()).first;
688 changed |= mismatch_it != m_qvars.rend();
690 m_qvars.erase(m_qvars.begin(), mismatch_it.base());
694 std::vector<data::data_expression> deleted_constraints;
696 for (
auto par = params.
begin(); i != e.
end(); ++i, ++par)
698 auto k = m_constraints.find(*par);
699 if(k == m_constraints.end())
705 if (fi != ei || !bound_in_quantifiers(m_qvars, fi))
708 deleted_constraints.push_back(fi);
709 deleted_constraints.push_back(ei);
710 m_constraints.erase(k);
713 fix_constraints(deleted_constraints);
720 typedef std::map<core::identifier_string, vertex>
vertex_map;
723 typedef std::map<core::identifier_string, std::vector<edge> >
edge_map;
739 std::ostringstream out;
740 for (
const auto& v: m_vertices)
742 out << v.second.to_string() << std::endl;
750 std::ostringstream out;
751 for (
const auto& source: m_edges)
753 for (
const auto& e: source.second)
755 out << e.to_string() << std::endl;
763 std::ostringstream out;
764 out <<
"\n<todo list> [";
765 for (
auto i = todo.begin(); i != todo.end(); ++i)
767 if (i != todo.begin())
773 out <<
"]" << std::endl;
779 std::ostringstream out;
780 out <<
"\n<updating edge> " << e.
to_string() << std::endl;
781 out <<
" <source vertex > " << u.
to_string() << std::endl;
782 out <<
" <target vertex before> " << v.
to_string() << std::endl;
788 std::ostringstream out;
791 out <<
" <condition > " << e.
condition() <<
sigma <<
" to " << value << std::endl;
797 std::ostringstream out;
800 out <<
"\nCould not evaluate condition " << e.
condition() <<
sigma <<
" to true or false";
804 template <
typename E>
805 std::list<E>
concat(
const std::list<E> a,
const std::list<E> b)
807 std::list<E> result(a);
808 result.insert(result.end(), b.begin(), b.end());
818 : m_data_rewriter(datar), m_pbes_rewriter(pbesr)
825 std::map<propositional_variable, std::vector<data::variable> > result;
826 for (
const std::pair<
const core::identifier_string, std::vector<std::size_t>>& red_pair: m_redundant_parameters)
828 const vertex& v = m_vertices.find(red_pair.first)->second;
829 std::vector<data::variable>& variables = result[v.
variable()];
830 for (
const std::size_t par: red_pair.second)
833 std::advance(k, par);
834 variables.push_back(*k);
844 void run(
pbes& p,
bool compute_conditions =
false,
bool check_quantifiers =
true)
848 m_redundant_parameters.clear();
854 m_vertices[name] =
vertex(eqn.variable());
858 f.
apply(eqn.formula());
860 std::vector<edge>& edges = m_edges[name];
861 for (
const auto& [Q_X_e, details]: f.
result())
863 const auto& [Q, X_e] = Q_X_e;
864 const auto& [conditions, conj_FV, disj_FV] = details;
872 edges.emplace_back(eqn.variable(), quantifier_list, X_e, conj_FV, disj_FV, condition);
878 std::deque<propositional_variable> todo;
888 while (!todo.empty())
894 todo.erase(std::remove(todo.begin(), todo.end(), var), todo.end());
896 const vertex& u = m_vertices[var.name()];
897 const std::vector<edge>& u_edges = m_edges[var.name()];
899 for (
const edge& e: u_edges)
901 vertex& v = m_vertices[e.target().name()];
917 e.target().parameters(),
935 const vertex& v = m_vertices[name];
941 m_redundant_parameters[name] = r;
950 const vertex& v = m_vertices[name];
959 body = i->make_expr(body);
976 for (
const std::pair<
const propositional_variable, std::vector<data::variable>>& i: redundant_parameters())
997 bool compute_conditions =
false,
998 bool remove_redundant_equations =
true,
999 bool check_quantifiers =
true
1006 switch (rewriter_type)
1011 pbes_rewriter pbesr(datar);
1013 algorithm.
run(p, compute_conditions, check_quantifiers);
1014 if (remove_redundant_equations)
1016 std::vector<propositional_variable> V = algorithms::remove_unreachable_variables(p);
1024 bool enumerate_infinite_sorts = (rewriter_type ==
quantifier_all);
1027 algorithm.
run(p, compute_conditions, check_quantifiers);
1028 if (remove_redundant_equations)
1030 std::vector<propositional_variable> V = algorithms::remove_unreachable_variables(p);
Term containing a string.
const_iterator end() const
Returns a const_iterator pointing to the end of the term_list.
const Term & front() const
Returns the first element of the list.
const_iterator begin() const
Returns a const_iterator pointing to the beginning of the term_list.
data_expression()
\brief Default constructor X3.
Rewriter that operates on data expressions.
basic_rewriter< data_expression >::substitution_type substitution_type
\brief The and operator for pbes expressions
const data::variable & variable() const
pbes_expression make_expr(const pbes_expression &expr) const
std::string to_string() const
bool operator<(const quantified_variable &other) const
quantified_variable(bool is_forall, const data::variable &var)
bool operator==(const quantified_variable &other) const
bool operator!=(const quantified_variable &other) const
\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
Represents an edge of the dependency graph. The assignments are stored implicitly using the 'right' p...
edge(const propositional_variable &src, const qvar_list &qvars, const propositional_variable_instantiation &tgt, const std::set< data::variable > &conj_context, const std::set< data::variable > &disj_context, data::data_expression c=data::sort_bool::true_())
Constructor.
const propositional_variable_instantiation & target() const
The propositional variable instantiation that determines the target of the edge.
qvar_list quantifier_inside_approximation(const qvar_list &Q) const
Try to guess which quantifiers of Q can end up directly before target, when the quantifier inside rew...
const propositional_variable_instantiation m_target
The propositional variable instantiation that determines the target of the edge.
const qvar_list & quantified_variables() const
const qvar_list m_qvars
The quantifiers in whose direct context the target PVI occurs.
const propositional_variable m_source
The propositional variable at the source of the edge.
const std::set< data::variable > m_disj_context
edge()=default
Constructor.
const data::data_expression & condition() const
The condition of the edge.
const std::set< data::variable > m_conj_context
const propositional_variable & source() const
The propositional variable at the source of the edge.
std::string to_string() const
Returns a string representation of the edge.
Represents a vertex of the dependency graph.
void fix_constraints(std::vector< data::data_expression > deleted_constraints)
Weaken the constraints so they satisfy.
const qvar_list & quantified_variables() const
qvar_list m_qvars
The list of quantified variables that occur in the constraints.
std::string to_string() const
Returns a string representation of the vertex.
bool update(const qvar_list &qvars, const data::data_expression_list &e, const constraint_map &e_constraints, const DataRewriter &datar)
Assign new values to the parameters of this vertex, and update the constraints accordingly....
constraint_map m_constraints
Maps data variables to data expressions. If a parameter is not.
bool m_visited
Indicates whether this vertex has been visited at least once.
const constraint_map & constraints() const
Maps data variables to data expressions. If the right hand side is a data variable,...
bool is_constant(const data::variable &v) const
Returns true if the parameter v has been assigned a constant expression.
propositional_variable m_variable
The propositional variable that corresponds to the vertex.
std::vector< std::size_t > constant_parameter_indices() const
Returns the indices of the constant parameters of this vertex.
const propositional_variable & variable() const
The propositional variable that corresponds to the vertex.
bool bound_in_quantifiers(const qvar_list &qvars, const data::data_expression &e)
Returns true iff all free variables in e are bound in qvars.
vertex(propositional_variable x)
Constructor.
vertex()=default
Constructor.
Algorithm class for the constelm algorithm.
const PbesRewriter & m_pbes_rewriter
Compares data expressions for equality.
std::string print_todo_list(const std::deque< propositional_variable > &todo)
vertex_map m_vertices
The vertices of the dependency graph. They are stored in a map, to support searching for a vertex.
std::string print_edge_update(const edge &e, const vertex &u, const vertex &v)
std::map< propositional_variable, std::vector< data::variable > > redundant_parameters() const
Returns the parameters that have been removed by the constelm algorithm.
std::string print_edges()
Logs the edges of the dependency graph.
pbes_constelm_algorithm(const DataRewriter &datar, const PbesRewriter &pbesr)
Constructor.
std::map< core::identifier_string, std::vector< edge > > edge_map
The storage type for edges.
std::map< core::identifier_string, std::vector< std::size_t > > m_redundant_parameters
The redundant parameters.
std::list< E > concat(const std::list< E > a, const std::list< E > b)
std::string print_evaluation_failure(const edge &e, const vertex &u)
std::map< core::identifier_string, vertex > vertex_map
The storage type for vertices.
std::list< detail::quantified_variable > qvar_list
std::map< data::variable, data::data_expression > constraint_map
A map with constraints on the vertices of the graph.
const DataRewriter & m_data_rewriter
Compares data expressions for equality.
void run(pbes &p, bool compute_conditions=false, bool check_quantifiers=true)
Runs the constelm algorithm.
edge_map m_edges
The edges of the dependency graph. They are stored in a map, to easily access all out-edges correspon...
std::string print_condition(const edge &e, const vertex &u, const pbes_expression &value)
std::string print_vertices() const
Logs the vertices of the dependency graph.
parameterized boolean equation system
const data::data_specification & data() const
Returns the data specification.
const propositional_variable_instantiation & initial_state() const
Returns the initial state.
const std::vector< pbes_equation > & equations() const
Returns the equations.
\brief A propositional variable instantiation
const data::data_expression_list & parameters() const
const core::identifier_string & name() const
\brief A propositional variable declaration
const data::variable_list & parameters() const
const core::identifier_string & name() const
MCRL2_EXPORT bool init(rewriter_interface *i, RewriterCompilingJitty *this_rewriter)
static RewriterCompilingJitty::substitution_type & sigma(RewriterCompilingJitty *this_rewriter)
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
std::string pp(const identifier_string &x)
data_expression join_and(ForwardTraversalIterator first, ForwardTraversalIterator last)
Returns and applied to the sequence of data expressions [first, last)
const function_symbol & true_()
Constructor for function symbol true.
void optimized_exists(Term &result, const VariableSequence &l, const Term &p, bool remove_variables=false)
Make an existential quantification.
void optimized_or(Term &result, const Term &p, const Term &q)
Make a conjunction, and optimize if possible.
rewrite_strategy
The strategy of the rewriter.
std::string pp(const abstraction &x)
std::set< data::variable > find_free_variables(const data::data_expression &x)
void optimized_not(Term &result, const Term &arg)
Make a negation.
void optimized_and(Term &result, const Term &p, const Term &q)
Make a conjunction, and optimize if possible.
void optimized_forall(Term &result, const VariableSequence &l, const Term &p, bool remove_variables=false)
Make a universal quantification.
void remove_parameters(pbes &x, const std::set< data::variable > &to_be_removed)
Removes parameters from propositional variable instantiations in a pbes expression.
void make_constelm_substitution(const std::map< data::variable, data::data_expression > &m, data::rewriter::substitution_type &result)
bool is_conjunctive(const pbes_expression &phi)
pbes_rewriter_type
An enumerated type for the available pbes rewriters.
bool is_exists(const atermpp::aterm &x)
bool is_constant(const pbes_expression &x)
bool is_forall(const atermpp::aterm &x)
bool is_false(const pbes_expression &t)
Test for the value false.
void replace_free_variables(T &x, const Substitution &sigma, typename std::enable_if<!std::is_base_of< atermpp::aterm, T >::value >::type *=nullptr)
bool is_true(const pbes_expression &t)
Test for the value true.
std::set< T > set_union(const std::set< T > &x, const std::set< T > &y)
Returns the union of two sets.
std::set< T > set_difference(const std::set< T > &x, const std::set< T > &y)
Returns the difference of two sets.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
void swap(atermpp::unprotected_aterm_core &t1, atermpp::unprotected_aterm_core &t2) noexcept
Swaps two aterms.
add your file description here.
add your file description here.
add your file description here.
add your file description here.
add your file description here.
void apply(const pbes_system::pbes_equation &x)
A quantified predicate variable instantiation.
std::list< quantified_variable > Q
propositional_variable_instantiation X_e
bool operator<(const QPVI &other) const
void leave(const exists &x)
void push(const stack_elem &x)
void leave(const forall &x)
stack_elem::edge_map edge_map
std::vector< stack_elem > condition_fv_stack
pbes_expression_traverser< edge_condition_traverser > super
const stack_elem & top() const
void leave(const propositional_variable_instantiation &x)
std::list< detail::quantified_variable > qvar_list
void merge_conditions(stack_elem &ec1, bool negate1, stack_elem &ec2, bool negate2, stack_elem &ec, bool is_conjunctive)
const edge_map & result() const
std::list< pbes_expression > quantified_context
void enter(const forall &x)
edge_traverser_stack_elem stack_elem
void leave(const data::data_expression &x)
void enter(const exists &x)
std::set< data::variable > disjunctive_context_FV
The set of free variables that occur on the other side of the conjunctions this PVI occurs in....
std::set< data::variable > conjunctive_context_FV
The set of free variables that occur on the other side of the conjunctions this PVI occurs in....
std::set< data::data_expression > conditions
Contains expressions that characterise when an edge is enabled. The conjunction of these expressions ...
std::set< data::variable > FV
data::data_expression Cpos
std::multimap< QPVI, edge_details > edge_map
data::data_expression Cneg
edge_traverser_stack_elem(const data::data_expression &cond_pos, const data::data_expression &cond_neg, std::set< data::variable > &&free_vars)
An attempt for improving the efficiency.
A rewriter that simplifies boolean expressions in a term, and rewrites data expressions.