1
use std::hash::Hash;
2

            
3
/// A complete mCRL2 process specification.
4
#[derive(Debug, Default, Eq, PartialEq, Hash)]
5
pub struct UntypedProcessSpecification {
6
    pub data_specification: UntypedDataSpecification,
7
    pub global_variables: Vec<VarDecl>,
8
    pub action_declarations: Vec<ActDecl>,
9
    pub process_declarations: Vec<ProcDecl>,
10
    pub init: Option<ProcessExpr>,
11
}
12

            
13
/// An mCRL2 data specification.
14
#[derive(Debug, Default, Eq, PartialEq, Hash)]
15
pub struct UntypedDataSpecification {
16
    pub sort_declarations: Vec<SortDecl>,
17
    pub constructor_declarations: Vec<IdDecl>,
18
    pub map_declarations: Vec<IdDecl>,
19
    pub equation_declarations: Vec<EqnSpec>,
20
}
21

            
22
impl UntypedDataSpecification {
23
    /// Returns true if the data specification is empty.
24
    pub fn is_empty(&self) -> bool {
25
        self.sort_declarations.is_empty()
26
            && self.constructor_declarations.is_empty()
27
            && self.map_declarations.is_empty()
28
            && self.equation_declarations.is_empty()
29
    }
30
}
31

            
32
/// An mCRL2 parameterised boolean equation system (PBES).
33
#[derive(Debug, Default, Eq, PartialEq, Hash)]
34
pub struct UntypedPbes {
35
    pub data_specification: UntypedDataSpecification,
36
    pub global_variables: Vec<VarDecl>,
37
    pub equations: Vec<PbesEquation>,
38
    pub init: PropVarInst,
39
}
40

            
41
#[derive(Debug, Eq, PartialEq, Hash)]
42
pub struct PropVarDecl {
43
    pub identifier: String,
44
    pub parameters: Vec<VarDecl>,
45
    pub span: Span,
46
}
47

            
48
#[derive(Debug, Default, Eq, PartialEq, Hash)]
49
pub struct PropVarInst {
50
    pub identifier: String,
51
    pub arguments: Vec<DataExpr>,
52
}
53

            
54
/// A declaration of an identifier with its sort.
55
#[derive(Debug, Eq, PartialEq, Hash)]
56
pub struct IdDecl {
57
    /// Identifier being declared
58
    pub identifier: String,
59
    /// Sort expression for this identifier
60
    pub sort: SortExpression,
61
    /// Source location information
62
    pub span: Span,
63
}
64

            
65
/// Expression representing a sort (type).
66
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
67
pub enum SortExpression {
68
    /// Product of two sorts (A # B)
69
    Product {
70
        lhs: Box<SortExpression>,
71
        rhs: Box<SortExpression>,
72
    },
73
    /// Function sort (A -> B)
74
    Function {
75
        domain: Box<SortExpression>,
76
        range: Box<SortExpression>,
77
    },
78
    Struct {
79
        inner: Vec<ConstructorDecl>,
80
    },
81
    /// Reference to a named sort    
82
    Reference(String),
83
    /// Built-in simple sort
84
    Simple(Sort),
85
    /// Parameterized complex sort
86
    Complex(ComplexSort, Box<SortExpression>),
87
}
88

            
89
/// Constructor declaration
90
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
91
pub struct ConstructorDecl {
92
    pub name: String,
93
    pub args: Vec<(Option<String>, SortExpression)>,
94
    pub projection: Option<String>,
95
}
96

            
97
/// Built-in simple sorts.
98
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
99
pub enum Sort {
100
    Bool,
101
    Pos,
102
    Int,
103
    Nat,
104
    Real,
105
}
106

            
107
/// Complex (parameterized) sorts.
108
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
109
pub enum ComplexSort {
110
    List,
111
    Set,
112
    FSet,
113
    FBag,
114
    Bag,
115
}
116

            
117
/// Sort declaration
118
#[derive(Debug, Eq, PartialEq, Hash)]
119
pub struct SortDecl {
120
    /// Sort identifier
121
    pub identifier: String,
122
    /// Sort expression (if structured)
123
    pub expr: Option<SortExpression>,
124
    /// Where the sort is defined
125
    pub span: Span,
126
}
127

            
128
/// Variable declaration
129
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
130
pub struct VarDecl {
131
    pub identifier: String,
132
    pub sort: SortExpression,
133
    pub span: Span,
134
}
135

            
136
#[derive(Debug, Eq, PartialEq, Hash)]
137
pub struct EqnSpec {
138
    pub variables: Vec<VarDecl>,
139
    pub equations: Vec<EqnDecl>,
140
}
141

            
142
/// Equation declaration
143
#[derive(Debug, Eq, PartialEq, Hash)]
144
pub struct EqnDecl {
145
    pub condition: Option<DataExpr>,
146
    pub lhs: DataExpr,
147
    pub rhs: DataExpr,
148
    pub span: Span,
149
}
150

            
151
/// Action declaration
152
#[derive(Debug, Eq, PartialEq, Hash)]
153
pub struct ActDecl {
154
    pub identifier: String,
155
    pub args: Vec<SortExpression>,
156
    pub span: Span,
157
}
158

            
159
/// Process declaration
160
#[derive(Debug, Eq, PartialEq, Hash)]
161
pub struct ProcDecl {
162
    pub identifier: String,
163
    pub params: Vec<VarDecl>,
164
    pub body: ProcessExpr,
165
    pub span: Span,
166
}
167

            
168
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
169
pub enum DataExprUnaryOp {
170
    Negation,
171
    Minus,
172
    Size,
173
}
174

            
175
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
176
pub enum DataExprBinaryOp {
177
    Conj,
178
    Disj,
179
    Implies,
180
    Equal,
181
    NotEqual,
182
    LessThan,
183
    LessEqual,
184
    GreaterThan,
185
    GreaterEqual,
186
    Cons,
187
    Snoc,
188
    In,
189
    Concat,
190
    Add,
191
    Subtract,
192
    Div,
193
    IntDiv,
194
    Mod,
195
    Multiply,
196
    At,
197
}
198

            
199
/// Data expression
200
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
201
pub enum DataExpr {
202
    Id(String),
203
    Number(String), // Is string because the number can be any size.
204
    Bool(bool),
205
    Application {
206
        function: Box<DataExpr>,
207
        arguments: Vec<DataExpr>,
208
    },
209
    EmptyList,
210
    List(Vec<DataExpr>),
211
    EmptySet,
212
    Set(Vec<DataExpr>),
213
    EmptyBag,
214
    Bag(Vec<BagElement>),
215
    SetBagComp {
216
        variable: VarDecl,
217
        predicate: Box<DataExpr>,
218
    },
219
    Lambda {
220
        variables: Vec<VarDecl>,
221
        body: Box<DataExpr>,
222
    },
223
    Quantifier {
224
        op: Quantifier,
225
        variables: Vec<VarDecl>,
226
        body: Box<DataExpr>,
227
    },
228
    Unary {
229
        op: DataExprUnaryOp,
230
        expr: Box<DataExpr>,
231
    },
232
    Binary {
233
        op: DataExprBinaryOp,
234
        lhs: Box<DataExpr>,
235
        rhs: Box<DataExpr>,
236
    },
237
    FunctionUpdate {
238
        expr: Box<DataExpr>,
239
        update: Box<DataExprUpdate>,
240
    },
241
    Whr {
242
        expr: Box<DataExpr>,
243
        assignments: Vec<Assignment>,
244
    },
245
}
246

            
247
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
248
pub struct BagElement {
249
    pub expr: DataExpr,
250
    pub multiplicity: DataExpr,
251
}
252

            
253
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
254
pub struct DataExprUpdate {
255
    pub expr: DataExpr,
256
    pub update: DataExpr,
257
}
258

            
259
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
260
pub struct Assignment {
261
    pub identifier: String,
262
    pub expr: DataExpr,
263
}
264

            
265
#[derive(Debug, Eq, PartialEq, Hash)]
266
pub enum ProcExprBinaryOp {
267
    Sequence,
268
    Choice,
269
    Parallel,
270
    LeftMerge,
271
    CommMerge,
272
}
273

            
274
/// Process expression
275
#[derive(Debug, Eq, PartialEq, Hash)]
276
pub enum ProcessExpr {
277
    Id(String, Vec<Assignment>),
278
    Action(String, Vec<DataExpr>),
279
    Delta,
280
    Tau,
281
    Sum {
282
        variables: Vec<VarDecl>,
283
        operand: Box<ProcessExpr>,
284
    },
285
    Dist {
286
        variables: Vec<VarDecl>,
287
        expr: DataExpr,
288
        operand: Box<ProcessExpr>,
289
    },
290
    Binary {
291
        op: ProcExprBinaryOp,
292
        lhs: Box<ProcessExpr>,
293
        rhs: Box<ProcessExpr>,
294
    },
295
    Hide {
296
        actions: Vec<String>,
297
        operand: Box<ProcessExpr>,
298
    },
299
    Rename {
300
        renames: Vec<Rename>,
301
        operand: Box<ProcessExpr>,
302
    },
303
    Allow {
304
        actions: Vec<MultiActionLabel>,
305
        operand: Box<ProcessExpr>,
306
    },
307
    Block {
308
        actions: Vec<String>,
309
        operand: Box<ProcessExpr>,
310
    },
311
    Comm {
312
        comm: Vec<Comm>,
313
        operand: Box<ProcessExpr>,
314
    },
315
    Condition {
316
        condition: DataExpr,
317
        then: Box<ProcessExpr>,
318
        else_: Option<Box<ProcessExpr>>,
319
    },
320
    At {
321
        expr: Box<ProcessExpr>,
322
        operand: DataExpr,
323
    },
324
}
325

            
326
/// Communication action
327
#[derive(Debug, Eq, PartialEq, Hash)]
328
pub struct CommAction {
329
    pub inputs: Vec<String>,
330
    pub output: String,
331
    pub span: Span,
332
}
333

            
334
#[derive(Debug, Eq, PartialEq, Hash)]
335
pub struct UntypedStateFrmSpec {
336
    pub data_specification: UntypedDataSpecification,
337
    pub action_declarations: Vec<ActDecl>,
338
    pub formula: StateFrm,
339
}
340

            
341
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
342
pub enum StateFrmUnaryOp {
343
    Minus,
344
    Negation,
345
}
346

            
347
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
348
pub enum StateFrmOp {
349
    Addition,
350
    Implies,
351
    Disjunction,
352
    Conjunction,
353
}
354

            
355
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
356
pub enum FixedPointOperator {
357
    Least,
358
    Greatest,
359
}
360

            
361
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
362
pub struct StateVarDecl {
363
    pub identifier: String,
364
    pub arguments: Vec<StateVarAssignment>,
365
    pub span: Span,
366
}
367

            
368
impl StateVarDecl {
369
    /// Creates a new state variable declaration.
370
1424
    pub fn new(identifier: String, arguments: Vec<StateVarAssignment>) -> Self {
371
1424
        StateVarDecl {
372
1424
            identifier,
373
1424
            arguments,
374
1424
            span: Span::default(),
375
1424
        }
376
1424
    }
377
}
378

            
379
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
380
pub struct StateVarAssignment {
381
    pub identifier: String,
382
    pub sort: SortExpression,
383
    pub expr: DataExpr,
384
}
385

            
386
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
387
pub enum ModalityOperator {
388
    Diamond,
389
    Box,
390
}
391

            
392
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
393
pub enum StateFrm {
394
    True,
395
    False,
396
    Delay(DataExpr),
397
    Yaled(DataExpr),
398
    Id(String, Vec<DataExpr>),
399
    DataValExprLeftMult(DataExpr, Box<StateFrm>),
400
    DataValExprRightMult(Box<StateFrm>, DataExpr),
401
    DataValExpr(DataExpr),
402
    Modality {
403
        operator: ModalityOperator,
404
        formula: RegFrm,
405
        expr: Box<StateFrm>,
406
    },
407
    Unary {
408
        op: StateFrmUnaryOp,
409
        expr: Box<StateFrm>,
410
    },
411
    Binary {
412
        op: StateFrmOp,
413
        lhs: Box<StateFrm>,
414
        rhs: Box<StateFrm>,
415
    },
416
    Quantifier {
417
        quantifier: Quantifier,
418
        variables: Vec<VarDecl>,
419
        body: Box<StateFrm>,
420
    },
421
    Bound {
422
        bound: Bound,
423
        variables: Vec<VarDecl>,
424
        body: Box<StateFrm>,
425
    },
426
    FixedPoint {
427
        operator: FixedPointOperator,
428
        variable: StateVarDecl,
429
        body: Box<StateFrm>,
430
    },
431
}
432

            
433
/// Represents a multi action label `a | b | c ...`.
434
#[derive(Debug, Eq, PartialEq, Hash)]
435
pub struct MultiActionLabel {
436
    pub actions: Vec<String>,
437
}
438

            
439
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
440
pub struct Action {
441
    pub id: String,
442
    pub args: Vec<DataExpr>,
443
}
444

            
445
impl Action {
446
    /// Creates a new action from an identifier and a list of arguments.
447
776
    pub fn new(id: String, args: Vec<DataExpr>) -> Self {
448
776
        Action { id, args }
449
776
    }
450
}
451

            
452
#[derive(Clone, Debug, Eq)]
453
pub struct MultiAction {
454
    pub actions: Vec<Action>,
455
}
456

            
457
impl MultiAction {
458
    /// Creates a new multi-action from a list of actions.
459
776
    pub fn new(actions: Vec<Action>) -> Self {
460
776
        MultiAction { actions }
461
776
    }
462
}
463

            
464
impl PartialEq for MultiAction {
465
4184
    fn eq(&self, other: &Self) -> bool {
466
        // Check whether both multi-actions contain the same actions
467
4184
        if self.actions.len() != other.actions.len() {
468
            return false;
469
4184
        }
470

            
471
        // Map every action onto the other, equal length means they must be the same.
472
4184
        for action in self.actions.iter() {
473
4184
            if !other.actions.contains(action) {
474
3160
                return false;
475
1024
            }
476
        }
477

            
478
1024
        true
479
4184
    }
480
}
481

            
482
impl Hash for MultiAction {
483
474
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
484
474
        let mut actions = self.actions.clone();
485
        // Sort the action ids to ensure that the hash is independent of the order.
486
474
        actions.sort();
487
474
        for action in actions {
488
474
            action.hash(state);
489
474
        }
490
474
    }
