mCRL2
Loading...
Searching...
No Matches
normalize.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_MODAL_FORMULA_NORMALIZE_H
13#define MCRL2_MODAL_FORMULA_NORMALIZE_H
14
17
18namespace mcrl2
19{
20
21namespace state_formulas
22{
23
25// \brief Visitor for checking if a state formula is normalized.
26struct is_normalized_traverser: public state_formula_traverser<is_normalized_traverser>
27{
28 typedef state_formula_traverser<is_normalized_traverser> super;
29 using super::enter;
30 using super::leave;
31 using super::apply;
32
33 bool result;
34
35 is_normalized_traverser()
36 : result(true)
37 {}
38
40 void enter(const not_& /* x */)
41 {
42 result = false;
43 }
44
46 void enter(const minus& /* x */)
47 {
48 result = false;
49 }
50
52 void enter(const imp& /* x */)
53 {
54 result = false;
55 }
56};
58
60
61// \brief Visitor for normalizing a state formula.
62struct normalize_builder: public state_formula_builder<normalize_builder>
63{
64 typedef state_formula_builder<normalize_builder> super;
65 using super::enter;
66 using super::leave;
67 using super::update;
68 using super::apply;
69
70 bool m_quantitative;
71 bool m_negated;
72
73 // negated indicates that the formulas is under a negation.
74 // quantitative indicates that the formula yields a real value,
75 // in which case forall, exists and not are replaced by supremum, infimum and minus.
76 normalize_builder(bool quantitative, bool negated)
77 : m_quantitative(quantitative),
78 m_negated(negated)
79 {}
80
81 template <class T>
82 void apply(T& result, const data::data_expression& x)
83 {
84 if (m_quantitative)
85 {
86 if (m_negated)
87 {
88 if (x.sort()==data::sort_bool::bool_())
89 {
90 result = data::sort_bool::not_(x);
91 }
92 else
93 {
94 result = data::sort_real::negate(x);
95 }
96 }
97 else
98 {
99 result = x;
100 }
101 }
102 else // x is an ordinary modal formula.
103 {
104 assert(x.sort()==data::sort_bool::bool_());
105 result = m_negated ? data::sort_bool::not_(x) : x;
106 }
107 }
108
109 template <class T>
110 void apply(T& result, const true_& /*x*/)
111 {
112 if (m_negated)
113 {
114 result = false_();
115 }
116 else
117 {
118 result = true_();
119 }
120 }
121
122 template <class T>
123 void apply(T& result, const false_& /*x*/)
124 {
125 if (m_negated)
126 {
127 result = true_();
128 }
129 else
130 {
131 result = false_();
132 }
133 }
134
135 template <class T>
136 void apply(T& result, const not_& x)
137 {
138 assert(!m_quantitative);
139 m_negated=!m_negated;
140 apply(result, x.operand());
141 m_negated=!m_negated;
142 }
143
144 template <class T>
145 void apply(T& result, const minus& x)
146 {
147 assert(m_quantitative);
148 m_negated=!m_negated;
149 apply(result, x.operand());
150 m_negated=!m_negated;
151 }
152
153 template <class T>
154 void apply(T& result, const and_& x)
155 {
156 state_formula left, right;
157 apply(left, x.left());
158 apply(right, x.right());
159 if (m_negated)
160 {
161 make_or_(result, left, right);
162 }
163 else
164 {
165 make_and_(result, left, right);
166 }
167 }
168
169 template <class T>
170 void apply(T& result, const or_& x)
171 {
172 state_formula left, right;
173 apply(left, x.left());
174 apply(right, x.right());
175 if (m_negated)
176 {
177 make_and_(result, left, right);
178 }
179 else
180 {
181 make_or_(result, left, right);
182 }
183 }
184
185 template <class T>
186 void apply(T& result, const plus& x)
187 {
188 state_formula left, right;
189 apply(left, x.left());
190 apply(right, x.right());
191 if (m_negated)
192 {
193 // The plus operator can be inverted if for instance the operator eq_mininf(x) is present, being equal to -infinity
194 // if x is minus infinity, and being plus infinity otherwise.
195 // The dual plus then is: e1 dual+ e2 = eq_mininf(e1) && eq_mininf(e2) && (e1+e2).
196 throw mcrl2::runtime_error("Cannot negate the plus operator in quantitative modal formulas: " + pp(x) + ".");
197 }
198 else
199 {
200 make_plus(result, left, right);
201 }
202 }
203
204 template <class T>
205 void apply(T& result, const imp& x)
206 {
207 state_formula y = m_quantitative ?
208 or_(minus(x.left()), x.right()) :
209 or_(not_(x.left()), x.right());
210 apply(result, y);
211 }
212
213 template <class T>
214 void apply(T& result, const forall& x)
215 {
216 state_formula body;
217 apply(body, x.body());
218 if (m_negated)
219 {
220 state_formulas::make_exists(result, x.variables(), body);
221 }
222 else
223 {
224 state_formulas::make_forall(result, x.variables(), body);
225 }
226 }
227
228 template <class T>
229 void apply(T& result, const exists& x)
230 {
231 state_formula body;
232 apply(body, x.body());
233 if (m_negated)
234 {
235 state_formulas::make_forall(result, x.variables(), body);
236 }
237 else
238 {
239 state_formulas::make_exists(result, x.variables(), body);
240 }
241 }
242
243 template <class T>
244 void apply(T& result, const supremum& x)
245 {
246 state_formula body;
247 apply(body, x.body());
248 if (m_negated)
249 {
250 make_infimum(result, x.variables(), body);
251 }
252 else
253 {
254 make_supremum(result, x.variables(), body);
255 }
256 }
257
258 template <class T>
259 void apply(T& result, const infimum& x)
260 {
261 state_formula body;
262 apply(body, x.body());
263 if (m_negated)
264 {
265 make_supremum(result, x.variables(), body);
266 }
267 else
268 {
269 make_infimum(result, x.variables(), body);
270 }
271 }
272
273 template <class T>
274 void apply(T& result, const sum& x)
275 {
276 state_formula body;
277 apply(body, x.body());
278 make_sum(result, x.variables(), body);
279 }
280
281 template <class T>
282 void apply(T& result, const variable& x)
283 {
284 if (m_negated)
285 {
286 throw mcrl2::runtime_error(std::string("normalize error: illegal argument ") + pp(x));
287 }
288 result = x;
289 }
290
291 template <class T>
292 void apply(T& result, const must& x)
293 {
294 state_formula operand;
295 apply(operand, x.operand());
296 if (m_negated)
297 {
298 make_may(result, x.formula(), operand);
299 }
300 else
301 {
302 make_must(result, x.formula(), operand);
303 }
304 }
305
306 template <class T>
307 void apply(T& result, const may& x)
308 {
309 state_formula operand;
310 apply(operand, x.operand());
311 if (m_negated)
312 {
313 make_must(result, x.formula(), operand);
314 }
315 else
316 {
317 make_may(result, x.formula(), operand);
318 }
319 }
320
321 template <class T>
322 void apply(T& result, const mu& x)
323 {
324 state_formula operand;
325 if (m_negated)
326 {
327 apply(operand, negate_variables(x.name(), m_quantitative, x.operand()));
328 make_nu(result, x.name(), x.assignments(), operand);
329 }
330 else
331 {
332 apply(operand, x.operand());
333 make_mu(result, x.name(), x.assignments(), operand);
334 }
335 }
336
337 template <class T>
338 void apply(T& result, const nu& x)
339 {
340 state_formula operand;
341 if (m_negated)
342 {
343 apply(operand, negate_variables(x.name(), m_quantitative, x.operand()));
344 make_mu(result, x.name(), x.assignments(), operand);
345 }
346 else
347 {
348 apply(operand, x.operand());
349 make_nu(result, x.name(), x.assignments(), operand);
350 }
351 }
352
353 template <class T>
354 void apply(T& result, const delay& x)
355 {
356 if (m_negated)
357 {
358 result=yaled();
359 }
360 else
361 {
362 result=x;
363 }
364 }
365
366 template <class T>
367 void apply(T& result, const delay_timed& x)
368 {
369 if (m_negated)
370 {
371 make_yaled_timed(result, x.time_stamp());
372 }
373 else
374 {
375 result=x;
376 }
377 }
378
379 template <class T>
380 void apply(T& result, const yaled& x)
381 {
382 if (m_negated)
383 {
384 result=delay();
385 }
386 else
387 {
388 result=x;
389 }
390 }
391
392 template <class T>
393 void apply(T& result, const yaled_timed& x)
394 {
395 if (m_negated)
396 {
397 make_delay_timed(result, x.time_stamp());
398 }
399 else
400 {
401 result=x;
402 }
403 }
404};
406
410template <typename T>
411bool is_normalized(const T& x)
412{
413 is_normalized_traverser f;
414 f.apply(x);
415 return f.result;
416}
417
423template <typename T>
424void normalize(T& x, bool quantitative = false, bool negated = false, typename std::enable_if< !std::is_base_of< atermpp::aterm, T >::value>::type* = nullptr)
425{
426 normalize_builder f(quantitative, negated);
427 f.update(x);
428}
429
435template <typename T>
436T normalize(const T& x, bool quantitative = false, bool negated = false, typename std::enable_if< std::is_base_of< atermpp::aterm, T >::value>::type* = nullptr)
437{
438 T result;
439 normalize_builder f(quantitative, negated);
440 f.apply(result, x);
441 return result;
442}
443
444} // namespace state_formulas
445
446} // namespace mcrl2
447
448#endif // MCRL2_MODAL_FORMULA_NORMALIZE_H
Standard exception class for reporting runtime errors.
Definition exception.h:27
add your file description here.
std::string pp(const atermpp::aterm &t)
Transform an aterm to an ascii string.
Definition aterm.h:440
const data_expression & right(const data_expression &e)
Function for projecting out argument. right from an application.
Definition bag1.h:1636
const data_expression & left(const data_expression &e)
Function for projecting out argument. left from an application.
Definition bag1.h:1624
const function_symbol & false_()
Constructor for function symbol false.
Definition bool.h:109
const function_symbol & not_()
Constructor for function symbol !.
Definition bool.h:173
void make_and_(data_expression &result, const data_expression &arg0, const data_expression &arg1)
Make an application of function symbol &&.
Definition bool.h:271
const function_symbol & true_()
Constructor for function symbol true.
Definition bool.h:77
void make_or_(data_expression &result, const data_expression &arg0, const data_expression &arg1)
Make an application of function symbol ||.
Definition bool.h:335
function_symbol minus(const sort_expression &s0, const sort_expression &s1)
Definition int1.h:1039
void make_plus(data_expression &result, const data_expression &arg0, const data_expression &arg1)
Make an application of function symbol +.
Definition int1.h:1013
bool is_normalized(const T &x)
Checks if a state formula is normalized.
Definition normalize.h:411
void make_infimum(atermpp::aterm &t, const ARGUMENTS &... args)
void make_delay_timed(atermpp::aterm &t, const ARGUMENTS &... args)
void make_may(atermpp::aterm &t, const ARGUMENTS &... args)
void make_must(atermpp::aterm &t, const ARGUMENTS &... args)
void make_nu(atermpp::aterm &t, const ARGUMENTS &... args)
void make_supremum(atermpp::aterm &t, const ARGUMENTS &... args)
void make_sum(atermpp::aterm &t, const ARGUMENTS &... args)
state_formula negate_variables(const core::identifier_string &name, bool quantitative, const state_formula &x)
Negates variable instantiations in a state formula with a given name.
void make_yaled_timed(atermpp::aterm &t, const ARGUMENTS &... args)
void normalize(T &x, bool quantitative=false, bool negated=false, typename std::enable_if< !std::is_base_of< atermpp::aterm, T >::value >::type *=nullptr)
The function normalize brings (embedded) state formulas into positive normal form,...
Definition normalize.h:424
void make_mu(atermpp::aterm &t, const ARGUMENTS &... args)
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.