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
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
369
pub struct StateVarAssignment {
370
    pub identifier: String,
371
    pub sort: SortExpression,
372
    pub expr: DataExpr,
373
}
374

            
375
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
376
pub enum ModalityOperator {
377
    Diamond,
378
    Box,
379
}
380

            
381
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
382
pub enum StateFrm {
383
    True,
384
    False,
385
    Delay(DataExpr),
386
    Yaled(DataExpr),
387
    Id(String, Vec<DataExpr>),
388
    DataValExprLeftMult(DataExpr, Box<StateFrm>),
389
    DataValExprRightMult(Box<StateFrm>, DataExpr),
390
    DataValExpr(DataExpr),
391
    Modality {
392
        operator: ModalityOperator,
393
        formula: RegFrm,
394
        expr: Box<StateFrm>,
395
    },
396
    Unary {
397
        op: StateFrmUnaryOp,
398
        expr: Box<StateFrm>,
399
    },
400
    Binary {
401
        op: StateFrmOp,
402
        lhs: Box<StateFrm>,
403
        rhs: Box<StateFrm>,
404
    },
405
    Quantifier {
406
        quantifier: Quantifier,
407
        variables: Vec<VarDecl>,
408
        body: Box<StateFrm>,
409
    },
410
    Bound {
411
        bound: Bound,
412
        variables: Vec<VarDecl>,
413
        body: Box<StateFrm>,
414
    },
415
    FixedPoint {
416
        operator: FixedPointOperator,
417
        variable: StateVarDecl,
418
        body: Box<StateFrm>,
419
    },
420
}
421

            
422
/// Represents a multi action label `a | b | c ...`.
423
#[derive(Debug, Eq, PartialEq, Hash)]
424
pub struct MultiActionLabel {
425
    pub actions: Vec<String>,
426
}
427

            
428
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
429
pub struct Action {
430
    pub id: String,
431
    pub args: Vec<DataExpr>,
432
}
433

            
434
#[derive(Clone, Debug, Eq)]
435
pub struct MultiAction {
436
    pub actions: Vec<Action>,
437
}
438

            
439
impl PartialEq for MultiAction {
440
36
    fn eq(&self, other: &Self) -> bool {
441
        // Check whether both multi-actions contain the same actions
442
36
        if self.actions.len() != other.actions.len() {
443
            return false;
444
36
        }
445

            
446
        // Map every action onto the other, equal length means they must be the same.
447
36
        for action in self.actions.iter() {
448
36
            if !other.actions.contains(action) {
449
24
                return false;
450
12
            }
451
        }
452

            
453
12
        true
454
36
    }
455
}
456

            
457
impl Hash for MultiAction {
458
24
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
459
24
        let mut actions = self.actions.clone();
460
        // Sort the action ids to ensure that the hash is independent of the order.
461
24
        actions.sort();
462
24
        for action in actions {
463
24
            action.hash(state);
464
24
        }
465
24
    }
