Here is the Phase 1 refactor—the logic layer upgrade that completes the universal-gate set and adds reduction helpers.
Drop this into your existing state.rs module.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum State { Z, X, Zero, One }
impl State {
// --- Constructors --------------------------------------------------------
pub fn from_bool(v: Option<bool>) -> Self {
match v {
None => State::Z,
Some(true) => State::One,
Some(false) => State::Zero,
}
}
// --- Unary ---------------------------------------------------------------
pub fn not(self) -> Self {
match self {
State::Z => State::Z,
State::X => State::X,
State::Zero => State::One,
State::One => State::Zero,
}
}
// --- Binary core ops -----------------------------------------------------
pub fn and(self, rhs: Self) -> Self {
use State::*;
match (self, rhs) {
(X, _) | (_, X) => X,
(Zero, _) | (_, Zero) => Zero,
(Z, s) | (s, Z) => Z,
(One, One) => One,
}
}
pub fn or(self, rhs: Self) -> Self {
use State::*;
match (self, rhs) {
(X, _) | (_, X) => X,
(One, _) | (_, One) => One,
(Z, s) | (s, Z) => Z,
(Zero, Zero) => Zero,
}
}
pub fn xor(self, rhs: Self) -> Self {
use State::*;
match (self, rhs) {
(X, _) | (_, X) => X,
(Z, s) | (s, Z) => Z,
(Zero, One) | (One, Zero) => One,
(Zero, Zero) | (One, One) => Zero,
}
}
// --- Derived universal gates --------------------------------------------
pub fn nand(self, rhs: Self) -> Self {
self.and(rhs).not()
}
pub fn nor(self, rhs: Self) -> Self {
self.or(rhs).not()
}
pub fn xnor(self, rhs: Self) -> Self {
self.xor(rhs).not()
}
// --- Logical implication / equivalence ----------------------------------
pub fn implies(self, rhs: Self) -> Self {
use State::*;
match (self, rhs) {
(Z, _) | (_, Z) => Z,
(X, _) | (_, X) => X,
(One, Zero) => Zero,
_ => One,
}
}
pub fn equiv(self, rhs: Self) -> Self {
self.implies(rhs).and(rhs.implies(self))
}
// --- Multi-argument reductions ------------------------------------------
pub fn reduce_and(v: &[Self]) -> Self {
v.iter().copied().fold(State::One, |a,b| a.and(b))
}
pub fn reduce_or(v: &[Self]) -> Self {
v.iter().copied().fold(State::Zero, |a,b| a.or(b))
}
pub fn reduce_xor(v: &[Self]) -> Self {
v.iter().copied().fold(State::Zero, |a,b| a.xor(b))
}
// --- Inspection ----------------------------------------------------------
pub fn is_true(self) -> bool { matches!(self, State::One) }
pub fn is_false(self) -> bool { matches!(self, State::Zero) }
}#[cfg(test)]
mod tests {
use super::State::*;
#[test]
fn universal_gates() {
assert_eq!(One.nand(One), Zero);
assert_eq!(One.nor(Zero), Zero);
assert_eq!(Zero.xnor(Zero), One);
}
#[test]
fn reductions() {
let v = [One, One, Zero];
assert_eq!(State::reduce_and(&v), Zero);
assert_eq!(State::reduce_or(&v), One);
assert_eq!(State::reduce_xor(&v), Zero);
}
}| Function | Description |
|---|---|
nand, nor, xnor |
Universal gates completing functional basis |
reduce_and, reduce_or, reduce_xor |
Multi-argument chain evaluators |
| Fully De Morgan-compliant | nand = !(A∧B) , nor = !(A∨B) |
Preserves 4-state propagation (Z, X stay consistent) |
Next phase (2) will add trait implementations—Display, FromStr, and PartialOrd—to make the lattice serializable and ordered.
Proceed to Phase 2?