1
use std::fmt;
2

            
3
use itertools::Itertools;
4

            
5
use crate::ActDecl;
6
use crate::ActFrm;
7
use crate::ActFrmBinaryOp;
8
use crate::Action;
9
use crate::Assignment;
10
use crate::Bound;
11
use crate::Comm;
12
use crate::ComplexSort;
13
use crate::ConstructorDecl;
14
use crate::DataExpr;
15
use crate::DataExprBinaryOp;
16
use crate::DataExprUnaryOp;
17
use crate::DataExprUpdate;
18
use crate::EqnDecl;
19
use crate::EqnSpec;
20
use crate::FixedPointOperator;
21
use crate::IdDecl;
22
use crate::ModalityOperator;
23
use crate::MultiAction;
24
use crate::MultiActionLabel;
25
use crate::PbesEquation;
26
use crate::PbesExpr;
27
use crate::PbesExprBinaryOp;
28
use crate::ProcDecl;
29
use crate::ProcExprBinaryOp;
30
use crate::ProcessExpr;
31
use crate::PropVarDecl;
32
use crate::PropVarInst;
33
use crate::Quantifier;
34
use crate::RegFrm;
35
use crate::Rename;
36
use crate::Sort;
37
use crate::SortDecl;
38
use crate::SortExpression;
39
use crate::Span;
40
use crate::StateFrm;
41
use crate::StateFrmOp;
42
use crate::StateFrmUnaryOp;
43
use crate::StateVarAssignment;
44
use crate::StateVarDecl;
45
use crate::UntypedDataSpecification;
46
use crate::UntypedPbes;
47
use crate::UntypedProcessSpecification;
48
use crate::UntypedStateFrmSpec;
49
use crate::VarDecl;
50

            
51
/// Prints location information for a span in the source.
52
pub fn print_location(input: &str, span: &Span) {
53
    input.lines().enumerate().fold(span.start, |current, (number, line)| {
54
        if current < line.len() {
55
            println!("ln {number}, col {}", span.start - current);
56
        }
57
        current - line.len()
58
    });
59
}
60

            
61
// Display implementations
62
impl fmt::Display for Sort {
63
13737
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64
13737
        write!(f, "{self:?}")
65
13737
    }
66
}
67

            
68
impl fmt::Display for ComplexSort {
69
3213
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70
3213
        write!(f, "{self:?}")
71
3213
    }
72
}
73

            
74
impl fmt::Display for Assignment {
75
1749
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76
1749
        write!(f, "{} = {}", self.identifier, self.expr)
77
1749
    }
78
}
79

            
80
impl fmt::Display for UntypedProcessSpecification {
81
513
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82
513
        writeln!(f, "{}", self.data_specification)?;
83

            
84
513
        if !self.action_declarations.is_empty() {
85
471
            writeln!(f, "act")?;
86
5979
            for act_decl in &self.action_declarations {
87
5979
                writeln!(f, "   {act_decl};")?;
88
            }
89

            
90
471
            writeln!(f)?;
91
42
        }
92

            
93
513
        if !self.process_declarations.is_empty() {
94
471
            writeln!(f, "proc")?;
95
2718
            for proc_decl in &self.process_declarations {
96
2718
                writeln!(f, "   {proc_decl};")?;
97
            }
98

            
99
471
            writeln!(f)?;
100
42
        }
101

            
102
513
        if !self.global_variables.is_empty() {
103
3
            writeln!(f, "glob")?;
104
3
            for var_decl in &self.global_variables {
105
3
                writeln!(f, "   {var_decl};")?;
106
            }
107

            
108
3
            writeln!(f)?;
109
510
        }
110

            
111
513
        if let Some(init) = &self.init {
112
507
            writeln!(f, "init {init};")?;
113
6
        }
114
513
        Ok(())
115
513
    }
