Skip to main content

ternlang_core/
trit.rs

1use std::fmt;
2use std::ops::{Add, Mul, Neg};
3use serde::{Serialize, Deserialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
6pub enum Trit {
7    Reject = -1,   // logical -1 — conflict, negation
8    Tend   =  0,   // logical  0 — hold, uncertainty
9    Affirm =  1,   // logical +1 — truth, confirmation
10}
11
12impl From<i8> for Trit {
13    fn from(val: i8) -> Self {
14        // VM-PANIC-001: saturate to the nearest trit instead of panicking.
15        // Values outside {-1, 0, +1} (e.g. from arithmetic overflow in balanced-ternary
16        // tensor ops) previously hard-crashed the VM. Saturate: positive → Affirm,
17        // negative → Reject, zero → Tend.
18        if val > 0 { Trit::Affirm }
19        else if val < 0 { Trit::Reject }
20        else { Trit::Tend }
21    }
22}
23
24impl fmt::Display for Trit {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        match self {
27            Trit::Reject => write!(f, "reject"),
28            Trit::Tend   => write!(f, "tend"),
29            Trit::Affirm => write!(f, "affirm"),
30        }
31    }
32}
33
34impl Neg for Trit {
35    type Output = Self;
36
37    fn neg(self) -> Self::Output {
38        match self {
39            Trit::Reject => Trit::Affirm,
40            Trit::Tend => Trit::Tend,
41            Trit::Affirm => Trit::Reject,
42        }
43    }
44}
45
46impl Add for Trit {
47    type Output = (Self, Self); // (Sum, Carry)
48
49    fn add(self, rhs: Self) -> Self::Output {
50        match (self, rhs) {
51            (Trit::Reject, Trit::Reject) => (Trit::Affirm, Trit::Reject),
52            (Trit::Reject, Trit::Tend) => (Trit::Reject, Trit::Tend),
53            (Trit::Reject, Trit::Affirm) => (Trit::Tend, Trit::Tend),
54            (Trit::Tend, Trit::Reject) => (Trit::Reject, Trit::Tend),
55            (Trit::Tend, Trit::Tend) => (Trit::Tend, Trit::Tend),
56            (Trit::Tend, Trit::Affirm) => (Trit::Affirm, Trit::Tend),
57            (Trit::Affirm, Trit::Reject) => (Trit::Tend, Trit::Tend),
58            (Trit::Affirm, Trit::Tend) => (Trit::Affirm, Trit::Tend),
59            (Trit::Affirm, Trit::Affirm) => (Trit::Reject, Trit::Affirm),
60        }
61    }
62}
63
64impl Mul for Trit {
65    type Output = Self;
66
67    fn mul(self, rhs: Self) -> Self::Output {
68        match (self, rhs) {
69            (Trit::Tend, _) | (_, Trit::Tend) => Trit::Tend,
70            (Trit::Affirm, Trit::Affirm) | (Trit::Reject, Trit::Reject) => Trit::Affirm,
71            (Trit::Affirm, Trit::Reject) | (Trit::Reject, Trit::Affirm) => Trit::Reject,
72        }
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn test_negation() {
82        assert_eq!(-Trit::Reject, Trit::Affirm);
83        assert_eq!(-Trit::Tend, Trit::Tend);
84        assert_eq!(-Trit::Affirm, Trit::Reject);
85    }
86
87    #[test]
88    fn test_addition() {
89        assert_eq!(Trit::Reject + Trit::Reject, (Trit::Affirm, Trit::Reject));
90        assert_eq!(Trit::Reject + Trit::Tend, (Trit::Reject, Trit::Tend));
91        assert_eq!(Trit::Reject + Trit::Affirm, (Trit::Tend, Trit::Tend));
92        assert_eq!(Trit::Tend + Trit::Reject, (Trit::Reject, Trit::Tend));
93        assert_eq!(Trit::Tend + Trit::Tend, (Trit::Tend, Trit::Tend));
94        assert_eq!(Trit::Tend + Trit::Affirm, (Trit::Affirm, Trit::Tend));
95        assert_eq!(Trit::Affirm + Trit::Reject, (Trit::Tend, Trit::Tend));
96        assert_eq!(Trit::Affirm + Trit::Tend, (Trit::Affirm, Trit::Tend));
97        assert_eq!(Trit::Affirm + Trit::Affirm, (Trit::Reject, Trit::Affirm));
98    }
99
100    #[test]
101    fn test_multiplication() {
102        assert_eq!(Trit::Reject * Trit::Reject, Trit::Affirm);
103        assert_eq!(Trit::Reject * Trit::Tend, Trit::Tend);
104        assert_eq!(Trit::Reject * Trit::Affirm, Trit::Reject);
105        assert_eq!(Trit::Tend * Trit::Reject, Trit::Tend);
106        assert_eq!(Trit::Tend * Trit::Tend, Trit::Tend);
107        assert_eq!(Trit::Tend * Trit::Affirm, Trit::Tend);
108        assert_eq!(Trit::Affirm * Trit::Reject, Trit::Reject);
109        assert_eq!(Trit::Affirm * Trit::Tend, Trit::Tend);
110        assert_eq!(Trit::Affirm * Trit::Affirm, Trit::Affirm);
111    }
112}