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