116
}
117

            
118
impl fmt::Display for UntypedDataSpecification {
119
1212
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
120
1212
        if !self.sort_declarations.is_empty() {
121
576
            writeln!(f, "sort")?;
122
2559
            for decl in &self.sort_declarations {
123
2559
                writeln!(f, "   {decl};")?;
124
            }
125

            
126
576
            writeln!(f)?;
127
636
        }
128

            
129
1212
        if !self.constructor_declarations.is_empty() {
130
            writeln!(f, "cons")?;
131
            for decl in &self.constructor_declarations {
132
                writeln!(f, "   {decl};")?;
133
            }
134

            
135
            writeln!(f)?;
136
1212
        }
137

            
138
1212
        if !self.map_declarations.is_empty() {
139
639
            writeln!(f, "map")?;
140
20634
            for decl in &self.map_declarations {
141
20634
                writeln!(f, "   {decl};")?;
142
            }
143

            
144
639
            writeln!(f)?;
145
573
        }
146

            
147
1866
        for decl in &self.equation_declarations {
148
1866
            writeln!(f, "{decl}")?;
149
        }
150
1212
        Ok(())
151
1212
    }
152
}
153

            
154
impl fmt::Display for UntypedPbes {
155
9
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
156
9
        writeln!(f, "{}", self.data_specification)?;
157
9
        writeln!(f)?;
158
9
        if !self.global_variables.is_empty() {
159
            writeln!(f, "glob")?;
160
            for var_decl in &self.global_variables {
161
                writeln!(f, "   {var_decl};")?;
162
            }
163

            
164
            writeln!(f)?;
165
9
        }
166
9
        writeln!(f)?;
167

            
168
9
        if !self.equations.is_empty() {
169
9
            writeln!(f, "pbes")?;
170
15
            for equation in &self.equations {
171
15
                writeln!(f, "   {equation};")?;
172
            }
173
        }
174

            
175
9
        writeln!(f, "init {};", self.init)
176
9
    }
177
}
178

            
179
impl fmt::Display for PropVarInst {
180
21
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
181
21
        if self.arguments.is_empty() {
182
12
            write!(f, "{}", self.identifier)
183
        } else {
184
9
            write!(f, "{}({})", self.identifier, self.arguments.iter().format(", "))
185
        }
186
21
    }
187
}
188

            
189
impl fmt::Display for PbesEquation {
190
15
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
191
15
        write!(f, "{} {} = {}", self.operator, self.variable, self.formula)
192
15
    }
193
}
194

            
195
impl fmt::Display for PropVarDecl {
196
15
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
197
15
        if self.parameters.is_empty() {
198
9
            write!(f, "{}", self.identifier)
199
        } else {
200
6
            write!(f, "{}({})", self.identifier, self.parameters.iter().format(", "))
201
        }
202
15
    }
203
}
204

            
205
impl fmt::Display for PbesExpr {
206
30
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
207
30
        match self {
208
3
            PbesExpr::True => write!(f, "true"),
209
            PbesExpr::False => write!(f, "false"),
210
12
            PbesExpr::PropVarInst(instance) => write!(f, "{instance}"),
211
3
            PbesExpr::Negation(expr) => write!(f, "(! {expr})"),
212
6
            PbesExpr::Binary { op, lhs, rhs } => write!(f, "({lhs} {op} {rhs})"),
213
            PbesExpr::Quantifier {
214
                quantifier,
215
                variables,
216
                body,
217
            } => write!(f, "({} {} . {})", quantifier, variables.iter().format(", "), body),
218
6
            PbesExpr::DataValExpr(data_expr) => write!(f, "val({data_expr})"),
219
        }
220
30
    }
221
}
222

            
223
impl fmt::Display for PbesExprBinaryOp {
224
6
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
225
6
        match self {
226
6
            PbesExprBinaryOp::Conjunction => write!(f, "&&"),
227
            PbesExprBinaryOp::Disjunction => write!(f, "||"),
228
            PbesExprBinaryOp::Implies => write!(f, "=>"),
229
        }
230
6
    }
