12#ifndef MCRL2_LPS_BINARY_H
13#define MCRL2_LPS_BINARY_H
15#include "mcrl2/data/enumerator.h"
16#include "mcrl2/lps/detail/lps_algorithm.h"
17#include "mcrl2/lps/detail/parameter_selection.h"
43template<
typename DataRewriter,
typename Specification>
82 if (new_parameters.empty())
84 result = enumerated_elements.front();
88 std::size_t n = enumerated_elements.size();
89 std::size_t m =
static_cast<
std::size_t>(1) << (new_parameters.size() - 1);
108 new_parameters.pop_back();
109 result = if_(condition,
121 const data::
variable_list& process_parameters = m_spec.process().process_parameters();
122 bool use_selection = !parameter_selection.empty();
124 std::list<data::variable> selected_params;
128 detail::parse_lps_parameter_selection(process_parameters, m_spec.data(), parameter_selection);
129 selected_params = std::list<data::variable>(sel.begin(), sel.end());
133 selected_params = std::list<data::variable>(process_parameters.begin(), process_parameters.end());
135 selected_params.remove_if([&](
const data::variable& v)
137 bool cannot_replace = v.sort() == data::sort_bool::bool_() || !m_spec.data().is_certainly_finite(v.sort());
138 if (cannot_replace && use_selection)
140 mCRL2log(log::info) <<
"Not selecting " << v <<
":" << v.sort() <<
" since it is already Bool, or its type is not finite." << std::endl;
142 return cannot_replace;
146 if (use_selection && selected_params.empty())
151 return std::set<data::variable>(selected_params.begin(), selected_params.end());
165 mCRL2log(log::debug) <<
"Original process parameters: " << data::pp(process_parameters) << std::endl;
168 generator.add_identifiers(
lps::find_identifiers(m_spec));
169 generator.add_identifiers(data::function_and_mapping_identifiers(m_spec.data()));
170 bool accept_solutions_with_variables =
false;
171 data::enumerator_algorithm<> enumerator(m_rewriter, m_spec.data(), m_rewriter, m_id_generator, accept_solutions_with_variables);
174 for (
const data::variable& par: process_parameters)
176 if (selected_params.find(par) != selected_params.end())
179 data::data_expression_vector enumerated_elements;
181 data::mutable_indexed_substitution<> local_sigma;
182 const data::variable_list vl{ par };
183 enumerator.enumerate(enumerator_element(vl, data::sort_bool::true_()),
185 [&](
const enumerator_element& p)
187 p.add_assignments(vl, local_sigma, m_rewriter);
188 enumerated_elements.push_back(local_sigma(par));
192 m_enumerated_elements[par] = enumerated_elements;
195 std::size_t n = nr_of_booleans_for_elements(enumerated_elements.size());
198 std::string par_name = par.name();
201 data::variable_vector new_pars;
203 for (std::size_t i = 0; i<n; ++i)
205 data::variable v(generator(par_name), data::sort_bool::bool_());
206 new_parameters.push_back(v);
207 new_pars.push_back(v);
211 mCRL2log(log::verbose) <<
"Parameter " << data::pp(par) <<
":" << data::pp(par.sort()) <<
" has been replaced by " << new_pars.size() <<
" parameter(s) " << data::pp(new_pars) <<
" of sort Bool" << std::endl;
214 m_new_parameters[par]=new_pars;
216 m_if_trees[par]=make_if_tree(new_pars,
217 enumerated_elements);
221 new_parameters.push_back(par);
227 m_spec.process().process_parameters() =
data::
variable_list(new_parameters.begin(),new_parameters.end());
228 for (
const data::variable& v: data::substitution_variables(m_if_trees))
230 m_if_trees_generator.add_identifier(v.name());
246 data::variable_list::const_iterator i=vl.begin();
247 for (
const data::data_expression& a: el_)
249 const data::variable par= *i;
251 if (m_new_parameters.find(par) == m_new_parameters.end())
257 data::variable_vector new_parameters = m_new_parameters[par];
258 data::data_expression_vector elements = m_enumerated_elements[par];
260 mCRL2log(log::debug) <<
"Found " << new_parameters.size() <<
" new parameter(s) for parameter " << data::pp(par) << std::endl;
262 for (std::size_t j = 0; j < new_parameters.size(); ++j)
264 data::data_expression_vector disjuncts;
266 data::data_expression_vector::iterator k = elements.begin();
267 while (k != elements.end())
270 std::ptrdiff_t count(
static_cast<std::ptrdiff_t>(1) << j);
271 if (std::distance(k, elements.end()) < count)
277 std::advance(k, count);
281 for (std::ptrdiff_t l = 0; l < count && k != elements.end(); ++l)
283 disjuncts.push_back(data::equal_to(a, *k++));
286 result.push_back(data::lazy::join_or(disjuncts.begin(), disjuncts.end()));
291 mCRL2log(log::debug) <<
"Replaced expression(s) " << data::pp(el_) <<
" in the initial state with expression(s) " << data::pp(result) << std::endl;
293 return data::data_expression_list(result.begin(),result.end());
303 v = data::replace_variables(v, m_if_trees);
306 for (
const data::assignment& a: v)
308 if (m_new_parameters.find(a.lhs()) == m_new_parameters.end())
314 data::variable_vector new_parameters = m_new_parameters[a.lhs()];
315 data::data_expression_vector elements = m_enumerated_elements[a.lhs()];
317 mCRL2log(log::debug) <<
"Found " << new_parameters.size() <<
" new parameter(s) for parameter " << data::pp(a.lhs()) << std::endl;
319 for (std::size_t j = 0; j < new_parameters.size(); ++j)
321 data::data_expression_vector disjuncts;
323 data::data_expression_vector::iterator k = elements.begin();
324 while (k != elements.end())
327 std::ptrdiff_t count(
static_cast<std::ptrdiff_t>(1) << j);
328 if (std::distance(k, elements.end()) < count)
334 std::advance(k, count);
338 for (std::ptrdiff_t l = 0; l < count && k != elements.end(); ++l)
340 disjuncts.push_back(data::equal_to(a.rhs(), *k++));
343 result.push_back(data::assignment(new_parameters[j], data::lazy::join_or(disjuncts.begin(), disjuncts.end())));
349 mCRL2log(log::debug) <<
"Replaced assignment(s) " << data::pp(v) <<
" with assignment(s) " << data::pp(result) << std::endl;
351 return data::assignment_list(result.begin(),result.end());
357 s.condition() = data::replace_variables_capture_avoiding(s.condition(), m_if_trees, m_if_trees_generator);
358 s.multi_action()=lps::replace_variables_capture_avoiding(s.multi_action(), m_if_trees, m_if_trees_generator);
359 s.assignments() = replace_enumerated_parameters_in_assignments(s.assignments());
365 update_action_summand(
static_cast<action_summand&>(s));
366 s.distribution() = lps::replace_variables_capture_avoiding(s.distribution(), m_if_trees, m_if_trees_generator);
372 s.condition() = data::replace_variables_capture_avoiding(s.condition(), m_if_trees, m_if_trees_generator);
373 lps::replace_variables_capture_avoiding(s.deadlock(), m_if_trees, m_if_trees_generator);
378 return process_initializer(replace_enumerated_parameters_in_initial_expressions(parameters, init.expressions()));
384
385
386 data::
data_expression_list d = replace_enumerated_parameters_in_initial_expressions(parameters, init.expressions());
387 const stochastic_distribution dist = lps::replace_variables_capture_avoiding(init.distribution(), d, m_if_trees, m_if_trees_generator);
388 return stochastic_process_initializer(d, dist);
397 const std::string parameter_selection =
"")
408 const std::set<data::variable> to_replace = select_parameters(m_parameter_selection);
409 replace_enumerated_parameters(to_replace);
413 m_spec.initial_process() = update_initial_process(old_parameters, m_spec.initial_process());
420 update_action_summand(a);
Rewriter that operates on data expressions.
Identifier generator that stores the identifiers of the context in a set. Using the operator()() and ...
logger(const log_level_t l)
Default constructor.
LPS summand containing a multi-action.
Algorithm class that can be used to apply the binary algorithm.
data::assignment_list replace_enumerated_parameters_in_assignments(data::assignment_list v)
Replace assignments in v that are of a finite sort with a vector of assignments to Boolean variables.
data::data_expression make_if_tree(data::variable_vector new_parameters, const data::data_expression_vector &enumerated_elements)
Build an if-then-else tree of enumerated elements in terms of new parameters.
binary_algorithm(Specification &spec, DataRewriter &r, const std::string parameter_selection="")
Constructor for binary algorithm.
void update_deadlock_summand(deadlock_summand &s)
Update a deadlock summand with the new Boolean parameters.
detail::lps_algorithm< Specification > super
std::map< data::variable, std::vector< data::data_expression > > m_enumerated_elements
Mapping of variables to all values they can be assigned.
stochastic_process_initializer update_initial_process(const data::variable_list ¶meters, const stochastic_process_initializer &init)
Specification::process_type process_type
data::set_identifier_generator m_if_trees_generator
Contains the names of variables appearing in rhs of m_if_trees.
const std::string m_parameter_selection
void replace_enumerated_parameters(const std::set< data::variable > &selected_params)
Take a specification and calculate a vector of boolean variables for each process parameter in select...
data::data_expression_list replace_enumerated_parameters_in_initial_expressions(const data::variable_list &vl, const data::data_expression_list &el)
Replace expressions in v that are of a finite sort with a vector of assignments to Boolean variables.
void update_action_summand(action_summand &s)
Update an action summand with the new Boolean parameters.
std::set< data::variable > select_parameters(const std::string parameter_selection) const
Determine which variables should be replaced, based on parameter_selection.
void run()
Apply the algorithm to the specification passed in the constructor.
process_type::action_summand_type action_summand_type
data::mutable_map_substitution m_if_trees
Mapping of variables to corresponding if-tree.
process_initializer update_initial_process(const data::variable_list ¶meters, const process_initializer &init)
DataRewriter m_rewriter
Rewriter.
std::map< data::variable, std::vector< data::variable > > m_new_parameters
Mapping of finite variables to boolean vectors.
void update_action_summand(stochastic_action_summand &s)
Update an action summand with the new Boolean parameters.
data::enumerator_list_element_with_substitution enumerator_element
data::enumerator_identifier_generator m_id_generator
Identifier generator for the enumerator.
Algorithm class for elimination of constant parameters.
LPS summand containing a deadlock.
Algorithm class for algorithms on linear process specifications. It can be instantiated with lps::spe...
Stores the following properties of a linear process specification:
LPS summand containing a multi-action.
\brief A stochastic distribution
A stochastic process initializer.
Linear process specification.
Standard exception class for reporting runtime errors.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
std::string pp(const atermpp::aterm &t)
Transform an aterm to an ascii string.
std::string pp_format_to_string(const print_format_type pp_format)
Print string representation of pretty print format.
smt_solver_type
The enumeration type smt_solver_type enumerates all available SMT solvers.
Namespace for all data library functionality.
std::vector< assignment > assignment_vector
\brief vector of assignments
std::vector< variable > variable_vector
\brief vector of variables
std::vector< data_expression > data_expression_vector
\brief vector of data_expressions
atermpp::term_list< data_expression > data_expression_list
\brief list of data_expressions
atermpp::term_list< variable > variable_list
\brief list of variables
atermpp::term_list< assignment > assignment_list
\brief list of assignments
std::string pp(const data::sort_expression_vector &x)
The main namespace for the LPS library.
void lpspp(const std::string &input_filename, const std::string &output_filename, bool print_summand_numbers, core::print_format_type format)
void lpssumelm(const std::string &input_filename, const std::string &output_filename, const bool decluster)
void txt2lps(const std::string &input_filename, const std::string &output_filename)
void lpsuntime(const std::string &input_filename, const std::string &output_filename, const bool add_invariants, const bool apply_fourier_motzkin, const data::rewriter::strategy rewrite_strategy)
std::string pp(const lps::stochastic_specification &x)
void lpssuminst(const std::string &input_filename, const std::string &output_filename, const data::rewriter::strategy rewrite_strategy, const std::string &sorts_string, const bool finite_sorts_only, const bool tau_summands_only)
std::size_t nr_of_booleans_for_elements(std::size_t n)
bool lpsinvelm(const std::string &input_filename, const std::string &output_filename, const std::string &invariant_filename, const std::string &dot_file_name, data::rewriter::strategy rewrite_strategy, data::detail::smt_solver_type solver_type, const bool no_check, const bool no_elimination, const bool simplify_all, const bool all_violations, const bool counter_example, const bool path_eliminator, const bool apply_induction, const int time_limit)
void lpsparelm(const std::string &input_filename, const std::string &output_filename)
void lpsbinary(const std::string &input_filename, const std::string &output_filename, const std::string ¶meter_selection)
lps_rewriter_type
An enumerated type for the available lps rewriters.
void lpsconstelm(const std::string &input_filename, const std::string &output_filename, data::rewriter::strategy rewrite_strategy, bool instantiate_free_variables, bool ignore_conditions, bool remove_trivial_summands, bool remove_singleton_sorts)
void lpsinfo(const std::string &input_filename, const std::string &input_file_message)
void parse_lps< stochastic_specification >(std::istream &from, stochastic_specification &result)
Parses a stochastic linear process specification from an input stream.
void lpsrewr(const std::string &input_filename, const std::string &output_filename, const data::rewriter::strategy rewrite_strategy, const lps_rewriter_type rewriter_type)
std::string pp_with_summand_numbers(const stochastic_specification &x)
std::size_t ceil_log2(std::size_t n)
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
std::size_t operator()(const atermpp::detail::reference_aterm< T > &t) const