1use std::borrow::Borrow;
2use std::ops::{Add, Mul, Neg, Sub};
3
4use group::ff::Field;
5
6use crate::plonk::{Assigned, Error};
7
8#[derive(Clone, Copy, Debug)]
16pub struct Value<V> {
17 inner: Option<V>,
18}
19
20impl<V> Default for Value<V> {
21 fn default() -> Self {
22 Self::unknown()
23 }
24}
25
26impl<V> Value<V> {
27 pub const fn unknown() -> Self {
29 Self { inner: None }
30 }
31
32 pub const fn known(value: V) -> Self {
42 Self { inner: Some(value) }
43 }
44
45 pub(crate) fn assign(self) -> Result<V, Error> {
49 self.inner.ok_or(Error::Synthesis)
50 }
51
52 pub fn as_ref(&self) -> Value<&V> {
54 Value {
55 inner: self.inner.as_ref(),
56 }
57 }
58
59 pub fn as_mut(&mut self) -> Value<&mut V> {
61 Value {
62 inner: self.inner.as_mut(),
63 }
64 }
65
66 pub(crate) fn into_option(self) -> Option<V> {
68 self.inner
69 }
70
71 pub fn assert_if_known<F: FnOnce(&V) -> bool>(&self, f: F) {
80 if let Some(value) = self.inner.as_ref() {
81 assert!(f(value));
82 }
83 }
84
85 pub fn error_if_known_and<F: FnOnce(&V) -> bool>(&self, f: F) -> Result<(), Error> {
90 match self.inner.as_ref() {
91 Some(value) if f(value) => Err(Error::Synthesis),
92 _ => Ok(()),
93 }
94 }
95
96 pub fn map<W, F: FnOnce(V) -> W>(self, f: F) -> Value<W> {
98 Value {
99 inner: self.inner.map(f),
100 }
101 }
102
103 pub fn and_then<W, F: FnOnce(V) -> Value<W>>(self, f: F) -> Value<W> {
106 match self.inner {
107 Some(v) => f(v),
108 None => Value::unknown(),
109 }
110 }
111
112 pub fn zip<W>(self, other: Value<W>) -> Value<(V, W)> {
117 Value {
118 inner: self.inner.zip(other.inner),
119 }
120 }
121}
122
123impl<V, W> Value<(V, W)> {
124 pub fn unzip(self) -> (Value<V>, Value<W>) {
130 match self.inner {
131 Some((a, b)) => (Value::known(a), Value::known(b)),
132 None => (Value::unknown(), Value::unknown()),
133 }
134 }
135}
136
137impl<V> Value<&V> {
138 #[must_use = "`self` will be dropped if the result is not used"]
140 pub fn copied(self) -> Value<V>
141 where
142 V: Copy,
143 {
144 Value {
145 inner: self.inner.copied(),
146 }
147 }
148
149 #[must_use = "`self` will be dropped if the result is not used"]
151 pub fn cloned(self) -> Value<V>
152 where
153 V: Clone,
154 {
155 Value {
156 inner: self.inner.cloned(),
157 }
158 }
159}
160
161impl<V> Value<&mut V> {
162 #[must_use = "`self` will be dropped if the result is not used"]
164 pub fn copied(self) -> Value<V>
165 where
166 V: Copy,
167 {
168 Value {
169 inner: self.inner.copied(),
170 }
171 }
172
173 #[must_use = "`self` will be dropped if the result is not used"]
175 pub fn cloned(self) -> Value<V>
176 where
177 V: Clone,
178 {
179 Value {
180 inner: self.inner.cloned(),
181 }
182 }
183}
184
185impl<V: Copy, const LEN: usize> Value<[V; LEN]> {
186 pub fn transpose_array(self) -> [Value<V>; LEN] {
190 let mut ret = [Value::unknown(); LEN];
191 if let Some(arr) = self.inner {
192 for (entry, value) in ret.iter_mut().zip(arr) {
193 *entry = Value::known(value);
194 }
195 }
196 ret
197 }
198}
199
200impl<V, I> Value<I>
201where
202 I: IntoIterator<Item = V>,
203 I::IntoIter: ExactSizeIterator,
204{
205 pub fn transpose_vec(self, length: usize) -> Vec<Value<V>> {
213 match self.inner {
214 Some(values) => {
215 let values = values.into_iter();
216 assert_eq!(values.len(), length);
217 values.map(Value::known).collect()
218 }
219 None => (0..length).map(|_| Value::unknown()).collect(),
220 }
221 }
222}
223
224impl<A, V: FromIterator<A>> FromIterator<Value<A>> for Value<V> {
229 fn from_iter<I: IntoIterator<Item = Value<A>>>(iter: I) -> Self {
234 Self {
235 inner: iter.into_iter().map(|v| v.inner).collect(),
236 }
237 }
238}
239
240impl<V: Neg> Neg for Value<V> {
245 type Output = Value<V::Output>;
246
247 fn neg(self) -> Self::Output {
248 Value {
249 inner: self.inner.map(|v| -v),
250 }
251 }
252}
253
254impl<V, O> Add for Value<V>
259where
260 V: Add<Output = O>,
261{
262 type Output = Value<O>;
263
264 fn add(self, rhs: Self) -> Self::Output {
265 Value {
266 inner: self.inner.zip(rhs.inner).map(|(a, b)| a + b),
267 }
268 }
269}
270
271impl<V, O> Add for &Value<V>
272where
273 for<'v> &'v V: Add<Output = O>,
274{
275 type Output = Value<O>;
276
277 fn add(self, rhs: Self) -> Self::Output {
278 Value {
279 inner: self
280 .inner
281 .as_ref()
282 .zip(rhs.inner.as_ref())
283 .map(|(a, b)| a + b),
284 }
285 }
286}
287
288impl<V, O> Add<Value<&V>> for Value<V>
289where
290 for<'v> V: Add<&'v V, Output = O>,
291{
292 type Output = Value<O>;
293
294 fn add(self, rhs: Value<&V>) -> Self::Output {
295 Value {
296 inner: self.inner.zip(rhs.inner).map(|(a, b)| a + b),
297 }
298 }
299}
300
301impl<V, O> Add<Value<V>> for Value<&V>
302where
303 for<'v> &'v V: Add<V, Output = O>,
304{
305 type Output = Value<O>;
306
307 fn add(self, rhs: Value<V>) -> Self::Output {
308 Value {
309 inner: self.inner.zip(rhs.inner).map(|(a, b)| a + b),
310 }
311 }
312}
313
314impl<V, O> Add<&Value<V>> for Value<V>
315where
316 for<'v> V: Add<&'v V, Output = O>,
317{
318 type Output = Value<O>;
319
320 fn add(self, rhs: &Self) -> Self::Output {
321 self + rhs.as_ref()
322 }
323}
324
325impl<V, O> Add<Value<V>> for &Value<V>
326where
327 for<'v> &'v V: Add<V, Output = O>,
328{
329 type Output = Value<O>;
330
331 fn add(self, rhs: Value<V>) -> Self::Output {
332 self.as_ref() + rhs
333 }
334}
335
336impl<V, O> Sub for Value<V>
341where
342 V: Sub<Output = O>,
343{
344 type Output = Value<O>;
345
346 fn sub(self, rhs: Self) -> Self::Output {
347 Value {
348 inner: self.inner.zip(rhs.inner).map(|(a, b)| a - b),
349 }
350 }
351}
352
353impl<V, O> Sub for &Value<V>
354where
355 for<'v> &'v V: Sub<Output = O>,
356{
357 type Output = Value<O>;
358
359 fn sub(self, rhs: Self) -> Self::Output {
360 Value {
361 inner: self
362 .inner
363 .as_ref()
364 .zip(rhs.inner.as_ref())
365 .map(|(a, b)| a - b),
366 }
367 }
368}
369
370impl<V, O> Sub<Value<&V>> for Value<V>
371where
372 for<'v> V: Sub<&'v V, Output = O>,
373{
374 type Output = Value<O>;
375
376 fn sub(self, rhs: Value<&V>) -> Self::Output {
377 Value {
378 inner: self.inner.zip(rhs.inner).map(|(a, b)| a - b),
379 }
380 }
381}
382
383impl<V, O> Sub<Value<V>> for Value<&V>
384where
385 for<'v> &'v V: Sub<V, Output = O>,
386{
387 type Output = Value<O>;
388
389 fn sub(self, rhs: Value<V>) -> Self::Output {
390 Value {
391 inner: self.inner.zip(rhs.inner).map(|(a, b)| a - b),
392 }
393 }
394}
395
396impl<V, O> Sub<&Value<V>> for Value<V>
397where
398 for<'v> V: Sub<&'v V, Output = O>,
399{
400 type Output = Value<O>;
401
402 fn sub(self, rhs: &Self) -> Self::Output {
403 self - rhs.as_ref()
404 }
405}
406
407impl<V, O> Sub<Value<V>> for &Value<V>
408where
409 for<'v> &'v V: Sub<V, Output = O>,
410{
411 type Output = Value<O>;
412
413 fn sub(self, rhs: Value<V>) -> Self::Output {
414 self.as_ref() - rhs
415 }
416}
417
418impl<V, O> Mul for Value<V>
423where
424 V: Mul<Output = O>,
425{
426 type Output = Value<O>;
427
428 fn mul(self, rhs: Self) -> Self::Output {
429 Value {
430 inner: self.inner.zip(rhs.inner).map(|(a, b)| a * b),
431 }
432 }
433}
434
435impl<V, O> Mul for &Value<V>
436where
437 for<'v> &'v V: Mul<Output = O>,
438{
439 type Output = Value<O>;
440
441 fn mul(self, rhs: Self) -> Self::Output {
442 Value {
443 inner: self
444 .inner
445 .as_ref()
446 .zip(rhs.inner.as_ref())
447 .map(|(a, b)| a * b),
448 }
449 }
450}
451
452impl<V, O> Mul<Value<&V>> for Value<V>
453where
454 for<'v> V: Mul<&'v V, Output = O>,
455{
456 type Output = Value<O>;
457
458 fn mul(self, rhs: Value<&V>) -> Self::Output {
459 Value {
460 inner: self.inner.zip(rhs.inner).map(|(a, b)| a * b),
461 }
462 }
463}
464
465impl<V, O> Mul<Value<V>> for Value<&V>
466where
467 for<'v> &'v V: Mul<V, Output = O>,
468{
469 type Output = Value<O>;
470
471 fn mul(self, rhs: Value<V>) -> Self::Output {
472 Value {
473 inner: self.inner.zip(rhs.inner).map(|(a, b)| a * b),
474 }
475 }
476}
477
478impl<V, O> Mul<&Value<V>> for Value<V>
479where
480 for<'v> V: Mul<&'v V, Output = O>,
481{
482 type Output = Value<O>;
483
484 fn mul(self, rhs: &Self) -> Self::Output {
485 self * rhs.as_ref()
486 }
487}
488
489impl<V, O> Mul<Value<V>> for &Value<V>
490where
491 for<'v> &'v V: Mul<V, Output = O>,
492{
493 type Output = Value<O>;
494
495 fn mul(self, rhs: Value<V>) -> Self::Output {
496 self.as_ref() * rhs
497 }
498}
499
500impl<F: Field> From<Value<F>> for Value<Assigned<F>> {
505 fn from(value: Value<F>) -> Self {
506 Self {
507 inner: value.inner.map(Assigned::from),
508 }
509 }
510}
511
512impl<F: Field> Add<Value<F>> for Value<Assigned<F>> {
513 type Output = Value<Assigned<F>>;
514
515 fn add(self, rhs: Value<F>) -> Self::Output {
516 Value {
517 inner: self.inner.zip(rhs.inner).map(|(a, b)| a + b),
518 }
519 }
520}
521
522impl<F: Field> Add<F> for Value<Assigned<F>> {
523 type Output = Value<Assigned<F>>;
524
525 fn add(self, rhs: F) -> Self::Output {
526 self + Value::known(rhs)
527 }
528}
529
530impl<F: Field> Add<Value<F>> for Value<&Assigned<F>> {
531 type Output = Value<Assigned<F>>;
532
533 fn add(self, rhs: Value<F>) -> Self::Output {
534 Value {
535 inner: self.inner.zip(rhs.inner).map(|(a, b)| a + b),
536 }
537 }
538}
539
540impl<F: Field> Add<F> for Value<&Assigned<F>> {
541 type Output = Value<Assigned<F>>;
542
543 fn add(self, rhs: F) -> Self::Output {
544 self + Value::known(rhs)
545 }
546}
547
548impl<F: Field> Sub<Value<F>> for Value<Assigned<F>> {
549 type Output = Value<Assigned<F>>;
550
551 fn sub(self, rhs: Value<F>) -> Self::Output {
552 Value {
553 inner: self.inner.zip(rhs.inner).map(|(a, b)| a - b),
554 }
555 }
556}
557
558impl<F: Field> Sub<F> for Value<Assigned<F>> {
559 type Output = Value<Assigned<F>>;
560
561 fn sub(self, rhs: F) -> Self::Output {
562 self - Value::known(rhs)
563 }
564}
565
566impl<F: Field> Sub<Value<F>> for Value<&Assigned<F>> {
567 type Output = Value<Assigned<F>>;
568
569 fn sub(self, rhs: Value<F>) -> Self::Output {
570 Value {
571 inner: self.inner.zip(rhs.inner).map(|(a, b)| a - b),
572 }
573 }
574}
575
576impl<F: Field> Sub<F> for Value<&Assigned<F>> {
577 type Output = Value<Assigned<F>>;
578
579 fn sub(self, rhs: F) -> Self::Output {
580 self - Value::known(rhs)
581 }
582}
583
584impl<F: Field> Mul<Value<F>> for Value<Assigned<F>> {
585 type Output = Value<Assigned<F>>;
586
587 fn mul(self, rhs: Value<F>) -> Self::Output {
588 Value {
589 inner: self.inner.zip(rhs.inner).map(|(a, b)| a * b),
590 }
591 }
592}
593
594impl<F: Field> Mul<F> for Value<Assigned<F>> {
595 type Output = Value<Assigned<F>>;
596
597 fn mul(self, rhs: F) -> Self::Output {
598 self * Value::known(rhs)
599 }
600}
601
602impl<F: Field> Mul<Value<F>> for Value<&Assigned<F>> {
603 type Output = Value<Assigned<F>>;
604
605 fn mul(self, rhs: Value<F>) -> Self::Output {
606 Value {
607 inner: self.inner.zip(rhs.inner).map(|(a, b)| a * b),
608 }
609 }
610}
611
612impl<F: Field> Mul<F> for Value<&Assigned<F>> {
613 type Output = Value<Assigned<F>>;
614
615 fn mul(self, rhs: F) -> Self::Output {
616 self * Value::known(rhs)
617 }
618}
619
620impl<V> Value<V> {
621 pub fn to_field<F: Field>(&self) -> Value<Assigned<F>>
623 where
624 for<'v> Assigned<F>: From<&'v V>,
625 {
626 Value {
627 inner: self.inner.as_ref().map(|v| v.into()),
628 }
629 }
630
631 pub fn into_field<F: Field>(self) -> Value<Assigned<F>>
633 where
634 V: Into<Assigned<F>>,
635 {
636 Value {
637 inner: self.inner.map(|v| v.into()),
638 }
639 }
640
641 pub fn double<F: Field>(&self) -> Value<Assigned<F>>
655 where
656 V: Borrow<Assigned<F>>,
657 {
658 Value {
659 inner: self.inner.as_ref().map(|v| v.borrow().double()),
660 }
661 }
662
663 pub fn square<F: Field>(&self) -> Value<Assigned<F>>
665 where
666 V: Borrow<Assigned<F>>,
667 {
668 Value {
669 inner: self.inner.as_ref().map(|v| v.borrow().square()),
670 }
671 }
672
673 pub fn cube<F: Field>(&self) -> Value<Assigned<F>>
675 where
676 V: Borrow<Assigned<F>>,
677 {
678 Value {
679 inner: self.inner.as_ref().map(|v| v.borrow().cube()),
680 }
681 }
682
683 pub fn invert<F: Field>(&self) -> Value<Assigned<F>>
685 where
686 V: Borrow<Assigned<F>>,
687 {
688 Value {
689 inner: self.inner.as_ref().map(|v| v.borrow().invert()),
690 }
691 }
692}
693
694impl<F: Field> Value<Assigned<F>> {
695 pub fn evaluate(self) -> Value<F> {
699 Value {
700 inner: self.inner.map(|v| v.evaluate()),
701 }
702 }
703}