231
}
232

            
233
impl fmt::Display for EqnSpec {
234
1866
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
235
1866
        writeln!(f, "var")?;
236
9069
        for decl in &self.variables {
237
9069
            writeln!(f, "   {decl};")?;
238
        }
239

            
240
1866
        writeln!(f, "eqn")?;
241
32916
        for decl in &self.equations {
242
32916
            writeln!(f, "   {decl};")?;
243
        }
244
1866
        Ok(())
245
1866
    }
246
}
247

            
248
impl fmt::Display for SortDecl {
249
2559
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
250
2559
        write!(f, "{}", self.identifier)?;
251

            
252
2559
        if let Some(expr) = &self.expr {
253
2550
            write!(f, " = {expr}")?;
254
9
        }
255

            
256
2559
        Ok(())
257
2559
    }
258
}
259

            
260
impl fmt::Display for ActDecl {
261
5979
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
262
5979
        if self.args.is_empty() {
263
759
            write!(f, "{}", self.identifier)
264
        } else {
265
5220
            write!(f, "{}({})", self.identifier, self.args.iter().format(", "))
266
        }
267
5979
    }
268
}
269

            
270
impl fmt::Display for VarDecl {
271
19701
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
272
19701
        write!(f, "{} : {}", self.identifier, self.sort)
273
19701
    }
274
}
275

            
276
impl fmt::Display for EqnDecl {
277
32916
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
278
32916
        match &self.condition {
279
2211
            Some(condition) => write!(f, "{} -> {} = {}", condition, self.lhs, self.rhs),
280
30705
            None => write!(f, "{} = {}", self.lhs, self.rhs),
281
        }
282
32916
    }
283
}
284

            
285
impl fmt::Display for DataExprUnaryOp {
286
1566
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287
1566
        match self {
288
1269
            DataExprUnaryOp::Negation => write!(f, "!"),
289
123
            DataExprUnaryOp::Minus => write!(f, "-"),
290
174
            DataExprUnaryOp::Size => write!(f, "#"),
291
        }
292
1566
    }
293
}
294

            
295
impl fmt::Display for DataExpr {
296
577719
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
297
577719
        match self {
298
1662
            DataExpr::EmptyList => write!(f, "[]"),
299
105
            DataExpr::EmptyBag => write!(f, "{{:}}"),
300
510
            DataExpr::EmptySet => write!(f, "{{}}"),
301
1425
            DataExpr::List(expressions) => write!(f, "[{}]", expressions.iter().format(", ")),
302
138
            DataExpr::Bag(expressions) => write!(
303
138
                f,
304
                "{{ {} }}",
305
138
                expressions
306
138
                    .iter()
307
150
                    .format_with(", ", |e, f| f(&format_args!("{}: {}", e.expr, e.multiplicity)))
308
            ),
309
1044
            DataExpr::Set(expressions) => write!(f, "{{ {} }}", expressions.iter().format(", ")),
310
399981
            DataExpr::Id(identifier) => write!(f, "{identifier}"),
311
31764
            DataExpr::Binary { op, lhs, rhs } => write!(f, "({lhs} {op} {rhs})"),
312
1566
            DataExpr::Unary { op, expr } => write!(f, "({op} {expr})"),
313
3435
            DataExpr::Bool(value) => write!(f, "{value}"),
314
189
            DataExpr::Quantifier { op, variables, body } => {
315
189
                write!(f, "({} {} . {})", op, variables.iter().format(", "), body)
316
            }
317
87
            DataExpr::Lambda { variables, body } => write!(f, "(lambda {} . {})", variables.iter().format(", "), body),
318
116958
            DataExpr::Application { function, arguments } => {
319
116958
                if arguments.is_empty() {
320
                    write!(f, "{function}")
321
                } else {
322
116958
                    write!(f, "{}({})", function, arguments.iter().format(", "))
323
                }
324
            }
325
17892
            DataExpr::Number(value) => write!(f, "{value}"),
326
858
            DataExpr::FunctionUpdate { expr, update } => write!(f, "{expr}[{update}]"),
327
33
            DataExpr::SetBagComp { variable, predicate } => write!(f, "{{ {variable} | {predicate} }}"),
328
72
            DataExpr::Whr { expr, assignments } => write!(f, "{} whr {} end", expr, assignments.iter().format(", ")),
329
        }
330
577719
    }
