mCRL2
Loading...
Searching...
No Matches
binary.h
Go to the documentation of this file.
1// Author(s): Jeroen Keiren
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
11
12#ifndef MCRL2_LPS_BINARY_H
13#define MCRL2_LPS_BINARY_H
14
18
19namespace mcrl2
20{
21
22namespace lps
23{
24
25// Compute the number of booleans needed to represent a set of size n.
26inline
27std::size_t nr_of_booleans_for_elements(std::size_t n)
28{
29 if(n == 1)
30 {
31 return 1;
32 }
33 else
34 {
35 return utilities::ceil_log2(n-1);
36 }
37}
38
43template<typename DataRewriter, typename Specification>
44class binary_algorithm: public detail::lps_algorithm<Specification>
45{
48 typedef typename Specification::process_type process_type;
49 typedef typename process_type::action_summand_type action_summand_type;
50 using super::m_spec;
51
52 protected:
54 DataRewriter m_rewriter;
55
56 const std::string m_parameter_selection;
57
59 std::map<data::variable, std::vector<data::variable> > m_new_parameters;
60
62 std::map<data::variable, std::vector<data::data_expression> > m_enumerated_elements;
63
66
69
72
78 const data::data_expression_vector& enumerated_elements)
79 {
81
82 if (new_parameters.empty())
83 {
84 result = enumerated_elements.front();
85 }
86 else
87 {
88 std::size_t n = enumerated_elements.size();
89 std::size_t m = static_cast<std::size_t>(1) << (new_parameters.size() - 1); //m == 2^(new_parameters.size() - 1)
90
91 if (m > n)
92 {
93 m = n;
94 }
95
96 data::data_expression_vector left_list(enumerated_elements.begin(), enumerated_elements.begin() + m);
98 if (m == n)
99 {
100 right_list = data::data_expression_vector(enumerated_elements.begin() + m - 1, enumerated_elements.end());
101 }
102 else
103 {
104 right_list = data::data_expression_vector(enumerated_elements.begin() + m, enumerated_elements.end());
105 }
106
107 data::data_expression condition = new_parameters.back();
108 new_parameters.pop_back();
109 result = if_(condition,
110 make_if_tree(new_parameters, right_list),
111 make_if_tree(new_parameters, left_list));
112 }
113
114 return result;
115 }
116
119 std::set<data::variable> select_parameters(const std::string parameter_selection) const
120 {
121 const data::variable_list& process_parameters = m_spec.process().process_parameters();
122 bool use_selection = !parameter_selection.empty();
123
124 std::list<data::variable> selected_params;
125 if (use_selection)
126 {
127 const data::variable_vector sel =
128 detail::parse_lps_parameter_selection(process_parameters, m_spec.data(), parameter_selection);
129 selected_params = std::list<data::variable>(sel.begin(), sel.end());
130 }
131 else
132 {
133 selected_params = std::list<data::variable>(process_parameters.begin(), process_parameters.end());
134 }
135 selected_params.remove_if([&](const data::variable& v)
136 {
137 bool cannot_replace = v.sort() == data::sort_bool::bool_() || !m_spec.data().is_certainly_finite(v.sort());
138 if (cannot_replace && use_selection)
139 {
140 mCRL2log(log::info) << "Not selecting " << v << ":" << v.sort() << " since it is already Bool, or its type is not finite." << std::endl;
141 }
142 return cannot_replace;
143 }
144 );
145
146 if (use_selection && selected_params.empty())
147 {
148 mCRL2log(log::info) << "No parameters were selected to be replaced." << std::endl;
149 }
150
151 return std::set<data::variable>(selected_params.begin(), selected_params.end());
152 }
153
160 void replace_enumerated_parameters(const std::set<data::variable>& selected_params)
161 {
162 data::variable_list process_parameters = m_spec.process().process_parameters();
163 data::variable_vector new_parameters;
164
165 mCRL2log(log::debug) << "Original process parameters: " << data::pp(process_parameters) << std::endl;
166
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);
172
173 // Transpose all process parameters, and replace those that are finite, and not bool with boolean variables.
174 for (const data::variable& par: process_parameters)
175 {
176 if (selected_params.find(par) != selected_params.end())
177 {
178 //Get all constructors for par
179 data::data_expression_vector enumerated_elements; // List to store enumerated elements of a parameter
180
182 const data::variable_list vl{ par };
184 local_sigma,
185 [&](const enumerator_element& p)
186 {
187 p.add_assignments(vl, local_sigma, m_rewriter);
188 enumerated_elements.push_back(local_sigma(par));
189 return false;
190 }
191 );
192 m_enumerated_elements[par] = enumerated_elements;
193
194 //Calculate the number of booleans needed to encode par
195 std::size_t n = nr_of_booleans_for_elements(enumerated_elements.size());
196
197 //Set hint for fresh variable names
198 std::string par_name = par.name();
199
200 // Temp list for storage
201 data::variable_vector new_pars;
202 //Create new parameters and add them to the parameter list.
203 for (std::size_t i = 0; i<n; ++i)
204 {
205 data::variable v(generator(par_name), data::sort_bool::bool_());
206 new_parameters.push_back(v);
207 new_pars.push_back(v);
208 }
209 // n = new_pars.size() && new_pars.size() = ceil(log_2(j)) && new_pars.size() = ceil(log_2(enumerated_elements.size()))
210
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;
212
213 //Store new parameters in a hastable
214 m_new_parameters[par]=new_pars;
215
216 m_if_trees[par]=make_if_tree(new_pars,
217 enumerated_elements);
218 }
219 else
220 {
221 new_parameters.push_back(par);
222 }
223 }
224
225 mCRL2log(log::debug) << "New process parameter(s): " << data::pp(new_parameters) << std::endl;
226
227 m_spec.process().process_parameters() = data::variable_list(new_parameters.begin(),new_parameters.end());
229 {
231 }
232 }
233
237 const data::variable_list& vl,
239 {
240 // We use replace_variables, to make sure that the binding variables of assignments are ignored.
241 // Note that this operation is safe because the generated fresh variables can not clash with other
242 // binding variables.
244
247 for (const data::data_expression& a: el_)
248 {
249 const data::variable par= *i;
250 i++;
251 if (m_new_parameters.find(par) == m_new_parameters.end()) // This parameter is not replaced by a boolean parameters.
252 {
253 result.push_back(a);
254 }
255 else
256 {
257 data::variable_vector new_parameters = m_new_parameters[par];
259
260 mCRL2log(log::debug) << "Found " << new_parameters.size() << " new parameter(s) for parameter " << data::pp(par) << std::endl;
261
262 for (std::size_t j = 0; j < new_parameters.size(); ++j)
263 {
265
266 data::data_expression_vector::iterator k = elements.begin();
267 while (k != elements.end())
268 {
269 // Elements that get boolean value false
270 std::ptrdiff_t count(static_cast<std::ptrdiff_t>(1) << j);
271 if (std::distance(k, elements.end()) < count)
272 {
273 k = elements.end();
274 }
275 else
276 {
277 std::advance(k, count);
278 }
279
280 // Elements that get value true
281 for (std::ptrdiff_t l = 0; l < count && k != elements.end(); ++l)
282 {
283 disjuncts.push_back(data::equal_to(a, *k++));
284 }
285 }
286 result.push_back(data::lazy::join_or(disjuncts.begin(), disjuncts.end()));
287 }
288 }
289 }
290
291 mCRL2log(log::debug) << "Replaced expression(s) " << data::pp(el_) << " in the initial state with expression(s) " << data::pp(result) << std::endl;
292
293 return data::data_expression_list(result.begin(),result.end());
294 }
295
299 {
300 // We use replace_variables, to make sure that the binding variables of assignments are ignored.
301 // Note that this operation is safe because the generated fresh variables can not clash with other
302 // binding variables.
304
306 for (const data::assignment& a: v)
307 {
308 if (m_new_parameters.find(a.lhs()) == m_new_parameters.end())
309 {
310 result.push_back(a);
311 }
312 else
313 {
314 data::variable_vector new_parameters = m_new_parameters[a.lhs()];
316
317 mCRL2log(log::debug) << "Found " << new_parameters.size() << " new parameter(s) for parameter " << data::pp(a.lhs()) << std::endl;
318
319 for (std::size_t j = 0; j < new_parameters.size(); ++j)
320 {
322
323 data::data_expression_vector::iterator k = elements.begin();
324 while (k != elements.end())
325 {
326 // Elements that get boolean value false
327 std::ptrdiff_t count(static_cast<std::ptrdiff_t>(1) << j);
328 if (std::distance(k, elements.end()) < count)
329 {
330 k = elements.end();
331 }
332 else
333 {
334 std::advance(k, count);
335 }
336
337 // Elements that get value true
338 for (std::ptrdiff_t l = 0; l < count && k != elements.end(); ++l)
339 {
340 disjuncts.push_back(data::equal_to(a.rhs(), *k++));
341 }
342 }
343 result.push_back(data::assignment(new_parameters[j], data::lazy::join_or(disjuncts.begin(), disjuncts.end())));
344 }
345
346 }
347 }
348
349 mCRL2log(log::debug) << "Replaced assignment(s) " << data::pp(v) << " with assignment(s) " << data::pp(result) << std::endl;
350
351 return data::assignment_list(result.begin(),result.end());
352 }
353
356 {
360 }
361
364 {
365 update_action_summand(static_cast<action_summand&>(s));
367 }
368
371 {
374 }
375
377 {
379 }
380
382 {
383 /* return stochastic_process_initializer(replace_enumerated_parameters_in_initial_expressions(parameters, init.expressions()),
384 lps::replace_variables_capture_avoiding(init.distribution(), m_if_trees, m_if_trees_generator)
385 ); */
388 return stochastic_process_initializer(d, dist);
389 }
390
391 public:
395 binary_algorithm(Specification& spec,
396 DataRewriter& r,
397 const std::string parameter_selection = "")
398 : detail::lps_algorithm<Specification>(spec),
399 m_rewriter(r),
400 m_parameter_selection(parameter_selection)
401 {}
402
405 void run()
406 {
407 data::variable_list old_parameters = m_spec.process().process_parameters();
408 const std::set<data::variable> to_replace = select_parameters(m_parameter_selection);
410
411 // Initial process
412 mCRL2log(log::debug) << "Updating process initializer" << std::endl;
413 m_spec.initial_process() = update_initial_process(old_parameters, m_spec.initial_process());
414
415 // Summands
416 mCRL2log(log::debug) << "Updating summands" << std::endl;
417
418 for (action_summand& a: m_spec.process().action_summands())
419 {
421 }
422
423 for (deadlock_summand& d: m_spec.process().deadlock_summands())
424 {
426 }
427 }
428};
429
430} // namespace lps
431
432} // namespace mcrl2
433
434#endif // MCRL2_LPS_BINARY_H
size_type size() const
Returns the number of arguments of this term.
Definition aterm.h:151
Iterator for term_list.
const_iterator end() const
Returns a const_iterator pointing to the end of the term_list.
Definition aterm_list.h:282
const_iterator begin() const
Returns a const_iterator pointing to the beginning of the term_list.
Definition aterm_list.h:275
\brief Assignment of a data expression to a variable
Definition assignment.h:91
const_iterator end() const
An enumerator algorithm that generates solutions of a condition.
Definition enumerator.h:601
std::size_t enumerate(const EnumeratorListElement &p, MutableSubstitution &sigma, ReportSolution report_solution, Reject reject=Reject(), Accept accept=Accept()) const
Enumerates the element p. Solutions are reported using the callback function report_solution....
Definition enumerator.h:977
An element for the todo list of the enumerator that collects the substitution corresponding to the ex...
Definition enumerator.h:348
void add_identifiers(const std::set< core::identifier_string > &ids)
Add a set of identifiers to the context.
Generic substitution function. The substitution is stored as a mapping of variables to expressions....
Identifier generator that stores the identifiers of the context in a set. Using the operator()() and ...
void add_identifier(const core::identifier_string &s) override
Adds the identifier s to the context.
\brief A data variable
Definition variable.h:28
const sort_expression & sort() const
Definition variable.h:43
LPS summand containing a multi-action.
const lps::multi_action & multi_action() const
Returns the multi-action of this summand.
const data::assignment_list & assignments() const
Returns the sequence of assignments.
Algorithm class that can be used to apply the binary algorithm.
Definition binary.h:45
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.
Definition binary.h:298
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.
Definition binary.h:77
binary_algorithm(Specification &spec, DataRewriter &r, const std::string parameter_selection="")
Constructor for binary algorithm.
Definition binary.h:395
void update_deadlock_summand(deadlock_summand &s)
Update a deadlock summand with the new Boolean parameters.
Definition binary.h:370
detail::lps_algorithm< Specification > super
Definition binary.h:47
std::map< data::variable, std::vector< data::data_expression > > m_enumerated_elements
Mapping of variables to all values they can be assigned.
Definition binary.h:62
stochastic_process_initializer update_initial_process(const data::variable_list &parameters, const stochastic_process_initializer &init)
Definition binary.h:381
Specification::process_type process_type
Definition binary.h:48
data::set_identifier_generator m_if_trees_generator
Contains the names of variables appearing in rhs of m_if_trees.
Definition binary.h:68
const std::string m_parameter_selection
Definition binary.h:56
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...
Definition binary.h:160
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.
Definition binary.h:236
void update_action_summand(action_summand &s)
Update an action summand with the new Boolean parameters.
Definition binary.h:355
std::set< data::variable > select_parameters(const std::string parameter_selection) const
Determine which variables should be replaced, based on parameter_selection.
Definition binary.h:119
void run()
Apply the algorithm to the specification passed in the constructor.
Definition binary.h:405
process_type::action_summand_type action_summand_type
Definition binary.h:49
data::mutable_map_substitution m_if_trees
Mapping of variables to corresponding if-tree.
Definition binary.h:65
process_initializer update_initial_process(const data::variable_list &parameters, const process_initializer &init)
Definition binary.h:376
DataRewriter m_rewriter
Rewriter.
Definition binary.h:54
std::map< data::variable, std::vector< data::variable > > m_new_parameters
Mapping of finite variables to boolean vectors.
Definition binary.h:59
void update_action_summand(stochastic_action_summand &s)
Update an action summand with the new Boolean parameters.
Definition binary.h:363
data::enumerator_list_element_with_substitution enumerator_element
Definition binary.h:46
data::enumerator_identifier_generator m_id_generator
Identifier generator for the enumerator.
Definition binary.h:71
LPS summand containing a deadlock.
const lps::deadlock & deadlock() const
Returns the deadlock of this summand.
Algorithm class for algorithms on linear process specifications. It can be instantiated with lps::spe...
lps_algorithm(Specification &spec)
Constructor.
Specification & m_spec
The specification that is processed by the algorithm.
LPS summand containing a multi-action.
const stochastic_distribution & distribution() const
Returns the distribution of this summand.
\brief A stochastic distribution
const data::data_expression & condition() const
Returns the condition expression.
Definition summand.h:60
The class enumerator.
MCRL2_EXPORT bool init(rewriter_interface *i, RewriterCompilingJitty *this_rewriter)
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:391
Add your file description here.
data_expression join_or(ForwardTraversalIterator first, ForwardTraversalIterator last)
Returns or applied to the sequence of data expressions [first, last)
const basic_sort & bool_()
Constructor for sort expression Bool.
Definition bool.h:44
const function_symbol & true_()
Constructor for function symbol true.
Definition bool.h:77
std::vector< assignment > assignment_vector
\brief vector of assignments
Definition assignment.h:149
std::set< data::variable > substitution_variables(const Substitution &)
Returns the variables appearing in the right hand sides of the substitution.
Definition replace.h:161
std::vector< variable > variable_vector
\brief vector of variables
Definition variable.h:89
std::vector< data_expression > data_expression_vector
\brief vector of data_expressions
std::string pp(const abstraction &x)
Definition data.cpp:39
atermpp::term_list< data_expression > data_expression_list
\brief list of data_expressions
atermpp::term_list< variable > variable_list
\brief list of variables
std::set< core::identifier_string > function_and_mapping_identifiers(const data_specification &dataspec)
Returns the names of functions and mappings that occur in a data specification.
void replace_variables_capture_avoiding(T &x, Substitution &sigma, data::set_identifier_generator &id_generator, typename std::enable_if<!std::is_base_of< atermpp::aterm, T >::value >::type *=nullptr)
atermpp::term_list< assignment > assignment_list
\brief list of assignments
Definition assignment.h:146
function_symbol equal_to(const sort_expression &s)
Constructor for function symbol ==.
Definition standard.h:126
void replace_variables(T &x, const Substitution &sigma, typename std::enable_if<!std::is_base_of< atermpp::aterm, T >::value >::type *=nullptr)
Definition replace.h:213
@ verbose
Definition logger.h:37
std::vector< data::variable > parse_lps_parameter_selection(const data::variable_list &params, const data::data_specification &dataspec, const std::string &text)
Parses parameter selection for finite pbesinst algorithm.
void replace_variables_capture_avoiding(T &x, Substitution &sigma, data::set_identifier_generator &id_generator, typename std::enable_if<!std::is_base_of< atermpp::aterm, T >::value >::type *=nullptr)
std::size_t nr_of_booleans_for_elements(std::size_t n)
Definition binary.h:27
void find_identifiers(const T &x, OutputIterator o)
Definition find.h:96
std::size_t ceil_log2(std::size_t n)
Definition math.h:28
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72