1use crate::dag::{Dag, DagLike};
9use crate::types::{CompleteBound, Final};
10use crate::{BitIter, Tmr};
11
12use crate::{BitCollector, EarlyEndOfStreamError};
13use core::{cmp, fmt, iter};
14use std::collections::VecDeque;
15use std::hash::Hash;
16use std::sync::Arc;
17
18#[derive(Clone)]
20pub struct Value {
21 inner: Arc<[u8]>,
32 bit_offset: usize,
36 ty: Arc<Final>,
38}
39
40#[derive(Debug, Clone, Copy)]
42pub struct ValueRef<'v> {
43 inner: &'v Arc<[u8]>,
44 bit_offset: usize,
45 ty: &'v Arc<Final>,
46}
47
48impl PartialEq for Value {
54 fn eq(&self, other: &Self) -> bool {
55 self.ty == other.ty && self.raw_byte_iter().eq(other.raw_byte_iter())
56 }
57}
58impl Eq for Value {}
59
60impl PartialOrd for Value {
61 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
62 Some(self.cmp(other))
63 }
64}
65impl Ord for Value {
66 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
67 self.ty
68 .cmp(&other.ty)
69 .then_with(|| self.raw_byte_iter().cmp(other.raw_byte_iter()))
70 }
71}
72
73impl core::hash::Hash for Value {
74 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
75 b"Simplicity\x1fValue".hash(h);
76 self.ty.hash(h);
77 for val in self.raw_byte_iter() {
78 val.hash(h);
79 }
80 }
81}
82
83impl DagLike for ValueRef<'_> {
84 type Node = Self;
85
86 fn data(&self) -> &Self {
87 self
88 }
89
90 fn as_dag_node(&self) -> Dag<Self> {
91 if let Some((left, right)) = self.as_product() {
92 Dag::Binary(left, right)
93 } else if let Some(left) = self.as_left() {
94 Dag::Unary(left)
95 } else if let Some(right) = self.as_right() {
96 Dag::Unary(right)
97 } else {
98 assert!(self.ty.is_unit());
99 Dag::Nullary
100 }
101 }
102}
103
104impl<'v> ValueRef<'v> {
105 pub fn is_unit(&self) -> bool {
107 self.ty.is_unit()
108 }
109
110 fn first_bit(&self) -> Option<bool> {
115 let mask = if self.bit_offset % 8 == 0 {
116 0x80
117 } else {
118 1 << (7 - self.bit_offset % 8)
119 };
120 let res = self
121 .inner
122 .get(self.bit_offset / 8)
123 .map(|x| x & mask == mask);
124 res
125 }
126
127 pub fn as_left(&self) -> Option<Self> {
129 if self.first_bit() == Some(false) {
130 if let Some((lty, rty)) = self.ty.as_sum() {
131 let sum_width = 1 + cmp::max(lty.bit_width(), rty.bit_width());
132 Some(Self {
133 inner: self.inner,
134 bit_offset: self.bit_offset + sum_width - lty.bit_width(),
135 ty: lty,
136 })
137 } else {
138 None
139 }
140 } else {
141 None
142 }
143 }
144
145 pub fn as_right(&self) -> Option<Self> {
147 if self.first_bit() == Some(true) {
148 if let Some((lty, rty)) = self.ty.as_sum() {
149 let sum_width = 1 + cmp::max(lty.bit_width(), rty.bit_width());
150 Some(Self {
151 inner: self.inner,
152 bit_offset: self.bit_offset + sum_width - rty.bit_width(),
153 ty: rty,
154 })
155 } else {
156 None
157 }
158 } else {
159 None
160 }
161 }
162
163 pub fn as_product(&self) -> Option<(Self, Self)> {
165 if let Some((lty, rty)) = self.ty.as_product() {
166 Some((
167 Self {
168 inner: self.inner,
169 bit_offset: self.bit_offset,
170 ty: lty,
171 },
172 Self {
173 inner: self.inner,
174 bit_offset: self.bit_offset + lty.bit_width(),
175 ty: rty,
176 },
177 ))
178 } else {
179 None
180 }
181 }
182
183 pub fn to_value(&self) -> Value {
185 Value {
186 inner: Arc::clone(self.inner),
187 bit_offset: self.bit_offset,
188 ty: Arc::clone(self.ty),
189 }
190 }
191
192 pub fn to_word(&self) -> Option<Word> {
194 self.ty.as_word().map(|n| Word {
195 value: self.to_value(),
196 n,
197 })
198 }
199
200 pub fn raw_byte_iter(&self) -> RawByteIter<'v> {
206 RawByteIter {
207 value: *self,
208 yielded_bytes: 0,
209 }
210 }
211
212 pub fn iter_compact(&self) -> CompactBitsIter<'v> {
216 CompactBitsIter::new(*self)
217 }
218
219 pub fn iter_padded(&self) -> PreOrderIter<'v> {
223 PreOrderIter {
224 inner: BitIter::new(self.raw_byte_iter()).take(self.ty.bit_width()),
225 }
226 }
227}
228
229pub struct RawByteIter<'v> {
230 value: ValueRef<'v>,
231 yielded_bytes: usize,
232}
233
234impl Iterator for RawByteIter<'_> {
235 type Item = u8;
236 fn next(&mut self) -> Option<Self::Item> {
237 if 8 * self.yielded_bytes >= self.value.ty.bit_width() {
238 None
239 } else if self.value.bit_offset % 8 == 0 {
240 self.yielded_bytes += 1;
241
242 Some(self.value.inner[self.value.bit_offset / 8 + self.yielded_bytes - 1])
243 } else {
244 self.yielded_bytes += 1;
245
246 let ret1 = self.value.inner[self.value.bit_offset / 8 + self.yielded_bytes - 1];
247 let ret2 = self
248 .value
249 .inner
250 .get(self.value.bit_offset / 8 + self.yielded_bytes)
251 .copied()
252 .unwrap_or(0);
253 let bit_offset = self.value.bit_offset % 8;
254 Some((ret1 << bit_offset) | (ret2 >> (8 - bit_offset)))
255 }
256 }
257}
258
259pub struct PreOrderIter<'v> {
260 inner: iter::Take<BitIter<RawByteIter<'v>>>,
261}
262
263impl Iterator for PreOrderIter<'_> {
264 type Item = bool;
265 fn next(&mut self) -> Option<Self::Item> {
266 self.inner.next()
267 }
268}
269
270fn right_shift_1(inner: &Arc<[u8]>, bit_offset: usize, new_bit: bool) -> (Arc<[u8]>, usize) {
276 if bit_offset > 0 {
279 if new_bit {
280 let new_bit_offset = bit_offset - 1;
281 let mut bx: Box<[u8]> = inner.as_ref().into();
282 bx[new_bit_offset / 8] |= 1 << (7 - new_bit_offset % 8);
283 (bx.into(), new_bit_offset)
284 } else {
285 (Arc::clone(inner), bit_offset - 1)
287 }
288 } else {
289 let mut new = Vec::with_capacity(inner.len() + 1);
293 new.push(u8::from(new_bit));
294 new.extend(inner.iter().copied());
295 (new.into(), 7)
296 }
297}
298
299fn copy_bits(src: &[u8], src_offset: usize, dst: &mut [u8], dst_offset: usize, nbits: usize) {
304 for i in 0..nbits {
307 let bit = (src[(src_offset + i) / 8] >> (7 - (src_offset + i) % 8)) & 1;
308 dst[(dst_offset + i) / 8] |= bit << (7 - (dst_offset + i) % 8);
309 }
310}
311
312fn product(
319 left: Option<(&Arc<[u8]>, usize)>,
320 left_bit_length: usize,
321 right: Option<(&Arc<[u8]>, usize)>,
322 right_bit_length: usize,
323) -> (Arc<[u8]>, usize) {
324 if left_bit_length == 0 {
325 if let Some((right, right_bit_offset)) = right {
326 (Arc::clone(right), right_bit_offset)
327 } else if right_bit_length == 0 {
328 (Arc::new([]), 0)
329 } else {
330 (Arc::from(vec![0; right_bit_length.div_ceil(8)]), 0)
331 }
332 } else if right_bit_length == 0 {
333 if let Some((lt, left_bit_offset)) = left {
334 (Arc::clone(lt), left_bit_offset)
335 } else {
336 (Arc::from(vec![0; left_bit_length.div_ceil(8)]), 0)
337 }
338 } else {
339 let mut bx = Box::<[u8]>::from(vec![0; (left_bit_length + right_bit_length).div_ceil(8)]);
343 if let Some((left, left_bit_offset)) = left {
344 copy_bits(left, left_bit_offset, &mut bx, 0, left_bit_length);
345 }
346 if let Some((right, right_bit_offset)) = right {
347 copy_bits(
348 right,
349 right_bit_offset,
350 &mut bx,
351 left_bit_length,
352 right_bit_length,
353 );
354 }
355
356 (bx.into(), 0)
357 }
358}
359
360impl Value {
361 pub fn shallow_clone(&self) -> Self {
363 Self {
364 inner: Arc::clone(&self.inner),
365 bit_offset: self.bit_offset,
366 ty: Arc::clone(&self.ty),
367 }
368 }
369
370 pub fn ty(&self) -> &Final {
372 &self.ty
373 }
374
375 pub fn unit() -> Self {
377 Self {
378 inner: Arc::new([]),
379 bit_offset: 0,
380 ty: Final::unit(),
381 }
382 }
383
384 pub fn left(inner: Self, right: Arc<Final>) -> Self {
386 let total_width = cmp::max(inner.ty.bit_width(), right.bit_width());
387
388 let (concat, concat_offset) = product(
389 None,
390 total_width - inner.ty.bit_width(),
391 Some((&inner.inner, inner.bit_offset)),
392 inner.ty.bit_width(),
393 );
394 let (new_inner, new_bit_offset) = right_shift_1(&concat, concat_offset, false);
395 Self {
396 inner: new_inner,
397 bit_offset: new_bit_offset,
398 ty: Final::sum(Arc::clone(&inner.ty), right),
399 }
400 }
401
402 pub fn right(left: Arc<Final>, inner: Self) -> Self {
404 let total_width = cmp::max(left.bit_width(), inner.ty.bit_width());
405 let (concat, concat_offset) = product(
406 None,
407 total_width - inner.ty.bit_width(),
408 Some((&inner.inner, inner.bit_offset)),
409 inner.ty.bit_width(),
410 );
411 let (new_inner, new_bit_offset) = right_shift_1(&concat, concat_offset, true);
412 Self {
413 inner: new_inner,
414 bit_offset: new_bit_offset,
415 ty: Final::sum(left, Arc::clone(&inner.ty)),
416 }
417 }
418
419 pub fn product(left: Self, right: Self) -> Self {
421 let (new_inner, new_bit_offset) = product(
422 Some((&left.inner, left.bit_offset)),
423 left.ty.bit_width(),
424 Some((&right.inner, right.bit_offset)),
425 right.ty.bit_width(),
426 );
427 Self {
428 inner: new_inner,
429 bit_offset: new_bit_offset,
430 ty: Final::product(Arc::clone(&left.ty), Arc::clone(&right.ty)),
431 }
432 }
433
434 pub fn none(right: Arc<Final>) -> Self {
436 Self::left(Value::unit(), right)
437 }
438
439 pub fn some(inner: Self) -> Self {
441 Self::right(Final::unit(), inner)
442 }
443
444 pub fn compact_len(&self) -> usize {
446 self.iter_compact().count()
447 }
448
449 pub fn padded_len(&self) -> usize {
451 self.ty.bit_width()
452 }
453
454 pub fn is_empty(&self) -> bool {
457 self.ty.bit_width() == 0
458 }
459
460 pub fn is_unit(&self) -> bool {
462 self.ty.is_unit()
463 }
464
465 pub fn as_ref(&self) -> ValueRef<'_> {
467 ValueRef {
468 inner: &self.inner,
469 bit_offset: self.bit_offset,
470 ty: &self.ty,
471 }
472 }
473
474 pub fn as_left(&self) -> Option<ValueRef<'_>> {
476 self.as_ref().as_left()
477 }
478
479 pub fn as_right(&self) -> Option<ValueRef<'_>> {
481 self.as_ref().as_right()
482 }
483
484 pub fn as_product(&self) -> Option<(ValueRef<'_>, ValueRef<'_>)> {
486 self.as_ref().as_product()
487 }
488
489 pub fn u1(value: u8) -> Self {
495 assert!(value <= 1, "{} out of range for Value::u1", value);
496 Self {
497 inner: Arc::new([value]),
498 bit_offset: 7,
499 ty: Final::two_two_n(0),
500 }
501 }
502
503 pub fn u2(value: u8) -> Self {
509 assert!(value <= 3, "{} out of range for Value::u2", value);
510 Self {
511 inner: Arc::new([value]),
512 bit_offset: 6,
513 ty: Final::two_two_n(1),
514 }
515 }
516
517 pub fn u4(value: u8) -> Self {
523 assert!(value <= 15, "{} out of range for Value::u2", value);
524 Self {
525 inner: Arc::new([value]),
526 bit_offset: 4,
527 ty: Final::two_two_n(2),
528 }
529 }
530
531 pub fn u8(value: u8) -> Self {
533 Self {
534 inner: Arc::new([value]),
535 bit_offset: 0,
536 ty: Final::two_two_n(3),
537 }
538 }
539
540 pub fn u16(bytes: u16) -> Self {
542 Self {
543 inner: Arc::new(bytes.to_be_bytes()),
544 bit_offset: 0,
545 ty: Final::two_two_n(4),
546 }
547 }
548
549 pub fn u32(bytes: u32) -> Self {
551 Self {
552 inner: Arc::new(bytes.to_be_bytes()),
553 bit_offset: 0,
554 ty: Final::two_two_n(5),
555 }
556 }
557
558 pub fn u64(bytes: u64) -> Self {
560 Self {
561 inner: Arc::new(bytes.to_be_bytes()),
562 bit_offset: 0,
563 ty: Final::two_two_n(6),
564 }
565 }
566
567 pub fn u128(bytes: u128) -> Self {
569 Self {
570 inner: Arc::new(bytes.to_be_bytes()),
571 bit_offset: 0,
572 ty: Final::two_two_n(7),
573 }
574 }
575
576 pub fn u256(bytes: [u8; 32]) -> Self {
578 Self {
579 inner: Arc::new(bytes),
580 bit_offset: 0,
581 ty: Final::two_two_n(8),
582 }
583 }
584
585 pub fn u512(bytes: [u8; 64]) -> Self {
587 Self {
588 inner: Arc::new(bytes),
589 bit_offset: 0,
590 ty: Final::two_two_n(9),
591 }
592 }
593
594 pub fn from_byte_array<const N: usize>(bytes: [u8; N]) -> Self {
600 assert!(N.is_power_of_two(), "Array length must be a power of two");
601 let mut values: VecDeque<_> = bytes.into_iter().map(Value::u8).collect();
602
603 while values.len() > 1 {
604 let mut alt_values = VecDeque::with_capacity(values.len() / 2);
605
606 while let (Some(left), Some(right)) = (values.pop_front(), values.pop_front()) {
607 alt_values.push_back(Value::product(left, right));
608 }
609
610 values = alt_values;
611 }
612
613 values.into_iter().next().unwrap()
614 }
615
616 pub fn raw_byte_iter(&self) -> RawByteIter<'_> {
622 self.as_ref().raw_byte_iter()
623 }
624
625 pub fn iter_compact(&self) -> CompactBitsIter<'_> {
629 self.as_ref().iter_compact()
630 }
631
632 pub fn iter_padded(&self) -> PreOrderIter<'_> {
636 self.as_ref().iter_padded()
637 }
638
639 pub fn is_of_type(&self, ty: &Final) -> bool {
641 self.ty.as_ref() == ty
642 }
643
644 pub fn zero(ty: &Final) -> Self {
654 Self {
655 inner: Arc::from(vec![0; ty.bit_width().div_ceil(8)]),
656 bit_offset: 0,
657 ty: Arc::new(ty.clone()),
658 }
659 }
660
661 pub fn to_word(&self) -> Option<Word> {
665 self.ty.as_word().map(|n| Word {
666 value: self.shallow_clone(),
667 n,
668 })
669 }
670
671 pub fn prune(&self, pruned_ty: &Final) -> Option<Self> {
690 enum Task<'v, 'ty> {
691 Prune(ValueRef<'v>, &'ty Final),
692 MakeLeft(Arc<Final>),
693 MakeRight(Arc<Final>),
694 MakeProduct,
695 }
696
697 let mut stack = vec![Task::Prune(self.as_ref(), pruned_ty)];
698 let mut output = vec![];
699
700 while let Some(task) = stack.pop() {
701 match task {
702 Task::Prune(value, pruned_ty) if value.ty.as_ref() == pruned_ty => {
703 output.push(value.to_value())
704 }
705 Task::Prune(value, pruned_ty) => match pruned_ty.bound() {
706 CompleteBound::Unit => output.push(Value::unit()),
707 CompleteBound::Sum(l_ty, r_ty) => {
708 if let Some(l_value) = value.as_left() {
709 stack.push(Task::MakeLeft(Arc::clone(r_ty)));
710 stack.push(Task::Prune(l_value, l_ty));
711 } else {
712 let r_value = value.as_right()?;
713 stack.push(Task::MakeRight(Arc::clone(l_ty)));
714 stack.push(Task::Prune(r_value, r_ty));
715 }
716 }
717 CompleteBound::Product(l_ty, r_ty) => {
718 let (l_value, r_value) = value.as_product()?;
719 stack.push(Task::MakeProduct);
720 stack.push(Task::Prune(r_value, r_ty));
721 stack.push(Task::Prune(l_value, l_ty));
722 }
723 },
724 Task::MakeLeft(r_ty) => {
725 let l_value = output.pop().unwrap();
726 output.push(Value::left(l_value, r_ty));
727 }
728 Task::MakeRight(l_ty) => {
729 let r_value = output.pop().unwrap();
730 output.push(Value::right(l_ty, r_value));
731 }
732 Task::MakeProduct => {
733 let r_value = output.pop().unwrap();
734 let l_value = output.pop().unwrap();
735 output.push(Value::product(l_value, r_value));
736 }
737 }
738 }
739
740 debug_assert_eq!(output.len(), 1);
741 output.pop()
742 }
743}
744
745impl fmt::Debug for Value {
746 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
747 f.debug_struct("Value")
748 .field("value", &format_args!("{}", self))
749 .field("ty", &self.ty)
750 .field("raw_value", &self.inner)
751 .field("raw_bit_offset", &self.bit_offset)
752 .finish()
753 }
754}
755
756impl fmt::Display for Value {
757 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
758 enum S<'v> {
761 Disp(ValueRef<'v>),
762 DispCh(char),
763 }
764
765 let mut stack = Vec::with_capacity(1024);
766 stack.push(S::Disp(self.as_ref()));
768
769 'main_loop: while let Some(next) = stack.pop() {
770 let value = match next {
771 S::Disp(ref value) => value,
772 S::DispCh(ch) => {
773 write!(f, "{}", ch)?;
774 continue;
775 }
776 };
777
778 if value.is_unit() {
779 f.write_str("ε")?;
780 } else {
781 for tmr in &Tmr::TWO_TWO_N {
783 if value.ty.tmr() == *tmr {
784 if value.ty.bit_width() < 4 {
785 f.write_str("0b")?;
786 for bit in value.iter_padded() {
787 f.write_str(if bit { "1" } else { "0" })?;
788 }
789 } else {
790 f.write_str("0x")?;
791 let mut iter = value.iter_padded();
794 while let (Some(a), Some(b), Some(c), Some(d)) =
795 (iter.next(), iter.next(), iter.next(), iter.next())
796 {
797 let n = (u8::from(a) << 3)
798 + (u8::from(b) << 2)
799 + (u8::from(c) << 1)
800 + u8::from(d);
801 write!(f, "{:x}", n)?;
802 }
803 }
804 continue 'main_loop;
805 }
806 }
807
808 if let Some(l_value) = value.as_left() {
810 f.write_str("L(")?;
811 stack.push(S::DispCh(')'));
812 stack.push(S::Disp(l_value));
813 } else if let Some(r_value) = value.as_right() {
814 f.write_str("R(")?;
815 stack.push(S::DispCh(')'));
816 stack.push(S::Disp(r_value));
817 } else if let Some((l_value, r_value)) = value.as_product() {
818 stack.push(S::DispCh(')'));
819 stack.push(S::Disp(r_value));
820 stack.push(S::DispCh(','));
821 stack.push(S::Disp(l_value));
822 stack.push(S::DispCh('('));
823 } else {
824 unreachable!()
825 }
826 }
827 }
828 Ok(())
829 }
830}
831
832#[derive(Debug, Clone)]
834pub struct CompactBitsIter<'v> {
835 stack: Vec<ValueRef<'v>>,
836}
837
838impl<'v> CompactBitsIter<'v> {
839 fn new(value: ValueRef<'v>) -> Self {
841 Self { stack: vec![value] }
842 }
843}
844
845impl Iterator for CompactBitsIter<'_> {
846 type Item = bool;
847
848 fn next(&mut self) -> Option<Self::Item> {
849 while let Some(value) = self.stack.pop() {
850 if value.ty.bit_width() == 0 {
851 } else if let Some(l_value) = value.as_left() {
853 self.stack.push(l_value);
854 return Some(false);
855 } else if let Some(r_value) = value.as_right() {
856 self.stack.push(r_value);
857 return Some(true);
858 } else if let Some((l_value, r_value)) = value.as_product() {
859 self.stack.push(r_value);
860 self.stack.push(l_value);
861 }
862 }
863
864 None
865 }
866}
867
868impl Value {
869 pub fn from_compact_bits<I: Iterator<Item = u8>>(
871 bits: &mut BitIter<I>,
872 ty: &Final,
873 ) -> Result<Self, EarlyEndOfStreamError> {
874 enum State<'a> {
875 ProcessType(&'a Final),
876 DoSumL(Arc<Final>),
877 DoSumR(Arc<Final>),
878 DoProduct,
879 }
880
881 let mut stack = vec![State::ProcessType(ty)];
882 let mut result_stack = vec![];
883 while let Some(state) = stack.pop() {
884 match state {
885 State::ProcessType(ty) if ty.has_padding() => match ty.bound() {
886 CompleteBound::Unit => result_stack.push(Value::unit()),
887 CompleteBound::Sum(ref l, ref r) => {
888 if !bits.next().ok_or(EarlyEndOfStreamError)? {
889 stack.push(State::DoSumL(Arc::clone(r)));
890 stack.push(State::ProcessType(l));
891 } else {
892 stack.push(State::DoSumR(Arc::clone(l)));
893 stack.push(State::ProcessType(r));
894 }
895 }
896 CompleteBound::Product(ref l, ref r) => {
897 stack.push(State::DoProduct);
898 stack.push(State::ProcessType(r));
899 stack.push(State::ProcessType(l));
900 }
901 },
902 State::ProcessType(ty) => {
903 result_stack.push(Value::from_padded_bits(bits, ty)?);
905 }
906 State::DoSumL(r) => {
907 let val = result_stack.pop().unwrap();
908 result_stack.push(Value::left(val, r));
909 }
910 State::DoSumR(l) => {
911 let val = result_stack.pop().unwrap();
912 result_stack.push(Value::right(l, val));
913 }
914 State::DoProduct => {
915 let val_r = result_stack.pop().unwrap();
916 let val_l = result_stack.pop().unwrap();
917 result_stack.push(Value::product(val_l, val_r));
918 }
919 }
920 }
921 debug_assert_eq!(result_stack.len(), 1);
922 Ok(result_stack.pop().unwrap())
923 }
924
925 pub fn from_padded_bits<I: Iterator<Item = u8>>(
927 bits: &mut BitIter<I>,
928 ty: &Final,
929 ) -> Result<Self, EarlyEndOfStreamError> {
930 const MAX_INITIAL_ALLOC: usize = 32 * 1024 * 1024; let cap = cmp::min(MAX_INITIAL_ALLOC, ty.bit_width().div_ceil(8));
933 let mut blob = Vec::with_capacity(cap);
934 for _ in 0..ty.bit_width() / 8 {
935 blob.push(bits.read_u8()?);
936 }
937 let mut last = 0u8;
938 for i in 0..ty.bit_width() % 8 {
939 if bits.read_bit()? {
940 last |= 1 << (7 - i);
941 }
942 }
943 blob.push(last);
944
945 Ok(Value {
946 inner: blob.into(),
947 bit_offset: 0,
948 ty: Arc::new(ty.clone()),
949 })
950 }
951}
952
953#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
955pub struct Word {
956 value: Value,
958 n: u32,
960}
961
962macro_rules! construct_word_fallible {
963 ($name: ident, $n: expr, $text: expr) => {
964 #[doc = "Create"]
965 #[doc = $text]
966 #[doc = "word.\n\n"]
967 #[doc = "## Panics\n"]
968 #[doc = "The value is ouf of range."]
969 pub fn $name(bit: u8) -> Self {
970 Self {
971 value: Value::$name(bit),
972 n: $n,
973 }
974 }
975 };
976}
977
978macro_rules! construct_word {
979 ($name: ident, $ty: ty, $n: expr, $text: expr) => {
980 #[doc = "Create"]
981 #[doc = $text]
982 #[doc = "word."]
983 pub fn $name(bit: $ty) -> Self {
984 Self {
985 value: Value::$name(bit),
986 n: $n,
987 }
988 }
989 };
990}
991
992impl Word {
993 pub fn product(self, right: Self) -> Option<Self> {
1003 if self.n == right.n && self.n < 30 {
1004 Some(Self {
1005 value: Value::product(self.value, right.value),
1006 n: self.n + 1,
1007 })
1008 } else {
1009 None
1010 }
1011 }
1012
1013 construct_word_fallible!(u1, 0, "a 1-bit");
1014 construct_word_fallible!(u2, 1, "a 2-bit");
1015 construct_word_fallible!(u4, 2, "a 4-bit");
1016 construct_word!(u8, u8, 3, "an 8-bit");
1017 construct_word!(u16, u16, 4, "a 16-bit");
1018 construct_word!(u32, u32, 5, "a 32-bit");
1019 construct_word!(u64, u64, 6, "a 64-bit");
1020 construct_word!(u128, u128, 7, "a 128-bit");
1021 construct_word!(u256, [u8; 32], 8, "a 256-bit");
1022 construct_word!(u512, [u8; 64], 9, "a 512-bit");
1023
1024 pub fn shallow_clone(&self) -> Self {
1026 Self {
1027 value: self.value.shallow_clone(),
1028 n: self.n,
1029 }
1030 }
1031
1032 pub fn as_value(&self) -> &Value {
1034 &self.value
1035 }
1036
1037 pub fn n(&self) -> u32 {
1039 self.n
1040 }
1041
1042 #[allow(clippy::len_without_is_empty)]
1046 pub fn len(&self) -> usize {
1047 2usize.pow(self.n)
1048 }
1049
1050 pub fn iter(&self) -> impl Iterator<Item = bool> + '_ {
1055 self.value.iter_compact()
1056 }
1057
1058 pub fn from_bits<I: Iterator<Item = u8>>(
1064 bits: &mut BitIter<I>,
1065 n: u32,
1066 ) -> Result<Self, EarlyEndOfStreamError> {
1067 assert!(n < 32, "TWO^(2^{n}) is not supported as a word type");
1068 let ty = Final::two_two_n(n as usize); let value = Value::from_compact_bits(bits, &ty)?;
1070 Ok(Self { value, n })
1071 }
1072}
1073
1074impl fmt::Debug for Word {
1075 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1076 fmt::Display::fmt(self, f)
1077 }
1078}
1079
1080impl fmt::Display for Word {
1081 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1082 use hex::DisplayHex;
1083
1084 if let Ok(hex) = self.iter().try_collect_bytes() {
1085 write!(f, "0x{}", hex.as_hex())
1086 } else {
1087 f.write_str("0b")?;
1088 for bit in self.iter() {
1089 match bit {
1090 false => f.write_str("0")?,
1091 true => f.write_str("1")?,
1092 }
1093 }
1094 Ok(())
1095 }
1096 }
1097}
1098
1099#[cfg(test)]
1100mod tests {
1101 use super::*;
1102 use crate::bit_encoding::{BitCollector as _, BitIter};
1103 use crate::jet::type_name::TypeName;
1104
1105 #[test]
1106 fn value_len() {
1107 let v = Value::u4(6);
1108 let s_v = Value::some(v.shallow_clone());
1109 let n_v = Value::none(Final::two_two_n(2));
1110
1111 assert_eq!(v.compact_len(), 4);
1112 assert_eq!(v.padded_len(), 4);
1113 assert_eq!(s_v.compact_len(), 5);
1114 assert_eq!(s_v.padded_len(), 5);
1115 assert_eq!(n_v.compact_len(), 1);
1116 assert_eq!(n_v.padded_len(), 5);
1117 }
1118
1119 #[test]
1120 fn value_display() {
1121 assert_eq!(Value::u1(0).to_string(), "0b0",);
1124 assert_eq!(Value::u1(1).to_string(), "0b1",);
1125 assert_eq!(Value::u4(6).to_string(), "0x6",);
1126 }
1127
1128 #[test]
1129 fn is_of_type() {
1130 let value_typename = [
1131 (Value::unit(), TypeName(b"1")),
1132 (Value::left(Value::unit(), Final::unit()), TypeName(b"+11")),
1133 (Value::right(Final::unit(), Value::unit()), TypeName(b"+11")),
1134 (
1135 Value::left(Value::unit(), Final::two_two_n(8)),
1136 TypeName(b"+1h"),
1137 ),
1138 (
1139 Value::right(Final::two_two_n(8), Value::unit()),
1140 TypeName(b"+h1"),
1141 ),
1142 (
1143 Value::product(Value::unit(), Value::unit()),
1144 TypeName(b"*11"),
1145 ),
1146 (Value::u8(u8::MAX), TypeName(b"c")),
1147 (Value::u64(u64::MAX), TypeName(b"l")),
1148 ];
1149
1150 for (value, typename) in value_typename {
1151 let ty = typename.to_final();
1152 assert!(value.is_of_type(ty.as_ref()));
1153 }
1154 }
1155
1156 #[test]
1157 fn prune_regression_1() {
1158 let nontrivial_sum = Value::product(
1160 Value::right(Final::two_two_n(4), Value::u16(0)),
1161 Value::u8(0),
1162 );
1163 let _ = format!("{nontrivial_sum}");
1165 assert_eq!(
1167 nontrivial_sum.prune(nontrivial_sum.ty()),
1168 Some(nontrivial_sum)
1169 );
1170 }
1171
1172 #[test]
1173 fn prune() {
1174 let test_vectors = [
1175 (Value::unit(), Value::unit()),
1176 (Value::u64(42), Value::unit()),
1177 (
1178 Value::left(Value::u64(42), Final::u64()),
1179 Value::left(Value::u64(42), Final::unit()),
1180 ),
1181 (
1182 Value::right(Final::u64(), Value::u64(1337)),
1183 Value::right(Final::unit(), Value::u64(1337)),
1184 ),
1185 (
1186 Value::product(Value::u64(42), Value::u64(1337)),
1187 Value::product(Value::u64(42), Value::unit()),
1188 ),
1189 (
1190 Value::product(Value::u64(42), Value::u64(1337)),
1191 Value::product(Value::unit(), Value::u64(1337)),
1192 ),
1193 ];
1194
1195 for (value, expected_pruned_value) in test_vectors {
1196 assert_eq!(
1197 value.prune(expected_pruned_value.ty()),
1198 Some(expected_pruned_value)
1199 );
1200 }
1201
1202 let bad_test_vectors = [
1203 (Value::unit(), Final::u1()),
1204 (
1205 Value::product(Value::unit(), Value::unit()),
1206 Final::sum(Final::unit(), Final::unit()),
1207 ),
1208 (
1209 Value::left(Value::unit(), Final::unit()),
1210 Final::product(Final::unit(), Final::unit()),
1211 ),
1212 (
1213 Value::right(Final::unit(), Value::unit()),
1214 Final::product(Final::unit(), Final::unit()),
1215 ),
1216 ];
1217
1218 for (value, pruned_ty) in bad_test_vectors {
1219 assert_eq!(value.prune(&pruned_ty), None);
1220 }
1221 }
1222
1223 #[test]
1224 fn zero_value() {
1225 let test_vectors = [
1226 (Final::unit(), Value::unit()),
1227 (Final::u8(), Value::u8(0)),
1228 (Final::u64(), Value::u64(0)),
1229 (
1230 Final::product(Final::u16(), Final::u32()),
1231 Value::product(Value::u16(0), Value::u32(0)),
1232 ),
1233 (
1234 Final::sum(Final::unit(), Final::u64()),
1235 Value::left(Value::unit(), Final::u64()),
1236 ),
1237 (
1238 Final::product(Final::unit(), Final::unit()),
1239 Value::product(Value::unit(), Value::unit()),
1240 ),
1241 ];
1242
1243 for (ty, expected_default_value) in test_vectors {
1244 assert_eq!(Value::zero(&ty), expected_default_value);
1245 }
1246 }
1247
1248 #[test]
1249 fn compact_round_trip() {
1250 let v = Value::u64(0xff00_00ff_ff00_00ff);
1251 let (bits, _) = v.iter_compact().collect_bits();
1252 let mut iter = BitIter::new(bits.into_iter());
1253 let new_v = Value::from_compact_bits(&mut iter, &v.ty).unwrap();
1254 assert_eq!(v, new_v);
1255 }
1256
1257 #[test]
1258 fn padded_round_trip() {
1259 let v = Value::u64(0xff00_00ff_ff00_00ff);
1260 let (bits, _) = v.iter_padded().collect_bits();
1261 let mut iter = BitIter::new(bits.into_iter());
1262 let new_v = Value::from_padded_bits(&mut iter, &v.ty).unwrap();
1263 assert_eq!(v, new_v);
1264 }
1265}
1266
1267#[cfg(bench)]
1268mod benches {
1269 use super::*;
1270
1271 use crate::bit_encoding::{BitCollector as _, BitIter};
1272
1273 use test::{black_box, Bencher};
1274
1275 #[bench]
1277 fn bench_value_create_u64(bh: &mut Bencher) {
1278 bh.iter(|| black_box(Value::u64(0xff00_00ff_ff00_00ff)))
1279 }
1280
1281 #[bench]
1282 fn bench_value_create_u2048(bh: &mut Bencher) {
1283 bh.iter(|| black_box(Value::from_byte_array([0xcd; 2048])));
1284 }
1285
1286 #[bench]
1287 fn bench_value_create_deep_some(bh: &mut Bencher) {
1288 bh.iter(|| {
1289 let mut kilo = Value::from_byte_array([0xab; 1024]);
1290 for _ in 0..1000 {
1291 kilo = Value::some(kilo.shallow_clone());
1292 }
1293 black_box(kilo)
1294 });
1295 }
1296
1297 #[bench]
1298 fn bench_value_create_64k(bh: &mut Bencher) {
1299 bh.iter(|| {
1300 let mut kilo = Value::from_byte_array([0xab; 1024]);
1301 for _ in 0..5 {
1302 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1303 }
1304 black_box(kilo)
1305 });
1306 }
1307
1308 #[bench]
1309 fn bench_value_create_512_256(bh: &mut Bencher) {
1310 bh.iter(|| {
1311 let mut s512_256 = Value::product(
1320 Value::from_byte_array([0x12; 64]),
1321 Value::from_byte_array([0x23; 32]),
1322 );
1323 for _ in 0..5 {
1324 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1325 }
1326 black_box(s512_256);
1327 });
1328 }
1329
1330 fn padded_bits(v: &Value) -> (Vec<u8>, &Final) {
1332 let (bits, _) = v.iter_padded().collect_bits();
1333 (bits, v.ty.as_ref())
1334 }
1335
1336 #[bench]
1337 fn bench_value_create_u64_padded(bh: &mut Bencher) {
1338 let v = Value::u64(0xff00_00ff_ff00_00ff);
1339 let (bits, ty) = padded_bits(&v);
1340 bh.iter(|| {
1341 black_box(Value::from_padded_bits(
1342 &mut BitIter::new(bits.iter().copied()),
1343 ty,
1344 ))
1345 })
1346 }
1347
1348 #[bench]
1349 fn bench_value_create_u2048_padded(bh: &mut Bencher) {
1350 let v = Value::from_byte_array([0xcd; 2048]);
1351 let (bits, ty) = padded_bits(&v);
1352 bh.iter(|| {
1353 black_box(Value::from_padded_bits(
1354 &mut BitIter::new(bits.iter().copied()),
1355 ty,
1356 ))
1357 })
1358 }
1359
1360 #[bench]
1361 fn bench_value_create_deep_some_padded(bh: &mut Bencher) {
1362 let mut kilo = Value::from_byte_array([0xab; 1024]);
1363 for _ in 0..1000 {
1364 kilo = Value::some(kilo.shallow_clone());
1365 }
1366 let (bits, ty) = padded_bits(&kilo);
1367 bh.iter(|| {
1368 black_box(Value::from_padded_bits(
1369 &mut BitIter::new(bits.iter().copied()),
1370 ty,
1371 ))
1372 })
1373 }
1374
1375 #[bench]
1376 fn bench_value_create_64k_padded(bh: &mut Bencher) {
1377 let mut kilo = Value::from_byte_array([0xab; 1024]);
1378 for _ in 0..5 {
1379 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1380 }
1381 let (bits, ty) = padded_bits(&kilo);
1382 bh.iter(|| {
1383 black_box(Value::from_padded_bits(
1384 &mut BitIter::new(bits.iter().copied()),
1385 ty,
1386 ))
1387 })
1388 }
1389
1390 #[bench]
1391 fn bench_value_create_512_256_padded(bh: &mut Bencher) {
1392 let mut s512_256 = Value::product(
1394 Value::from_byte_array([0x12; 64]),
1395 Value::from_byte_array([0x23; 32]),
1396 );
1397 for _ in 0..5 {
1398 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1399 }
1400 let (bits, ty) = padded_bits(&s512_256);
1401 bh.iter(|| {
1402 black_box(Value::from_padded_bits(
1403 &mut BitIter::new(bits.iter().copied()),
1404 ty,
1405 ))
1406 })
1407 }
1408
1409 fn compact_bits(v: &Value) -> (Vec<u8>, &Final) {
1411 let (bits, _) = v.iter_compact().collect_bits();
1412 (bits, v.ty.as_ref())
1413 }
1414
1415 #[bench]
1416 fn bench_value_create_u64_compact(bh: &mut Bencher) {
1417 let v = Value::u64(0xff00_00ff_ff00_00ff);
1418 let (bits, ty) = compact_bits(&v);
1419 bh.iter(|| {
1420 black_box(Value::from_compact_bits(
1421 &mut BitIter::new(bits.iter().copied()),
1422 ty,
1423 ))
1424 })
1425 }
1426
1427 #[bench]
1428 fn bench_value_create_u2048_compact(bh: &mut Bencher) {
1429 let v = Value::from_byte_array([0xcd; 2048]);
1430 let (bits, ty) = compact_bits(&v);
1431 bh.iter(|| {
1432 black_box(Value::from_compact_bits(
1433 &mut BitIter::new(bits.iter().copied()),
1434 ty,
1435 ))
1436 })
1437 }
1438
1439 #[bench]
1440 fn bench_value_create_deep_some_compact(bh: &mut Bencher) {
1441 let mut kilo = Value::from_byte_array([0xab; 1024]);
1442 for _ in 0..1000 {
1443 kilo = Value::some(kilo.shallow_clone());
1444 }
1445 let (bits, ty) = compact_bits(&kilo);
1446 bh.iter(|| {
1447 black_box(Value::from_compact_bits(
1448 &mut BitIter::new(bits.iter().copied()),
1449 ty,
1450 ))
1451 })
1452 }
1453
1454 #[bench]
1455 fn bench_value_create_64k_compact(bh: &mut Bencher) {
1456 let mut kilo = Value::from_byte_array([0xab; 1024]);
1457 for _ in 0..5 {
1458 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1459 }
1460 let (bits, ty) = compact_bits(&kilo);
1461 bh.iter(|| {
1462 black_box(Value::from_compact_bits(
1463 &mut BitIter::new(bits.iter().copied()),
1464 ty,
1465 ))
1466 })
1467 }
1468
1469 #[bench]
1470 fn bench_value_create_512_256_compact(bh: &mut Bencher) {
1471 let mut s512_256 = Value::product(
1473 Value::from_byte_array([0x12; 64]),
1474 Value::from_byte_array([0x23; 32]),
1475 );
1476 for _ in 0..5 {
1477 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1478 }
1479 let (bits, ty) = compact_bits(&s512_256);
1480 bh.iter(|| {
1481 black_box(Value::from_compact_bits(
1482 &mut BitIter::new(bits.iter().copied()),
1483 ty,
1484 ))
1485 })
1486 }
1487
1488 #[bench]
1490 fn bench_value_display_u64(bh: &mut Bencher) {
1491 let v = Value::u64(0xff00_00ff_ff00_00ff);
1492 bh.iter(|| black_box(format!("{}", v)))
1493 }
1494
1495 #[bench]
1496 fn bench_value_display_u2024(bh: &mut Bencher) {
1497 let v = Value::from_byte_array([0xcd; 2048]);
1498 bh.iter(|| black_box(format!("{}", v)))
1499 }
1500
1501 #[bench]
1502 fn bench_value_display_deep_some(bh: &mut Bencher) {
1503 let mut kilo = Value::from_byte_array([0xab; 1024]);
1504 for _ in 0..1000 {
1505 kilo = Value::some(kilo.shallow_clone());
1506 }
1507 bh.iter(|| black_box(format!("{}", kilo)))
1508 }
1509
1510 #[bench]
1511 fn bench_value_display_64k(bh: &mut Bencher) {
1512 let mut kilo = Value::from_byte_array([0xab; 1024]);
1513 for _ in 0..5 {
1514 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1515 }
1516 bh.iter(|| black_box(format!("{}", kilo)))
1517 }
1518
1519 #[bench]
1520 fn bench_value_display_512_256(bh: &mut Bencher) {
1521 let mut s512_256 = Value::product(
1523 Value::from_byte_array([0x12; 64]),
1524 Value::from_byte_array([0x23; 32]),
1525 );
1526 for _ in 0..5 {
1527 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1528 }
1529 bh.iter(|| black_box(format!("{}", s512_256)))
1530 }
1531
1532 }