331
}
332

            
333
impl fmt::Display for IdDecl {
334
20634
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
335
20634
        write!(f, "{} : {}", self.identifier, self.sort)
336
20634
    }
337
}
338

            
339
impl fmt::Display for DataExprUpdate {
340
858
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
341
858
        write!(f, "{} -> {}", self.expr, self.update)
342
858
    }
343
}
344

            
345
impl fmt::Display for SortExpression {
346
109569
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
347
109569
        match self {
348
14619
            SortExpression::Product { lhs, rhs } => write!(f, "({lhs} # {rhs})"),
349
10434
            SortExpression::Function { domain, range } => write!(f, "({domain} -> {range})"),
350
65502
            SortExpression::Reference(ident) => write!(f, "{ident}"),
351
13737
            SortExpression::Simple(sort) => write!(f, "{sort}"),
352
3213
            SortExpression::Complex(complex, inner) => write!(f, "{complex}({inner})"),
353
2064
            SortExpression::Struct { inner } => {
354
2064
                write!(f, "struct ")?;
355
2064
                write!(f, "{}", inner.iter().format(" | "))
356
            }
357
        }
358
109569
    }
359
}
360

            
361
impl fmt::Display for UntypedStateFrmSpec {
362
435
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
363
435
        writeln!(f, "{}", self.data_specification)?;
364

            
365
435
        writeln!(f, "{}", self.formula)
366
435
    }
367
}
368

            
369
impl fmt::Display for StateFrmUnaryOp {
370
45
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
371
45
        match self {
372
            StateFrmUnaryOp::Minus => write!(f, "-"),
373
45
            StateFrmUnaryOp::Negation => write!(f, "!"),
374
        }
375
45
    }
376
}
377

            
378
impl fmt::Display for FixedPointOperator {
379
606
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
380
606
        match self {
381
327
            FixedPointOperator::Greatest => write!(f, "nu"),
382
279
            FixedPointOperator::Least => write!(f, "mu"),
383
        }
384
606
    }
385
}
386

            
387
impl fmt::Display for StateFrm {
388
10362
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
389
10362
        match self {
390
291
            StateFrm::True => write!(f, "true"),
391
108
            StateFrm::False => write!(f, "false"),
392
            StateFrm::DataValExpr(expr) => write!(f, "val({expr})"),
393
3174
            StateFrm::Id(identifier, args) => {
394
3174
                if args.is_empty() {
395
297
                    write!(f, "{identifier}")
396
                } else {
397
2877
                    write!(f, "{}({})", identifier, args.iter().format(", "))
398
                }
399
            }
400
45
            StateFrm::Unary { op, expr } => write!(f, "({op} {expr})"),
401
            StateFrm::Modality {
402
2235
                operator,
403
2235
                formula,
404
2235
                expr,
405
2235
            } => match operator {
406
1371
                ModalityOperator::Box => write!(f, "[{formula}]{expr}"),
407
864
                ModalityOperator::Diamond => write!(f, "<{formula}>{expr}"),
408
            },
409
            StateFrm::Quantifier {
410
795
                quantifier,
411
795
                variables,
412
795
                body,
413
            } => {
414
795
                write!(f, "({} {} . {})", quantifier, variables.iter().format(", "), body)
415
            }
416
            StateFrm::Bound {
417
3
                bound: quantifier,
418
3
                variables,
419
3
                body,
420
            } => {
421
3
                write!(f, "({} {} . {})", quantifier, variables.iter().format(", "), body)
422
            }
423
3126
            StateFrm::Binary { op, lhs, rhs } => {
424
3126
                write!(f, "({lhs} {op} {rhs})")
425
            }
426
            StateFrm::FixedPoint {
427
579
                operator,
428
579
                variable,
429
579
                body,
430
            } => {
431
579
                write!(f, "({operator} {variable} . {body})")
432
            }
433
            StateFrm::Delay(expr) => write!(f, "delay@({expr})"),
434
            StateFrm::Yaled(expr) => write!(f, "yaled@({expr})"),
435
6
            StateFrm::DataValExprLeftMult(value, expr) => write!(f, "({value} * {expr})"),
436
            StateFrm::DataValExprRightMult(expr, value) => write!(f, "({expr} * {value})"),
437
        }
438
10362
    }
