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