mCRL2
Loading...
Searching...
No Matches
untime.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_UNTIME_H
13#define MCRL2_LPS_UNTIME_H
14
17
18namespace mcrl2
19{
20
21namespace lps
22{
23
24namespace detail
25{
26
27template <class INITIALIZER>
28INITIALIZER make_process_initializer(const data::data_expression_list& expressions, const INITIALIZER& init);
29
30template <>
32{
33 return lps::process_initializer(expressions);
34}
35
36template <>
38{
39 return stochastic_process_initializer(expressions, init.distribution());
40}
41
42} // namespace detail
43
44template <typename Specification>
45class untime_algorithm: public detail::lps_algorithm<Specification>
46{
47 protected:
49 typedef typename Specification::process_type process_type;
50 typedef typename process_type::action_summand_type action_summand_type;
51 using super::m_spec;
52
56
57 protected:
60
67
70
77 {
79
80 // The vector below contains exactly one boolean for each parameter. As long as the value
81 // for the elements in the vector is true, it is a candidate time variable.
82 std::vector <bool> time_variable_candidates(m_spec.process().process_parameters().size(),true);
83 std::vector <bool>::iterator j=time_variable_candidates.begin() ;
84 mCRL2log(log::verbose) << "For untiming to function optimally, it is assumed that the input lps is rewritten to normal form" << std::endl;
85
86 const data::data_expression_list& process_parameters = m_spec.initial_process().expressions();
87 for (data::data_expression_list::const_iterator k = process_parameters.begin(); k != process_parameters.end(); ++j, ++k)
88 {
89 if (*k != real_zero)
90 {
91 (*j) = false;
92 }
93 }
94
95 assert(j == time_variable_candidates.end());
96
97 auto const& summands = m_spec.process().action_summands();
98 for (auto i = summands.begin(); i != summands.end(); ++i)
99 {
100 const data::data_expression_list summand_arguments = i->next_state(m_spec.process().process_parameters());
101 std::vector <bool>::iterator j = time_variable_candidates.begin();
102 data::variable_list::const_iterator l=m_spec.process().process_parameters().begin();
103 for (data::data_expression_list::const_iterator k=summand_arguments.begin() ;
104 k!=summand_arguments.end(); ++j, ++k, l++)
105 {
106 if ((*k!=real_zero)&&(*k!=*l)&&(*k!=i->multi_action().time()))
107 {
108 (*j)=false;
109 }
110 }
111 assert(j==time_variable_candidates.end());
112 }
113
115 j=time_variable_candidates.begin();
116 for (data::variable_list::const_iterator k=m_spec.process().process_parameters().begin();
117 k!=m_spec.process().process_parameters().end() ; ++j, ++k)
118 {
119 if (*j)
120 {
121 data::variable kvar(*k);
123 time_invariant=data::lazy::and_(time_invariant,
124 data::lazy::and_(data::less_equal(real_zero,kvar),
125 data::less_equal(kvar,lat)));
126 }
127 }
128 assert(j==time_variable_candidates.end());
129 mCRL2log(log::verbose) << "Time invariant " << data::pp(time_invariant) << std::endl;
130 return time_invariant;
131 }
132
135 {
136 using namespace mcrl2::data;
137 if (s.has_time())
138 {
139 // Extend the original condition with an additional argument t.i(d,e.i)>m_last_action_time && t.i(d,e.i) > 0
140 s.condition() = lazy::and_(s.condition(),
141 lazy::and_(greater(s.multi_action().time(),m_last_action_time),
142 greater(s.multi_action().time(), sort_real::real_(0))));
143
144 // Extend original assignments to include m_last_action_time := t.i(d,e.i)
145 s.assignments()=push_back(s.assignments(),assignment(m_last_action_time,s.multi_action().time()));
146
147 // Remove time
148 s.multi_action() = multi_action(s.multi_action().actions());
149
150 // Try to apply Fourier-Motzkin elimination to simplify
151 std::set< variable > variables_in_action = process::find_all_variables(s.multi_action());
152 std::set< variable > variables_in_assignments = process::find_all_variables(s.assignments());
153 // Split the variables that do/do not occur in actions and assignments.
154 variable_list do_occur, do_not_occur;
155
156 for(const variable& v: s.summation_variables())
157 {
158 if (variables_in_action.count(v)>0 || variables_in_assignments.count(v)>0)
159 {
160 do_occur.push_front(v);
161 }
162 else
163 {
164 do_not_occur.push_front(v);
165 }
166 }
167
168 // Only apply Fourier Motzkin elimination to the new condition if the user
169 // explicitly asked for it.
170 // The application of Fourier Motzkin can change the structure of the
171 // condition significantly. Therefore, its application hides the real
172 // outcome of the untime algorithm.
173 if(m_apply_fm)
174 {
175 try
176 {
177 variable_list remaining_variables;
178 data_expression new_condition;
179 fourier_motzkin(s.condition(), do_not_occur, new_condition, remaining_variables, m_rewriter);
180 s.condition() = new_condition;
181 s.summation_variables() = do_occur + remaining_variables;
182 }
183 catch(mcrl2::runtime_error& e)
184 {
185 // The application of Fourier Motzkin failed because of mixed Real and
186 // non-Real variables. We leave the original condition, but show a
187 // warning to the user
188 mCRL2log(log::debug) << "Application of Fourier Motzkin failed with the message\n" << e.what() << std::endl;
189 }
190 }
191 }
192 else
193 {
194 // Add a new summation variable (this is allowed because according to an axiom the following equality holds):
195 // c -> a . X == sum t:Real . c -> a@t . X
196 variable time_var(m_identifier_generator("time_var"), sort_real::real_());
197 s.summation_variables().push_front(time_var);
198
199 // Extend the original condition with an additional argument time_var > m_last_action_time && time_var > 0
200 s.condition() = lazy::and_(s.condition(),
201 lazy::and_(greater(time_var, m_last_action_time),
202 greater(time_var, sort_real::real_(0))));
203
204 // Extend original assignments to include m_last_action_time := time_var
205 s.assignments()=push_back(s.assignments(),assignment(m_last_action_time, time_var));
206 } // s.has_time()
207
208 // Add the condition m_last_action_time>=0, which holds, and which is generally a useful fact for further processing.
209 s.condition() = lazy::and_(s.condition(),m_time_invariant);
210 }
211
212
213
214
215 public:
216 untime_algorithm(Specification& spec, bool add_invariants, bool apply_fourier_motzkin, const data::rewriter& r)
217 : detail::lps_algorithm<Specification>(spec),
218 m_add_invariants(add_invariants),
219 m_apply_fm(apply_fourier_motzkin),
220 m_rewriter(r)
221 {
224 }
225
226 void run()
227 {
228 m_spec.process().deadlock_summands() = deadlock_summand_vector();
229 m_spec.process().deadlock_summands().push_back(
231
232 if (m_spec.process().has_time())
233 {
234 mCRL2log(log::verbose) << "Untiming " << m_spec.process().summand_count() << " summands" << std::endl;
235
236 // Create extra parameter m_last_action_time and add it to the list of process parameters,
237 // m_last_action_time is used later on in the code
239 mCRL2log(log::verbose) << "Introduced variable " << data::pp(m_last_action_time) << " to denote time of last action" << std::endl;
240
241 // Should happen before updating the process
243
244 m_spec.process().process_parameters()=push_back(m_spec.process().process_parameters(),m_last_action_time);
245 data::data_expression_list init = m_spec.initial_process().expressions();
246 init = push_back(init, data::sort_real::real_(0));
247 m_spec.initial_process() = detail::make_process_initializer(init, m_spec.initial_process());
248
249 for(action_summand_type& s: m_spec.process().action_summands())
250 {
251 untime(s);
252 }
253 }
254 }
255};
256
257} // namespace lps
258
259} // namespace mcrl2
260
261#endif // MCRL2_LPS_UNTIME_H
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
void push_front(const Term &el)
Inserts a new element at the beginning of the current list.
\brief Assignment of a data expression to a variable
Definition assignment.h:91
void add_identifiers(const std::set< core::identifier_string > &ids)
Add a set of identifiers to the context.
Rewriter that operates on data expressions.
Definition rewriter.h:81
Identifier generator that stores the identifiers of the context in a set. Using the operator()() and ...
\brief A data variable
Definition variable.h:28
LPS summand containing a deadlock.
Represents a deadlock.
Definition deadlock.h:26
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.
\brief A timed multi-action
data::data_expression m_time_invariant
Data expression expressing the invariant for variables relating to time.
Definition untime.h:66
data::set_identifier_generator m_identifier_generator
Identifier generator, for generating fresh identifiers.
Definition untime.h:69
data::data_expression calculate_time_invariant()
Data expression expressing the invariant for variables relating to time.
Definition untime.h:76
void untime(action_summand_type &s)
Apply untime to an action summand.
Definition untime.h:134
detail::lps_algorithm< Specification > super
Definition untime.h:48
Specification::process_type process_type
Definition untime.h:49
process_type::action_summand_type action_summand_type
Definition untime.h:50
const data::rewriter & m_rewriter
Definition untime.h:55
untime_algorithm(Specification &spec, bool add_invariants, bool apply_fourier_motzkin, const data::rewriter &r)
Definition untime.h:216
data::variable m_last_action_time
Variable denoting the time at which the last action occurred.
Definition untime.h:59
Standard exception class for reporting runtime errors.
Definition exception.h:27
Contains functions to apply Fourier-Motzkin on linear inequalities and data expressions.
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 and_(data_expression const &p, data_expression const &q)
Returns an expression equivalent to p or q.
const function_symbol & true_()
Constructor for function symbol true.
Definition bool.h:77
const basic_sort & real_()
Constructor for sort expression Real.
Definition real1.h:48
Namespace for all data library functionality.
Definition abstraction.h:22
function_symbol less_equal(const sort_expression &s)
Constructor for function symbol <=.
Definition standard.h:277
std::string pp(const abstraction &x)
Definition data.cpp:39
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.
@ verbose
Definition logger.h:37
INITIALIZER make_process_initializer(const data::data_expression_list &expressions, const INITIALIZER &init)
std::vector< deadlock_summand > deadlock_summand_vector
\brief vector of deadlock_summands
void find_identifiers(const T &x, OutputIterator o)
Definition find.h:96
void find_all_variables(const T &x, OutputIterator o)
Definition find.h:129
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72