Lines
75.86 %
Functions
44.44 %
Branches
33.33 %
use std::hash::Hash;
/// A complete mCRL2 process specification.
#[derive(Debug, Default, Eq, PartialEq, Hash)]
pub struct UntypedProcessSpecification {
pub data_specification: UntypedDataSpecification,
pub global_variables: Vec<VarDecl>,
pub action_declarations: Vec<ActDecl>,
pub process_declarations: Vec<ProcDecl>,
pub init: Option<ProcessExpr>,
}
/// An mCRL2 data specification.
pub struct UntypedDataSpecification {
pub sort_declarations: Vec<SortDecl>,
pub constructor_declarations: Vec<IdDecl>,
pub map_declarations: Vec<IdDecl>,
pub equation_declarations: Vec<EqnSpec>,
impl UntypedDataSpecification {
/// Returns true if the data specification is empty.
pub fn is_empty(&self) -> bool {
self.sort_declarations.is_empty()
&& self.constructor_declarations.is_empty()
&& self.map_declarations.is_empty()
&& self.equation_declarations.is_empty()
/// An mCRL2 parameterised boolean equation system (PBES).
pub struct UntypedPbes {
pub equations: Vec<PbesEquation>,
pub init: PropVarInst,
#[derive(Debug, Eq, PartialEq, Hash)]
pub struct PropVarDecl {
pub identifier: String,
pub parameters: Vec<VarDecl>,
pub span: Span,
pub struct PropVarInst {
pub arguments: Vec<DataExpr>,
/// A declaration of an identifier with its sort.
pub struct IdDecl {
/// Identifier being declared
/// Sort expression for this identifier
pub sort: SortExpression,
/// Source location information
/// Expression representing a sort (type).
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
pub enum SortExpression {
/// Product of two sorts (A # B)
Product {
lhs: Box<SortExpression>,
rhs: Box<SortExpression>,
},
/// Function sort (A -> B)
Function {
domain: Box<SortExpression>,
range: Box<SortExpression>,
Struct {
inner: Vec<ConstructorDecl>,
/// Reference to a named sort
Reference(String),
/// Built-in simple sort
Simple(Sort),
/// Parameterized complex sort
Complex(ComplexSort, Box<SortExpression>),
/// Constructor declaration
pub struct ConstructorDecl {
pub name: String,
pub args: Vec<(Option<String>, SortExpression)>,
pub projection: Option<String>,
/// Built-in simple sorts.
pub enum Sort {
Bool,
Pos,
Int,
Nat,
Real,
/// Complex (parameterized) sorts.
pub enum ComplexSort {
List,
Set,
FSet,
FBag,
Bag,
/// Sort declaration
pub struct SortDecl {
/// Sort identifier
/// Sort expression (if structured)
pub expr: Option<SortExpression>,
/// Where the sort is defined
/// Variable declaration
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct VarDecl {
pub struct EqnSpec {
pub variables: Vec<VarDecl>,
pub equations: Vec<EqnDecl>,
/// Equation declaration
pub struct EqnDecl {
pub condition: Option<DataExpr>,
pub lhs: DataExpr,
pub rhs: DataExpr,
/// Action declaration
pub struct ActDecl {
pub args: Vec<SortExpression>,
/// Process declaration
pub struct ProcDecl {
pub params: Vec<VarDecl>,
pub body: ProcessExpr,
pub enum DataExprUnaryOp {
Negation,
Minus,
Size,
pub enum DataExprBinaryOp {
Conj,
Disj,
Implies,
Equal,
NotEqual,
LessThan,
LessEqual,
GreaterThan,
GreaterEqual,
Cons,
Snoc,
In,
Concat,
Add,
Subtract,
Div,
IntDiv,
Mod,
Multiply,
At,
/// Data expression
pub enum DataExpr {
Id(String),
Number(String), // Is string because the number can be any size.
Bool(bool),
Application {
function: Box<DataExpr>,
arguments: Vec<DataExpr>,
EmptyList,
List(Vec<DataExpr>),
EmptySet,
Set(Vec<DataExpr>),
EmptyBag,
Bag(Vec<BagElement>),
SetBagComp {
variable: VarDecl,
predicate: Box<DataExpr>,
Lambda {
variables: Vec<VarDecl>,
body: Box<DataExpr>,
Quantifier {
op: Quantifier,
Unary {
op: DataExprUnaryOp,
expr: Box<DataExpr>,
Binary {
op: DataExprBinaryOp,
lhs: Box<DataExpr>,
rhs: Box<DataExpr>,
FunctionUpdate {
update: Box<DataExprUpdate>,
Whr {
assignments: Vec<Assignment>,
pub struct BagElement {
pub expr: DataExpr,
pub multiplicity: DataExpr,
pub struct DataExprUpdate {
pub update: DataExpr,
pub struct Assignment {
pub enum ProcExprBinaryOp {
Sequence,
Choice,
Parallel,
LeftMerge,
CommMerge,
/// Process expression
pub enum ProcessExpr {
Id(String, Vec<Assignment>),
Action(String, Vec<DataExpr>),
Delta,
Tau,
Sum {
operand: Box<ProcessExpr>,
Dist {
expr: DataExpr,
op: ProcExprBinaryOp,
lhs: Box<ProcessExpr>,
rhs: Box<ProcessExpr>,
Hide {
actions: Vec<String>,
Rename {
renames: Vec<Rename>,
Allow {
actions: Vec<MultiActionLabel>,
Block {
Comm {
comm: Vec<Comm>,
Condition {
condition: DataExpr,
then: Box<ProcessExpr>,
else_: Option<Box<ProcessExpr>>,
At {
expr: Box<ProcessExpr>,
operand: DataExpr,
/// Communication action
pub struct CommAction {
pub inputs: Vec<String>,
pub output: String,
pub struct UntypedStateFrmSpec {
pub formula: StateFrm,
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum StateFrmUnaryOp {
pub enum StateFrmOp {
Addition,
Disjunction,
Conjunction,
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum FixedPointOperator {
Least,
Greatest,
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct StateVarDecl {
pub arguments: Vec<StateVarAssignment>,
pub struct StateVarAssignment {
pub enum ModalityOperator {
Diamond,
Box,
pub enum StateFrm {
True,
False,
Delay(DataExpr),
Yaled(DataExpr),
Id(String, Vec<DataExpr>),
DataValExprLeftMult(DataExpr, Box<StateFrm>),
DataValExprRightMult(Box<StateFrm>, DataExpr),
DataValExpr(DataExpr),
Modality {
operator: ModalityOperator,
formula: RegFrm,
expr: Box<StateFrm>,
op: StateFrmUnaryOp,
op: StateFrmOp,
lhs: Box<StateFrm>,
rhs: Box<StateFrm>,
quantifier: Quantifier,
body: Box<StateFrm>,
Bound {
bound: Bound,
FixedPoint {
operator: FixedPointOperator,
variable: StateVarDecl,
/// Represents a multi action label `a | b | c ...`.
pub struct MultiActionLabel {
pub actions: Vec<String>,
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
pub struct Action {
pub id: String,
pub args: Vec<DataExpr>,
#[derive(Clone, Debug, Eq)]
pub struct MultiAction {
pub actions: Vec<Action>,
impl PartialEq for MultiAction {
fn eq(&self, other: &Self) -> bool {
// Check whether both multi-actions contain the same actions
if self.actions.len() != other.actions.len() {
return false;
// Map every action onto the other, equal length means they must be the same.
for action in self.actions.iter() {
if !other.actions.contains(action) {
true
impl Hash for MultiAction {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
let mut actions = self.actions.clone();
// Sort the action ids to ensure that the hash is independent of the order.
actions.sort();
for action in actions {
action.hash(state);
pub enum Quantifier {
Exists,
Forall,
pub enum ActFrmBinaryOp {
Union,
Intersect,
pub enum ActFrm {
MultAct(MultiAction),
DataExprVal(DataExpr),
Negation(Box<ActFrm>),
body: Box<ActFrm>,
op: ActFrmBinaryOp,
lhs: Box<ActFrm>,
rhs: Box<ActFrm>,
pub enum PbesExpr {
PropVarInst(PropVarInst),
body: Box<PbesExpr>,
Negation(Box<PbesExpr>),
op: PbesExprBinaryOp,
lhs: Box<PbesExpr>,
rhs: Box<PbesExpr>,
pub enum Eq {
EqInf,
EqnInf,
pub enum Condition {
Condsm,
Condeq,
// TODO: What should this be called?
pub enum Bound {
Inf,
Sup,
Sum,
pub enum PresExpr {
LeftConstantMultiply {
constant: DataExpr,
expr: Box<PresExpr>,
op: Bound,
Equal {
eq: Eq,
condition: Condition,
lhs: Box<PresExpr>,
then: Box<PresExpr>,
else_: Box<PresExpr>,
Negation(Box<PresExpr>),
rhs: Box<PresExpr>,
pub struct PbesEquation {
pub operator: FixedPointOperator,
pub variable: PropVarDecl,
pub formula: PbesExpr,
pub enum PbesExprBinaryOp {
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum RegFrm {
Action(ActFrm),
Iteration(Box<RegFrm>),
Plus(Box<RegFrm>),
Sequence { lhs: Box<RegFrm>, rhs: Box<RegFrm> },
Choice { lhs: Box<RegFrm>, rhs: Box<RegFrm> },
pub struct Rename {
pub from: String,
pub to: String,
pub struct Comm {
pub from: MultiActionLabel,
pub struct UntypedActionRenameSpec {
pub rename_declarations: Vec<ActionRenameDecl>,
pub struct ActionRenameDecl {
pub variables_specification: Vec<VarDecl>,
pub rename_rule: ActionRenameRule,
pub struct ActionRenameRule {
pub action: Action,
pub rhs: ActionRHS,
pub enum ActionRHS {
Action(Action),
/// Source location information, spanning from start to end in the source text.
pub struct Span {
pub start: usize,
pub end: usize,
impl From<pest::Span<'_>> for Span {
fn from(span: pest::Span) -> Self {
Span {
start: span.start(),
end: span.end(),