491
}
492

            
493
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
494
pub enum Quantifier {
495
    Exists,
496
    Forall,
497
}
498

            
499
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
500
pub enum ActFrmBinaryOp {
501
    Implies,
502
    Union,
503
    Intersect,
504
}
505

            
506
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
507
pub enum ActFrm {
508
    True,
509
    False,
510
    MultAct(MultiAction),
511
    DataExprVal(DataExpr),
512
    Negation(Box<ActFrm>),
513
    Quantifier {
514
        quantifier: Quantifier,
515
        variables: Vec<VarDecl>,
516
        body: Box<ActFrm>,
517
    },
518
    Binary {
519
        op: ActFrmBinaryOp,
520
        lhs: Box<ActFrm>,
521
        rhs: Box<ActFrm>,
522
    },
523
}
524

            
525
#[derive(Debug, Eq, PartialEq, Hash)]
526
pub enum PbesExpr {
527
    DataValExpr(DataExpr),
528
    PropVarInst(PropVarInst),
529
    Quantifier {
530
        quantifier: Quantifier,
531
        variables: Vec<VarDecl>,
532
        body: Box<PbesExpr>,
533
    },
534
    Negation(Box<PbesExpr>),
535
    Binary {
536
        op: PbesExprBinaryOp,
537
        lhs: Box<PbesExpr>,
538
        rhs: Box<PbesExpr>,
539
    },
540
    True,
541
    False,
542
}
543

            
544
#[derive(Debug, Eq, PartialEq, Hash)]
545
pub enum Eq {
546
    EqInf,
547
    EqnInf,
548
}
549

            
550
#[derive(Debug, Eq, PartialEq, Hash)]
551
pub enum Condition {
552
    Condsm,
553
    Condeq,
554
}
555

            
556
// TODO: What should this be called?
557
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
558
pub enum Bound {
559
    Inf,
560
    Sup,
561
    Sum,
562
}
563

            
564
#[derive(Debug, Eq, PartialEq, Hash)]
565
pub enum PresExpr {
566
    DataValExpr(DataExpr),
567
    PropVarInst(PropVarInst),
568
    LeftConstantMultiply {
569
        constant: DataExpr,
570
        expr: Box<PresExpr>,
571
    },
572
    Bound {
573
        op: Bound,
574
        variables: Vec<VarDecl>,
575
        expr: Box<PresExpr>,
576
    },
577
    Equal {
578
        eq: Eq,
579
        body: Box<PbesExpr>,
580
    },
581
    Condition {
582
        condition: Condition,
583
        lhs: Box<PresExpr>,
584
        then: Box<PresExpr>,
585
        else_: Box<PresExpr>,
586
    },
587
    Negation(Box<PresExpr>),
588
    Binary {
589
        op: PbesExprBinaryOp,
590
        lhs: Box<PresExpr>,
591
        rhs: Box<PresExpr>,
592
    },
593
    True,
594
    False,
595
}
596

            
597
#[derive(Debug, Eq, PartialEq, Hash)]
598
pub struct PbesEquation {
599
    pub operator: FixedPointOperator,
600
    pub variable: PropVarDecl,
601
    pub formula: PbesExpr,
602
    pub span: Span,
603
}
604

            
605
#[derive(Debug, Eq, PartialEq, Hash)]
606
pub enum PbesExprBinaryOp {
607
    Implies,
608
    Disjunction,
609
    Conjunction,
610
}
611

            
612
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
613
pub enum RegFrm {
614
    Action(ActFrm),
615
    Iteration(Box<RegFrm>),
616
    Plus(Box<RegFrm>),
617
    Sequence { lhs: Box<RegFrm>, rhs: Box<RegFrm> },
618
    Choice { lhs: Box<RegFrm>, rhs: Box<RegFrm> },
619
}
620

            
621
#[derive(Debug, Eq, PartialEq, Hash)]
622
pub struct Rename {
623
    pub from: String,
624
    pub to: String,
625
}
626

            
627
#[derive(Debug, Eq, PartialEq, Hash)]
628
pub struct Comm {
629
    pub from: MultiActionLabel,
630
    pub to: String,
631
}
632

            
633
#[derive(Debug, Eq, PartialEq, Hash)]
634
pub struct UntypedActionRenameSpec {
635
    pub data_specification: UntypedDataSpecification,
636
    pub action_declarations: Vec<ActDecl>,
637
    pub rename_declarations: Vec<ActionRenameDecl>,
638
}
639

            
640
#[derive(Debug, Eq, PartialEq, Hash)]
641
pub struct ActionRenameDecl {
642
    pub variables_specification: Vec<VarDecl>,
643
    pub rename_rule: ActionRenameRule,
644
}
645

            
646
#[derive(Debug, Eq, PartialEq, Hash)]
647
pub struct ActionRenameRule {
648
    pub condition: Option<DataExpr>,
649
    pub action: Action,
650
    pub rhs: ActionRHS,
651
}
652

            
653
#[derive(Debug, Eq, PartialEq, Hash)]
654
pub enum ActionRHS {
655
    Tau,
656
    Delta,
657
    Action(Action),
658
}
659

            
660
/// Source location information, spanning from start to end in the source text.
661
#[derive(Clone, Default, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
662
pub struct Span {
663
    pub start: usize,
664
    pub end: usize,
665
}
666

            
667
impl From<pest::Span<'_>> for Span {
668
113534
    fn from(span: pest::Span) -> Self {
669
113534
        Span {
670
113534
            start: span.start(),
671
113534
            end: span.end(),
672
113534
        }
673
113534
    }
674
}