openvm_native_compiler/ir/
symbolic.rs

1use alloc::sync::Arc;
2use core::{
3    any::Any,
4    ops::{Add, Div, Mul, Neg, Sub},
5};
6use std::{
7    any::TypeId,
8    hash::Hash,
9    iter::{Product, Sum},
10    mem,
11    ops::{AddAssign, DivAssign, MulAssign, SubAssign},
12};
13
14use openvm_stark_backend::p3_field::{
15    ExtensionField, Field, FieldArray, PrimeCharacteristicRing, PrimeField,
16};
17use serde::{Deserialize, Serialize};
18
19use super::{utils::prime_field_to_usize, Ext, Felt, Usize, Var};
20
21const NUM_RANDOM_ELEMENTS: usize = 4;
22
23pub type Digest<T> = FieldArray<T, NUM_RANDOM_ELEMENTS>;
24
25pub fn elements<F: Field>() -> Digest<F> {
26    let powers = [1671541671, 1254988180, 442438744, 1716490559];
27    let generator = F::GENERATOR;
28
29    Digest::from(powers.map(|p| generator.exp_u64(p)))
30}
31
32pub fn ext_elements<F: Field, EF: ExtensionField<F>>() -> Digest<EF> {
33    let powers = [1021539871, 1430550064, 447478069, 1248903325];
34    let generator = EF::GENERATOR;
35
36    Digest::from(powers.map(|p| generator.exp_u64(p)))
37}
38
39fn digest_id<F: Field>(id: u32) -> Digest<F> {
40    let elements = elements();
41    Digest::from(
42        elements
43            .0
44            .map(|e: F| (e + F::from_u32(id)).try_inverse().unwrap_or(F::ONE)),
45    )
46}
47
48fn digest_id_ext<F: Field, EF: ExtensionField<F>>(id: u32) -> Digest<EF> {
49    let elements = ext_elements();
50    Digest::from(
51        elements
52            .0
53            .map(|e: EF| (e + EF::from_u32(id)).try_inverse().unwrap_or(EF::ONE)),
54    )
55}
56
57fn div_digests<F: Field>(a: Digest<F>, b: Digest<F>) -> Digest<F> {
58    Digest::from(core::array::from_fn(|i| a.0[i] / b.0[i]))
59}
60
61/// A symbolic variable. For any binary operator, at least one of the operands must be variable.
62#[derive(Debug, Clone)]
63pub enum SymbolicVar<N: Field> {
64    Const(N, Digest<N>),
65    Val(Var<N>, Digest<N>),
66    Add(Arc<SymbolicVar<N>>, Arc<SymbolicVar<N>>, Digest<N>),
67    Mul(Arc<SymbolicVar<N>>, Arc<SymbolicVar<N>>, Digest<N>),
68    Sub(Arc<SymbolicVar<N>>, Arc<SymbolicVar<N>>, Digest<N>),
69    Neg(Arc<SymbolicVar<N>>, Digest<N>),
70}
71
72#[derive(Debug, Clone)]
73pub enum SymbolicFelt<F: Field> {
74    Const(F, Digest<F>),
75    Val(Felt<F>, Digest<F>),
76    Add(Arc<SymbolicFelt<F>>, Arc<SymbolicFelt<F>>, Digest<F>),
77    Mul(Arc<SymbolicFelt<F>>, Arc<SymbolicFelt<F>>, Digest<F>),
78    Sub(Arc<SymbolicFelt<F>>, Arc<SymbolicFelt<F>>, Digest<F>),
79    Div(Arc<SymbolicFelt<F>>, Arc<SymbolicFelt<F>>, Digest<F>),
80    Neg(Arc<SymbolicFelt<F>>, Digest<F>),
81}
82
83#[derive(Debug, Clone)]
84pub enum SymbolicExt<F: Field, EF: Field> {
85    Const(EF, Digest<EF>),
86    Base(Arc<SymbolicFelt<F>>, Digest<EF>),
87    Val(Ext<F, EF>, Digest<EF>),
88    Add(Arc<SymbolicExt<F, EF>>, Arc<SymbolicExt<F, EF>>, Digest<EF>),
89    Mul(Arc<SymbolicExt<F, EF>>, Arc<SymbolicExt<F, EF>>, Digest<EF>),
90    Sub(Arc<SymbolicExt<F, EF>>, Arc<SymbolicExt<F, EF>>, Digest<EF>),
91    Div(Arc<SymbolicExt<F, EF>>, Arc<SymbolicExt<F, EF>>, Digest<EF>),
92    Neg(Arc<SymbolicExt<F, EF>>, Digest<EF>),
93}
94
95/// A right value of Var. It should never be assigned with a value.
96#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
97pub enum RVar<N> {
98    Const(N),
99    Val(Var<N>),
100}
101
102impl<N: PrimeField> RVar<N> {
103    pub fn zero() -> Self {
104        RVar::Const(N::ZERO)
105    }
106    pub fn one() -> Self {
107        RVar::Const(N::ONE)
108    }
109    pub fn from_field(n: N) -> Self {
110        RVar::Const(n)
111    }
112    pub fn is_const(&self) -> bool {
113        match self {
114            RVar::Const(_) => true,
115            RVar::Val(_) => false,
116        }
117    }
118    pub fn value(&self) -> usize {
119        match self {
120            RVar::Const(c) => prime_field_to_usize(*c),
121            _ => panic!("RVar::value() called on non-const value"),
122        }
123    }
124    pub fn field_value(&self) -> N {
125        match self {
126            RVar::Const(c) => *c,
127            _ => panic!("RVar::field_value() called on non-const value"),
128        }
129    }
130
131    pub fn variable(&self) -> Var<N> {
132        match self {
133            RVar::Const(_) => panic!("RVar::variable() called on const value"),
134            RVar::Val(var) => *var,
135        }
136    }
137}
138
139impl<N: Field> Hash for SymbolicVar<N> {
140    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
141        for elem in self.digest().0.iter() {
142            elem.hash(state);
143        }
144    }
145}
146
147impl<N: Field> PartialEq for SymbolicVar<N> {
148    fn eq(&self, other: &Self) -> bool {
149        if self.digest() != other.digest() {
150            return false;
151        }
152        match (self, other) {
153            (SymbolicVar::Const(a, _), SymbolicVar::Const(b, _)) => a == b,
154            (SymbolicVar::Val(a, _), SymbolicVar::Val(b, _)) => a == b,
155            (SymbolicVar::Add(a, b, _), SymbolicVar::Add(c, d, _)) => a == c && b == d,
156            (SymbolicVar::Mul(a, b, _), SymbolicVar::Mul(c, d, _)) => a == c && b == d,
157            (SymbolicVar::Sub(a, b, _), SymbolicVar::Sub(c, d, _)) => a == c && b == d,
158            (SymbolicVar::Neg(a, _), SymbolicVar::Neg(b, _)) => a == b,
159            _ => false,
160        }
161    }
162}
163
164impl<N: Field> Eq for SymbolicVar<N> {}
165
166impl<F: Field> Hash for SymbolicFelt<F> {
167    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
168        for elem in self.digest().0.iter() {
169            elem.hash(state);
170        }
171    }
172}
173
174impl<F: Field> PartialEq for SymbolicFelt<F> {
175    fn eq(&self, other: &Self) -> bool {
176        if self.digest() != other.digest() {
177            return false;
178        }
179        match (self, other) {
180            (SymbolicFelt::Const(a, _), SymbolicFelt::Const(b, _)) => a == b,
181            (SymbolicFelt::Val(a, _), SymbolicFelt::Val(b, _)) => a == b,
182            (SymbolicFelt::Add(a, b, _), SymbolicFelt::Add(c, d, _)) => a == c && b == d,
183            (SymbolicFelt::Mul(a, b, _), SymbolicFelt::Mul(c, d, _)) => a == c && b == d,
184            (SymbolicFelt::Sub(a, b, _), SymbolicFelt::Sub(c, d, _)) => a == c && b == d,
185            (SymbolicFelt::Div(a, b, _), SymbolicFelt::Div(c, d, _)) => a == c && b == d,
186            (SymbolicFelt::Neg(a, _), SymbolicFelt::Neg(b, _)) => a == b,
187            _ => false,
188        }
189    }
190}
191
192impl<F: Field> Eq for SymbolicFelt<F> {}
193
194impl<F: Field, EF: Field> Hash for SymbolicExt<F, EF> {
195    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
196        for elem in self.digest().0.iter() {
197            elem.hash(state);
198        }
199    }
200}
201
202impl<F: Field, EF: Field> PartialEq for SymbolicExt<F, EF> {
203    fn eq(&self, other: &Self) -> bool {
204        if self.digest() != other.digest() {
205            return false;
206        }
207        match (self, other) {
208            (SymbolicExt::Const(a, _), SymbolicExt::Const(b, _)) => a == b,
209            (SymbolicExt::Base(a, _), SymbolicExt::Base(b, _)) => a == b,
210            (SymbolicExt::Val(a, _), SymbolicExt::Val(b, _)) => a == b,
211            (SymbolicExt::Add(a, b, _), SymbolicExt::Add(c, d, _)) => a == c && b == d,
212            (SymbolicExt::Mul(a, b, _), SymbolicExt::Mul(c, d, _)) => a == c && b == d,
213            (SymbolicExt::Sub(a, b, _), SymbolicExt::Sub(c, d, _)) => a == c && b == d,
214            (SymbolicExt::Div(a, b, _), SymbolicExt::Div(c, d, _)) => a == c && b == d,
215            (SymbolicExt::Neg(a, _), SymbolicExt::Neg(b, _)) => a == b,
216            _ => false,
217        }
218    }
219}
220
221impl<F: Field, EF: Field> Eq for SymbolicExt<F, EF> {}
222
223impl<N: Field> SymbolicVar<N> {
224    pub(crate) const fn digest(&self) -> Digest<N> {
225        match self {
226            SymbolicVar::Const(_, d) => *d,
227            SymbolicVar::Val(_, d) => *d,
228            SymbolicVar::Add(_, _, d) => *d,
229            SymbolicVar::Mul(_, _, d) => *d,
230            SymbolicVar::Sub(_, _, d) => *d,
231            SymbolicVar::Neg(_, d) => *d,
232        }
233    }
234}
235
236impl<F: Field> SymbolicFelt<F> {
237    pub(crate) const fn digest(&self) -> Digest<F> {
238        match self {
239            SymbolicFelt::Const(_, d) => *d,
240            SymbolicFelt::Val(_, d) => *d,
241            SymbolicFelt::Add(_, _, d) => *d,
242            SymbolicFelt::Mul(_, _, d) => *d,
243            SymbolicFelt::Sub(_, _, d) => *d,
244            SymbolicFelt::Div(_, _, d) => *d,
245            SymbolicFelt::Neg(_, d) => *d,
246        }
247    }
248}
249
250impl<F: Field, EF: Field> SymbolicExt<F, EF> {
251    pub(crate) const fn digest(&self) -> Digest<EF> {
252        match self {
253            SymbolicExt::Const(_, d) => *d,
254            SymbolicExt::Base(_, d) => *d,
255            SymbolicExt::Val(_, d) => *d,
256            SymbolicExt::Add(_, _, d) => *d,
257            SymbolicExt::Mul(_, _, d) => *d,
258            SymbolicExt::Sub(_, _, d) => *d,
259            SymbolicExt::Div(_, _, d) => *d,
260            SymbolicExt::Neg(_, d) => *d,
261        }
262    }
263}
264
265#[derive(Debug, Clone)]
266pub enum ExtOperand<F: Field, EF: ExtensionField<F>> {
267    Base(F),
268    Const(EF),
269    Felt(Felt<F>),
270    Ext(Ext<F, EF>),
271    SymFelt(SymbolicFelt<F>),
272    Sym(SymbolicExt<F, EF>),
273}
274
275impl<F: Field, EF: ExtensionField<F>> ExtOperand<F, EF> {
276    pub fn digest(&self) -> Digest<EF> {
277        match self {
278            ExtOperand::Base(f) => SymbolicFelt::from(*f).digest().0.map(EF::from).into(),
279            ExtOperand::Const(ef) => (*ef).into(),
280            ExtOperand::Felt(f) => SymbolicFelt::from(*f).digest().0.map(EF::from).into(),
281            ExtOperand::Ext(e) => digest_id_ext::<F, EF>(e.0),
282            ExtOperand::SymFelt(f) => f.digest().0.map(EF::from).into(),
283            ExtOperand::Sym(e) => e.digest(),
284        }
285    }
286
287    pub fn symbolic(self) -> SymbolicExt<F, EF> {
288        let digest = self.digest();
289        match self {
290            ExtOperand::Base(f) => SymbolicExt::Base(Arc::new(SymbolicFelt::from(f)), digest),
291            ExtOperand::Const(ef) => SymbolicExt::Const(ef, digest),
292            ExtOperand::Felt(f) => SymbolicExt::Base(Arc::new(SymbolicFelt::from(f)), digest),
293            ExtOperand::Ext(e) => SymbolicExt::Val(e, digest),
294            ExtOperand::SymFelt(f) => SymbolicExt::Base(Arc::new(f), digest),
295            ExtOperand::Sym(e) => e,
296        }
297    }
298}
299
300pub trait ExtConst<F: Field, EF: ExtensionField<F>> {
301    fn cons(self) -> SymbolicExt<F, EF>;
302}
303
304impl<F: Field, EF: ExtensionField<F>> ExtConst<F, EF> for EF {
305    fn cons(self) -> SymbolicExt<F, EF> {
306        SymbolicExt::Const(self, self.into())
307    }
308}
309
310pub trait ExtensionOperand<F: Field, EF: ExtensionField<F>> {
311    fn to_operand(self) -> ExtOperand<F, EF>;
312}
313
314impl<N: Field> PrimeCharacteristicRing for SymbolicVar<N> {
315    type PrimeSubfield = N::PrimeSubfield;
316
317    const ZERO: Self = SymbolicVar::Const(N::ZERO, FieldArray([N::ZERO; 4]));
318    const ONE: Self = SymbolicVar::Const(N::ONE, FieldArray([N::ONE; 4]));
319    const TWO: Self = SymbolicVar::Const(N::TWO, FieldArray([N::TWO; 4]));
320    const NEG_ONE: Self = SymbolicVar::Const(N::NEG_ONE, FieldArray([N::NEG_ONE; 4]));
321
322    fn from_prime_subfield(f: Self::PrimeSubfield) -> Self {
323        SymbolicVar::from(N::from_prime_subfield(f))
324    }
325}
326
327/// Trait to exclude SymbolicVar in generic parameters.
328trait NotSymbolicVar {}
329impl<N: Field> NotSymbolicVar for N {}
330impl<N: Field> NotSymbolicVar for Var<N> {}
331impl<N: PrimeField> NotSymbolicVar for Usize<N> {}
332impl<N: Field> NotSymbolicVar for RVar<N> {}
333
334impl<F: Field> PrimeCharacteristicRing for SymbolicFelt<F> {
335    type PrimeSubfield = F::PrimeSubfield;
336
337    const ZERO: Self = SymbolicFelt::Const(F::ZERO, FieldArray([F::ZERO; 4]));
338    const ONE: Self = SymbolicFelt::Const(F::ONE, FieldArray([F::ONE; 4]));
339    const TWO: Self = SymbolicFelt::Const(F::TWO, FieldArray([F::TWO; 4]));
340    const NEG_ONE: Self = SymbolicFelt::Const(F::NEG_ONE, FieldArray([F::NEG_ONE; 4]));
341
342    fn from_prime_subfield(f: Self::PrimeSubfield) -> Self {
343        SymbolicFelt::from(F::from_prime_subfield(f))
344    }
345}
346
347impl<F: Field, EF: ExtensionField<F>> PrimeCharacteristicRing for SymbolicExt<F, EF> {
348    type PrimeSubfield = F::PrimeSubfield;
349
350    const ZERO: Self = SymbolicExt::Const(EF::ZERO, FieldArray([EF::ZERO; 4]));
351    const ONE: Self =
352        SymbolicExt::Const(EF::ONE, FieldArray([EF::ZERO, EF::ZERO, EF::ZERO, EF::ONE]));
353    const TWO: Self =
354        SymbolicExt::Const(EF::TWO, FieldArray([EF::ZERO, EF::ZERO, EF::ZERO, EF::TWO]));
355    const NEG_ONE: Self = SymbolicExt::Const(
356        EF::NEG_ONE,
357        FieldArray([EF::ZERO, EF::ZERO, EF::ZERO, EF::NEG_ONE]),
358    );
359
360    fn from_prime_subfield(f: Self::PrimeSubfield) -> Self {
361        let ef = EF::from(F::from_prime_subfield(f));
362        SymbolicExt::Const(ef, ef.into())
363    }
364}
365
366// Implement all conversions from constants N, F, EF, to the corresponding symbolic types
367
368impl<N: Field> From<N> for SymbolicVar<N> {
369    fn from(n: N) -> Self {
370        SymbolicVar::Const(n, n.into())
371    }
372}
373
374impl<F: Field> From<F> for SymbolicFelt<F> {
375    fn from(f: F) -> Self {
376        SymbolicFelt::Const(f, f.into())
377    }
378}
379
380impl<F: Field, EF: ExtensionField<F>> From<F> for SymbolicExt<F, EF> {
381    fn from(f: F) -> Self {
382        f.to_operand().symbolic()
383    }
384}
385
386// Implement all conversions from Var<N>, Felt<F>, Ext<F, EF> to the corresponding symbolic types
387
388impl<N: Field> From<Var<N>> for SymbolicVar<N> {
389    fn from(v: Var<N>) -> Self {
390        SymbolicVar::Val(v, digest_id(v.0))
391    }
392}
393
394impl<F: Field> From<Felt<F>> for SymbolicFelt<F> {
395    fn from(f: Felt<F>) -> Self {
396        SymbolicFelt::Val(f, digest_id(f.0))
397    }
398}
399
400impl<F: Field, EF: ExtensionField<F>> From<Ext<F, EF>> for SymbolicExt<F, EF> {
401    fn from(e: Ext<F, EF>) -> Self {
402        e.to_operand().symbolic()
403    }
404}
405
406// Implement all operations for SymbolicVar<N>, SymbolicFelt<F>, SymbolicExt<F, EF>
407
408impl<N: Field> Add for SymbolicVar<N> {
409    type Output = Self;
410
411    fn add(self, rhs: Self) -> Self::Output {
412        let digest = self.digest() + rhs.digest();
413        match (&self, &rhs) {
414            (SymbolicVar::Const(a, _), SymbolicVar::Const(b, _)) => {
415                return SymbolicVar::Const(*a + *b, digest);
416            }
417            (SymbolicVar::Const(a, _), _) => {
418                if a.is_zero() {
419                    return rhs;
420                }
421            }
422            (_, SymbolicVar::Const(b, _)) => {
423                if b.is_zero() {
424                    return self;
425                }
426            }
427            _ => (),
428        }
429        SymbolicVar::Add(Arc::new(self), Arc::new(rhs), digest)
430    }
431}
432
433impl<N: Field, RHS: Into<SymbolicVar<N>> + NotSymbolicVar> Add<RHS> for SymbolicVar<N> {
434    type Output = Self;
435
436    fn add(self, rhs: RHS) -> Self::Output {
437        self + rhs.into()
438    }
439}
440
441impl<F: Field> Add for SymbolicFelt<F> {
442    type Output = Self;
443
444    fn add(self, rhs: Self) -> Self::Output {
445        let digest = self.digest() + rhs.digest();
446        SymbolicFelt::Add(Arc::new(self), Arc::new(rhs), digest)
447    }
448}
449
450impl<F: Field, EF: ExtensionField<F>, E: ExtensionOperand<F, EF>> Add<E> for SymbolicExt<F, EF> {
451    type Output = Self;
452
453    fn add(self, rhs: E) -> Self::Output {
454        let rhs = rhs.to_operand().symbolic();
455        let digest = self.digest() + rhs.digest();
456        SymbolicExt::Add(Arc::new(self), Arc::new(rhs), digest)
457    }
458}
459
460impl<N: Field> Mul for SymbolicVar<N> {
461    type Output = Self;
462
463    fn mul(self, rhs: Self) -> Self::Output {
464        let digest = self.digest() * rhs.digest();
465        match (&self, &rhs) {
466            (SymbolicVar::Const(a, _), SymbolicVar::Const(b, _)) => {
467                return SymbolicVar::Const(*a * *b, digest);
468            }
469            (SymbolicVar::Const(a, _), _) => {
470                if a.is_zero() {
471                    return self;
472                }
473                if a.is_one() {
474                    return rhs;
475                }
476            }
477            (_, SymbolicVar::Const(b, _)) => {
478                if b.is_zero() {
479                    return rhs;
480                }
481                if b.is_one() {
482                    return self;
483                }
484            }
485            _ => (),
486        }
487        SymbolicVar::Mul(Arc::new(self), Arc::new(rhs), digest)
488    }
489}
490
491impl<N: Field, RHS: Into<SymbolicVar<N>> + NotSymbolicVar> Mul<RHS> for SymbolicVar<N> {
492    type Output = Self;
493
494    fn mul(self, rhs: RHS) -> Self::Output {
495        self * rhs.into()
496    }
497}
498
499impl<F: Field> Mul for SymbolicFelt<F> {
500    type Output = Self;
501
502    fn mul(self, rhs: Self) -> Self::Output {
503        let digest = self.digest() * rhs.digest();
504        SymbolicFelt::Mul(Arc::new(self), Arc::new(rhs), digest)
505    }
506}
507
508impl<F: Field, EF: ExtensionField<F>, E: Any> Mul<E> for SymbolicExt<F, EF> {
509    type Output = Self;
510
511    fn mul(self, rhs: E) -> Self::Output {
512        let rhs = rhs.to_operand();
513        let rhs_digest = rhs.digest();
514        let prod_digest = self.digest() * rhs_digest;
515        match rhs {
516            ExtOperand::Base(f) => SymbolicExt::Mul(
517                Arc::new(self),
518                Arc::new(SymbolicExt::Base(
519                    Arc::new(SymbolicFelt::from(f)),
520                    rhs_digest,
521                )),
522                prod_digest,
523            ),
524            ExtOperand::Const(ef) => SymbolicExt::Mul(
525                Arc::new(self),
526                Arc::new(SymbolicExt::Const(ef, rhs_digest)),
527                prod_digest,
528            ),
529            ExtOperand::Felt(f) => SymbolicExt::Mul(
530                Arc::new(self),
531                Arc::new(SymbolicExt::Base(
532                    Arc::new(SymbolicFelt::from(f)),
533                    rhs_digest,
534                )),
535                prod_digest,
536            ),
537            ExtOperand::Ext(e) => SymbolicExt::Mul(
538                Arc::new(self),
539                Arc::new(SymbolicExt::Val(e, rhs_digest)),
540                prod_digest,
541            ),
542            ExtOperand::SymFelt(f) => SymbolicExt::Mul(
543                Arc::new(self),
544                Arc::new(SymbolicExt::Base(Arc::new(f), rhs_digest)),
545                prod_digest,
546            ),
547            ExtOperand::Sym(e) => SymbolicExt::Mul(Arc::new(self), Arc::new(e), prod_digest),
548        }
549    }
550}
551
552impl<N: Field> Sub for SymbolicVar<N> {
553    type Output = Self;
554
555    fn sub(self, rhs: Self) -> Self::Output {
556        let digest = self.digest() - rhs.digest();
557        match (&self, &rhs) {
558            (SymbolicVar::Const(a, _), SymbolicVar::Const(b, _)) => {
559                return SymbolicVar::Const(*a - *b, digest);
560            }
561            (SymbolicVar::Const(a, _), _) => {
562                if a.is_zero() {
563                    return rhs;
564                }
565            }
566            (_, SymbolicVar::Const(b, _)) => {
567                if b.is_zero() {
568                    return self;
569                }
570            }
571            _ => (),
572        }
573        SymbolicVar::Sub(Arc::new(self), Arc::new(rhs), digest)
574    }
575}
576
577impl<N: Field, RHS: Into<SymbolicVar<N>> + NotSymbolicVar> Sub<RHS> for SymbolicVar<N> {
578    type Output = Self;
579
580    fn sub(self, rhs: RHS) -> Self::Output {
581        self - rhs.into()
582    }
583}
584
585impl<F: Field> Sub for SymbolicFelt<F> {
586    type Output = Self;
587
588    fn sub(self, rhs: Self) -> Self::Output {
589        let digest = self.digest() - rhs.digest();
590        SymbolicFelt::Sub(Arc::new(self), Arc::new(rhs), digest)
591    }
592}
593
594impl<F: Field, EF: ExtensionField<F>, E: Any> Sub<E> for SymbolicExt<F, EF> {
595    type Output = Self;
596
597    fn sub(self, rhs: E) -> Self::Output {
598        let rhs = rhs.to_operand();
599        let rhs_digest = rhs.digest();
600        let digest = self.digest() - rhs_digest;
601        match rhs {
602            ExtOperand::Base(f) => SymbolicExt::Sub(
603                Arc::new(self),
604                Arc::new(SymbolicExt::Base(
605                    Arc::new(SymbolicFelt::from(f)),
606                    rhs_digest,
607                )),
608                digest,
609            ),
610            ExtOperand::Const(ef) => SymbolicExt::Sub(
611                Arc::new(self),
612                Arc::new(SymbolicExt::Const(ef, rhs_digest)),
613                digest,
614            ),
615            ExtOperand::Felt(f) => SymbolicExt::Sub(
616                Arc::new(self),
617                Arc::new(SymbolicExt::Base(
618                    Arc::new(SymbolicFelt::from(f)),
619                    rhs_digest,
620                )),
621                digest,
622            ),
623            ExtOperand::Ext(e) => SymbolicExt::Sub(
624                Arc::new(self),
625                Arc::new(SymbolicExt::Val(e, rhs_digest)),
626                digest,
627            ),
628            ExtOperand::SymFelt(f) => SymbolicExt::Sub(
629                Arc::new(self),
630                Arc::new(SymbolicExt::Base(Arc::new(f), rhs_digest)),
631                digest,
632            ),
633            ExtOperand::Sym(e) => SymbolicExt::Sub(Arc::new(self), Arc::new(e), digest),
634        }
635    }
636}
637
638impl<F: Field> Div for SymbolicFelt<F> {
639    type Output = Self;
640
641    fn div(self, rhs: Self) -> Self::Output {
642        let self_digest = self.digest();
643        let rhs_digest = rhs.digest();
644        let digest = div_digests(self_digest, rhs_digest);
645        SymbolicFelt::Div(Arc::new(self), Arc::new(rhs), digest)
646    }
647}
648
649impl<F: Field, EF: ExtensionField<F>, E: Any> Div<E> for SymbolicExt<F, EF> {
650    type Output = Self;
651
652    fn div(self, rhs: E) -> Self::Output {
653        let rhs = rhs.to_operand();
654        let rhs_digest = rhs.digest();
655        let digest = div_digests(self.digest(), rhs_digest);
656        match rhs {
657            ExtOperand::Base(f) => SymbolicExt::Div(
658                Arc::new(self),
659                Arc::new(SymbolicExt::Base(
660                    Arc::new(SymbolicFelt::from(f)),
661                    rhs_digest,
662                )),
663                digest,
664            ),
665            ExtOperand::Const(ef) => SymbolicExt::Div(
666                Arc::new(self),
667                Arc::new(SymbolicExt::Const(ef, rhs_digest)),
668                digest,
669            ),
670            ExtOperand::Felt(f) => SymbolicExt::Div(
671                Arc::new(self),
672                Arc::new(SymbolicExt::Base(
673                    Arc::new(SymbolicFelt::from(f)),
674                    rhs_digest,
675                )),
676                digest,
677            ),
678            ExtOperand::Ext(e) => SymbolicExt::Div(
679                Arc::new(self),
680                Arc::new(SymbolicExt::Val(e, rhs_digest)),
681                digest,
682            ),
683            ExtOperand::SymFelt(f) => SymbolicExt::Div(
684                Arc::new(self),
685                Arc::new(SymbolicExt::Base(Arc::new(f), rhs_digest)),
686                digest,
687            ),
688            ExtOperand::Sym(e) => SymbolicExt::Div(Arc::new(self), Arc::new(e), digest),
689        }
690    }
691}
692
693impl<N: Field> Neg for SymbolicVar<N> {
694    type Output = Self;
695
696    fn neg(self) -> Self::Output {
697        let digest = -self.digest();
698        match &self {
699            SymbolicVar::Const(c, _) => SymbolicVar::Const(-*c, digest),
700            _ => SymbolicVar::Neg(Arc::new(self), digest),
701        }
702    }
703}
704
705impl<F: Field> Neg for SymbolicFelt<F> {
706    type Output = Self;
707
708    fn neg(self) -> Self::Output {
709        let digest = -self.digest();
710        SymbolicFelt::Neg(Arc::new(self), digest)
711    }
712}
713
714impl<F: Field, EF: ExtensionField<F>> Neg for SymbolicExt<F, EF> {
715    type Output = Self;
716
717    fn neg(self) -> Self::Output {
718        let digest = -self.digest();
719        SymbolicExt::Neg(Arc::new(self), digest)
720    }
721}
722
723// Implement all operations between N, F, EF, and SymbolicVar<N>, SymbolicFelt<F>, SymbolicExt<F,
724// EF>
725
726impl<F: Field> Add<F> for SymbolicFelt<F> {
727    type Output = Self;
728
729    fn add(self, rhs: F) -> Self::Output {
730        self + SymbolicFelt::from(rhs)
731    }
732}
733
734impl<F: Field> Mul<F> for SymbolicFelt<F> {
735    type Output = Self;
736
737    fn mul(self, rhs: F) -> Self::Output {
738        self * SymbolicFelt::from(rhs)
739    }
740}
741
742impl<F: Field> Sub<F> for SymbolicFelt<F> {
743    type Output = Self;
744
745    fn sub(self, rhs: F) -> Self::Output {
746        self - SymbolicFelt::from(rhs)
747    }
748}
749
750// Implement all operations between SymbolicVar<N>, SymbolicFelt<F>, SymbolicExt<F, EF>, and Var<N>,
751//  Felt<F>, Ext<F, EF>.
752
753impl<F: Field> Add<Felt<F>> for SymbolicFelt<F> {
754    type Output = SymbolicFelt<F>;
755
756    fn add(self, rhs: Felt<F>) -> Self::Output {
757        self + SymbolicFelt::from(rhs)
758    }
759}
760
761impl<F: Field> Mul<Felt<F>> for SymbolicFelt<F> {
762    type Output = SymbolicFelt<F>;
763
764    fn mul(self, rhs: Felt<F>) -> Self::Output {
765        self * SymbolicFelt::from(rhs)
766    }
767}
768
769impl<F: Field> Sub<Felt<F>> for SymbolicFelt<F> {
770    type Output = SymbolicFelt<F>;
771
772    fn sub(self, rhs: Felt<F>) -> Self::Output {
773        self - SymbolicFelt::from(rhs)
774    }
775}
776
777impl<F: Field> Div<SymbolicFelt<F>> for Felt<F> {
778    type Output = SymbolicFelt<F>;
779
780    fn div(self, rhs: SymbolicFelt<F>) -> Self::Output {
781        SymbolicFelt::<F>::from(self) / rhs
782    }
783}
784
785// Implement operations between constants N, F, EF, and Var<N>, Felt<F>, Ext<F, EF>.
786
787impl<F: Field> Add for Felt<F> {
788    type Output = SymbolicFelt<F>;
789
790    fn add(self, rhs: Self) -> Self::Output {
791        SymbolicFelt::<F>::from(self) + rhs
792    }
793}
794
795impl<F: Field> Add<F> for Felt<F> {
796    type Output = SymbolicFelt<F>;
797
798    fn add(self, rhs: F) -> Self::Output {
799        SymbolicFelt::from(self) + rhs
800    }
801}
802
803impl<N: Field> Mul for Var<N> {
804    type Output = SymbolicVar<N>;
805
806    fn mul(self, rhs: Self) -> Self::Output {
807        SymbolicVar::<N>::from(self) * rhs
808    }
809}
810
811impl<N: Field> Mul<N> for Var<N> {
812    type Output = SymbolicVar<N>;
813
814    fn mul(self, rhs: N) -> Self::Output {
815        SymbolicVar::from(self) * rhs
816    }
817}
818
819impl<F: Field> Mul for Felt<F> {
820    type Output = SymbolicFelt<F>;
821
822    fn mul(self, rhs: Self) -> Self::Output {
823        SymbolicFelt::<F>::from(self) * rhs
824    }
825}
826
827impl<F: Field> Mul<F> for Felt<F> {
828    type Output = SymbolicFelt<F>;
829
830    fn mul(self, rhs: F) -> Self::Output {
831        SymbolicFelt::from(self) * rhs
832    }
833}
834
835impl<F: Field> Sub for Felt<F> {
836    type Output = SymbolicFelt<F>;
837
838    fn sub(self, rhs: Self) -> Self::Output {
839        SymbolicFelt::<F>::from(self) - rhs
840    }
841}
842
843impl<F: Field> Sub<F> for Felt<F> {
844    type Output = SymbolicFelt<F>;
845
846    fn sub(self, rhs: F) -> Self::Output {
847        SymbolicFelt::from(self) - rhs
848    }
849}
850
851impl<F: Field, EF: ExtensionField<F>, E: Any> Add<E> for Ext<F, EF> {
852    type Output = SymbolicExt<F, EF>;
853
854    fn add(self, rhs: E) -> Self::Output {
855        let rhs: ExtOperand<F, EF> = rhs.to_operand();
856        let self_sym = self.to_operand().symbolic();
857        self_sym + rhs
858    }
859}
860
861impl<F: Field, EF: ExtensionField<F>, E: Any> Mul<E> for Ext<F, EF> {
862    type Output = SymbolicExt<F, EF>;
863
864    fn mul(self, rhs: E) -> Self::Output {
865        let self_sym = self.to_operand().symbolic();
866        self_sym * rhs
867    }
868}
869
870impl<F: Field, EF: ExtensionField<F>, E: Any> Sub<E> for Ext<F, EF> {
871    type Output = SymbolicExt<F, EF>;
872
873    fn sub(self, rhs: E) -> Self::Output {
874        let self_sym = self.to_operand().symbolic();
875        self_sym - rhs
876    }
877}
878
879impl<F: Field, EF: ExtensionField<F>, E: Any> Div<E> for Ext<F, EF> {
880    type Output = SymbolicExt<F, EF>;
881
882    fn div(self, rhs: E) -> Self::Output {
883        let self_sym = self.to_operand().symbolic();
884        self_sym / rhs
885    }
886}
887
888impl<F: Field, EF: ExtensionField<F>> Add<SymbolicExt<F, EF>> for Felt<F> {
889    type Output = SymbolicExt<F, EF>;
890
891    fn add(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
892        let self_sym = self.to_operand().symbolic();
893        self_sym + rhs
894    }
895}
896
897impl<F: Field, EF: ExtensionField<F>> Mul<SymbolicExt<F, EF>> for Felt<F> {
898    type Output = SymbolicExt<F, EF>;
899
900    fn mul(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
901        let self_sym = self.to_operand().symbolic();
902        self_sym * rhs
903    }
904}
905
906impl<F: Field, EF: ExtensionField<F>> Sub<SymbolicExt<F, EF>> for Felt<F> {
907    type Output = SymbolicExt<F, EF>;
908
909    fn sub(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
910        let self_sym = self.to_operand().symbolic();
911        self_sym - rhs
912    }
913}
914
915impl<F: Field, EF: ExtensionField<F>> Div<SymbolicExt<F, EF>> for Felt<F> {
916    type Output = SymbolicExt<F, EF>;
917
918    fn div(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
919        let self_sym = self.to_operand().symbolic();
920        self_sym / rhs
921    }
922}
923
924impl<F: Field> Div for Felt<F> {
925    type Output = SymbolicFelt<F>;
926
927    fn div(self, rhs: Self) -> Self::Output {
928        SymbolicFelt::<F>::from(self) / rhs
929    }
930}
931
932impl<F: Field> Div<F> for Felt<F> {
933    type Output = SymbolicFelt<F>;
934
935    fn div(self, rhs: F) -> Self::Output {
936        SymbolicFelt::from(self) / rhs
937    }
938}
939
940impl<F: Field> Div<Felt<F>> for SymbolicFelt<F> {
941    type Output = SymbolicFelt<F>;
942
943    fn div(self, rhs: Felt<F>) -> Self::Output {
944        self / SymbolicFelt::from(rhs)
945    }
946}
947
948impl<F: Field> Div<F> for SymbolicFelt<F> {
949    type Output = SymbolicFelt<F>;
950
951    fn div(self, rhs: F) -> Self::Output {
952        self / SymbolicFelt::from(rhs)
953    }
954}
955
956impl<N: Field> Product for SymbolicVar<N> {
957    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
958        iter.fold(SymbolicVar::ONE, |acc, x| acc * x)
959    }
960}
961
962impl<N: Field> Sum for SymbolicVar<N> {
963    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
964        iter.fold(SymbolicVar::ZERO, |acc, x| acc + x)
965    }
966}
967
968impl<N: Field> AddAssign for SymbolicVar<N> {
969    fn add_assign(&mut self, rhs: Self) {
970        *self = self.clone() + rhs;
971    }
972}
973
974impl<N: Field> SubAssign for SymbolicVar<N> {
975    fn sub_assign(&mut self, rhs: Self) {
976        *self = self.clone() - rhs;
977    }
978}
979
980impl<N: Field> MulAssign for SymbolicVar<N> {
981    fn mul_assign(&mut self, rhs: Self) {
982        *self = self.clone() * rhs;
983    }
984}
985
986impl<N: Field> Default for SymbolicVar<N> {
987    fn default() -> Self {
988        SymbolicVar::ZERO
989    }
990}
991
992impl<F: Field> Sum for SymbolicFelt<F> {
993    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
994        iter.fold(SymbolicFelt::ZERO, |acc, x| acc + x)
995    }
996}
997
998impl<F: Field> Product for SymbolicFelt<F> {
999    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1000        iter.fold(SymbolicFelt::ONE, |acc, x| acc * x)
1001    }
1002}
1003
1004impl<F: Field> AddAssign for SymbolicFelt<F> {
1005    fn add_assign(&mut self, rhs: Self) {
1006        *self = self.clone() + rhs;
1007    }
1008}
1009
1010impl<F: Field> SubAssign for SymbolicFelt<F> {
1011    fn sub_assign(&mut self, rhs: Self) {
1012        *self = self.clone() - rhs;
1013    }
1014}
1015
1016impl<F: Field> MulAssign for SymbolicFelt<F> {
1017    fn mul_assign(&mut self, rhs: Self) {
1018        *self = self.clone() * rhs;
1019    }
1020}
1021
1022impl<F: Field> Default for SymbolicFelt<F> {
1023    fn default() -> Self {
1024        SymbolicFelt::ZERO
1025    }
1026}
1027
1028impl<F: Field, EF: ExtensionField<F>> Sum for SymbolicExt<F, EF> {
1029    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1030        iter.fold(SymbolicExt::ZERO, |acc, x| acc + x)
1031    }
1032}
1033
1034impl<F: Field, EF: ExtensionField<F>> Product for SymbolicExt<F, EF> {
1035    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1036        iter.fold(SymbolicExt::ONE, |acc, x| acc * x)
1037    }
1038}
1039
1040impl<F: Field, EF: ExtensionField<F>> Default for SymbolicExt<F, EF> {
1041    fn default() -> Self {
1042        SymbolicExt::ZERO
1043    }
1044}
1045
1046impl<F: Field, EF: ExtensionField<F>, E: Any> AddAssign<E> for SymbolicExt<F, EF> {
1047    fn add_assign(&mut self, rhs: E) {
1048        *self = self.clone() + rhs;
1049    }
1050}
1051
1052impl<F: Field, EF: ExtensionField<F>, E: Any> SubAssign<E> for SymbolicExt<F, EF> {
1053    fn sub_assign(&mut self, rhs: E) {
1054        *self = self.clone() - rhs;
1055    }
1056}
1057
1058impl<F: Field, EF: ExtensionField<F>, E: Any> MulAssign<E> for SymbolicExt<F, EF> {
1059    fn mul_assign(&mut self, rhs: E) {
1060        *self = self.clone() * rhs;
1061    }
1062}
1063
1064impl<F: Field, EF: ExtensionField<F>, E: Any> DivAssign<E> for SymbolicExt<F, EF> {
1065    fn div_assign(&mut self, rhs: E) {
1066        *self = self.clone() / rhs;
1067    }
1068}
1069
1070impl<F: Field, EF: ExtensionField<F>, E: Any> ExtensionOperand<F, EF> for E {
1071    fn to_operand(self) -> ExtOperand<F, EF> {
1072        match self.type_id() {
1073            ty if ty == TypeId::of::<F>() => {
1074                // *Safety*: We know that E is a F and we can transmute it to F which implements
1075                // the Copy trait.
1076                let value = unsafe { mem::transmute_copy::<E, F>(&self) };
1077                ExtOperand::<F, EF>::Base(value)
1078            }
1079            ty if ty == TypeId::of::<EF>() => {
1080                // *Safety*: We know that E is a EF and we can transmute it to EF which implements
1081                // the Copy trait.
1082                let value = unsafe { mem::transmute_copy::<E, EF>(&self) };
1083                ExtOperand::<F, EF>::Const(value)
1084            }
1085            ty if ty == TypeId::of::<Felt<F>>() => {
1086                // *Safety*: We know that E is a Felt<F> and we can transmute it to Felt<F> which
1087                // implements the Copy trait.
1088                let value = unsafe { mem::transmute_copy::<E, Felt<F>>(&self) };
1089                ExtOperand::<F, EF>::Felt(value)
1090            }
1091            ty if ty == TypeId::of::<Ext<F, EF>>() => {
1092                // *Safety*: We know that E is a Ext<F, EF> and we can transmute it to Ext<F, EF>
1093                // which implements the Copy trait.
1094                let value = unsafe { mem::transmute_copy::<E, Ext<F, EF>>(&self) };
1095                ExtOperand::<F, EF>::Ext(value)
1096            }
1097            ty if ty == TypeId::of::<SymbolicFelt<F>>() => {
1098                // *Safety*: We know that E is a Symbolic Felt<F> and we can transmute it to
1099                // SymbolicFelt<F> but we need to clone the pointer.
1100                let value_ref = unsafe { mem::transmute::<&E, &SymbolicFelt<F>>(&self) };
1101                let value = value_ref.clone();
1102                ExtOperand::<F, EF>::SymFelt(value)
1103            }
1104            ty if ty == TypeId::of::<SymbolicExt<F, EF>>() => {
1105                // *Safety*: We know that E is a SymbolicExt<F, EF> and we can transmute it to
1106                // SymbolicExt<F, EF> but we need to clone the pointer.
1107                let value_ref = unsafe { mem::transmute::<&E, &SymbolicExt<F, EF>>(&self) };
1108                let value = value_ref.clone();
1109                ExtOperand::<F, EF>::Sym(value)
1110            }
1111            ty if ty == TypeId::of::<ExtOperand<F, EF>>() => {
1112                let value_ref = unsafe { mem::transmute::<&E, &ExtOperand<F, EF>>(&self) };
1113                value_ref.clone()
1114            }
1115            _ => unimplemented!("unsupported type"),
1116        }
1117    }
1118}
1119
1120impl<F: Field> Add<SymbolicFelt<F>> for Felt<F> {
1121    type Output = SymbolicFelt<F>;
1122
1123    fn add(self, rhs: SymbolicFelt<F>) -> Self::Output {
1124        SymbolicFelt::<F>::from(self) + rhs
1125    }
1126}
1127
1128impl<F: Field, EF: ExtensionField<F>> From<Felt<F>> for SymbolicExt<F, EF> {
1129    fn from(value: Felt<F>) -> Self {
1130        value.to_operand().symbolic()
1131    }
1132}
1133
1134impl<F: Field, EF: ExtensionField<F>> Neg for Ext<F, EF> {
1135    type Output = SymbolicExt<F, EF>;
1136    fn neg(self) -> Self::Output {
1137        -SymbolicExt::from(self)
1138    }
1139}
1140
1141impl<F: Field> Neg for Felt<F> {
1142    type Output = SymbolicFelt<F>;
1143
1144    fn neg(self) -> Self::Output {
1145        -SymbolicFelt::from(self)
1146    }
1147}
1148
1149impl<N: Field> Neg for Var<N> {
1150    type Output = SymbolicVar<N>;
1151
1152    fn neg(self) -> Self::Output {
1153        -SymbolicVar::from(self)
1154    }
1155}
1156
1157impl<F: Field> MulAssign<Felt<F>> for SymbolicFelt<F> {
1158    fn mul_assign(&mut self, rhs: Felt<F>) {
1159        *self = self.clone() * Self::from(rhs);
1160    }
1161}
1162
1163impl<F: Field> Mul<SymbolicFelt<F>> for Felt<F> {
1164    type Output = SymbolicFelt<F>;
1165
1166    fn mul(self, rhs: SymbolicFelt<F>) -> Self::Output {
1167        SymbolicFelt::<F>::from(self) * rhs
1168    }
1169}
1170
1171impl<N: Field> Mul<SymbolicVar<N>> for Var<N> {
1172    type Output = SymbolicVar<N>;
1173
1174    fn mul(self, rhs: SymbolicVar<N>) -> Self::Output {
1175        SymbolicVar::<N>::from(self) * rhs
1176    }
1177}
1178
1179impl<N: Field, RHS: Into<SymbolicVar<N>>> Add<RHS> for Var<N> {
1180    type Output = SymbolicVar<N>;
1181
1182    fn add(self, rhs: RHS) -> Self::Output {
1183        SymbolicVar::from(self) + rhs.into()
1184    }
1185}
1186
1187impl<N: Field, RHS: Into<SymbolicVar<N>>> Sub<RHS> for Var<N> {
1188    type Output = SymbolicVar<N>;
1189
1190    fn sub(self, rhs: RHS) -> Self::Output {
1191        SymbolicVar::from(self) - rhs.into()
1192    }
1193}
1194
1195impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Add<RHS> for Usize<N> {
1196    type Output = SymbolicVar<N>;
1197
1198    fn add(self, rhs: RHS) -> Self::Output {
1199        SymbolicVar::from(self) + rhs.into()
1200    }
1201}
1202
1203impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Sub<RHS> for Usize<N> {
1204    type Output = SymbolicVar<N>;
1205
1206    fn sub(self, rhs: RHS) -> Self::Output {
1207        SymbolicVar::from(self) - rhs.into()
1208    }
1209}
1210
1211impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Mul<RHS> for Usize<N> {
1212    type Output = SymbolicVar<N>;
1213
1214    fn mul(self, rhs: RHS) -> Self::Output {
1215        SymbolicVar::from(self) * rhs.into()
1216    }
1217}
1218
1219impl<N: PrimeField> From<Usize<N>> for SymbolicVar<N> {
1220    fn from(value: Usize<N>) -> Self {
1221        match value {
1222            Usize::Const(n) => SymbolicVar::from(*n.borrow()),
1223            Usize::Var(n) => SymbolicVar::from(n),
1224        }
1225    }
1226}
1227
1228impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Add<RHS> for RVar<N> {
1229    type Output = SymbolicVar<N>;
1230
1231    fn add(self, rhs: RHS) -> Self::Output {
1232        SymbolicVar::from(self) + rhs.into()
1233    }
1234}
1235
1236impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Sub<RHS> for RVar<N> {
1237    type Output = SymbolicVar<N>;
1238
1239    fn sub(self, rhs: RHS) -> Self::Output {
1240        SymbolicVar::from(self) - rhs.into()
1241    }
1242}
1243
1244impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Mul<RHS> for RVar<N> {
1245    type Output = SymbolicVar<N>;
1246
1247    fn mul(self, rhs: RHS) -> Self::Output {
1248        SymbolicVar::from(self) * rhs.into()
1249    }
1250}
1251
1252impl<N: Field> From<RVar<N>> for SymbolicVar<N> {
1253    fn from(value: RVar<N>) -> Self {
1254        match value {
1255            RVar::Const(n) => SymbolicVar::from(n),
1256            RVar::Val(n) => SymbolicVar::from(n),
1257        }
1258    }
1259}
1260
1261impl<N: PrimeField> From<usize> for RVar<N> {
1262    fn from(value: usize) -> Self {
1263        RVar::Const(N::from_usize(value))
1264    }
1265}
1266
1267impl<N: Field> From<Var<N>> for RVar<N> {
1268    fn from(value: Var<N>) -> Self {
1269        RVar::Val(value)
1270    }
1271}