mCRL2
Loading...
Searching...
No Matches
linear_inequalities_utilities.h
Go to the documentation of this file.
1// Author(s): Jan Friso Groote
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
13#ifndef MCRL2_LPSREALELM_DETAIL_LINEAR_INEQUALITY_UTILITIES_H
14#define MCRL2_LPSREALELM_DETAIL_LINEAR_INEQUALITY_UTILITIES_H
15
16
18
19namespace mcrl2
20{
21
22namespace data
23{
24
25namespace detail
26{
27
29{
31 {
32 return not_equal_to(data::binary_left(atermpp::down_cast<application>(e)),data::binary_right(atermpp::down_cast<application>(e)));
33 }
35 {
36 return equal_to(data::binary_left(atermpp::down_cast<application>(e)),data::binary_right(atermpp::down_cast<application>(e)));
37 }
38 else if (is_less_application(e))
39 {
40 return greater_equal(data::binary_left(atermpp::down_cast<application>(e)),data::binary_right(atermpp::down_cast<application>(e)));
41 }
42 else if (is_less_equal_application(e))
43 {
44 return data::greater(data::binary_left(atermpp::down_cast<application>(e)),data::binary_right(atermpp::down_cast<application>(e)));
45 }
46 else if (is_greater_application(e))
47 {
48 return less_equal(data::binary_left(atermpp::down_cast<application>(e)),data::binary_right(atermpp::down_cast<application>(e)));
49 }
51 {
52 return data::less(data::binary_left(atermpp::down_cast<application>(e)),data::binary_right(atermpp::down_cast<application>(e)));
53 }
54 else
55 {
56 throw mcrl2::runtime_error("Expression " + data::pp(e) + " is expected to be an inequality over sort Real");
57 }
58}
59
60
65
66inline bool is_inequality(const data_expression& e)
67{
71}
72
73// Functions below should have been defined in the data library.
75{
76 assert(is_if_application(e));
77 const data::application& a = atermpp::down_cast<const application>(e);
79 return *i;
80}
81
83{
84 assert(is_if_application(e));
85 const data::application& a = atermpp::down_cast<const application>(e);
87 return *(++i);
88}
89
91{
92 assert(is_if_application(e));
93 const data::application& a = atermpp::down_cast<const application>(e);
95 return *(++(++i));
96}
97
98
99
113
115 const data_expression& e,
116 std::vector < data_expression_list >& real_conditions,
117 std::vector < data_expression_list >& non_real_conditions,
118 const bool negate=false)
119{
120 assert(real_conditions.empty());
121 assert(non_real_conditions.empty());
122
123 // In these three cases, we rewrite the expression and call this function recursively
124 // with the rewritten expression
126 {
128 return split_condition_aux(rewritten, real_conditions, non_real_conditions, negate);
129 }
130 else if (is_if_application(e))
131 {
134 real_conditions,non_real_conditions,negate);
135 }
137 {
138 return split_condition_aux(sort_bool::arg(e),real_conditions,non_real_conditions,!negate);
139 }
140
142 {
143 // Recursive case
144 std::vector < data_expression_list > real_conditions_aux1, non_real_conditions_aux1;
145 bool left_is_real = split_condition_aux(sort_bool::left(e),real_conditions_aux1,non_real_conditions_aux1,negate);
146 std::vector < data_expression_list > real_conditions_aux2, non_real_conditions_aux2;
147 bool right_is_real = split_condition_aux(sort_bool::right(e),real_conditions_aux2,non_real_conditions_aux2,negate);
148 if(!left_is_real && !right_is_real)
149 {
150 // There are no real variables on either side so we can
151 // just store the expression e in non_real_conditions
152 real_conditions.push_back(data_expression_list());
153 non_real_conditions.push_back(data_expression_list({ negate ? data_expression(sort_bool::not_(e)) : e }));
154 }
156 {
157 // Combine the recursive results (whis are disjunctiosn of conjunctions)
158 // of the left and right sides of e (which is a conjunction or negated disjunction)
159 // by using the distributivity of && and || to obtain a result
160 // which is again a disjunction of conjuctions.
161 for (std::vector < data_expression_list >::const_iterator
162 i1r=real_conditions_aux1.begin(), i1n=non_real_conditions_aux1.begin() ;
163 i1r!=real_conditions_aux1.end(); ++i1r, ++i1n)
164 {
165 for (std::vector < data_expression_list >::const_iterator
166 i2r=real_conditions_aux2.begin(), i2n=non_real_conditions_aux2.begin() ;
167 i2r!=real_conditions_aux2.end(); ++i2r, ++i2n)
168 {
169 real_conditions.push_back(*i1r + *i2r);
170 non_real_conditions.push_back(*i1n + *i2n);
171 }
172 }
173 }
174 else
175 {
177
178 // Combine the recursive results of the left and right sides
179 // of the disjunction (or negated conjunction) by concatenating
180 // them.
181 real_conditions.insert(real_conditions.end(), real_conditions_aux1.begin(), real_conditions_aux1.end());
182 real_conditions.insert(real_conditions.end(), real_conditions_aux2.begin(), real_conditions_aux2.end());
183 non_real_conditions.insert(non_real_conditions.end(), non_real_conditions_aux1.begin(), non_real_conditions_aux1.end());
184 non_real_conditions.insert(non_real_conditions.end(), non_real_conditions_aux2.begin(), non_real_conditions_aux2.end());
185 }
186 return left_is_real || right_is_real;
187 }
188 else if (is_inequality(e) && (data::binary_left(atermpp::down_cast<application>(e)).sort() == sort_real::real_() || data::binary_right(atermpp::down_cast<application>(e)).sort() == sort_real::real_()))
189 {
190 // Base case 1: an inequality over real numbers
191 std::set < variable > vars=data::find_all_variables(e);
192 for (const variable& v: vars)
193 {
194 if (v.sort() != sort_real::real_())
195 {
196 throw mcrl2::runtime_error("Expression " + data::pp(e) + " contains variable " +
197 data::pp(v) + " not of sort Real.");
198 }
199 }
200 real_conditions.push_back(data_expression_list({ negate ? negate_inequality(e) : e }));
201 non_real_conditions.push_back(data_expression_list());
202 return true;
203 }
204 else
205 {
206 // Base case 2: an expression not containing real numbers
207 // e is assumed to be a non_real expression.
208 std::set < variable > vars=data::find_all_variables(e);
209 for (const variable& v: vars)
210 {
211 if (v.sort() == sort_real::real_())
212 {
213 throw mcrl2::runtime_error("Expression " + data::pp(e) + " contains variable " +
214 data::pp(v) + " of sort Real.");
215 }
216 }
217 non_real_conditions.push_back(data_expression_list({ negate ? data_expression(sort_bool::not_(e)) : e }));
218 real_conditions.push_back(data_expression_list());
219 return false;
220 }
221}
222
226// it merges equal real conditions by merging the non-real conditions. No further
227// calculations take place with the non-real conditions, but if the non-real conditions
228// lead to unnecessary copying, this may lead to a huge overhead in removing the
229// real conditions.
230inline void split_condition(
231 const data_expression& e,
232 std::vector < data_expression_list >& real_conditions,
233 std::vector < data_expression >& non_real_conditions)
234{
235 std::vector < data_expression_list > aux_real_conditions;
236 std::vector < data_expression_list > aux_non_real_conditions;
237
238 split_condition_aux(e,aux_real_conditions, aux_non_real_conditions);
239 assert(aux_non_real_conditions.size()==aux_real_conditions.size() && aux_non_real_conditions.size()>0);
240
241 // For every list of real expressions, gather the corresponding non real expressions
242 std::map< data_expression_list, data_expression > non_real_expression_map;
243 for(std::vector < data_expression_list >::const_iterator i=aux_real_conditions.begin(), j=aux_non_real_conditions.begin();
244 i!=aux_real_conditions.end(); ++i, ++j)
245 {
246 // Find the entry for *i, inserting false if it does not exist yet
247 std::map< data_expression_list, data_expression >::iterator insert_result =
248 non_real_expression_map.insert(std::make_pair(*i, sort_bool::false_())).first;
249 insert_result->second = lazy::or_(insert_result->second, lazy::join_and(j->begin(), j->end()));
250 }
251 // Convert the map to a pair of vectors
252 for(const std::pair<const data_expression_list, data_expression >& expr_pair: non_real_expression_map)
253 {
254 real_conditions.push_back(expr_pair.first);
255 non_real_conditions.push_back(expr_pair.second);
256 }
257 assert(non_real_conditions.size()==real_conditions.size() && non_real_conditions.size()>0);
258}
259
260} // end namespace detail
261
262
263} // namespace data
264
265} // namespace mcrl2
266
267#endif // MCRL2_LPSREALELM_DETAIL_LINEAR_INEQUALITY_UTILITIES_H
Iterator for term_appl.
An application of a data expression to a number of arguments.
const_iterator begin() const
Returns an iterator pointing to the first argument of the application.
\brief A data variable
Definition variable.h:28
Standard exception class for reporting runtime errors.
Definition exception.h:27
Contains a class linear_inequality to represent mcrl2 data expressions that are linear equalities,...
void split_condition(const data_expression &e, std::vector< data_expression_list > &real_conditions, std::vector< data_expression > &non_real_conditions)
This function first splits the given condition e into real conditions and non real conditions....
data_expression negate_inequality(const data_expression &e)
const data_expression & else_part(const data_expression &e)
bool is_inequality(const data_expression &e)
Determine whether a data expression is an inequality.
detail::comparison_t negate(const detail::comparison_t t)
const data_expression & condition_part(const data_expression &e)
const data_expression & then_part(const data_expression &e)
static bool split_condition_aux(const data_expression &e, std::vector< data_expression_list > &real_conditions, std::vector< data_expression_list > &non_real_conditions, const bool negate=false)
Splits a condition in expressions ranging over reals and the others.
data_expression join_and(ForwardTraversalIterator first, ForwardTraversalIterator last)
Returns and applied to the sequence of data expressions [first, last)
data_expression or_(data_expression const &p, data_expression const &q)
Returns an expression equivalent to p and q.
const data_expression & arg(const data_expression &e)
Function for projecting out argument. arg from an application.
Definition bool.h:469
bool is_or_application(const atermpp::aterm &e)
Recogniser for application of ||.
Definition bool.h:345
const data_expression & right(const data_expression &e)
Function for projecting out argument. right from an application.
Definition bool.h:493
bool is_implies_application(const atermpp::aterm &e)
Recogniser for application of =>.
Definition bool.h:409
const function_symbol & and_()
Constructor for function symbol &&.
Definition bool.h:235
const function_symbol & false_()
Constructor for function symbol false.
Definition bool.h:109
bool is_and_application(const atermpp::aterm &e)
Recogniser for application of &&.
Definition bool.h:281
const function_symbol & or_()
Constructor for function symbol ||.
Definition bool.h:299
bool is_not_application(const atermpp::aterm &e)
Recogniser for application of !.
Definition bool.h:217
const function_symbol & not_()
Constructor for function symbol !.
Definition bool.h:173
const data_expression & left(const data_expression &e)
Function for projecting out argument. left from an application.
Definition bool.h:481
const basic_sort & real_()
Constructor for sort expression Real.
Definition real1.h:48
bool is_greater_application(const DataExpression &e)
Recogniser for application of >
Definition standard.h:343
function_symbol less_equal(const sort_expression &s)
Constructor for function symbol <=.
Definition standard.h:277
const data_expression & binary_right(const application &x)
function_symbol not_equal_to(const sort_expression &s)
Constructor for function symbol !=.
Definition standard.h:163
bool is_if_application(const DataExpression &e)
Recogniser for application of if.
Definition standard.h:232
bool is_not_equal_to_application(const DataExpression &e)
Recogniser for application of !=.
Definition standard.h:192
std::set< data::variable > find_all_variables(const data::data_expression &x)
Definition data.cpp:94
function_symbol less(const sort_expression &s)
Constructor for function symbol <.
Definition standard.h:240
bool is_greater_equal_application(const DataExpression &e)
Recogniser for application of >=.
Definition standard.h:380
const data_expression & binary_left(const application &x)
std::string pp(const abstraction &x)
Definition data.cpp:39
function_symbol greater_equal(const sort_expression &s)
Constructor for function symbol >=.
Definition standard.h:351
atermpp::term_list< data_expression > data_expression_list
\brief list of data_expressions
function_symbol equal_to(const sort_expression &s)
Constructor for function symbol ==.
Definition standard.h:126
bool is_less_application(const DataExpression &e)
Recogniser for application of <.
Definition standard.h:269
bool is_less_equal_application(const DataExpression &e)
Recogniser for application of <=.
Definition standard.h:306
bool is_equal_to_application(const DataExpression &e)
Recogniser for application of ==.
Definition standard.h:155
function_symbol greater(const sort_expression &s)
Constructor for function symbol >
Definition standard.h:314
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72