1use crate::trit::Trit;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub struct Kleene {
8 t: Trit,
9}
10
11impl Kleene {
12 pub const FALSE: Self = Self { t: Trit::N };
14
15 pub const UNKNOWN: Self = Self { t: Trit::Z };
17
18 pub const TRUE: Self = Self { t: Trit::P };
20
21 pub const fn new(t: Trit) -> Self {
23 Self { t }
24 }
25
26 pub const fn trit(&self) -> Trit {
28 self.t
29 }
30
31 pub const fn is_true(self) -> bool {
33 matches!(self.t, Trit::P)
34 }
35
36 pub const fn is_false(self) -> bool {
38 matches!(self.t, Trit::N)
39 }
40
41 pub const fn is_unknown(self) -> bool {
43 matches!(self.t, Trit::Z)
44 }
45
46 #[must_use]
48 pub const fn and(self, other: Self) -> Self {
49 Self::new(self.t.tmin(other.t))
50 }
51
52 #[must_use]
54 pub const fn or(self, other: Self) -> Self {
55 Self::new(self.t.tmax(other.t))
56 }
57
58 #[must_use]
60 pub fn implies(self, other: Self) -> Self {
61 (!self).or(other)
62 }
63
64 #[must_use]
66 pub fn iff(self, other: Self) -> Self {
67 self.implies(other).and(other.implies(self))
68 }
69}
70
71impl std::ops::Not for Kleene {
72 type Output = Self;
73
74 fn not(self) -> Self::Output {
75 Self::new(self.t.tnot())
76 }
77}