439
}
440

            
441
impl fmt::Display for StateVarDecl {
442
591
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
443
591
        if self.arguments.is_empty() {
444
297
            write!(f, "{}", self.identifier)
445
        } else {
446
294
            write!(f, "{}({})", self.identifier, self.arguments.iter().format(","))
447
        }
448
591
    }
449
}
450

            
451
impl fmt::Display for StateVarAssignment {
452
402
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
453
402
        write!(f, "{} : {} = {}", self.identifier, self.sort, self.expr)
454
402
    }
455
}
456

            
457
impl fmt::Display for StateFrmOp {
458
3126
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
459
3126
        match self {
460
771
            StateFrmOp::Implies => write!(f, "=>"),
461
1767
            StateFrmOp::Conjunction => write!(f, "&&"),
462
585
            StateFrmOp::Disjunction => write!(f, "||"),
463
3
            StateFrmOp::Addition => write!(f, "+"),
464
        }
465
3126
    }
466
}
467

            
468
impl fmt::Display for RegFrm {
469
3324
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
470
3324
        match self {
471
2577
            RegFrm::Action(action) => write!(f, "{action}"),
472
402
            RegFrm::Iteration(body) => write!(f, "({body})*"),
473
3
            RegFrm::Plus(body) => write!(f, "({body})+"),
474
15
            RegFrm::Choice { lhs, rhs } => write!(f, "({lhs} + {rhs})"),
475
327
            RegFrm::Sequence { lhs, rhs } => write!(f, "({lhs} . {rhs})"),
476
        }
477
3324
    }
478
}
479

            
480
impl fmt::Display for DataExprBinaryOp {
481
31764
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
482
31764
        match self {
483
2832
            DataExprBinaryOp::At => write!(f, "."),
484
129
            DataExprBinaryOp::Concat => write!(f, "++"),
485
2343
            DataExprBinaryOp::Cons => write!(f, "|>"),
486
6081
            DataExprBinaryOp::Equal => write!(f, "=="),
487
1749
            DataExprBinaryOp::NotEqual => write!(f, "!="),
488
1068
            DataExprBinaryOp::LessThan => write!(f, "<"),
489
1206
            DataExprBinaryOp::LessEqual => write!(f, "<="),
490
720
            DataExprBinaryOp::GreaterThan => write!(f, ">"),
491
477
            DataExprBinaryOp::GreaterEqual => write!(f, ">="),
492
4578
            DataExprBinaryOp::Conj => write!(f, "&&"),
493
1416
            DataExprBinaryOp::Disj => write!(f, "||"),
494
4377
            DataExprBinaryOp::Add => write!(f, "+"),
495
1950
            DataExprBinaryOp::Subtract => write!(f, "-"),
496
240
            DataExprBinaryOp::Div => write!(f, "/"),
497
165
            DataExprBinaryOp::Implies => write!(f, "=>"),
498
1467
            DataExprBinaryOp::In => write!(f, "in"),
499
39
            DataExprBinaryOp::IntDiv => write!(f, "div"),
500
264
            DataExprBinaryOp::Mod => write!(f, "mod"),
501
630
            DataExprBinaryOp::Multiply => write!(f, "*"),
502
33
            DataExprBinaryOp::Snoc => write!(f, "<|"),
503
        }
504
31764
    }
