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 let new_bit_offset = bit_offset - 1;
280 let mask = 1u8 << (7 - new_bit_offset % 8);
281 let current_bit = inner[new_bit_offset / 8] & mask != 0;
282 if current_bit == new_bit {
283 (Arc::clone(inner), new_bit_offset)
284 } else if new_bit {
285 let mut bx: Box<[u8]> = inner.as_ref().into();
286 bx[new_bit_offset / 8] |= mask;
287 (bx.into(), new_bit_offset)
288 } else {
289 let mut bx: Box<[u8]> = inner.as_ref().into();
290 bx[new_bit_offset / 8] &= !mask;
291 (bx.into(), new_bit_offset)
292 }
293 } else {
294 let mut new = Vec::with_capacity(inner.len() + 1);
298 new.push(u8::from(new_bit));
299 new.extend(inner.iter().copied());
300 (new.into(), 7)
301 }
302}
303
304fn copy_bits(src: &[u8], src_offset: usize, dst: &mut [u8], dst_offset: usize, nbits: usize) {
309 for i in 0..nbits {
312 let bit = (src[(src_offset + i) / 8] >> (7 - (src_offset + i) % 8)) & 1;
313 dst[(dst_offset + i) / 8] |= bit << (7 - (dst_offset + i) % 8);
314 }
315}
316
317fn product(
324 left: Option<(&Arc<[u8]>, usize)>,
325 left_bit_length: usize,
326 right: Option<(&Arc<[u8]>, usize)>,
327 right_bit_length: usize,
328) -> (Arc<[u8]>, usize) {
329 if left_bit_length == 0 {
330 if let Some((right, right_bit_offset)) = right {
331 (Arc::clone(right), right_bit_offset)
332 } else if right_bit_length == 0 {
333 (Arc::new([]), 0)
334 } else {
335 (Arc::from(vec![0; right_bit_length.div_ceil(8)]), 0)
336 }
337 } else if right_bit_length == 0 {
338 if let Some((lt, left_bit_offset)) = left {
339 (Arc::clone(lt), left_bit_offset)
340 } else {
341 (Arc::from(vec![0; left_bit_length.div_ceil(8)]), 0)
342 }
343 } else {
344 let mut bx = Box::<[u8]>::from(vec![0; (left_bit_length + right_bit_length).div_ceil(8)]);
348 if let Some((left, left_bit_offset)) = left {
349 copy_bits(left, left_bit_offset, &mut bx, 0, left_bit_length);
350 }
351 if let Some((right, right_bit_offset)) = right {
352 copy_bits(
353 right,
354 right_bit_offset,
355 &mut bx,
356 left_bit_length,
357 right_bit_length,
358 );
359 }
360
361 (bx.into(), 0)
362 }
363}
364
365impl Value {
366 pub fn shallow_clone(&self) -> Self {
368 Self {
369 inner: Arc::clone(&self.inner),
370 bit_offset: self.bit_offset,
371 ty: Arc::clone(&self.ty),
372 }
373 }
374
375 pub fn ty(&self) -> &Final {
377 &self.ty
378 }
379
380 pub fn unit() -> Self {
382 Self {
383 inner: Arc::new([]),
384 bit_offset: 0,
385 ty: Final::unit(),
386 }
387 }
388
389 pub fn left(inner: Self, right: Arc<Final>) -> Self {
391 let total_width = cmp::max(inner.ty.bit_width(), right.bit_width());
392
393 let (concat, concat_offset) = product(
394 None,
395 total_width - inner.ty.bit_width(),
396 Some((&inner.inner, inner.bit_offset)),
397 inner.ty.bit_width(),
398 );
399 let (new_inner, new_bit_offset) = right_shift_1(&concat, concat_offset, false);
400 Self {
401 inner: new_inner,
402 bit_offset: new_bit_offset,
403 ty: Final::sum(Arc::clone(&inner.ty), right),
404 }
405 }
406
407 pub fn right(left: Arc<Final>, inner: Self) -> Self {
409 let total_width = cmp::max(left.bit_width(), inner.ty.bit_width());
410 let (concat, concat_offset) = product(
411 None,
412 total_width - inner.ty.bit_width(),
413 Some((&inner.inner, inner.bit_offset)),
414 inner.ty.bit_width(),
415 );
416 let (new_inner, new_bit_offset) = right_shift_1(&concat, concat_offset, true);
417 Self {
418 inner: new_inner,
419 bit_offset: new_bit_offset,
420 ty: Final::sum(left, Arc::clone(&inner.ty)),
421 }
422 }
423
424 pub fn product(left: Self, right: Self) -> Self {
426 let (new_inner, new_bit_offset) = product(
427 Some((&left.inner, left.bit_offset)),
428 left.ty.bit_width(),
429 Some((&right.inner, right.bit_offset)),
430 right.ty.bit_width(),
431 );
432 Self {
433 inner: new_inner,
434 bit_offset: new_bit_offset,
435 ty: Final::product(Arc::clone(&left.ty), Arc::clone(&right.ty)),
436 }
437 }
438
439 pub fn none(right: Arc<Final>) -> Self {
441 Self::left(Value::unit(), right)
442 }
443
444 pub fn some(inner: Self) -> Self {
446 Self::right(Final::unit(), inner)
447 }
448
449 pub fn compact_len(&self) -> usize {
451 self.iter_compact().count()
452 }
453
454 pub fn padded_len(&self) -> usize {
456 self.ty.bit_width()
457 }
458
459 pub fn is_empty(&self) -> bool {
462 self.ty.bit_width() == 0
463 }
464
465 pub fn is_unit(&self) -> bool {
467 self.ty.is_unit()
468 }
469
470 pub fn as_ref(&self) -> ValueRef<'_> {
472 ValueRef {
473 inner: &self.inner,
474 bit_offset: self.bit_offset,
475 ty: &self.ty,
476 }
477 }
478
479 pub fn as_left(&self) -> Option<ValueRef<'_>> {
481 self.as_ref().as_left()
482 }
483
484 pub fn as_right(&self) -> Option<ValueRef<'_>> {
486 self.as_ref().as_right()
487 }
488
489 pub fn as_product(&self) -> Option<(ValueRef<'_>, ValueRef<'_>)> {
491 self.as_ref().as_product()
492 }
493
494 pub fn u1(value: u8) -> Self {
500 assert!(value <= 1, "{} out of range for Value::u1", value);
501 Self {
502 inner: Arc::new([value]),
503 bit_offset: 7,
504 ty: Final::two_two_n(0),
505 }
506 }
507
508 pub fn u2(value: u8) -> Self {
514 assert!(value <= 3, "{} out of range for Value::u2", value);
515 Self {
516 inner: Arc::new([value]),
517 bit_offset: 6,
518 ty: Final::two_two_n(1),
519 }
520 }
521
522 pub fn u4(value: u8) -> Self {
528 assert!(value <= 15, "{} out of range for Value::u2", value);
529 Self {
530 inner: Arc::new([value]),
531 bit_offset: 4,
532 ty: Final::two_two_n(2),
533 }
534 }
535
536 pub fn u8(value: u8) -> Self {
538 Self {
539 inner: Arc::new([value]),
540 bit_offset: 0,
541 ty: Final::two_two_n(3),
542 }
543 }
544
545 pub fn u16(bytes: u16) -> Self {
547 Self {
548 inner: Arc::new(bytes.to_be_bytes()),
549 bit_offset: 0,
550 ty: Final::two_two_n(4),
551 }
552 }
553
554 pub fn u32(bytes: u32) -> Self {
556 Self {
557 inner: Arc::new(bytes.to_be_bytes()),
558 bit_offset: 0,
559 ty: Final::two_two_n(5),
560 }
561 }
562
563 pub fn u64(bytes: u64) -> Self {
565 Self {
566 inner: Arc::new(bytes.to_be_bytes()),
567 bit_offset: 0,
568 ty: Final::two_two_n(6),
569 }
570 }
571
572 pub fn u128(bytes: u128) -> Self {
574 Self {
575 inner: Arc::new(bytes.to_be_bytes()),
576 bit_offset: 0,
577 ty: Final::two_two_n(7),
578 }
579 }
580
581 pub fn u256(bytes: [u8; 32]) -> Self {
583 Self {
584 inner: Arc::new(bytes),
585 bit_offset: 0,
586 ty: Final::two_two_n(8),
587 }
588 }
589
590 pub fn u512(bytes: [u8; 64]) -> Self {
592 Self {
593 inner: Arc::new(bytes),
594 bit_offset: 0,
595 ty: Final::two_two_n(9),
596 }
597 }
598
599 pub fn from_byte_array<const N: usize>(bytes: [u8; N]) -> Self {
605 assert!(N.is_power_of_two(), "Array length must be a power of two");
606 let mut values: VecDeque<_> = bytes.into_iter().map(Value::u8).collect();
607
608 while values.len() > 1 {
609 let mut alt_values = VecDeque::with_capacity(values.len() / 2);
610
611 while let (Some(left), Some(right)) = (values.pop_front(), values.pop_front()) {
612 alt_values.push_back(Value::product(left, right));
613 }
614
615 values = alt_values;
616 }
617
618 values.into_iter().next().unwrap()
619 }
620
621 pub fn raw_byte_iter(&self) -> RawByteIter<'_> {
627 self.as_ref().raw_byte_iter()
628 }
629
630 pub fn iter_compact(&self) -> CompactBitsIter<'_> {
634 self.as_ref().iter_compact()
635 }
636
637 pub fn iter_padded(&self) -> PreOrderIter<'_> {
641 self.as_ref().iter_padded()
642 }
643
644 pub fn is_of_type(&self, ty: &Final) -> bool {
646 self.ty.as_ref() == ty
647 }
648
649 pub fn zero(ty: &Final) -> Self {
659 Self {
660 inner: Arc::from(vec![0; ty.bit_width().div_ceil(8)]),
661 bit_offset: 0,
662 ty: Arc::new(ty.clone()),
663 }
664 }
665
666 pub fn to_word(&self) -> Option<Word> {
670 self.ty.as_word().map(|n| Word {
671 value: self.shallow_clone(),
672 n,
673 })
674 }
675
676 pub fn prune(&self, pruned_ty: &Final) -> Option<Self> {
695 enum Task<'v, 'ty> {
696 Prune(ValueRef<'v>, &'ty Final),
697 MakeLeft(Arc<Final>),
698 MakeRight(Arc<Final>),
699 MakeProduct,
700 }
701
702 let mut stack = vec![Task::Prune(self.as_ref(), pruned_ty)];
703 let mut output = vec![];
704
705 while let Some(task) = stack.pop() {
706 match task {
707 Task::Prune(value, pruned_ty) if value.ty.as_ref() == pruned_ty => {
708 output.push(value.to_value())
709 }
710 Task::Prune(value, pruned_ty) => match pruned_ty.bound() {
711 CompleteBound::Unit => output.push(Value::unit()),
712 CompleteBound::Sum(l_ty, r_ty) => {
713 if let Some(l_value) = value.as_left() {
714 stack.push(Task::MakeLeft(Arc::clone(r_ty)));
715 stack.push(Task::Prune(l_value, l_ty));
716 } else {
717 let r_value = value.as_right()?;
718 stack.push(Task::MakeRight(Arc::clone(l_ty)));
719 stack.push(Task::Prune(r_value, r_ty));
720 }
721 }
722 CompleteBound::Product(l_ty, r_ty) => {
723 let (l_value, r_value) = value.as_product()?;
724 stack.push(Task::MakeProduct);
725 stack.push(Task::Prune(r_value, r_ty));
726 stack.push(Task::Prune(l_value, l_ty));
727 }
728 },
729 Task::MakeLeft(r_ty) => {
730 let l_value = output.pop().unwrap();
731 output.push(Value::left(l_value, r_ty));
732 }
733 Task::MakeRight(l_ty) => {
734 let r_value = output.pop().unwrap();
735 output.push(Value::right(l_ty, r_value));
736 }
737 Task::MakeProduct => {
738 let r_value = output.pop().unwrap();
739 let l_value = output.pop().unwrap();
740 output.push(Value::product(l_value, r_value));
741 }
742 }
743 }
744
745 debug_assert_eq!(output.len(), 1);
746 output.pop()
747 }
748}
749
750impl fmt::Debug for Value {
751 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
752 f.debug_struct("Value")
753 .field("value", &format_args!("{}", self))
754 .field("ty", &self.ty)
755 .field("raw_value", &self.inner)
756 .field("raw_bit_offset", &self.bit_offset)
757 .finish()
758 }
759}
760
761impl fmt::Display for Value {
762 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
763 enum S<'v> {
766 Disp(ValueRef<'v>),
767 DispCh(char),
768 }
769
770 let mut stack = Vec::with_capacity(1024);
771 stack.push(S::Disp(self.as_ref()));
773
774 'main_loop: while let Some(next) = stack.pop() {
775 let value = match next {
776 S::Disp(ref value) => value,
777 S::DispCh(ch) => {
778 write!(f, "{}", ch)?;
779 continue;
780 }
781 };
782
783 if value.is_unit() {
784 f.write_str("ε")?;
785 } else {
786 for tmr in &Tmr::TWO_TWO_N {
788 if value.ty.tmr() == *tmr {
789 if value.ty.bit_width() < 4 {
790 f.write_str("0b")?;
791 for bit in value.iter_padded() {
792 f.write_str(if bit { "1" } else { "0" })?;
793 }
794 } else {
795 f.write_str("0x")?;
796 let mut iter = value.iter_padded();
799 while let (Some(a), Some(b), Some(c), Some(d)) =
800 (iter.next(), iter.next(), iter.next(), iter.next())
801 {
802 let n = (u8::from(a) << 3)
803 + (u8::from(b) << 2)
804 + (u8::from(c) << 1)
805 + u8::from(d);
806 write!(f, "{:x}", n)?;
807 }
808 }
809 continue 'main_loop;
810 }
811 }
812
813 if let Some(l_value) = value.as_left() {
815 f.write_str("L(")?;
816 stack.push(S::DispCh(')'));
817 stack.push(S::Disp(l_value));
818 } else if let Some(r_value) = value.as_right() {
819 f.write_str("R(")?;
820 stack.push(S::DispCh(')'));
821 stack.push(S::Disp(r_value));
822 } else if let Some((l_value, r_value)) = value.as_product() {
823 stack.push(S::DispCh(')'));
824 stack.push(S::Disp(r_value));
825 stack.push(S::DispCh(','));
826 stack.push(S::Disp(l_value));
827 stack.push(S::DispCh('('));
828 } else {
829 unreachable!()
830 }
831 }
832 }
833 Ok(())
834 }
835}
836
837#[derive(Debug, Clone)]
839pub struct CompactBitsIter<'v> {
840 stack: Vec<ValueRef<'v>>,
841}
842
843impl<'v> CompactBitsIter<'v> {
844 fn new(value: ValueRef<'v>) -> Self {
846 Self { stack: vec![value] }
847 }
848}
849
850impl Iterator for CompactBitsIter<'_> {
851 type Item = bool;
852
853 fn next(&mut self) -> Option<Self::Item> {
854 while let Some(value) = self.stack.pop() {
855 if value.ty.bit_width() == 0 {
856 } else if let Some(l_value) = value.as_left() {
858 self.stack.push(l_value);
859 return Some(false);
860 } else if let Some(r_value) = value.as_right() {
861 self.stack.push(r_value);
862 return Some(true);
863 } else if let Some((l_value, r_value)) = value.as_product() {
864 self.stack.push(r_value);
865 self.stack.push(l_value);
866 }
867 }
868
869 None
870 }
871}
872
873impl Value {
874 pub fn from_compact_bits<I: Iterator<Item = u8>>(
876 bits: &mut BitIter<I>,
877 ty: &Final,
878 ) -> Result<Self, EarlyEndOfStreamError> {
879 enum State<'a> {
880 ProcessType(&'a Final),
881 DoSumL(Arc<Final>),
882 DoSumR(Arc<Final>),
883 DoProduct,
884 }
885
886 let mut stack = vec![State::ProcessType(ty)];
887 let mut result_stack = vec![];
888 while let Some(state) = stack.pop() {
889 match state {
890 State::ProcessType(ty) if ty.has_padding() => match ty.bound() {
891 CompleteBound::Unit => result_stack.push(Value::unit()),
892 CompleteBound::Sum(ref l, ref r) => {
893 if !bits.next().ok_or(EarlyEndOfStreamError)? {
894 stack.push(State::DoSumL(Arc::clone(r)));
895 stack.push(State::ProcessType(l));
896 } else {
897 stack.push(State::DoSumR(Arc::clone(l)));
898 stack.push(State::ProcessType(r));
899 }
900 }
901 CompleteBound::Product(ref l, ref r) => {
902 stack.push(State::DoProduct);
903 stack.push(State::ProcessType(r));
904 stack.push(State::ProcessType(l));
905 }
906 },
907 State::ProcessType(ty) => {
908 result_stack.push(Value::from_padded_bits(bits, ty)?);
910 }
911 State::DoSumL(r) => {
912 let val = result_stack.pop().unwrap();
913 result_stack.push(Value::left(val, r));
914 }
915 State::DoSumR(l) => {
916 let val = result_stack.pop().unwrap();
917 result_stack.push(Value::right(l, val));
918 }
919 State::DoProduct => {
920 let val_r = result_stack.pop().unwrap();
921 let val_l = result_stack.pop().unwrap();
922 result_stack.push(Value::product(val_l, val_r));
923 }
924 }
925 }
926 debug_assert_eq!(result_stack.len(), 1);
927 Ok(result_stack.pop().unwrap())
928 }
929
930 pub fn from_padded_bits<I: Iterator<Item = u8>>(
932 bits: &mut BitIter<I>,
933 ty: &Final,
934 ) -> Result<Self, EarlyEndOfStreamError> {
935 const MAX_INITIAL_ALLOC: usize = 32 * 1024 * 1024; let cap = cmp::min(MAX_INITIAL_ALLOC, ty.bit_width().div_ceil(8));
938 let mut blob = Vec::with_capacity(cap);
939 for _ in 0..ty.bit_width() / 8 {
940 blob.push(bits.read_u8()?);
941 }
942 let mut last = 0u8;
943 for i in 0..ty.bit_width() % 8 {
944 if bits.read_bit()? {
945 last |= 1 << (7 - i);
946 }
947 }
948 blob.push(last);
949
950 Ok(Value {
951 inner: blob.into(),
952 bit_offset: 0,
953 ty: Arc::new(ty.clone()),
954 })
955 }
956}
957
958#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
960pub struct Word {
961 value: Value,
963 n: u32,
965}
966
967macro_rules! construct_word_fallible {
968 ($name: ident, $n: expr, $text: expr) => {
969 #[doc = "Create"]
970 #[doc = $text]
971 #[doc = "word.\n\n"]
972 #[doc = "## Panics\n"]
973 #[doc = "The value is ouf of range."]
974 pub fn $name(bit: u8) -> Self {
975 Self {
976 value: Value::$name(bit),
977 n: $n,
978 }
979 }
980 };
981}
982
983macro_rules! construct_word {
984 ($name: ident, $ty: ty, $n: expr, $text: expr) => {
985 #[doc = "Create"]
986 #[doc = $text]
987 #[doc = "word."]
988 pub fn $name(bit: $ty) -> Self {
989 Self {
990 value: Value::$name(bit),
991 n: $n,
992 }
993 }
994 };
995}
996
997impl Word {
998 pub fn product(self, right: Self) -> Option<Self> {
1008 if self.n == right.n && self.n < 30 {
1009 Some(Self {
1010 value: Value::product(self.value, right.value),
1011 n: self.n + 1,
1012 })
1013 } else {
1014 None
1015 }
1016 }
1017
1018 construct_word_fallible!(u1, 0, "a 1-bit");
1019 construct_word_fallible!(u2, 1, "a 2-bit");
1020 construct_word_fallible!(u4, 2, "a 4-bit");
1021 construct_word!(u8, u8, 3, "an 8-bit");
1022 construct_word!(u16, u16, 4, "a 16-bit");
1023 construct_word!(u32, u32, 5, "a 32-bit");
1024 construct_word!(u64, u64, 6, "a 64-bit");
1025 construct_word!(u128, u128, 7, "a 128-bit");
1026 construct_word!(u256, [u8; 32], 8, "a 256-bit");
1027 construct_word!(u512, [u8; 64], 9, "a 512-bit");
1028
1029 pub fn shallow_clone(&self) -> Self {
1031 Self {
1032 value: self.value.shallow_clone(),
1033 n: self.n,
1034 }
1035 }
1036
1037 pub fn as_value(&self) -> &Value {
1039 &self.value
1040 }
1041
1042 pub fn n(&self) -> u32 {
1044 self.n
1045 }
1046
1047 #[allow(clippy::len_without_is_empty)]
1051 pub fn len(&self) -> usize {
1052 2usize.pow(self.n)
1053 }
1054
1055 pub fn iter(&self) -> impl Iterator<Item = bool> + '_ {
1060 self.value.iter_compact()
1061 }
1062
1063 pub fn from_bits<I: Iterator<Item = u8>>(
1069 bits: &mut BitIter<I>,
1070 n: u32,
1071 ) -> Result<Self, EarlyEndOfStreamError> {
1072 assert!(n < 32, "TWO^(2^{n}) is not supported as a word type");
1073 let ty = Final::two_two_n(n as usize); let value = Value::from_compact_bits(bits, &ty)?;
1075 Ok(Self { value, n })
1076 }
1077}
1078
1079impl fmt::Debug for Word {
1080 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1081 fmt::Display::fmt(self, f)
1082 }
1083}
1084
1085impl fmt::Display for Word {
1086 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1087 use hex::DisplayHex;
1088
1089 if let Ok(hex) = self.iter().try_collect_bytes() {
1090 write!(f, "0x{}", hex.as_hex())
1091 } else {
1092 f.write_str("0b")?;
1093 for bit in self.iter() {
1094 match bit {
1095 false => f.write_str("0")?,
1096 true => f.write_str("1")?,
1097 }
1098 }
1099 Ok(())
1100 }
1101 }
1102}
1103
1104#[cfg(test)]
1105mod tests {
1106 use super::*;
1107 use crate::bit_encoding::{BitCollector as _, BitIter};
1108 use crate::jet::type_name::TypeName;
1109
1110 #[test]
1111 fn value_len() {
1112 let v = Value::u4(6);
1113 let s_v = Value::some(v.shallow_clone());
1114 let n_v = Value::none(Final::two_two_n(2));
1115
1116 assert_eq!(v.compact_len(), 4);
1117 assert_eq!(v.padded_len(), 4);
1118 assert_eq!(s_v.compact_len(), 5);
1119 assert_eq!(s_v.padded_len(), 5);
1120 assert_eq!(n_v.compact_len(), 1);
1121 assert_eq!(n_v.padded_len(), 5);
1122 }
1123
1124 #[test]
1125 fn value_display() {
1126 assert_eq!(Value::u1(0).to_string(), "0b0",);
1129 assert_eq!(Value::u1(1).to_string(), "0b1",);
1130 assert_eq!(Value::u4(6).to_string(), "0x6",);
1131 }
1132
1133 #[test]
1134 fn is_of_type() {
1135 let value_typename = [
1136 (Value::unit(), TypeName(b"1")),
1137 (Value::left(Value::unit(), Final::unit()), TypeName(b"+11")),
1138 (Value::right(Final::unit(), Value::unit()), TypeName(b"+11")),
1139 (
1140 Value::left(Value::unit(), Final::two_two_n(8)),
1141 TypeName(b"+1h"),
1142 ),
1143 (
1144 Value::right(Final::two_two_n(8), Value::unit()),
1145 TypeName(b"+h1"),
1146 ),
1147 (
1148 Value::product(Value::unit(), Value::unit()),
1149 TypeName(b"*11"),
1150 ),
1151 (Value::u8(u8::MAX), TypeName(b"c")),
1152 (Value::u64(u64::MAX), TypeName(b"l")),
1153 ];
1154
1155 for (value, typename) in value_typename {
1156 let ty = typename.to_final();
1157 assert!(value.is_of_type(ty.as_ref()));
1158 }
1159 }
1160
1161 #[test]
1162 fn prune_regression_1() {
1163 let nontrivial_sum = Value::product(
1165 Value::right(Final::two_two_n(4), Value::u16(0)),
1166 Value::u8(0),
1167 );
1168 let _ = format!("{nontrivial_sum}");
1170 assert_eq!(
1172 nontrivial_sum.prune(nontrivial_sum.ty()),
1173 Some(nontrivial_sum)
1174 );
1175 }
1176
1177 #[test]
1178 fn prune() {
1179 let test_vectors = [
1180 (Value::unit(), Value::unit()),
1181 (Value::u64(42), Value::unit()),
1182 (
1183 Value::left(Value::u64(42), Final::u64()),
1184 Value::left(Value::u64(42), Final::unit()),
1185 ),
1186 (
1187 Value::right(Final::u64(), Value::u64(1337)),
1188 Value::right(Final::unit(), Value::u64(1337)),
1189 ),
1190 (
1191 Value::product(Value::u64(42), Value::u64(1337)),
1192 Value::product(Value::u64(42), Value::unit()),
1193 ),
1194 (
1195 Value::product(Value::u64(42), Value::u64(1337)),
1196 Value::product(Value::unit(), Value::u64(1337)),
1197 ),
1198 ];
1199
1200 for (value, expected_pruned_value) in test_vectors {
1201 assert_eq!(
1202 value.prune(expected_pruned_value.ty()),
1203 Some(expected_pruned_value)
1204 );
1205 }
1206
1207 let bad_test_vectors = [
1208 (Value::unit(), Final::u1()),
1209 (
1210 Value::product(Value::unit(), Value::unit()),
1211 Final::sum(Final::unit(), Final::unit()),
1212 ),
1213 (
1214 Value::left(Value::unit(), Final::unit()),
1215 Final::product(Final::unit(), Final::unit()),
1216 ),
1217 (
1218 Value::right(Final::unit(), Value::unit()),
1219 Final::product(Final::unit(), Final::unit()),
1220 ),
1221 ];
1222
1223 for (value, pruned_ty) in bad_test_vectors {
1224 assert_eq!(value.prune(&pruned_ty), None);
1225 }
1226 }
1227
1228 #[test]
1229 fn zero_value() {
1230 let test_vectors = [
1231 (Final::unit(), Value::unit()),
1232 (Final::u8(), Value::u8(0)),
1233 (Final::u64(), Value::u64(0)),
1234 (
1235 Final::product(Final::u16(), Final::u32()),
1236 Value::product(Value::u16(0), Value::u32(0)),
1237 ),
1238 (
1239 Final::sum(Final::unit(), Final::u64()),
1240 Value::left(Value::unit(), Final::u64()),
1241 ),
1242 (
1243 Final::product(Final::unit(), Final::unit()),
1244 Value::product(Value::unit(), Value::unit()),
1245 ),
1246 ];
1247
1248 for (ty, expected_default_value) in test_vectors {
1249 assert_eq!(Value::zero(&ty), expected_default_value);
1250 }
1251 }
1252
1253 #[test]
1254 fn compact_round_trip() {
1255 let v = Value::u64(0xff00_00ff_ff00_00ff);
1256 let (bits, _) = v.iter_compact().collect_bits();
1257 let mut iter = BitIter::new(bits.into_iter());
1258 let new_v = Value::from_compact_bits(&mut iter, &v.ty).unwrap();
1259 assert_eq!(v, new_v);
1260 }
1261
1262 #[test]
1263 fn padded_round_trip() {
1264 let v = Value::u64(0xff00_00ff_ff00_00ff);
1265 let (bits, _) = v.iter_padded().collect_bits();
1266 let mut iter = BitIter::new(bits.into_iter());
1267 let new_v = Value::from_padded_bits(&mut iter, &v.ty).unwrap();
1268 assert_eq!(v, new_v);
1269 }
1270
1271 #[test]
1296 fn left_tag_not_corrupted_by_dirty_buffer() {
1297 let product_val = Value::product(
1298 Value::right(Final::u1(), Value::u1(1)), Value::right(Final::u1(), Value::u1(0)), );
1301
1302 let (_, right_sub) = product_val.as_product().unwrap();
1303 let right_sub_owned = right_sub.to_value();
1305
1306 let left_val = Value::left(right_sub_owned, Final::unit());
1307
1308 assert!(
1309 left_val.as_left().is_some(),
1310 "BUG: Left tag corrupted — right_shift_1(false) did not clear dirty bit; \
1311 value reads as Right instead of Left"
1312 );
1313 assert!(
1314 left_val.as_right().is_none(),
1315 "BUG: Left tag corrupted — as_right() should return None for a Left value"
1316 );
1317 }
1318
1319 #[test]
1322 fn left_tag_first_padded_bit_is_zero() {
1323 let product_val = Value::product(
1324 Value::right(Final::u1(), Value::u1(1)),
1325 Value::right(Final::u1(), Value::u1(0)),
1326 );
1327
1328 let (_, right_sub) = product_val.as_product().unwrap();
1329 let left_val = Value::left(right_sub.to_value(), Final::unit());
1330
1331 let first_bit = left_val.iter_padded().next();
1332 assert_eq!(
1333 first_bit,
1334 Some(false),
1335 "BUG: first padded bit of Left value is {:?}, expected Some(false)",
1336 first_bit
1337 );
1338 }
1339
1340 #[test]
1354 fn prune_does_not_corrupt_left_tag_via_shared_buffer() {
1355 let original = Value::left(
1356 Value::product(
1357 Value::right(Final::u1(), Value::u1(1)),
1358 Value::right(Final::u1(), Value::u1(0)),
1359 ),
1360 Final::unit(),
1361 );
1362
1363 let pruned_ty = Final::sum(
1367 Final::product(Final::unit(), Final::sum(Final::u1(), Final::u1())),
1368 Final::unit(),
1369 );
1370
1371 let pruned = original
1372 .prune(&pruned_ty)
1373 .expect("prune returned None; the target type is compatible");
1374
1375 assert!(
1376 pruned.as_left().is_some(),
1377 "BUG: prune corrupted the Left tag — right_shift_1(false) did not clear \
1378 a dirty bit from the shared product buffer; value reads as Right"
1379 );
1380 }
1381}
1382
1383#[cfg(bench)]
1384mod benches {
1385 use super::*;
1386
1387 use crate::bit_encoding::{BitCollector as _, BitIter};
1388
1389 use test::{black_box, Bencher};
1390
1391 #[bench]
1393 fn bench_value_create_u64(bh: &mut Bencher) {
1394 bh.iter(|| black_box(Value::u64(0xff00_00ff_ff00_00ff)))
1395 }
1396
1397 #[bench]
1398 fn bench_value_create_u2048(bh: &mut Bencher) {
1399 bh.iter(|| black_box(Value::from_byte_array([0xcd; 2048])));
1400 }
1401
1402 #[bench]
1403 fn bench_value_create_deep_some(bh: &mut Bencher) {
1404 bh.iter(|| {
1405 let mut kilo = Value::from_byte_array([0xab; 1024]);
1406 for _ in 0..1000 {
1407 kilo = Value::some(kilo.shallow_clone());
1408 }
1409 black_box(kilo)
1410 });
1411 }
1412
1413 #[bench]
1414 fn bench_value_create_64k(bh: &mut Bencher) {
1415 bh.iter(|| {
1416 let mut kilo = Value::from_byte_array([0xab; 1024]);
1417 for _ in 0..5 {
1418 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1419 }
1420 black_box(kilo)
1421 });
1422 }
1423
1424 #[bench]
1425 fn bench_value_create_512_256(bh: &mut Bencher) {
1426 bh.iter(|| {
1427 let mut s512_256 = Value::product(
1436 Value::from_byte_array([0x12; 64]),
1437 Value::from_byte_array([0x23; 32]),
1438 );
1439 for _ in 0..5 {
1440 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1441 }
1442 black_box(s512_256);
1443 });
1444 }
1445
1446 fn padded_bits(v: &Value) -> (Vec<u8>, &Final) {
1448 let (bits, _) = v.iter_padded().collect_bits();
1449 (bits, v.ty.as_ref())
1450 }
1451
1452 #[bench]
1453 fn bench_value_create_u64_padded(bh: &mut Bencher) {
1454 let v = Value::u64(0xff00_00ff_ff00_00ff);
1455 let (bits, ty) = padded_bits(&v);
1456 bh.iter(|| {
1457 black_box(Value::from_padded_bits(
1458 &mut BitIter::new(bits.iter().copied()),
1459 ty,
1460 ))
1461 })
1462 }
1463
1464 #[bench]
1465 fn bench_value_create_u2048_padded(bh: &mut Bencher) {
1466 let v = Value::from_byte_array([0xcd; 2048]);
1467 let (bits, ty) = padded_bits(&v);
1468 bh.iter(|| {
1469 black_box(Value::from_padded_bits(
1470 &mut BitIter::new(bits.iter().copied()),
1471 ty,
1472 ))
1473 })
1474 }
1475
1476 #[bench]
1477 fn bench_value_create_deep_some_padded(bh: &mut Bencher) {
1478 let mut kilo = Value::from_byte_array([0xab; 1024]);
1479 for _ in 0..1000 {
1480 kilo = Value::some(kilo.shallow_clone());
1481 }
1482 let (bits, ty) = padded_bits(&kilo);
1483 bh.iter(|| {
1484 black_box(Value::from_padded_bits(
1485 &mut BitIter::new(bits.iter().copied()),
1486 ty,
1487 ))
1488 })
1489 }
1490
1491 #[bench]
1492 fn bench_value_create_64k_padded(bh: &mut Bencher) {
1493 let mut kilo = Value::from_byte_array([0xab; 1024]);
1494 for _ in 0..5 {
1495 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1496 }
1497 let (bits, ty) = padded_bits(&kilo);
1498 bh.iter(|| {
1499 black_box(Value::from_padded_bits(
1500 &mut BitIter::new(bits.iter().copied()),
1501 ty,
1502 ))
1503 })
1504 }
1505
1506 #[bench]
1507 fn bench_value_create_512_256_padded(bh: &mut Bencher) {
1508 let mut s512_256 = Value::product(
1510 Value::from_byte_array([0x12; 64]),
1511 Value::from_byte_array([0x23; 32]),
1512 );
1513 for _ in 0..5 {
1514 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1515 }
1516 let (bits, ty) = padded_bits(&s512_256);
1517 bh.iter(|| {
1518 black_box(Value::from_padded_bits(
1519 &mut BitIter::new(bits.iter().copied()),
1520 ty,
1521 ))
1522 })
1523 }
1524
1525 fn compact_bits(v: &Value) -> (Vec<u8>, &Final) {
1527 let (bits, _) = v.iter_compact().collect_bits();
1528 (bits, v.ty.as_ref())
1529 }
1530
1531 #[bench]
1532 fn bench_value_create_u64_compact(bh: &mut Bencher) {
1533 let v = Value::u64(0xff00_00ff_ff00_00ff);
1534 let (bits, ty) = compact_bits(&v);
1535 bh.iter(|| {
1536 black_box(Value::from_compact_bits(
1537 &mut BitIter::new(bits.iter().copied()),
1538 ty,
1539 ))
1540 })
1541 }
1542
1543 #[bench]
1544 fn bench_value_create_u2048_compact(bh: &mut Bencher) {
1545 let v = Value::from_byte_array([0xcd; 2048]);
1546 let (bits, ty) = compact_bits(&v);
1547 bh.iter(|| {
1548 black_box(Value::from_compact_bits(
1549 &mut BitIter::new(bits.iter().copied()),
1550 ty,
1551 ))
1552 })
1553 }
1554
1555 #[bench]
1556 fn bench_value_create_deep_some_compact(bh: &mut Bencher) {
1557 let mut kilo = Value::from_byte_array([0xab; 1024]);
1558 for _ in 0..1000 {
1559 kilo = Value::some(kilo.shallow_clone());
1560 }
1561 let (bits, ty) = compact_bits(&kilo);
1562 bh.iter(|| {
1563 black_box(Value::from_compact_bits(
1564 &mut BitIter::new(bits.iter().copied()),
1565 ty,
1566 ))
1567 })
1568 }
1569
1570 #[bench]
1571 fn bench_value_create_64k_compact(bh: &mut Bencher) {
1572 let mut kilo = Value::from_byte_array([0xab; 1024]);
1573 for _ in 0..5 {
1574 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1575 }
1576 let (bits, ty) = compact_bits(&kilo);
1577 bh.iter(|| {
1578 black_box(Value::from_compact_bits(
1579 &mut BitIter::new(bits.iter().copied()),
1580 ty,
1581 ))
1582 })
1583 }
1584
1585 #[bench]
1586 fn bench_value_create_512_256_compact(bh: &mut Bencher) {
1587 let mut s512_256 = Value::product(
1589 Value::from_byte_array([0x12; 64]),
1590 Value::from_byte_array([0x23; 32]),
1591 );
1592 for _ in 0..5 {
1593 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1594 }
1595 let (bits, ty) = compact_bits(&s512_256);
1596 bh.iter(|| {
1597 black_box(Value::from_compact_bits(
1598 &mut BitIter::new(bits.iter().copied()),
1599 ty,
1600 ))
1601 })
1602 }
1603
1604 #[bench]
1606 fn bench_value_display_u64(bh: &mut Bencher) {
1607 let v = Value::u64(0xff00_00ff_ff00_00ff);
1608 bh.iter(|| black_box(format!("{}", v)))
1609 }
1610
1611 #[bench]
1612 fn bench_value_display_u2024(bh: &mut Bencher) {
1613 let v = Value::from_byte_array([0xcd; 2048]);
1614 bh.iter(|| black_box(format!("{}", v)))
1615 }
1616
1617 #[bench]
1618 fn bench_value_display_deep_some(bh: &mut Bencher) {
1619 let mut kilo = Value::from_byte_array([0xab; 1024]);
1620 for _ in 0..1000 {
1621 kilo = Value::some(kilo.shallow_clone());
1622 }
1623 bh.iter(|| black_box(format!("{}", kilo)))
1624 }
1625
1626 #[bench]
1627 fn bench_value_display_64k(bh: &mut Bencher) {
1628 let mut kilo = Value::from_byte_array([0xab; 1024]);
1629 for _ in 0..5 {
1630 kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1631 }
1632 bh.iter(|| black_box(format!("{}", kilo)))
1633 }
1634
1635 #[bench]
1636 fn bench_value_display_512_256(bh: &mut Bencher) {
1637 let mut s512_256 = Value::product(
1639 Value::from_byte_array([0x12; 64]),
1640 Value::from_byte_array([0x23; 32]),
1641 );
1642 for _ in 0..5 {
1643 s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1644 }
1645 bh.iter(|| black_box(format!("{}", s512_256)))
1646 }
1647
1648 }