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