505
}
506

            
507
impl fmt::Display for ActFrm {
508
4206
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
509
4206
        match self {
510
3
            ActFrm::False => write!(f, "false"),
511
369
            ActFrm::True => write!(f, "true"),
512
2523
            ActFrm::MultAct(action) => write!(f, "{action}"),
513
381
            ActFrm::Binary { op, lhs, rhs } => {
514
381
                write!(f, "({lhs}) {op} ({rhs})")
515
            }
516
63
            ActFrm::DataExprVal(expr) => write!(f, "val({expr})"),
517
            ActFrm::Quantifier {
518
402
                quantifier,
519
402
                variables,
520
402
                body,
521
402
            } => write!(f, "({} {} . {})", quantifier, variables.iter().format(", "), body),
522
465
            ActFrm::Negation(expr) => write!(f, "(!{expr})"),
523
        }
524
4206
    }
525
}
526

            
527
impl fmt::Display for ActFrmBinaryOp {
528
381
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
529
381
        match self {
530
6
            ActFrmBinaryOp::Implies => write!(f, "=>"),
531
150
            ActFrmBinaryOp::Intersect => write!(f, "&&"),
532
225
            ActFrmBinaryOp::Union => write!(f, "||"),
533
        }
534
381
    }
535
}
536

            
537
impl fmt::Display for Bound {
538
3
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
539
3
        match self {
540
            Bound::Inf => write!(f, "inf"),
541
            Bound::Sum => write!(f, "sum"),
542
3
            Bound::Sup => write!(f, "sup"),
543
        }
544
3
    }
545
}
546

            
547
impl fmt::Display for MultiAction {
548
2523
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
549
2523
        if self.actions.is_empty() {
550
3
            write!(f, "tau")
551
        } else {
552
2520
            write!(f, "{}", self.actions.iter().format("|"))
553
        }
554
2523
    }
555
}
556

            
557
impl fmt::Display for Action {
558
2598
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
559
2598
        if self.args.is_empty() {
560
957
            write!(f, "{}", self.id)
561
        } else {
562
1641
            write!(f, "{}({})", self.id, self.args.iter().format(", "))
563
        }
564
2598
    }
565
}
566

            
567
impl fmt::Display for Quantifier {
568
1386
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
569
1386
        match self {
570
777
            Quantifier::Exists => write!(f, "exists"),
571
609
            Quantifier::Forall => write!(f, "forall"),
572
        }
573
1386
    }
574
}
575

            
576
impl fmt::Display for ConstructorDecl {
577
5760
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
578
5760
        if self.args.is_empty() {
579
4098
            write!(f, "{}", self.name)
580
        } else {
581
1662
            write!(f, "{}(", self.name)?;
582
3573
            for (i, (name, sort)) in self.args.iter().enumerate() {
583
3573
                if i > 0 {
584
1911
                    write!(f, ", ")?;
585
1662
                }
586
3573
                match name {
587
1374
                    Some(name) => write!(f, "{name} : {sort}")?,
588
2199
                    None => write!(f, "{sort}")?,
589
                }
590
            }
591
1662
            write!(f, ")")?;
592

            
593
1662
            if let Some(projection) = &self.projection {
594
150
                write!(f, "?{projection}")?;
595
1512
            }
596

            
597
1662
            Ok(())
598
        }
599
5760
    }
600
}
601

            
602
impl fmt::Display for ProcDecl {
603
2718
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
604
2718
        if self.params.is_empty() {
605
414
            write!(f, "{} = {};", self.identifier, self.body)
606
        } else {
607
2304
            write!(
608
2304
                f,
609
                "{}({}) = {};",
610
                self.identifier,
611
2304
                self.params.iter().format(", "),
612
                self.body
613
            )
614
        }
615
2718
    }
616
}
617

            
618
impl fmt::Display for ProcExprBinaryOp {
619
13977
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
620
13977
        match self {
621
8019
            ProcExprBinaryOp::Sequence => write!(f, "."),
622
3126
            ProcExprBinaryOp::Choice => write!(f, "+"),
623
1611
            ProcExprBinaryOp::Parallel => write!(f, "||"),
624
            ProcExprBinaryOp::LeftMerge => write!(f, "_||"),
625
1221
            ProcExprBinaryOp::CommMerge => write!(f, "|"),
626
        }
627
13977
    }
