libreda_logic/
logic_value.rs1use std::hash::Hash;
8
9use crate::traits::LogicValue;
10
11impl LogicValue for bool {
12 fn num_values() -> usize {
13 2
14 }
15
16 fn value(idx: usize) -> Self {
17 match idx {
18 0 => false,
19 1 => true,
20 _ => panic!("index out of bounds"),
21 }
22 }
23
24 fn zero() -> Self {
25 false
26 }
27
28 fn one() -> Self {
29 true
30 }
31}
32
33#[derive(Copy, Clone, Eq, PartialEq, Hash)]
35pub enum Bool {
36 L,
38 H,
40}
41
42impl LogicValue for Bool {
43 fn num_values() -> usize {
44 2
45 }
46
47 fn value(idx: usize) -> Self {
48 match idx {
49 0 => Self::L,
50 1 => Self::H,
51 _ => panic!("index out of bounds"),
52 }
53 }
54
55 fn zero() -> Self {
56 Self::L
57 }
58
59 fn one() -> Self {
60 Self::H
61 }
62}
63
64#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default)]
68pub enum Logic3 {
69 L,
71 H,
73 #[default]
75 X,
76}
77
78impl From<bool> for Logic3 {
79 fn from(value: bool) -> Self {
80 match value {
81 true => Self::H,
82 false => Self::L,
83 }
84 }
85}
86
87impl From<Option<bool>> for Logic3 {
88 fn from(value: Option<bool>) -> Self {
89 match value {
90 None => Self::X,
91 Some(true) => Self::H,
92 Some(false) => Self::L,
93 }
94 }
95}
96
97impl TryInto<bool> for Logic3 {
98 type Error = ();
99
100 fn try_into(self) -> Result<bool, Self::Error> {
101 match self {
102 Logic3::L => Ok(false),
103 Logic3::H => Ok(true),
104 Logic3::X => Err(()),
105 }
106 }
107}
108
109impl LogicValue for Logic3 {
110 fn value(idx: usize) -> Self {
111 match idx {
112 0 => Self::L,
113 1 => Self::H,
114 2 => Self::X,
115 _ => panic!("index out of bounds"),
116 }
117 }
118
119 fn zero() -> Self {
120 Self::L
121 }
122
123 fn one() -> Self {
124 Self::H
125 }
126
127 fn num_values() -> usize {
128 3
129 }
130}
131
132impl std::ops::Not for Logic3 {
133 type Output = Self;
134
135 fn not(self) -> Self::Output {
136 use Logic3::*;
137 match self {
138 L => H,
139 H => L,
140 X => X,
141 }
142 }
143}
144
145impl std::ops::BitAnd for Logic3 {
146 type Output = Self;
147
148 fn bitand(self, rhs: Self) -> Self::Output {
149 use Logic3::*;
150 match (self, rhs) {
151 (L, _) | (_, L) => L,
152 (H, H) => H,
153 _ => X,
154 }
155 }
156}
157
158impl std::ops::BitOr for Logic3 {
159 type Output = Self;
160
161 fn bitor(self, rhs: Self) -> Self::Output {
162 use Logic3::*;
163 match (self, rhs) {
164 (H, _) | (_, H) => H,
165 (L, L) => L,
166 _ => X,
167 }
168 }
169}
170
171impl std::ops::BitXor for Logic3 {
172 type Output = Self;
173
174 fn bitxor(self, rhs: Self) -> Self::Output {
175 use Logic3::*;
176 match (self, rhs) {
177 (H, H) | (L, L) => L,
178 (H, L) | (L, H) => H,
179 (X, _) | (_, X) => X,
180 }
181 }
182}
183
184#[test]
185fn test_logic3_ops() {
186 use Logic3::*;
187
188 assert_eq!(H & H, H);
189 assert_eq!(L & X, L);
190 assert_eq!(X & L, L);
191 assert_eq!(H & X, X);
192
193 assert_eq!(L | L, L);
194 assert_eq!(H | X, H);
195 assert_eq!(X | H, H);
196 assert_eq!(X | L, X);
197}