1
use std::fmt;
2

            
3
use itertools::Itertools;
4
use mcrl2::aterm::ATerm;
5
use mcrl2::data::BoolSort;
6
use mcrl2::data::DataExpression;
7
use mcrl2::data::DataSpecification;
8

            
9
/// A rewrite specification contains the bare info we need for rewriting (can be untyped).
10
#[derive(Debug, Default, Clone)]
11
pub struct RewriteSpecification {
12
    pub rewrite_rules: Vec<Rule>,
13
}
14

            
15
/// Either lhs == rhs or lhs != rhs depending on equality being true.
16
#[derive(Clone, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
17
pub struct Condition {
18
    pub lhs: DataExpression,
19
    pub rhs: DataExpression,
20
    pub equality: bool,
21
}
22

            
23
#[derive(Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
24
pub struct Rule {
25
    /// A conjunction of clauses
26
    pub conditions: Vec<Condition>,
27
    pub lhs: DataExpression,
28
    pub rhs: DataExpression,
29
}
30

            
31
impl From<DataSpecification> for RewriteSpecification {
32
105
    fn from(value: DataSpecification) -> Self {
33
105
        let equations = value.equations();
34
105

            
35
105
        // Convert the equations.
36
105
        let mut rewrite_rules = vec![];
37
34510
        for equation in equations {
38
34405
            if *equation.condition == *BoolSort::true_term() {
39
                // Ignore the condition if it is trivial.
40
30400
                rewrite_rules.push(Rule {
41
30400
                    conditions: vec![],
42
30400
                    lhs: equation.lhs,
43
30400
                    rhs: equation.rhs,
44
30400
                })
45
            } else {
46
4005
                let t: ATerm = BoolSort::true_term().into();
47
4005

            
48
4005
                rewrite_rules.push(Rule {
49
4005
                    conditions: vec![Condition {
50
4005
                        lhs: equation.condition,
51
4005
                        rhs: t.into(),
52
4005
                        equality: true,
53
4005
                    }],
54
4005
                    lhs: equation.lhs,
55
4005
                    rhs: equation.rhs,
56
4005
                })
57
            }
58
        }
59

            
60
105
        RewriteSpecification { rewrite_rules }
61
105
    }
62
}
63

            
64
impl fmt::Display for RewriteSpecification {
65
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66
        for rule in &self.rewrite_rules {
67
            writeln!(f, "{}", rule)?;
68
        }
69
        Ok(())
70
    }
71
}
72

            
73
impl fmt::Display for Rule {
74
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75
        if self.conditions.is_empty() {
76
            write!(f, "{} = {}", self.lhs, self.rhs)
77
        } else {
78
            write!(
79
                f,
80
                "{} -> {} = {}",
81
                self.conditions.iter().format(", "),
82
                self.lhs,
83
                self.rhs
84
            )
85
        }
86
    }
87
}
88

            
89
impl fmt::Display for Condition {
90
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91
        if self.equality {
92
            write!(f, "{} == {}", self.lhs, self.rhs)
93
        } else {
94
            write!(f, "{} <> {}", self.lhs, self.rhs)
95
        }
96
    }
97
}