1use std::{
2 borrow::Cow,
3 fmt::{Debug, Display},
4 ops::{Index, IndexMut},
5 hash::Hash,
6 slice::SliceIndex,
7};
8
9use crate::{Const, Design, Trit};
10
11#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
16pub struct Net {
17 pub(crate) index: u32,
18}
19
20impl Net {
21 pub const UNDEF: Net = Net { index: u32::MAX };
22 pub const ZERO: Net = Net { index: 0 };
23 pub const ONE: Net = Net { index: 1 };
24
25 const FIRST_CELL: u32 = 2; pub fn as_const(self) -> Option<Trit> {
28 if self == Self::UNDEF {
29 Some(Trit::Undef)
30 } else if self == Self::ZERO {
31 Some(Trit::Zero)
32 } else if self == Self::ONE {
33 Some(Trit::One)
34 } else {
35 None
36 }
37 }
38
39 pub(crate) fn from_cell_index(cell_index: usize) -> Net {
40 assert!(cell_index <= u32::MAX as usize - 3);
41 Net { index: cell_index as u32 + Net::FIRST_CELL }
42 }
43
44 pub(crate) fn as_cell_index(self) -> Result<usize, Trit> {
45 if self.index >= Self::FIRST_CELL && self != Self::UNDEF {
46 Ok((self.index - Self::FIRST_CELL) as usize)
47 } else {
48 Err(self.as_const().unwrap())
49 }
50 }
51
52 pub fn is_const(self) -> bool {
53 self.as_const().is_some()
54 }
55
56 pub fn is_cell(self) -> bool {
57 self.as_const().is_none()
58 }
59
60 pub fn visit(self, mut f: impl FnMut(Net)) {
61 f(self)
62 }
63
64 pub fn visit_mut(&mut self, mut f: impl FnMut(&mut Net)) {
65 f(self)
66 }
67}
68
69impl From<bool> for Net {
70 fn from(value: bool) -> Self {
71 match value {
72 false => Net::ZERO,
73 true => Net::ONE,
74 }
75 }
76}
77
78impl From<Trit> for Net {
79 fn from(value: Trit) -> Self {
80 match value {
81 Trit::Undef => Self::UNDEF,
82 Trit::Zero => Self::ZERO,
83 Trit::One => Self::ONE,
84 }
85 }
86}
87
88impl From<&Net> for Net {
89 fn from(net: &Net) -> Self {
90 *net
91 }
92}
93
94impl TryFrom<Value> for Net {
95 type Error = ();
96
97 fn try_from(value: Value) -> Result<Self, Self::Error> {
98 value.as_net().ok_or(())
99 }
100}
101
102impl Debug for Net {
103 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
104 match self {
105 Net { index: 0 } => write!(f, "Net::ZERO"),
106 Net { index: 1 } => write!(f, "Net::ONE"),
107 Net { index: u32::MAX } => write!(f, "Net::UNDEF"),
108 _ => {
109 let cell_index = self.index.checked_sub(Net::FIRST_CELL).unwrap();
110 write!(f, "Net::from_cell({cell_index})")
111 }
112 }
113 }
114}
115
116impl Display for Net {
117 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
118 match self {
119 Net { index: 0 } => write!(f, "0"),
120 Net { index: 1 } => write!(f, "1"),
121 Net { index: u32::MAX } => write!(f, "X"),
122 _ => {
123 let cell_index = self.index.checked_sub(Net::FIRST_CELL).unwrap();
124 write!(f, "%_{cell_index}")
125 }
126 }
127 }
128}
129
130#[derive(Clone)]
131enum ValueRepr {
132 None,
133 Some(Net),
134 Many(Vec<Net>),
135}
136
137impl ValueRepr {
138 fn as_slice(&self) -> &[Net] {
139 match self {
140 ValueRepr::None => &[],
141 ValueRepr::Some(net) => std::slice::from_ref(net),
142 ValueRepr::Many(nets) => nets.as_slice(),
143 }
144 }
145
146 fn as_slice_mut(&mut self) -> &mut [Net] {
147 match self {
148 ValueRepr::None => &mut [],
149 ValueRepr::Some(net) => std::slice::from_mut(net),
150 ValueRepr::Many(nets) => nets.as_mut_slice(),
151 }
152 }
153
154 fn push(&mut self, new_net: Net) {
155 match self {
156 ValueRepr::None => *self = ValueRepr::Some(new_net),
157 ValueRepr::Some(net) => *self = ValueRepr::Many(vec![*net, new_net]),
158 ValueRepr::Many(nets) => {
159 nets.push(new_net);
160 }
161 }
162 }
163}
164
165impl PartialEq for ValueRepr {
166 fn eq(&self, other: &Self) -> bool {
167 match (self, other) {
168 (ValueRepr::Some(lft), ValueRepr::Some(rgt)) => lft.eq(rgt),
169 _ => self.as_slice().eq(other.as_slice()),
170 }
171 }
172}
173
174impl Eq for ValueRepr {}
175
176impl PartialOrd for ValueRepr {
177 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
178 match (self, other) {
179 (ValueRepr::Some(lft), ValueRepr::Some(rgt)) => lft.partial_cmp(rgt),
180 _ => self.as_slice().partial_cmp(other.as_slice()),
181 }
182 }
183}
184
185impl Ord for ValueRepr {
186 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
187 match (self, other) {
188 (ValueRepr::Some(lft), ValueRepr::Some(rgt)) => lft.cmp(rgt),
189 _ => self.as_slice().cmp(other.as_slice()),
190 }
191 }
192}
193
194impl Hash for ValueRepr {
195 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
196 self.as_slice().hash(state);
197 }
198}
199
200#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
202pub struct Value(ValueRepr);
203
204impl Value {
205 pub fn new() -> Self {
207 Value(ValueRepr::None)
208 }
209
210 pub fn zero(width: usize) -> Self {
212 Value::from_iter(std::iter::repeat_n(Net::ZERO, width))
213 }
214
215 pub fn ones(width: usize) -> Self {
217 Value::from_iter(std::iter::repeat_n(Net::ONE, width))
218 }
219
220 pub fn undef(width: usize) -> Self {
222 Value::from_iter(std::iter::repeat_n(Net::UNDEF, width))
223 }
224
225 pub(crate) fn from_cell_range(cell_index: usize, count: usize) -> Value {
227 Value::from_iter((cell_index..(cell_index + count)).map(Net::from_cell_index))
228 }
229
230 pub fn len(&self) -> usize {
231 self.0.as_slice().len()
232 }
233
234 pub fn is_empty(&self) -> bool {
235 self.0.as_slice().is_empty()
236 }
237
238 pub fn iter(&self) -> impl DoubleEndedIterator<Item = Net> + ExactSizeIterator + '_ {
239 self.0.as_slice().iter().copied()
240 }
241
242 pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut Net> + ExactSizeIterator + '_ {
243 self.0.as_slice_mut().iter_mut()
244 }
245
246 pub fn push(&mut self, new_net: impl Into<Net>) {
247 self.0.push(new_net.into())
248 }
249
250 pub fn is_undef(&self) -> bool {
251 self.iter().all(|net| net == Net::UNDEF)
252 }
253
254 pub fn is_zero(&self) -> bool {
255 self.iter().all(|net| net == Net::ZERO)
256 }
257
258 pub fn is_ones(&self) -> bool {
259 self.iter().all(|net| net == Net::ONE)
260 }
261
262 pub fn lsb(&self) -> Net {
263 self[0]
264 }
265
266 pub fn msb(&self) -> Net {
267 self[self.len() - 1]
268 }
269
270 pub fn has_undef(&self) -> bool {
271 self.iter().any(|net| net == Net::UNDEF)
272 }
273
274 pub fn as_const(&self) -> Option<Const> {
275 let nets = self.0.as_slice();
276 if nets.iter().all(|net| net.is_const()) {
277 Some(Const::from_iter(nets.iter().map(|net| net.as_const().unwrap())))
278 } else {
279 None
280 }
281 }
282
283 pub fn as_net(&self) -> Option<Net> {
284 if self.len() == 1 { Some(self[0]) } else { None }
285 }
286
287 pub fn unwrap_net(&self) -> Net {
288 self.as_net().unwrap()
289 }
290
291 pub fn concat<'a>(&self, other: impl Into<Cow<'a, Value>>) -> Self {
292 Value::from_iter(self.iter().chain(other.into().iter()))
293 }
294
295 pub fn repeat(&self, count: usize) -> Self {
296 Value::from_iter((0..count).flat_map(|_| self))
297 }
298
299 pub fn slice(&self, range: impl std::ops::RangeBounds<usize>) -> Value {
300 Value::from(&self[(range.start_bound().cloned(), range.end_bound().cloned())])
301 }
302
303 pub fn zext(&self, width: usize) -> Self {
304 assert!(width >= self.len());
305 self.concat(Value::zero(width - self.len()))
306 }
307
308 pub fn sext(&self, width: usize) -> Self {
309 assert!(!self.is_empty());
310 assert!(width >= self.len());
311 Value::from_iter(self.iter().chain(std::iter::repeat_n(self.msb(), width - self.len())))
312 }
313
314 fn shift_count(value: &Const, stride: u32) -> usize {
315 let stride = stride as usize;
316 let mut result: usize = 0;
317 for (index, trit) in value.iter().enumerate() {
318 if trit == Trit::One {
319 if index >= usize::BITS as usize {
320 return usize::MAX;
321 } else {
322 result |= 1 << index;
323 }
324 }
325 }
326 result.checked_mul(stride).unwrap_or(usize::MAX)
327 }
328
329 pub fn shl<'a>(&self, other: impl Into<Cow<'a, Const>>, stride: u32) -> Value {
330 let other = other.into();
331 if other.has_undef() {
332 return Value::undef(self.len());
333 }
334 let shcnt = Self::shift_count(&other, stride);
335 if shcnt >= self.len() {
336 return Value::zero(self.len());
337 }
338 Value::zero(shcnt).concat(Value::from(&self[..self.len() - shcnt]))
339 }
340
341 pub fn ushr<'a>(&self, other: impl Into<Cow<'a, Const>>, stride: u32) -> Value {
342 let other = other.into();
343 if other.has_undef() {
344 return Value::undef(self.len());
345 }
346 let shcnt = Self::shift_count(&other, stride);
347 if shcnt >= self.len() {
348 return Value::zero(self.len());
349 }
350 Value::from(&self[shcnt..]).zext(self.len())
351 }
352
353 pub fn sshr<'a>(&self, other: impl Into<Cow<'a, Const>>, stride: u32) -> Value {
354 let other = other.into();
355 if other.has_undef() {
356 return Value::undef(self.len());
357 }
358 let shcnt = Self::shift_count(&other, stride);
359 if shcnt >= self.len() {
360 return Value::from(self.msb()).sext(self.len());
361 }
362 Value::from(&self[shcnt..]).sext(self.len())
363 }
364
365 pub fn xshr<'a>(&self, other: impl Into<Cow<'a, Const>>, stride: u32) -> Value {
366 let other = other.into();
367 if other.has_undef() {
368 return Value::undef(self.len());
369 }
370 let shcnt = Self::shift_count(&other, stride);
371 if shcnt >= self.len() {
372 return Value::undef(self.len());
373 }
374 Value::from(&self[shcnt..]).concat(Value::undef(shcnt))
375 }
376
377 pub fn visit(&self, mut f: impl FnMut(Net)) {
378 for net in self.iter() {
379 f(net)
380 }
381 }
382
383 pub fn visit_mut(&mut self, mut f: impl FnMut(&mut Net)) {
384 for net in self.iter_mut() {
385 f(net)
386 }
387 }
388}
389
390impl Default for Value {
391 fn default() -> Self {
392 Value::new()
393 }
394}
395
396impl Debug for Value {
397 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
398 write!(f, "Value::from_iter([")?;
399 for (index, net) in self.iter().enumerate() {
400 if index != 0 {
401 write!(f, ", ")?;
402 }
403 write!(f, "{:?}", net)?;
404 }
405 write!(f, "])")?;
406 Ok(())
407 }
408}
409
410impl Display for Value {
411 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
412 if self.is_empty() {
413 write!(f, "[]")
414 } else if self.len() == 1 {
415 write!(f, "{}", self[0])
416 } else {
417 write!(f, "[")?;
418 for net in self.iter().rev() {
419 write!(f, " {}", net)?;
420 }
421 write!(f, " ]")
422 }
423 }
424}
425
426impl<I: SliceIndex<[Net]>> Index<I> for Value {
427 type Output = I::Output;
428
429 fn index(&self, index: I) -> &Self::Output {
430 &self.0.as_slice()[index]
431 }
432}
433
434impl<I: SliceIndex<[Net]>> IndexMut<I> for Value {
435 fn index_mut(&mut self, index: I) -> &mut Self::Output {
436 &mut self.0.as_slice_mut()[index]
437 }
438}
439
440impl Extend<Net> for Value {
441 fn extend<T: IntoIterator<Item = Net>>(&mut self, iter: T) {
442 for net in iter {
443 self.push(net);
444 }
445 }
446}
447
448impl From<&Value> for Value {
449 fn from(value: &Value) -> Self {
450 value.clone()
451 }
452}
453
454impl From<Net> for Value {
455 fn from(net: Net) -> Self {
456 Value(ValueRepr::Some(net))
457 }
458}
459
460impl From<&Net> for Value {
461 fn from(net: &Net) -> Self {
462 Value::from(*net)
463 }
464}
465
466impl From<Trit> for Value {
467 fn from(trit: Trit) -> Self {
468 Value(ValueRepr::Some(trit.into()))
469 }
470}
471
472impl From<&[Net]> for Value {
473 fn from(nets: &[Net]) -> Self {
474 Value::from_iter(nets.iter().cloned())
475 }
476}
477
478impl From<Vec<Net>> for Value {
479 fn from(nets: Vec<Net>) -> Self {
480 Value::from(&nets[..])
481 }
482}
483
484impl From<&Const> for Value {
485 fn from(value: &Const) -> Self {
486 Value::from_iter(value.into_iter().map(Net::from))
487 }
488}
489
490impl From<Const> for Value {
491 fn from(value: Const) -> Self {
492 Value::from(&value)
493 }
494}
495
496impl From<Value> for Cow<'_, Value> {
497 fn from(value: Value) -> Self {
498 Cow::Owned(value)
499 }
500}
501
502impl From<Net> for Cow<'_, Value> {
503 fn from(value: Net) -> Self {
504 Cow::Owned(Value::from(value))
505 }
506}
507
508impl From<Trit> for Cow<'_, Value> {
509 fn from(value: Trit) -> Self {
510 Cow::Owned(Value::from(Net::from(value)))
511 }
512}
513
514impl From<&Const> for Cow<'_, Value> {
515 fn from(value: &Const) -> Self {
516 Cow::Owned(Value::from(value))
517 }
518}
519
520impl From<Const> for Cow<'_, Value> {
521 fn from(value: Const) -> Self {
522 Cow::Owned(Value::from(value))
523 }
524}
525
526impl<'a> From<&'a Value> for Cow<'a, Value> {
527 fn from(value: &'a Value) -> Self {
528 Cow::Borrowed(value)
529 }
530}
531
532impl FromIterator<Net> for Value {
533 fn from_iter<T: IntoIterator<Item = Net>>(iter: T) -> Self {
534 let mut iter = iter.into_iter();
535 match iter.size_hint() {
536 (_, Some(0 | 1)) => {
537 let mut value = match iter.next() {
538 None => Value::new(),
539 Some(net) => Value::from(net),
540 };
541 while let Some(net) = iter.next() {
542 value.push(net);
543 }
544 value
545 }
546 _ => Value(ValueRepr::Many(iter.collect())),
547 }
548 }
549}
550
551impl<'a> IntoIterator for &'a Value {
552 type Item = Net;
553 type IntoIter = std::iter::Cloned<std::slice::Iter<'a, Net>>;
554
555 fn into_iter(self) -> Self::IntoIter {
556 self.0.as_slice().into_iter().cloned()
557 }
558}
559
560pub struct ValueIntoIter {
561 repr: ValueRepr,
562 index: usize,
563}
564
565impl Iterator for ValueIntoIter {
566 type Item = Net;
567
568 fn next(&mut self) -> Option<Self::Item> {
569 let item = self.repr.as_slice().get(self.index).cloned();
570 if item.is_some() {
571 self.index += 1;
572 }
573 item
574 }
575}
576
577impl IntoIterator for Value {
578 type Item = Net;
579 type IntoIter = ValueIntoIter;
580
581 fn into_iter(self) -> Self::IntoIter {
582 ValueIntoIter { repr: self.0, index: 0 }
583 }
584}
585
586#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
588pub enum ControlNet {
589 Pos(Net),
590 Neg(Net),
591}
592
593impl ControlNet {
594 pub const UNDEF: ControlNet = ControlNet::Pos(Net::UNDEF);
595 pub const ZERO: ControlNet = ControlNet::Pos(Net::ZERO);
596 pub const ONE: ControlNet = ControlNet::Pos(Net::ONE);
597
598 pub fn from_net_invert(net: Net, invert: bool) -> Self {
599 match invert {
600 false => ControlNet::Pos(net),
601 true => ControlNet::Neg(net),
602 }
603 }
604
605 pub fn net(self) -> Net {
606 match self {
607 Self::Pos(net) => net,
608 Self::Neg(net) => net,
609 }
610 }
611
612 pub fn is_positive(self) -> bool {
613 matches!(self, Self::Pos(_))
614 }
615
616 pub fn is_negative(self) -> bool {
617 matches!(self, Self::Neg(_))
618 }
619
620 pub fn is_active(self) -> Option<bool> {
621 match self {
622 Self::Pos(net) if net == Net::ZERO => Some(false),
623 Self::Neg(net) if net == Net::ONE => Some(false),
624 Self::Pos(net) if net == Net::ONE => Some(true),
625 Self::Neg(net) if net == Net::ZERO => Some(true),
626 _ => None,
627 }
628 }
629
630 pub fn is_always(self, active: bool) -> bool {
631 self.is_active() == Some(active)
632 }
633
634 pub fn is_const(self) -> bool {
635 self.net().as_const().is_some()
636 }
637
638 pub fn canonicalize(self) -> Self {
639 match self {
640 Self::Neg(net) if net == Net::UNDEF => Self::Pos(net),
641 Self::Neg(net) if net == Net::ZERO => Self::Pos(Net::ONE),
642 Self::Neg(net) if net == Net::ONE => Self::Pos(Net::ZERO),
643 _ => self,
644 }
645 }
646
647 pub fn into_pos(self, design: &Design) -> Net {
648 match self {
649 ControlNet::Pos(net) => net,
650 ControlNet::Neg(net) => {
651 if let Some(trit) = net.as_const() {
652 Net::from(!trit)
653 } else {
654 design.add_not(net).unwrap_net()
655 }
656 }
657 }
658 }
659
660 pub fn into_neg(self, design: &Design) -> Net {
661 match self {
662 ControlNet::Pos(net) => {
663 if let Some(trit) = net.as_const() {
664 Net::from(!trit)
665 } else {
666 design.add_not(net).unwrap_net()
667 }
668 }
669 ControlNet::Neg(net) => net,
670 }
671 }
672
673 pub fn visit(self, f: impl FnMut(Net)) {
674 match self {
675 ControlNet::Pos(net) => net.visit(f),
676 ControlNet::Neg(net) => net.visit(f),
677 }
678 }
679
680 pub fn visit_mut(&mut self, f: impl FnMut(&mut Net)) {
681 match self {
682 ControlNet::Pos(net) => net.visit_mut(f),
683 ControlNet::Neg(net) => net.visit_mut(f),
684 }
685 }
686}
687
688impl std::ops::Not for ControlNet {
689 type Output = ControlNet;
690
691 fn not(self) -> Self::Output {
692 match self {
693 ControlNet::Pos(net) => ControlNet::Neg(net),
694 ControlNet::Neg(net) => ControlNet::Pos(net),
695 }
696 .canonicalize()
697 }
698}
699
700impl From<Net> for ControlNet {
701 fn from(net: Net) -> Self {
702 ControlNet::Pos(net)
703 }
704}
705
706#[cfg(test)]
707mod test {
708 use crate::{Net, Trit, Value};
709
710 #[test]
711 fn test_net() {
712 assert_eq!(Net::from(Trit::Zero), Net::ZERO);
713 assert_eq!(Net::from(Trit::One), Net::ONE);
714 assert_eq!(Net::from(Trit::Undef), Net::UNDEF);
715 assert_eq!(Net::from_cell_index(3), Net { index: 5 });
716 }
717
718 #[test]
719 fn test_from_bool() {
720 assert_eq!(Net::from(false), Net::ZERO);
721 assert_eq!(Net::from(true), Net::ONE);
722 }
723
724 #[test]
725 fn test_from_trit() {
726 assert_eq!(Net::from(Trit::Zero), Net::ZERO);
727 assert_eq!(Net::from(Trit::One), Net::ONE);
728 assert_eq!(Net::from(Trit::Undef), Net::UNDEF);
729 }
730
731 #[test]
732 fn test_net_debug() {
733 assert_eq!(format!("{:?}", Net::ZERO), "Net::ZERO");
734 assert_eq!(format!("{:?}", Net::ONE), "Net::ONE");
735 assert_eq!(format!("{:?}", Net::UNDEF), "Net::UNDEF");
736 assert_eq!(format!("{:?}", Net::from_cell_index(0)), "Net::from_cell(0)");
737 }
738
739 #[test]
740 fn test_value() {
741 let v01 = Value::from_iter([Net::ONE, Net::ZERO]);
742 assert_eq!(v01.into_iter().collect::<Vec<_>>(), vec![Net::ONE, Net::ZERO]);
743 }
744}