mCRL2
Loading...
Searching...
No Matches
print.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_PROCESS_PRINT_H
13#define MCRL2_PROCESS_PRINT_H
14
15#include "mcrl2/data/print.h"
17
18namespace mcrl2 {
19
20namespace process {
21
22constexpr inline int precedence(const choice&) { return 1; }
23constexpr inline int precedence(const sum&) { return 2; }
24constexpr inline int precedence(const stochastic_operator&) { return 2; }
25constexpr inline int precedence(const merge&) { return 3; }
26constexpr inline int precedence(const left_merge&) { return 4; }
27constexpr inline int precedence(const if_then&) { return 5; }
28constexpr inline int precedence(const if_then_else&) { return 5; }
29constexpr inline int precedence(const bounded_init&) { return 6; }
30constexpr inline int precedence(const seq&) { return 7; }
31constexpr inline int precedence(const at&) { return 8; }
32constexpr inline int precedence(const sync&) { return 9; }
33inline int precedence(const process_expression& x)
34{
35 if (is_choice(x)) { return precedence(atermpp::down_cast<choice>(x)); }
36 else if (is_sum(x)) { return precedence(atermpp::down_cast<sum>(x)); }
37 else if (is_stochastic_operator(x)) { return precedence(atermpp::down_cast<stochastic_operator>(x)); }
38 else if (is_merge(x)) { return precedence(atermpp::down_cast<merge>(x)); }
39 else if (is_left_merge(x)) { return precedence(atermpp::down_cast<left_merge>(x)); }
40 else if (is_if_then(x)) { return precedence(atermpp::down_cast<if_then>(x)); }
41 else if (is_if_then_else(x)) { return precedence(atermpp::down_cast<if_then_else>(x)); }
42 else if (is_bounded_init(x)) { return precedence(atermpp::down_cast<bounded_init>(x)); }
43 else if (is_seq(x)) { return precedence(atermpp::down_cast<seq>(x)); }
44 else if (is_at(x)) { return precedence(atermpp::down_cast<at>(x)); }
45 else if (is_sync(x)) { return precedence(atermpp::down_cast<sync>(x)); }
46 return core::detail::max_precedence;
47}
48
49// only defined for binary operators
50inline bool is_left_associative(const choice&) { return true; }
51inline bool is_left_associative(const merge&) { return true; }
52inline bool is_left_associative(const left_merge&) { return false; }
53inline bool is_left_associative(const bounded_init&) { return true; }
54inline bool is_left_associative(const seq&) { return true; }
55inline bool is_left_associative(const sync&) { return false; }
57{
58 if (is_choice(x)) { return is_left_associative(atermpp::down_cast<choice>(x)); }
59 else if (is_merge(x)) { return is_left_associative(atermpp::down_cast<merge>(x)); }
60 else if (is_left_merge(x)) { return is_left_associative(atermpp::down_cast<left_merge>(x)); }
61 else if (is_bounded_init(x)) { return is_left_associative(atermpp::down_cast<bounded_init>(x)); }
62 else if (is_seq(x)) { return is_left_associative(atermpp::down_cast<seq>(x)); }
63 else if (is_sync(x)) { return is_left_associative(atermpp::down_cast<sync>(x)); }
64 return false;
65}
66
67// only defined for binary operators
68inline bool is_right_associative(const choice&) { return true; }
69inline bool is_right_associative(const merge&) { return true; }
70inline bool is_right_associative(const left_merge&) { return true; }
71inline bool is_right_associative(const bounded_init&) { return true; }
72inline bool is_right_associative(const seq&) { return true; }
73inline bool is_right_associative(const sync&) { return true; }
75{
76 if (is_choice(x)) { return is_right_associative(atermpp::down_cast<choice>(x)); }
77 else if (is_merge(x)) { return is_right_associative(atermpp::down_cast<merge>(x)); }
78 else if (is_left_merge(x)) { return is_right_associative(atermpp::down_cast<left_merge>(x)); }
79 else if (is_bounded_init(x)) { return is_right_associative(atermpp::down_cast<bounded_init>(x)); }
80 else if (is_seq(x)) { return is_right_associative(atermpp::down_cast<seq>(x)); }
81 else if (is_sync(x)) { return is_right_associative(atermpp::down_cast<sync>(x)); }
82 return false;
83}
84
85namespace detail
86{
87
88template <typename Derived>
89struct printer: public process::add_traverser_sort_expressions<data::detail::printer, Derived>
90{
92
93 using super::enter;
94 using super::leave;
95 using super::apply;
96 using super::derived;
97 using super::print_assignments;
98 using super::print_list;
99 using super::print_variables;
100 using super::print_expression;
101 using super::print_unary_operand;
102 using super::print_binary_operation;
103
105 {
106 derived().print("init ");
107 derived().apply(init);
108 derived().print(";\n");
109 }
110
111 void print_if_then_condition(const data::data_expression& condition, const std::string& arrow = " -> ")
112 {
113 print_expression(condition, false);
114 derived().print(arrow);
115 }
116
117 // Container contains elements of type T such that t.sort() is a sort_expression.
118 template <typename Container>
119 void print_action_declarations(const Container& container,
120 const std::string& opener = "(",
121 const std::string& closer = ")",
122 const std::string& separator = ", "
123 )
124 {
125 // print nothing if the container is empty
126 if (container.empty())
127 {
128 return;
129 }
130
131 auto first = container.begin();
132 auto last = container.end();
133
134 derived().print(opener);
135
136 while (first != last)
137 {
138 if (first != container.begin())
139 {
140 derived().print(separator);
141 }
142
143 typename Container::const_iterator i = first;
144 do
145 {
146 ++i;
147 }
148 while (i != last && first->sorts() == i->sorts());
149
150 print_list(std::vector<process::action_label>(first, i), "", "", ",");
151 if (!first->sorts().empty())
152 {
153 derived().print(": ");
154 print_list(first->sorts(), "", "", " # ");
155 }
156
157 first = i;
158 }
159 derived().print(closer);
160 }
161
162 // Container contains elements of type T such that t.sort() is a sort_expression.
163 template <typename Container>
164 void print_action_declarations_maximally_shared(const Container& container,
165 const std::string& opener = "(",
166 const std::string& closer = ")",
167 const std::string& separator = ", "
168 )
169 {
170 typedef typename Container::value_type T;
171
172 // print nothing if the container is empty
173 if (container.empty())
174 {
175 return;
176 }
177
178 // sort_map[s] will contain all elements t of container with t.sorts() == s.
179 std::map<data::sort_expression_list, std::vector<T> > sort_map;
180
181 // sort_lists will contain all sort expression lists s that appear as a key in sort_map,
182 // in the order they are encountered in container
183 std::vector<data::sort_expression_list> sort_lists;
184
185 for (auto i = container.begin(); i != container.end(); ++i)
186 {
187 if (sort_map.find(i->sorts()) == sort_map.end())
188 {
189 sort_lists.push_back(i->sorts());
190 }
191 sort_map[i->sorts()].push_back(*i);
192 }
193
194 // do the actual printing
195 derived().print(opener);
196 for (auto i = sort_lists.begin(); i != sort_lists.end(); ++i)
197 {
198 if (i != sort_lists.begin())
199 {
200 derived().print(separator);
201 }
202 const std::vector<T>& v = sort_map[*i];
203 print_list(v, "", "", ",");
204 if (!i->empty())
205 {
206 derived().print(": ");
207 print_list(*i, "", "", " # ");
208 }
209 }
210 derived().print(closer);
211 }
212
214 {
215 derived().enter(x);
216 derived().apply(x.name());
217 derived().leave(x);
218 }
219
220 void apply(const process::action& x)
221 {
222 derived().enter(x);
223 derived().apply(x.label());
224 print_list(x.arguments(), "(", ")", ", ");
225 derived().leave(x);
226 }
227
229 {
230 derived().enter(x);
231 derived().apply(x.data());
232 print_action_declarations(x.action_labels(), "act ",";\n\n", ";\n ");
233 print_variables(x.global_variables(), true, true, true, "glob ", ";\n\n", ";\n ");
234 print_list(x.equations(), "proc ", "\n\n", "\n ");
236 derived().leave(x);
237 }
238
240 {
241 derived().enter(x);
242 derived().apply(x.name());
243 derived().leave(x);
244 }
245
247 {
248 derived().enter(x);
249 derived().apply(x.identifier().name());
250 print_variables(x.formal_parameters(), true, true, false);
251 derived().print(" = ");
252 derived().apply(x.expression());
253 derived().print(";");
254 derived().leave(x);
255 }
256
258 {
259 derived().enter(x);
260 derived().apply(x.identifier().name());
261 print_variables(x.actual_parameters(), false);
262 derived().leave(x);
263 }
264
266 {
267 derived().enter(x);
268 derived().apply(x.identifier().name());
269 derived().print("(");
270 print_assignments(x.assignments(), true, "", "");
271 derived().print(")");
272 derived().leave(x);
273 }
274
275 void apply(const process::delta& x)
276 {
277 derived().enter(x);
278 derived().print("delta");
279 derived().leave(x);
280 }
281
282 void apply(const process::tau& x)
283 {
284 derived().enter(x);
285 derived().print("tau");
286 derived().leave(x);
287 }
288
289 void apply(const process::sum& x)
290 {
291 derived().enter(x);
292 derived().print("sum ");
293 print_variables(x.variables(), true, true, false, "", "");
294 derived().print(". ");
295 print_unary_operand(x, x.operand());
296 derived().leave(x);
297 }
298
300 {
301 derived().enter(x);
302 derived().print("dist ");
303 print_variables(x.variables(), true, true, false, "", "");
304 derived().print("[");
305 derived().apply(x.distribution());
306 derived().print("] . ");
307 print_unary_operand(x, x.operand());
308 derived().leave(x);
309 }
310
311 void apply(const process::block& x)
312 {
313 derived().enter(x);
314 derived().print("block(");
315 print_list(x.block_set(), "{", "}, ", ", ", true);
316 derived().apply(x.operand());
317 derived().print(")");
318 derived().leave(x);
319 }
320
321 void apply(const process::hide& x)
322 {
323 derived().enter(x);
324 derived().print("hide(");
325 print_list(x.hide_set(), "{", "}, ", ", ");
326 derived().apply(x.operand());
327 derived().print(")");
328 derived().leave(x);
329 }
330
332 {
333 derived().enter(x);
334 derived().apply(x.source());
335 derived().print(" -> ");
336 derived().apply(x.target());
337 derived().leave(x);
338 }
339
340 void apply(const process::rename& x)
341 {
342 derived().enter(x);
343 derived().print("rename(");
344 print_list(x.rename_set(), "{", "}, ", ", ");
345 derived().apply(x.operand());
346 derived().print(")");
347 derived().leave(x);
348 }
349
351 {
352 derived().enter(x);
353 print_list(x.names(), "", "", " | ");
354 derived().leave(x);
355 }
356
358 {
359 derived().enter(x);
360 derived().apply(x.action_name());
361 derived().print(" -> ");
362 derived().apply(x.name());
363 derived().leave(x);
364 }
365
366 void apply(const process::comm& x)
367 {
368 derived().enter(x);
369 derived().print("comm(");
370 print_list(x.comm_set(), "{", "}, ", ", ");
371 derived().apply(x.operand());
372 derived().print(")");
373 derived().leave(x);
374 }
375
376 void apply(const process::allow& x)
377 {
378 derived().enter(x);
379 derived().print("allow(");
380 print_list(x.allow_set(), "{", "}, ", ", ", true);
381 derived().apply(x.operand());
382 derived().print(")");
383 derived().leave(x);
384 }
385
386 void apply(const process::sync& x)
387 {
388 derived().enter(x);
389 print_binary_operation(x, " | ");
390 derived().leave(x);
391 }
392
393 void apply(const process::at& x)
394 {
395 derived().enter(x);
396 derived().apply(x.operand());
397 derived().print(" @ ");
398 print_expression(x.time_stamp(), precedence(x.time_stamp()) < core::detail::max_precedence);
399 derived().leave(x);
400 }
401
402 void apply(const process::seq& x)
403 {
404 derived().enter(x);
405 print_binary_operation(x, " . ");
406 derived().leave(x);
407 }
408
409 void apply(const process::if_then& x)
410 {
411 derived().enter(x);
413 print_expression(x.then_case(), precedence(x.then_case()) < precedence(x));
414 derived().leave(x);
415 }
416
418 {
419 derived().enter(x);
421 // N.B. the then case is printed with a higher precedence, since we want the expression a -> b -> c <> d <> e
422 // to be printed as a -> (b -> c <> d) <> e
423 print_expression(x.then_case(), precedence(x.then_case()) <= precedence(x));
424 derived().print(" <> ");
425 print_expression(x.else_case(), precedence(x.else_case()) < precedence(x));
426 derived().leave(x);
427 }
428
430 {
431 derived().enter(x);
432 print_binary_operation(x, " << ");
433 derived().leave(x);
434 }
435
436 void apply(const process::merge& x)
437 {
438 derived().enter(x);
439 print_binary_operation(x, " || ");
440 derived().leave(x);
441 }
442
444 {
445 derived().enter(x);
446 print_binary_operation(x, " ||_ ");
447 derived().leave(x);
448 }
449
450 void apply(const process::choice& x)
451 {
452 derived().enter(x);
453 print_binary_operation(x, " + ");
454 derived().leave(x);
455 }
456
458 {
459 derived().enter(x);
460 derived().apply(x.name());
461 print_assignments(x.assignments(), true, "(", ")", ", ");
462 derived().leave(x);
463 }
464
466 {
467 derived().enter(x);
468 print_list(x.actions(), "", "", " | ");
469 derived().leave(x);
470 }
471
472};
473
474} // namespace detail
475
478{
479 template <typename T>
480 void operator()(const T& x, std::ostream& out)
481 {
482 core::detail::apply_printer<process::detail::printer> printer(out);
483 printer.apply(x);
484 }
485};
486
488template <typename T>
489std::string pp(const T& x)
490{
491 std::ostringstream out;
492 stream_printer()(x, out);
493 return out.str();
494}
495
496} // namespace process
497
498} // namespace mcrl2
499
500#endif // MCRL2_PROCESS_PRINT_H
bool empty() const
Returns true if the term has no arguments.
Definition aterm.h:158
const_iterator end() const
const_iterator begin() const
\brief An action label
const core::identifier_string & name() const
\brief A multiset of action names
const core::identifier_string_list & names() const
const data::data_expression_list & arguments() const
const action_label & label() const
\brief The allow operator
const process_expression & operand() const
const action_name_multiset_list & allow_set() const
\brief The at operator
const data::data_expression & time_stamp() const
const process_expression & operand() const
\brief The block operator
const process_expression & operand() const
const core::identifier_string_list & block_set() const
\brief The bounded initialization
\brief The choice operator
\brief The communication operator
const communication_expression_list & comm_set() const
const process_expression & operand() const
const core::identifier_string & name() const
const action_name_multiset & action_name() const
\brief The value delta
\brief The hide operator
const core::identifier_string_list & hide_set() const
const process_expression & operand() const
\brief The if-then-else operator
const process_expression & else_case() const
const process_expression & then_case() const
const data::data_expression & condition() const
\brief The if-then operator
const process_expression & then_case() const
const data::data_expression & condition() const
\brief The left merge operator
\brief The merge operator
\brief A process equation
const data::variable_list & formal_parameters() const
const process_identifier & identifier() const
const process_expression & expression() const
\brief A process expression
\brief A process identifier
const core::identifier_string & name() const
const data::assignment_list & assignments() const
const process_identifier & identifier() const
const data::data_expression_list & actual_parameters() const
const process_identifier & identifier() const
Process specification consisting of a data specification, action labels, a sequence of process equati...
const std::vector< process_equation > & equations() const
Returns the equations of the process specification.
const process_expression & init() const
Returns the initialization of the process specification.
const data::data_specification & data() const
Returns the data specification.
const process::action_label_list & action_labels() const
Returns the action label specification.
const std::set< data::variable > & global_variables() const
Returns the declared free variables of the process specification.
\brief A rename expression
const core::identifier_string & source() const
const core::identifier_string & target() const
\brief The rename operator
const process_expression & operand() const
const rename_expression_list & rename_set() const
\brief The sequential composition
\brief The distribution operator
const data::variable_list & variables() const
const data::data_expression & distribution() const
const process_expression & operand() const
\brief The sum operator
const process_expression & operand() const
const data::variable_list & variables() const
\brief The synchronization operator
\brief The value tau
\brief An untyped multi action or data application
const data::untyped_data_parameter_list & actions() const
\brief An untyped process assginment
const data::untyped_identifier_assignment_list & assignments() const
const core::identifier_string & name() const
Provides utilities for pretty printing.
MCRL2_EXPORT bool init(rewriter_interface *i, RewriterCompilingJitty *this_rewriter)
bool is_at(const atermpp::aterm &x)
bool is_left_associative(const choice &)
Definition print.h:50
bool is_seq(const atermpp::aterm &x)
bool is_merge(const atermpp::aterm &x)
bool is_bounded_init(const atermpp::aterm &x)
bool is_sum(const atermpp::aterm &x)
constexpr int precedence(const choice &)
Definition print.h:22
bool is_if_then_else(const atermpp::aterm &x)
bool is_right_associative(const choice &)
Definition print.h:68
bool is_left_merge(const atermpp::aterm &x)
std::string pp(const action_label &x)
Definition process.cpp:36
bool is_if_then(const atermpp::aterm &x)
bool is_choice(const atermpp::aterm &x)
bool is_stochastic_operator(const atermpp::aterm &x)
bool is_sync(const atermpp::aterm &x)
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.
void apply(const process::action_label &x)
Definition traverser.h:40
void apply(const process::stochastic_operator &x)
Definition print.h:299
void apply(const process::delta &x)
Definition print.h:275
void apply(const process::process_instance_assignment &x)
Definition print.h:265
void apply(const process::process_identifier &x)
Definition print.h:239
void apply(const process::process_equation &x)
Definition print.h:246
void print_if_then_condition(const data::data_expression &condition, const std::string &arrow=" -> ")
Definition print.h:111
void apply(const process::tau &x)
Definition print.h:282
void apply(const process::if_then &x)
Definition print.h:409
void apply(const process::choice &x)
Definition print.h:450
void apply(const process::sum &x)
Definition print.h:289
void apply(const process::allow &x)
Definition print.h:376
void apply(const process::merge &x)
Definition print.h:436
void apply(const process::at &x)
Definition print.h:393
void apply(const process::if_then_else &x)
Definition print.h:417
void apply(const process::bounded_init &x)
Definition print.h:429
void apply(const process::sync &x)
Definition print.h:386
void apply(const process::rename &x)
Definition print.h:340
void apply(const process::block &x)
Definition print.h:311
void apply(const process::action_name_multiset &x)
Definition print.h:350
void apply(const process::seq &x)
Definition print.h:402
void apply(const process::rename_expression &x)
Definition print.h:331
void apply(const process::hide &x)
Definition print.h:321
void print_initial_state(const process_expression &init)
Definition print.h:104
void print_action_declarations(const Container &container, const std::string &opener="(", const std::string &closer=")", const std::string &separator=", ")
Definition print.h:119
void print_action_declarations_maximally_shared(const Container &container, const std::string &opener="(", const std::string &closer=")", const std::string &separator=", ")
Definition print.h:164
void apply(const process::action &x)
Definition print.h:220
void apply(const process::process_specification &x)
Definition print.h:228
void apply(const process::untyped_multi_action &x)
Definition print.h:465
process::add_traverser_sort_expressions< data::detail::printer, Derived > super
Definition print.h:91
void apply(const process::comm &x)
Definition print.h:366
void apply(const process::left_merge &x)
Definition print.h:443
void apply(const process::action_label &x)
Definition print.h:213
void apply(const process::process_instance &x)
Definition print.h:257
void apply(const process::communication_expression &x)
Definition print.h:357
void apply(const process::untyped_process_assignment &x)
Definition print.h:457
Prints the object x to a stream.
Definition print.h:478
void operator()(const T &x, std::ostream &out)
Definition print.h:480