mCRL2
Loading...
Searching...
No Matches
parelm.h
Go to the documentation of this file.
1// Author(s): Wieger Wesselink
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_PARELM_H
13#define MCRL2_LPS_PARELM_H
14
18#include <boost/integer.hpp>
19
20namespace mcrl2
21{
22
23namespace lps
24{
25
26namespace detail
27{
28 inline
29 void collect_transition_variables(const action_summand& s, std::set<data::variable>& result)
30 {
31 std::set<data::variable> tmp;
32
34 result.insert(tmp.begin(), tmp.end());
35
37 result.insert(tmp.begin(), tmp.end());
38 }
39
40 inline
41 void collect_transition_variables(const stochastic_action_summand& s, std::set<data::variable>& result)
42 {
43 collect_transition_variables(static_cast<const action_summand&>(s), result);
44 std::set<data::variable> tmp = lps::find_all_variables(s.distribution());
45 result.insert(tmp.begin(), tmp.end());
46 }
47
48 inline
49 void collect_transition_variables(const deadlock_summand& s, std::set<data::variable>& result)
50 {
51 std::set<data::variable> tmp;
52
54 result.insert(tmp.begin(), tmp.end());
55
57 result.insert(tmp.begin(), tmp.end());
58 }
59
60} // namespace detail
61
64template <typename Specification>
65class parelm_algorithm: public lps::detail::lps_algorithm<Specification>
66{
68 using super::m_spec;
69 using super::verbose;
70
71 protected:
72
75 std::set<data::variable> transition_variables()
76 {
77 std::set<data::variable> result;
78
79 auto const& action_summands = m_spec.process().action_summands();
80 for (auto i = action_summands.begin(); i != action_summands.end(); ++i)
81 {
83 }
84
85 auto const& deadlock_summands = m_spec.process().deadlock_summands();
86 for (auto i = deadlock_summands.begin(); i != deadlock_summands.end(); ++i)
87 {
89 }
90 return result;
91 }
92
93 void report_results(const std::set<data::variable>& to_be_removed) const
94 {
95 if (verbose())
96 {
97 std::clog << "parelm removed " << to_be_removed.size() << " process parameters: " <<std::endl;
98 for (const data::variable& v: to_be_removed)
99 {
100 std::clog << v << ":" << v.sort() << std::endl;
101 }
102 }
103 }
104
106 void parelm1()
107 {
108#ifdef MCRL2_LPS_PARELM_DEBUG
109 std::clog << "--- parelm 1 ---" << std::endl;
110#endif
111 const data::variable_list& pars = m_spec.process().process_parameters();
112 std::set<data::variable> process_parameters(pars.begin(),pars.end());
113
114 // significant variables may not be removed by parelm
115 std::set<data::variable> significant_variables = transition_variables();
116
117#ifdef MCRL2_LPS_PARELM_DEBUG
118 std::clog << "initial significant variables: ";
119 for (auto i = significant_variables.begin(); i != significant_variables.end(); ++i)
120 {
121 std::clog << *i << " ";
122 }
123 std::clog << std::endl;
124#endif
125
126 // recursively extend the set of significant variables
127 std::set<data::variable> todo = significant_variables;
128 while (!todo.empty())
129 {
130 data::variable x = *todo.begin();
131 todo.erase(todo.begin());
132
133 for (auto i = m_spec.process().action_summands().begin(); i != m_spec.process().action_summands().end(); ++i)
134 {
135 const data::assignment_list& assignments = i->assignments();
136 auto j = std::find_if(assignments.begin(), assignments.end(), [&](const data::assignment& a) { return a.lhs() == x; });
137 if (j != assignments.end())
138 {
139 std::set<data::variable> vars;
140 data::find_all_variables(j->rhs(), std::inserter(vars, vars.end()));
141 std::set<data::variable> new_variables = utilities::detail::set_difference(vars, significant_variables);
142 todo.insert(new_variables.begin(), new_variables.end());
143 significant_variables.insert(new_variables.begin(), new_variables.end());
144#ifdef MCRL2_LPS_PARELM_DEBUG
145 for (auto k = new_variables.begin(); k != new_variables.end(); ++k)
146 {
147 std::clog << "found dependency " << x << " -> " << *k << std::endl;
148 }
149#endif
150 }
151 }
152 }
153 std::set<data::variable> to_be_removed = utilities::detail::set_difference(process_parameters, significant_variables);
154#ifdef MCRL2_LPS_PARELM_DEBUG
155 std::clog << "to be removed: " << data::pp(data::variable_list(to_be_removed.begin(), to_be_removed.end())) << std::endl;
156#endif
157 report_results(to_be_removed);
158 lps::remove_parameters(m_spec, to_be_removed);
160 }
161
163 void parelm2()
164 {
165#ifdef MCRL2_LPS_PARELM_DEBUG
166 std::clog << "--- parelm 2 ---" << std::endl;
167#endif
168 const data::variable_list& pars = m_spec.process().process_parameters();
169 std::set<data::variable> process_parameters(pars.begin(),pars.end());
170
171 // create a mapping m from process parameters to integers
172 std::map<data::variable, std::size_t> m;
173 int index = 0;
174 for (const data::variable& process_parameter: process_parameters)
175 {
176#ifdef MCRL2_LPS_PARELM_DEBUG
177 std::clog << "vertex " << index << " = " << data::pp(*i) << std::endl;
178#endif
179 m[process_parameter] = index++;
180 }
181
182 // compute the initial set v of significant variables
183 std::set<data::variable> significant_variables = transition_variables();
184 std::vector<std::size_t> v;
185 for (const data::variable& significant_variable: significant_variables)
186 {
187 v.push_back(m[significant_variable]);
188 }
189
190 // compute the dependency graph G
191 typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> graph;
192 graph G(process_parameters.size());
193 for (auto i = m_spec.process().action_summands().begin(); i != m_spec.process().action_summands().end(); ++i)
194 {
195 for (const data::assignment& a: i->assignments())
196 {
197 std::size_t j0 = m[a.lhs()];
198 std::set<data::variable> vars;
199 data::find_all_variables(a.rhs(), std::inserter(vars, vars.end()));
200 for (const data::variable& var: vars)
201 {
202 std::size_t k0 = m[var];
203#ifdef MCRL2_LPS_PARELM_DEBUG
204 std::clog << "edge " << j0 << " -> " << k0 << std::endl;
205#endif
206 boost::add_edge(j0, k0, G);
207 }
208 }
209 }
210
211#ifdef MCRL2_LPS_PARELM_DEBUG
212 std::clog << "initial significant variables: ";
213 for (auto k = v.begin(); k != v.end(); ++k)
214 {
215 std::clog << *k << " ";
216 }
217 std::clog << std::endl;
218#endif
219
220 // compute the reachable nodes (i.e. the significant parameters)
221 std::vector<std::size_t> r1 = mcrl2::utilities::reachable_nodes(G, v.begin(), v.end());
222#ifdef MCRL2_LPS_PARELM_DEBUG
223 std::clog << "reachable nodes: ";
224 for (auto k = r1.begin(); k != r1.end(); ++k)
225 {
226 std::clog << *k << " ";
227 }
228 std::clog << std::endl;
229#endif
230 std::set<std::size_t> r2(r1.begin(), r1.end());
231 std::set<data::variable> to_be_removed;
232 for (const data::variable& process_parameter: process_parameters)
233 {
234 if (r2.find(m[process_parameter]) == r2.end())
235 {
236 to_be_removed.insert(process_parameter);
237 }
238 }
239#ifdef MCRL2_LPS_PARELM_DEBUG
240 std::clog << "to be removed: " << data::pp(data::variable_list(to_be_removed.begin(), to_be_removed.end())) << std::endl;
241#endif
242 report_results(to_be_removed);
243 lps::remove_parameters(m_spec, to_be_removed);
245 }
246
247 public:
248
250 parelm_algorithm(Specification& spec )
251 : lps::detail::lps_algorithm<Specification>(spec)
252 {}
253
255 void run(bool variant1 = true)
256 {
257 if (variant1)
258 {
259 parelm1();
260 }
261 else
262 {
263 parelm2();
264 }
265 }
266};
267
272template <typename Specification>
273void parelm(Specification& spec, bool variant1 = true)
274{
275 parelm_algorithm<Specification> algorithm(spec);
276 algorithm.run(variant1);
277}
278
279} // namespace lps
280
281} // namespace mcrl2
282
283#endif // MCRL2_LPS_PARELM_H
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 begin() const
\brief A data variable
Definition variable.h:28
LPS summand containing a multi-action.
const lps::multi_action & multi_action() const
Returns the multi-action of this summand.
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...
bool verbose() const
Flag for verbose output.
lps_algorithm(Specification &spec)
Constructor.
Specification & m_spec
The specification that is processed by the algorithm.
Algorithm class for elimination of unused parameters from a linear process specification.
Definition parelm.h:66
parelm_algorithm(Specification &spec)
Constructor.
Definition parelm.h:250
std::set< data::variable > transition_variables()
Returns the data variables that are considered in the parelm algorithm.
Definition parelm.h:75
void parelm2()
Second version of parelm that builds a dependency graph.
Definition parelm.h:163
void report_results(const std::set< data::variable > &to_be_removed) const
Definition parelm.h:93
void run(bool variant1=true)
Runs the parelm algorithm.
Definition parelm.h:255
void parelm1()
First version of parelm1.
Definition parelm.h:106
lps::detail::lps_algorithm< Specification > super
Definition parelm.h:67
LPS summand containing a multi-action.
const stochastic_distribution & distribution() const
Returns the distribution of this summand.
const data::data_expression & condition() const
Returns the condition expression.
Definition summand.h:60
The iota function.
Add your file description here.
std::set< data::variable > find_all_variables(const data::data_expression &x)
Definition data.cpp:94
std::string pp(const abstraction &x)
Definition data.cpp:39
void collect_transition_variables(const action_summand &s, std::set< data::variable > &result)
Definition parelm.h:29
bool check_well_typedness(const linear_process &x)
Definition lps.cpp:92
void remove_parameters(Object &x, const std::set< data::variable > &to_be_removed)
Rewrites an LPS data type.
Definition remove.h:190
void parelm(Specification &spec, bool variant1=true)
Removes unused parameters from a linear process specification.
Definition parelm.h:273
std::set< data::variable > find_all_variables(const lps::deadlock &x)
Definition lps.cpp:48
std::set< T > set_difference(const std::set< T > &x, const std::set< T > &y)
Returns the difference of two sets.
std::vector< std::size_t > reachable_nodes(const Graph &g, Iter first, Iter last)
Compute reachable nodes in a graph.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
add your file description here.