466
}
467

            
468
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
469
pub enum Quantifier {
470
    Exists,
471
    Forall,
472
}
473

            
474
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
475
pub enum ActFrmBinaryOp {
476
    Implies,
477
    Union,
478
    Intersect,
479
}
480

            
481
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
482
pub enum ActFrm {
483
    True,
484
    False,
485
    MultAct(MultiAction),
486
    DataExprVal(DataExpr),
487
    Negation(Box<ActFrm>),
488
    Quantifier {
489
        quantifier: Quantifier,
490
        variables: Vec<VarDecl>,
491
        body: Box<ActFrm>,
492
    },
493
    Binary {
494
        op: ActFrmBinaryOp,
495
        lhs: Box<ActFrm>,
496
        rhs: Box<ActFrm>,
497
    },
498
}
499

            
500
#[derive(Debug, Eq, PartialEq, Hash)]
501
pub enum PbesExpr {
502
    DataValExpr(DataExpr),
503
    PropVarInst(PropVarInst),
504
    Quantifier {
505
        quantifier: Quantifier,
506
        variables: Vec<VarDecl>,
507
        body: Box<PbesExpr>,
508
    },
509
    Negation(Box<PbesExpr>),
510
    Binary {
511
        op: PbesExprBinaryOp,
512
        lhs: Box<PbesExpr>,
513
        rhs: Box<PbesExpr>,
514
    },
515
    True,
516
    False,
517
}
518

            
519
#[derive(Debug, Eq, PartialEq, Hash)]
520
pub enum Eq {
521
    EqInf,
522
    EqnInf,
523
}
524

            
525
#[derive(Debug, Eq, PartialEq, Hash)]
526
pub enum Condition {
527
    Condsm,
528
    Condeq,
529
}
530

            
531
// TODO: What should this be called?
532
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
533
pub enum Bound {
534
    Inf,
535
    Sup,
536
    Sum,
537
}
538

            
539
#[derive(Debug, Eq, PartialEq, Hash)]
540
pub enum PresExpr {
541
    DataValExpr(DataExpr),
542
    PropVarInst(PropVarInst),
543
    LeftConstantMultiply {
544
        constant: DataExpr,
545
        expr: Box<PresExpr>,
546
    },
547
    Bound {
548
        op: Bound,
549
        variables: Vec<VarDecl>,
550
        expr: Box<PresExpr>,
551
    },
552
    Equal {
553
        eq: Eq,
554
        body: Box<PbesExpr>,
555
    },
556
    Condition {
557
        condition: Condition,
558
        lhs: Box<PresExpr>,
559
        then: Box<PresExpr>,
560
        else_: Box<PresExpr>,
561
    },
562
    Negation(Box<PresExpr>),
563
    Binary {
564
        op: PbesExprBinaryOp,
565
        lhs: Box<PresExpr>,
566
        rhs: Box<PresExpr>,
567
    },
568
    True,
569
    False,
570
}
571

            
572
#[derive(Debug, Eq, PartialEq, Hash)]
573
pub struct PbesEquation {
574
    pub operator: FixedPointOperator,
575
    pub variable: PropVarDecl,
576
    pub formula: PbesExpr,
577
    pub span: Span,
578
}
579

            
580
#[derive(Debug, Eq, PartialEq, Hash)]
581
pub enum PbesExprBinaryOp {
582
    Implies,
583
    Disjunction,
584
    Conjunction,
585
}
586

            
587
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
588
pub enum RegFrm {
589
    Action(ActFrm),
590
    Iteration(Box<RegFrm>),
591
    Plus(Box<RegFrm>),
592
    Sequence { lhs: Box<RegFrm>, rhs: Box<RegFrm> },
593
    Choice { lhs: Box<RegFrm>, rhs: Box<RegFrm> },
594
}
595

            
596
#[derive(Debug, Eq, PartialEq, Hash)]
597
pub struct Rename {
598
    pub from: String,
599
    pub to: String,
600
}
601

            
602
#[derive(Debug, Eq, PartialEq, Hash)]
603
pub struct Comm {
604
    pub from: MultiActionLabel,
605
    pub to: String,
606
}
607

            
608
#[derive(Debug, Eq, PartialEq, Hash)]
609
pub struct UntypedActionRenameSpec {
610
    pub data_specification: UntypedDataSpecification,
611
    pub action_declarations: Vec<ActDecl>,
612
    pub rename_declarations: Vec<ActionRenameDecl>,
613
}
614

            
615
#[derive(Debug, Eq, PartialEq, Hash)]
616
pub struct ActionRenameDecl {
617
    pub variables_specification: Vec<VarDecl>,
618
    pub rename_rule: ActionRenameRule,
619
}
620

            
621
#[derive(Debug, Eq, PartialEq, Hash)]
622
pub struct ActionRenameRule {
623
    pub condition: Option<DataExpr>,
624
    pub action: Action,
625
    pub rhs: ActionRHS,
626
}
627

            
628
#[derive(Debug, Eq, PartialEq, Hash)]
629
pub enum ActionRHS {
630
    Tau,
631
    Delta,
632
    Action(Action),
633
}
634

            
635
/// Source location information, spanning from start to end in the source text.
636
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
637
pub struct Span {
638
    pub start: usize,
639
    pub end: usize,
640
}
641

            
642
impl From<pest::Span<'_>> for Span {
643
85145
    fn from(span: pest::Span) -> Self {
644
85145
        Span {
645
85145
            start: span.start(),
646
85145
            end: span.end(),
647
85145
        }
648
85145
    }
649
}