machine_check_common/value/
param_valuation.rs

1use std::{
2    cmp::Ordering,
3    fmt::Display,
4    ops::{BitAnd, BitOr, Not},
5};
6
7use serde::{Deserialize, Serialize};
8
9use crate::value::three_valued::ThreeValued;
10
11#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
12pub enum KnownParamValuation {
13    False,
14    True,
15    Dependent,
16}
17
18#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
19pub enum ParamValuation {
20    False,
21    True,
22    Dependent,
23    Unknown,
24}
25
26impl Not for ParamValuation {
27    type Output = Self;
28
29    fn not(self) -> Self {
30        match self {
31            ParamValuation::False => ParamValuation::True,
32            ParamValuation::True => ParamValuation::False,
33            ParamValuation::Dependent => ParamValuation::Dependent,
34            ParamValuation::Unknown => ParamValuation::Unknown,
35        }
36    }
37}
38
39impl BitAnd for ParamValuation {
40    type Output = Self;
41
42    fn bitand(self, rhs: Self) -> Self {
43        if self.upward_bitand_ordering(&rhs).is_ge() {
44            self
45        } else {
46            rhs
47        }
48    }
49}
50
51impl BitOr for ParamValuation {
52    type Output = Self;
53
54    fn bitor(self, rhs: Self) -> Self {
55        if self.upward_bitor_ordering(&rhs).is_ge() {
56            self
57        } else {
58            rhs
59        }
60    }
61}
62
63impl ParamValuation {
64    pub fn from_bool(value: bool) -> Self {
65        if value {
66            Self::True
67        } else {
68            Self::False
69        }
70    }
71
72    pub fn from_three_valued(three_valued: ThreeValued) -> Self {
73        match three_valued {
74            ThreeValued::False => ParamValuation::False,
75            ThreeValued::True => ParamValuation::True,
76            ThreeValued::Unknown => ParamValuation::Unknown,
77        }
78    }
79
80    pub fn try_into_bool(self) -> Option<bool> {
81        match self {
82            ParamValuation::False => Some(false),
83            ParamValuation::True => Some(true),
84            ParamValuation::Dependent | ParamValuation::Unknown => None,
85        }
86    }
87
88    pub fn is_unknown(&self) -> bool {
89        matches!(self, ParamValuation::Unknown)
90    }
91
92    pub fn is_known(&self) -> bool {
93        !self.is_unknown()
94    }
95
96    pub fn upward_bitand_ordering(self, rhs: &Self) -> Ordering {
97        // we order from lowest True (ground value) to greatest False
98        // prefer False, then Unknown, then Dependent, then True
99
100        match (self, rhs) {
101            (ParamValuation::False, ParamValuation::False) => Ordering::Equal,
102            (ParamValuation::False, _) => Ordering::Greater,
103            (_, ParamValuation::False) => Ordering::Less,
104            (ParamValuation::Unknown, ParamValuation::Unknown) => Ordering::Equal,
105            (ParamValuation::Unknown, _) => Ordering::Greater,
106            (_, ParamValuation::Unknown) => Ordering::Less,
107            (ParamValuation::Dependent, ParamValuation::Dependent) => Ordering::Equal,
108            (ParamValuation::Dependent, ParamValuation::True) => Ordering::Greater,
109            (ParamValuation::True, ParamValuation::Dependent) => Ordering::Less,
110            (ParamValuation::True, ParamValuation::True) => Ordering::Equal,
111        }
112    }
113
114    pub fn upward_bitor_ordering(self, rhs: &Self) -> Ordering {
115        // we order from lowest False (ground value) to greatest True
116        // prefer True, then Unknown, then Dependent, then False
117
118        match (self, rhs) {
119            (ParamValuation::True, ParamValuation::True) => Ordering::Equal,
120            (ParamValuation::True, _) => Ordering::Greater,
121            (_, ParamValuation::True) => Ordering::Less,
122            (ParamValuation::Unknown, ParamValuation::Unknown) => Ordering::Equal,
123            (ParamValuation::Unknown, _) => Ordering::Greater,
124            (_, ParamValuation::Unknown) => Ordering::Less,
125            (ParamValuation::Dependent, ParamValuation::Dependent) => Ordering::Equal,
126            (ParamValuation::Dependent, ParamValuation::False) => Ordering::Greater,
127            (ParamValuation::False, ParamValuation::Dependent) => Ordering::Less,
128            (ParamValuation::False, ParamValuation::False) => Ordering::Equal,
129        }
130    }
131}
132
133impl Display for ParamValuation {
134    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135        let str = match self {
136            ParamValuation::False => "false",
137            ParamValuation::True => "true",
138            ParamValuation::Dependent => "dependent",
139            ParamValuation::Unknown => "unknown",
140        };
141        write!(f, "{}", str)
142    }
143}