628
}
629

            
630
impl fmt::Display for ProcessExpr {
631
41154
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
632
41154
        match self {
633
1755
            ProcessExpr::Id(identifier, assignments) => {
634
1755
                if assignments.is_empty() {
635
555
                    write!(f, "{identifier}")
636
                } else {
637
1200
                    write!(f, "{}({})", identifier, assignments.iter().format(", "))
638
                }
639
            }
640
16854
            ProcessExpr::Action(identifier, data_exprs) => {
641
16854
                if data_exprs.is_empty() {
642
1848
                    write!(f, "{identifier}")
643
                } else {
644
15006
                    write!(f, "{}({})", identifier, data_exprs.iter().format(", "))
645
                }
646
            }
647
276
            ProcessExpr::Delta => write!(f, "delta"),
648
18
            ProcessExpr::Tau => write!(f, "tau"),
649
2844
            ProcessExpr::Sum { variables, operand } => {
650
2844
                write!(f, "(sum {} . {})", variables.iter().format(", "), operand)
651
            }
652
            ProcessExpr::Dist {
653
78
                variables,
654
78
                expr,
655
78
                operand,
656
78
            } => write!(f, "(dist {} [{}] . {})", variables.iter().format(", "), expr, operand),
657
13977
            ProcessExpr::Binary { op, lhs, rhs } => write!(f, "({lhs} {op} {rhs})"),
658
138
            ProcessExpr::Hide { actions, operand } => {
659
138
                if !actions.is_empty() {
660
138
                    write!(f, "hide({{{}}}, {})", actions.iter().format(", "), operand)
661
                } else {
662
                    Ok(())
663
                }
664
            }
665
27
            ProcessExpr::Rename { renames, operand } => {
666
27
                if !renames.is_empty() {
667
27
                    write!(f, "rename({{{}}}, {})", renames.iter().format(", "), operand)
668
                } else {
669
                    Ok(())
670
                }
671
            }
672
297
            ProcessExpr::Allow { actions, operand } => {
673
297
                if !actions.is_empty() {
674
297
                    write!(f, "allow({{{}}}, {})", actions.iter().format(", "), operand)
675
                } else {
676
                    Ok(())
677
                }
678
            }
679
21
            ProcessExpr::Block { actions, operand } => {
680
21
                if !actions.is_empty() {
681
21
                    write!(f, "block({{{}}}, {})", actions.iter().format(", "), operand)
682
                } else {
683
                    Ok(())
684
                }
685
            }
686
303
            ProcessExpr::Comm { comm, operand } => {
687
303
                if !comm.is_empty() {
688
303
                    write!(f, "comm({{{}}}, {})", comm.iter().format(", "), operand)
689
                } else {
690
                    Ok(())
691
                }
692
            }
693
4524
            ProcessExpr::Condition { condition, then, else_ } => {
694
4524
                if let Some(else_) = else_ {
695
1701
                    write!(f, "({condition}) -> ({then}) <> ({else_})")
696
                } else {
697
2823
                    write!(f, "({condition}) -> ({then})")
698
                }
699
            }
700
42
            ProcessExpr::At { expr, operand } => write!(f, "({expr})@({operand})"),
701
        }
702
41154
    }
703
}
704

            
705
impl fmt::Display for Comm {
706
1383
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
707
1383
        write!(f, "{} -> {}", self.from, self.to)
708
1383
    }
709
}
710

            
711
impl fmt::Display for Rename {
712
84
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
713
84
        write!(f, "{} -> {}", self.from, self.to)
714
84
    }
715
}
716

            
717
impl fmt::Display for MultiActionLabel {
718
4194
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
719
4194
        if self.actions.is_empty() {
720
            write!(f, "tau")
721
        } else {
722
4194
            write!(f, "{}", self.actions.iter().format("|"))
723
        }
724
4194
    }
725
}