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