simplicity/
value.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! # Simplicity values
4//!
5//! Simplicity processes data in terms of [`Value`]s,
6//! i.e., inputs, intermediate results and outputs.
7
8use 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/// A Simplicity value.
19#[derive(Clone)]
20pub struct Value {
21    /// The underlying data, in "padded" bit-encoded form, with the leftmost
22    /// bits encoded in the most-significant bits. So e.g. right(unit) is 0x80.
23    ///
24    /// We use the padded form, even though it is space-inefficient (sometimes
25    /// significantly so), for a couple reasons: first, this is the representation
26    /// used by the bit machine, so we want encoding/decoding to be as fast as
27    /// possible. Secondly, when destructuring a value (which we need to do during
28    /// scribing and pruning, at least) it is quite difficult to destructure a
29    /// compact-encoded product, since we would need to determine the compact
30    /// bitlengths of the children, and these quantities are not readily available.
31    inner: Arc<[u8]>,
32    /// An offset, in bits, at which the actual data starts. This is useful
33    /// because it allows constructing sub-values of a value without needing
34    /// to construct a new `inner` with all the bits offset.
35    bit_offset: usize,
36    /// The Simplicity type of the value.
37    ty: Arc<Final>,
38}
39
40/// Reference to a value, or to a sub-value of a value.
41#[derive(Debug, Clone, Copy)]
42pub struct ValueRef<'v> {
43    inner: &'v Arc<[u8]>,
44    bit_offset: usize,
45    ty: &'v Arc<Final>,
46}
47
48// Because two equal values may have different bit offsets, we must manually
49// implement the comparison traits. We do so by first comparing types, which
50// is constant overhead (this just compares TMRs). If those match, we know
51// the lengths and structures match, so we then compare the underlying byte
52// iterators.
53impl 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    /// Check if the value is a unit.
106    pub fn is_unit(&self) -> bool {
107        self.ty.is_unit()
108    }
109
110    /// Helper function to read the first bit of a value
111    ///
112    /// If the first bit is not available (e.g. if the value has zero size)
113    /// then returns None.
114    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    /// Access the inner value of a left sum value.
128    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    /// Access the inner value of a right sum value.
146    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    /// Access the inner values of a product value.
164    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    /// Convert the reference back to a value.
184    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    /// Try to convert the value into a word.
193    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    /// Yields an iterator over the "raw bytes" of the value.
201    ///
202    /// The returned bytes match the padded bit-encoding of the value. You
203    /// may wish to call [`Self::iter_padded`] instead to obtain the bits,
204    /// but this method is more efficient in some contexts.
205    pub fn raw_byte_iter(&self) -> RawByteIter<'v> {
206        RawByteIter {
207            value: *self,
208            yielded_bytes: 0,
209        }
210    }
211
212    /// Return an iterator over the compact bit encoding of the value.
213    ///
214    /// This encoding is used for writing witness data and for computing IHRs.
215    pub fn iter_compact(&self) -> CompactBitsIter<'v> {
216        CompactBitsIter::new(*self)
217    }
218
219    /// Return an iterator over the padded bit encoding of the value.
220    ///
221    /// This encoding is used to represent the value in the Bit Machine.
222    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
270/// Helper function to right-shift a value by one bit.
271///
272/// This is used for putting a value into a sum type. It takes the value's
273/// bit encoding and current bit offset, and returns a new bit-encoding with
274/// a new bit inserted upfront and a new bit offset.
275fn right_shift_1(inner: &Arc<[u8]>, bit_offset: usize, new_bit: bool) -> (Arc<[u8]>, usize) {
276    // If the current bit offset is nonzero this is super easy: we just
277    // lower the bit offset and call that a fix.
278    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            // ...and if we are inserting a 0 we don't even need to allocate a new [u8]
286            (Arc::clone(inner), bit_offset - 1)
287        }
288    } else {
289        // If the current bit offset is 0, we just shift everything right by 8
290        // and then do pretty-much the same thing as above. This sometimes will
291        // waste 7 bits, but it avoids needing to iterate through all of `inner`.
292        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
299/// Helper function to copy `nbits` bits from `src`, starting at bit-offset `src_offset`,
300/// into `dst`, starting at bit-offset `dst_offset`.
301///
302/// Thanks ChatGPT for suggesting we extract this function.
303fn copy_bits(src: &[u8], src_offset: usize, dst: &mut [u8], dst_offset: usize, nbits: usize) {
304    // For each bit i in 0..nbits, extract the bit from `src`
305    // and insert it into `dst`.
306    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
312/// Helper function to take the product of two values (i.e. their concatenation).
313///
314/// If either `left_inner` or `right_inner` is not provided, it is assumed to be
315/// padding and will be stored as all zeros.
316///
317/// Returns the new bit data and the offset (NOT the length) of the data.
318fn 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        // Both left and right have nonzero lengths. This is the only "real" case
340        // in which we have to do something beyond cloning Arcs or allocating
341        // zeroed vectors. In this case we left-shift both as much as possible.
342        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    /// Make a cheap copy of the value.
362    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    /// Access the type of the value.
371    pub fn ty(&self) -> &Final {
372        &self.ty
373    }
374
375    /// Create the unit value.
376    pub fn unit() -> Self {
377        Self {
378            inner: Arc::new([]),
379            bit_offset: 0,
380            ty: Final::unit(),
381        }
382    }
383
384    /// Create a left value that wraps the given `inner` value.
385    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    /// Create a right value that wraps the given `inner` value.
403    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    /// Create a product value that wraps the given `left` and `right` values.
420    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    /// Create a none value.
435    pub fn none(right: Arc<Final>) -> Self {
436        Self::left(Value::unit(), right)
437    }
438
439    /// Create a some value.
440    pub fn some(inner: Self) -> Self {
441        Self::right(Final::unit(), inner)
442    }
443
444    /// Return the bit length of the value in compact encoding.
445    pub fn compact_len(&self) -> usize {
446        self.iter_compact().count()
447    }
448
449    /// Return the bit length of the value in padded encoding.
450    pub fn padded_len(&self) -> usize {
451        self.ty.bit_width()
452    }
453
454    /// Check if the value is a nested product of units.
455    /// In this case, the value contains no information.
456    pub fn is_empty(&self) -> bool {
457        self.ty.bit_width() == 0
458    }
459
460    /// Check if the value is a unit.
461    pub fn is_unit(&self) -> bool {
462        self.ty.is_unit()
463    }
464
465    /// A reference to this value, which can be recursed over.
466    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    /// Access the inner value of a left sum value.
475    pub fn as_left(&self) -> Option<ValueRef<'_>> {
476        self.as_ref().as_left()
477    }
478
479    /// Access the inner value of a right sum value.
480    pub fn as_right(&self) -> Option<ValueRef<'_>> {
481        self.as_ref().as_right()
482    }
483
484    /// Access the inner values of a product value.
485    pub fn as_product(&self) -> Option<(ValueRef<'_>, ValueRef<'_>)> {
486        self.as_ref().as_product()
487    }
488
489    /// Create a 1-bit integer.
490    ///
491    /// ## Panics
492    ///
493    /// The value is out of range.
494    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    /// Create a 2-bit integer.
504    ///
505    /// ## Panics
506    ///
507    /// The value is out of range.
508    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    /// Create a 4-bit integer.
518    ///
519    /// ## Panics
520    ///
521    /// The value is ouf of range.
522    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    /// Create an 8-bit integer.
532    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    /// Create a 16-bit integer.
541    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    /// Create a 32-bit integer.
550    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    /// Create a 64-bit integer.
559    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    /// Create a 128-bit integer.
568    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    /// Create a 256-bit integer.
577    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    /// Create a 512-bit integer.
586    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    /// Create a value from a byte array.
595    ///
596    /// ## Panics
597    ///
598    /// The array length is not a power of two.
599    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    /// Yields an iterator over the "raw bytes" of the value.
617    ///
618    /// The returned bytes match the padded bit-encoding of the value. You
619    /// may wish to call [`Self::iter_padded`] instead to obtain the bits,
620    /// but this method is more efficient in some contexts.
621    pub fn raw_byte_iter(&self) -> RawByteIter<'_> {
622        self.as_ref().raw_byte_iter()
623    }
624
625    /// Return an iterator over the compact bit encoding of the value.
626    ///
627    /// This encoding is used for writing witness data and for computing IHRs.
628    pub fn iter_compact(&self) -> CompactBitsIter<'_> {
629        self.as_ref().iter_compact()
630    }
631
632    /// Return an iterator over the padded bit encoding of the value.
633    ///
634    /// This encoding is used to represent the value in the Bit Machine.
635    pub fn iter_padded(&self) -> PreOrderIter<'_> {
636        self.as_ref().iter_padded()
637    }
638
639    /// Check if the value is of the given type.
640    pub fn is_of_type(&self, ty: &Final) -> bool {
641        self.ty.as_ref() == ty
642    }
643
644    /// Get the zero value for the given type.
645    ///
646    /// The zero value serializes to a string of zeroes.
647    ///
648    /// ## Construction
649    ///
650    /// - `zero( 1 )` = `()`
651    /// - `zero( A + B )` = `zero(A)`
652    /// - `zero( A × B )` = `zero(A) × zero(B)`
653    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    /// Try to convert the value into a word.
662    ///
663    /// The value is cheaply cloned.
664    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    /// Prune the value down to the given type.
672    ///
673    /// The pruned type must be _smaller than or equal to_ the current type of the value.
674    /// Otherwise, this method returns `None`.
675    ///
676    /// ## Smallness
677    ///
678    /// - `T` ≤ `T` for all types `T`
679    /// - `1` ≤ `T` for all types `T`
680    /// - `A1 + B1` ≤ `A2 + B2` if `A1` ≤ `A2` and `B1` ≤ `B2`
681    /// - `A1 × B1` ≤ `A2 × B2` if `A1` ≤ `A2` and `B1` ≤ `B2`
682    ///
683    /// ## Pruning
684    ///
685    /// - `prune( v: T, 1 )` = `(): 1`
686    /// - `prune( L(l): A1 + B1, A2 + B2 )` = `prune(l: A1, A2) : A2 + B2`
687    /// - `prune( R(r): A1 + B1, A2 + B2 )` = `prune(r: B1, B2) : A2 + B2`
688    /// - `prune( (l, r): A1 × B1, A2 × B2 )` = `( prune(l: A1, A2), prune(r: B1, B2): A2 × B2`
689    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        // This is a copy of the logic inside `CompactBitsIter` except
759        // that we handle products more explicitly.
760        enum S<'v> {
761            Disp(ValueRef<'v>),
762            DispCh(char),
763        }
764
765        let mut stack = Vec::with_capacity(1024);
766        // Next node to visit.
767        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                // First, write any bitstrings out
782                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                            // Annoyingly `array_chunks` is unstable so we have to do it manually
792                            // https://github.com/rust-lang/rust/issues/100450
793                            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 we don't have a bitstring, then write out the explicit value.
809                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/// An iterator over the bits of the compact encoding of a [`Value`].
833#[derive(Debug, Clone)]
834pub struct CompactBitsIter<'v> {
835    stack: Vec<ValueRef<'v>>,
836}
837
838impl<'v> CompactBitsIter<'v> {
839    /// Create an iterator over the bits of the compact encoding of the `value`.
840    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                // NOP
852            } 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    /// Decode a value of the given type from its compact bit encoding.
870    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                    // no padding no problem
904                    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    /// Decode a value of the given type from its padded bit encoding.
926    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; // 4 megabytes
931
932        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/// A Simplicity word. A value of type `TWO^(2^n)` for some `0 ≤ n < 32`.
954#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
955pub struct Word {
956    /// Value of type `TWO^(2^n)`.
957    value: Value,
958    /// 0 ≤ n < 32.
959    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    /// Concatenate two words into a larger word.
994    ///
995    /// Both words have to have the same length, which is 2^n bits.
996    /// The resulting word will be 2^(n + 1) bits long.
997    ///
998    /// Returns `None` if the words differ in length.
999    ///
1000    /// Returns `None` if the words are already 2^31 bits long
1001    /// _(the resulting word would be longer than 2^31 bits, which is not supported)_.
1002    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    /// Make a cheap copy of the word.
1025    pub fn shallow_clone(&self) -> Self {
1026        Self {
1027            value: self.value.shallow_clone(),
1028            n: self.n,
1029        }
1030    }
1031
1032    /// Access the value of the word.
1033    pub fn as_value(&self) -> &Value {
1034        &self.value
1035    }
1036
1037    /// The word is of type `TWO^(2^n)`. Return `n`.
1038    pub fn n(&self) -> u32 {
1039        self.n
1040    }
1041
1042    /// Return the bit length of the word.
1043    ///
1044    /// The word is of type `TWO^(2^n)`. Return `2^n`.
1045    #[allow(clippy::len_without_is_empty)]
1046    pub fn len(&self) -> usize {
1047        2usize.pow(self.n)
1048    }
1049
1050    /// Return an iterator over the bit encoding of the word.
1051    ///
1052    /// Words have no padding, so their compact encoding is the same as the padded encoding.
1053    /// The universal encoding can be used in all situations.
1054    pub fn iter(&self) -> impl Iterator<Item = bool> + '_ {
1055        self.value.iter_compact()
1056    }
1057
1058    /// Decode a word of type `TWO^(2^n)` from bits.
1059    ///
1060    /// ## Panics
1061    ///
1062    /// n is greater than 31.
1063    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); // cast safety: 32-bit machine or higher
1069        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        // Only test a couple values becasue we probably want to change this
1122        // at some point and will have to redo this test.
1123        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        // Found this when fuzzing Elements; unsure how to reduce it further.
1159        let nontrivial_sum = Value::product(
1160            Value::right(Final::two_two_n(4), Value::u16(0)),
1161            Value::u8(0),
1162        );
1163        // Formatting should succeed and have no effect.
1164        let _ = format!("{nontrivial_sum}");
1165        // Pruning should succeed and have no effect.
1166        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    // Create values directly
1276    #[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            // This is a common "slow" pattern in my Elements fuzzer; it is a deeply
1312            // nested product of 2^512 x 2^256, which is not a "primitive numeric
1313            // type" and therefore cannot be quickly decoded from compact bits by
1314            // simply matching to pre-computed types.
1315            //
1316            // However, this type is a giant product of bits. Its compact encoding
1317            // is therefore equal to its padded encoding and we should be able to
1318            // quickly decode it.
1319            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    // Create values from padded bits
1331    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        // See comment in bench_value_create_512_256 about this value
1393        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    // Create values from compact bits
1410    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        // See comment in bench_value_create_512_256 about this value
1472        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    // Display values
1489    #[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        // See comment in bench_value_create_512_256 about this value
1522        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    // Display values
1533}