sp1_recursion_compiler/ir/
symbolic.rs

1use core::{
2    any::Any,
3    ops::{Add, Div, Mul, Neg, Sub},
4};
5use std::{
6    any::TypeId,
7    iter::{Product, Sum},
8    mem::{self, ManuallyDrop},
9    ops::{AddAssign, DivAssign, MulAssign, SubAssign},
10};
11
12use p3_field::{AbstractField, ExtensionField, Field};
13
14use crate::ir::ExtHandle;
15
16use super::{Ext, Felt, Usize, Var};
17
18#[derive(Debug, Clone, Copy)]
19pub enum SymbolicVar<N: Field> {
20    Const(N),
21    Val(Var<N>),
22}
23
24#[derive(Debug, Clone, Copy)]
25pub enum SymbolicFelt<F: Field> {
26    Const(F),
27    Val(Felt<F>),
28}
29
30#[derive(Debug, Clone, Copy)]
31pub enum SymbolicExt<F: Field, EF: Field> {
32    Const(EF),
33    Base(SymbolicFelt<F>),
34    Val(Ext<F, EF>),
35}
36
37#[derive(Debug, Clone, Copy)]
38pub enum SymbolicUsize<N: Field> {
39    Const(usize),
40    Var(SymbolicVar<N>),
41}
42
43#[derive(Debug, Clone)]
44pub enum ExtOperand<F: Field, EF: ExtensionField<F>> {
45    Base(F),
46    Const(EF),
47    Felt(Felt<F>),
48    Ext(Ext<F, EF>),
49    SymFelt(SymbolicFelt<F>),
50    Sym(SymbolicExt<F, EF>),
51}
52
53impl<F: Field, EF: ExtensionField<F>> ExtOperand<F, EF> {
54    pub fn symbolic(self) -> SymbolicExt<F, EF> {
55        match self {
56            ExtOperand::Base(f) => SymbolicExt::Base(SymbolicFelt::from(f)),
57            ExtOperand::Const(ef) => SymbolicExt::Const(ef),
58            ExtOperand::Felt(f) => SymbolicExt::Base(SymbolicFelt::from(f)),
59            ExtOperand::Ext(e) => SymbolicExt::Val(e),
60            ExtOperand::SymFelt(f) => SymbolicExt::Base(f),
61            ExtOperand::Sym(e) => e,
62        }
63    }
64}
65
66pub trait ExtConst<F: Field, EF: ExtensionField<F>> {
67    fn cons(self) -> SymbolicExt<F, EF>;
68}
69
70impl<F: Field, EF: ExtensionField<F>> ExtConst<F, EF> for EF {
71    fn cons(self) -> SymbolicExt<F, EF> {
72        SymbolicExt::Const(self)
73    }
74}
75
76pub trait ExtensionOperand<F: Field, EF: ExtensionField<F>> {
77    fn to_operand(self) -> ExtOperand<F, EF>;
78}
79
80impl<N: Field> AbstractField for SymbolicVar<N> {
81    type F = N;
82
83    fn zero() -> Self {
84        SymbolicVar::from(N::zero())
85    }
86
87    fn one() -> Self {
88        SymbolicVar::from(N::one())
89    }
90
91    fn two() -> Self {
92        SymbolicVar::from(N::two())
93    }
94
95    fn neg_one() -> Self {
96        SymbolicVar::from(N::neg_one())
97    }
98
99    fn from_f(f: Self::F) -> Self {
100        SymbolicVar::from(f)
101    }
102    fn from_bool(b: bool) -> Self {
103        SymbolicVar::from(N::from_bool(b))
104    }
105    fn from_canonical_u8(n: u8) -> Self {
106        SymbolicVar::from(N::from_canonical_u8(n))
107    }
108    fn from_canonical_u16(n: u16) -> Self {
109        SymbolicVar::from(N::from_canonical_u16(n))
110    }
111    fn from_canonical_u32(n: u32) -> Self {
112        SymbolicVar::from(N::from_canonical_u32(n))
113    }
114    fn from_canonical_u64(n: u64) -> Self {
115        SymbolicVar::from(N::from_canonical_u64(n))
116    }
117    fn from_canonical_usize(n: usize) -> Self {
118        SymbolicVar::from(N::from_canonical_usize(n))
119    }
120
121    fn from_wrapped_u32(n: u32) -> Self {
122        SymbolicVar::from(N::from_wrapped_u32(n))
123    }
124    fn from_wrapped_u64(n: u64) -> Self {
125        SymbolicVar::from(N::from_wrapped_u64(n))
126    }
127
128    /// A generator of this field's entire multiplicative group.
129    fn generator() -> Self {
130        SymbolicVar::from(N::generator())
131    }
132}
133
134impl<F: Field> AbstractField for SymbolicFelt<F> {
135    type F = F;
136
137    fn zero() -> Self {
138        SymbolicFelt::from(F::zero())
139    }
140
141    fn one() -> Self {
142        SymbolicFelt::from(F::one())
143    }
144
145    fn two() -> Self {
146        SymbolicFelt::from(F::two())
147    }
148
149    fn neg_one() -> Self {
150        SymbolicFelt::from(F::neg_one())
151    }
152
153    fn from_f(f: Self::F) -> Self {
154        SymbolicFelt::from(f)
155    }
156    fn from_bool(b: bool) -> Self {
157        SymbolicFelt::from(F::from_bool(b))
158    }
159    fn from_canonical_u8(n: u8) -> Self {
160        SymbolicFelt::from(F::from_canonical_u8(n))
161    }
162    fn from_canonical_u16(n: u16) -> Self {
163        SymbolicFelt::from(F::from_canonical_u16(n))
164    }
165    fn from_canonical_u32(n: u32) -> Self {
166        SymbolicFelt::from(F::from_canonical_u32(n))
167    }
168    fn from_canonical_u64(n: u64) -> Self {
169        SymbolicFelt::from(F::from_canonical_u64(n))
170    }
171    fn from_canonical_usize(n: usize) -> Self {
172        SymbolicFelt::from(F::from_canonical_usize(n))
173    }
174
175    fn from_wrapped_u32(n: u32) -> Self {
176        SymbolicFelt::from(F::from_wrapped_u32(n))
177    }
178    fn from_wrapped_u64(n: u64) -> Self {
179        SymbolicFelt::from(F::from_wrapped_u64(n))
180    }
181
182    /// A generator of this field's entire multiplicative group.
183    fn generator() -> Self {
184        SymbolicFelt::from(F::generator())
185    }
186}
187
188impl<F: Field, EF: ExtensionField<F>> AbstractField for SymbolicExt<F, EF> {
189    type F = EF;
190
191    fn zero() -> Self {
192        SymbolicExt::from_f(EF::zero())
193    }
194
195    fn one() -> Self {
196        SymbolicExt::from_f(EF::one())
197    }
198
199    fn two() -> Self {
200        SymbolicExt::from_f(EF::two())
201    }
202
203    fn neg_one() -> Self {
204        SymbolicExt::from_f(EF::neg_one())
205    }
206
207    fn from_f(f: Self::F) -> Self {
208        SymbolicExt::Const(f)
209    }
210    fn from_bool(b: bool) -> Self {
211        SymbolicExt::from_f(EF::from_bool(b))
212    }
213    fn from_canonical_u8(n: u8) -> Self {
214        SymbolicExt::from_f(EF::from_canonical_u8(n))
215    }
216    fn from_canonical_u16(n: u16) -> Self {
217        SymbolicExt::from_f(EF::from_canonical_u16(n))
218    }
219    fn from_canonical_u32(n: u32) -> Self {
220        SymbolicExt::from_f(EF::from_canonical_u32(n))
221    }
222    fn from_canonical_u64(n: u64) -> Self {
223        SymbolicExt::from_f(EF::from_canonical_u64(n))
224    }
225    fn from_canonical_usize(n: usize) -> Self {
226        SymbolicExt::from_f(EF::from_canonical_usize(n))
227    }
228
229    fn from_wrapped_u32(n: u32) -> Self {
230        SymbolicExt::from_f(EF::from_wrapped_u32(n))
231    }
232    fn from_wrapped_u64(n: u64) -> Self {
233        SymbolicExt::from_f(EF::from_wrapped_u64(n))
234    }
235
236    /// A generator of this field's entire multiplicative group.
237    fn generator() -> Self {
238        SymbolicExt::from_f(EF::generator())
239    }
240}
241
242// Implement all conversions from constants N, F, EF, to the corresponding symbolic types
243
244impl<N: Field> From<N> for SymbolicVar<N> {
245    fn from(n: N) -> Self {
246        SymbolicVar::Const(n)
247    }
248}
249
250impl<F: Field> From<F> for SymbolicFelt<F> {
251    fn from(f: F) -> Self {
252        SymbolicFelt::Const(f)
253    }
254}
255
256impl<F: Field, EF: ExtensionField<F>> From<F> for SymbolicExt<F, EF> {
257    fn from(f: F) -> Self {
258        f.to_operand().symbolic()
259    }
260}
261
262// Implement all conversions from Var<N>, Felt<F>, Ext<F, EF> to the corresponding symbolic types
263
264impl<N: Field> From<Var<N>> for SymbolicVar<N> {
265    fn from(v: Var<N>) -> Self {
266        SymbolicVar::Val(v)
267    }
268}
269
270impl<F: Field> From<Felt<F>> for SymbolicFelt<F> {
271    fn from(f: Felt<F>) -> Self {
272        SymbolicFelt::Val(f)
273    }
274}
275
276impl<F: Field, EF: ExtensionField<F>> From<Ext<F, EF>> for SymbolicExt<F, EF> {
277    fn from(e: Ext<F, EF>) -> Self {
278        e.to_operand().symbolic()
279    }
280}
281
282// Implement all operations for SymbolicVar<N>, SymbolicFelt<F>, SymbolicExt<F, EF>
283
284impl<N: Field> Add for SymbolicVar<N> {
285    type Output = Self;
286
287    fn add(self, rhs: Self) -> Self::Output {
288        match (self, rhs) {
289            (Self::Const(lhs), Self::Const(rhs)) => Self::Const(lhs + rhs),
290            (Self::Val(lhs), Self::Const(rhs)) => {
291                let res = unsafe { (*lhs.handle).add_const_v(lhs, rhs) };
292                Self::Val(res)
293            }
294            (Self::Const(lhs), Self::Val(rhs)) => {
295                let res = unsafe { (*rhs.handle).add_v_const(lhs, rhs) };
296                Self::Val(res)
297            }
298            (Self::Val(lhs), Self::Val(rhs)) => {
299                let res = unsafe { (*lhs.handle).add_v(lhs, rhs) };
300                Self::Val(res)
301            }
302        }
303    }
304}
305
306impl<F: Field> Add for SymbolicFelt<F> {
307    type Output = Self;
308
309    fn add(self, rhs: Self) -> Self::Output {
310        match (self, rhs) {
311            (Self::Const(lhs), Self::Const(rhs)) => Self::Const(lhs + rhs),
312            (Self::Val(lhs), Self::Const(rhs)) => {
313                let res = unsafe { (*lhs.handle).add_const_f(lhs, rhs) };
314                Self::Val(res)
315            }
316            (Self::Const(lhs), Self::Val(rhs)) => {
317                let res = unsafe { (*rhs.handle).add_f_const(lhs, rhs) };
318                Self::Val(res)
319            }
320            (Self::Val(lhs), Self::Val(rhs)) => {
321                let res = unsafe { (*lhs.handle).add_f(lhs, rhs) };
322                Self::Val(res)
323            }
324        }
325    }
326}
327
328impl<F: Field, EF: ExtensionField<F>, E: ExtensionOperand<F, EF>> Add<E> for SymbolicExt<F, EF> {
329    type Output = Self;
330
331    fn add(self, rhs: E) -> Self::Output {
332        let rhs = rhs.to_operand().symbolic();
333
334        match (self, rhs) {
335            (Self::Const(lhs), Self::Const(rhs)) => Self::Const(lhs + rhs),
336            (Self::Val(lhs), Self::Const(rhs)) => {
337                let res = unsafe { (*lhs.handle).add_const_e(lhs, rhs) };
338                Self::Val(res)
339            }
340            (Self::Const(lhs), Self::Val(rhs)) => {
341                let res = unsafe { (*rhs.handle).add_e_const(lhs, rhs) };
342                Self::Val(res)
343            }
344            (Self::Const(lhs), Self::Base(rhs)) => match rhs {
345                SymbolicFelt::Const(rhs) => Self::Const(lhs + rhs),
346                SymbolicFelt::Val(rhs) => {
347                    let ext_handle_ptr =
348                        unsafe { (*rhs.handle).ext_handle_ptr as *mut ExtHandle<F, EF> };
349                    let ext_handle: ManuallyDrop<_> =
350                        unsafe { ManuallyDrop::new(Box::from_raw(ext_handle_ptr)) };
351                    let res = ext_handle.add_const_e_f(lhs, rhs, ext_handle_ptr);
352                    Self::Val(res)
353                }
354            },
355            (Self::Base(lhs), Self::Const(rhs)) => match lhs {
356                SymbolicFelt::Const(lhs) => Self::Const(rhs + lhs),
357                SymbolicFelt::Val(lhs) => {
358                    let ext_handle_ptr =
359                        unsafe { (*lhs.handle).ext_handle_ptr as *mut ExtHandle<F, EF> };
360                    let ext_handle: ManuallyDrop<_> =
361                        unsafe { ManuallyDrop::new(Box::from_raw(ext_handle_ptr)) };
362                    let res = ext_handle.add_f_const_e(lhs, rhs, ext_handle_ptr);
363                    Self::Val(res)
364                }
365            },
366
367            (Self::Val(lhs), Self::Val(rhs)) => {
368                let res = unsafe { (*lhs.handle).add_e(lhs, rhs) };
369                Self::Val(res)
370            }
371            (Self::Base(lhs), Self::Base(rhs)) => Self::Base(lhs + rhs),
372            (Self::Base(lhs), Self::Val(rhs)) => match lhs {
373                SymbolicFelt::Const(lhs) => {
374                    let res = unsafe { (*rhs.handle).add_e_const(EF::from_base(lhs), rhs) };
375                    Self::Val(res)
376                }
377                SymbolicFelt::Val(lhs) => {
378                    let res = unsafe { (*rhs.handle).add_f_e(lhs, rhs) };
379                    Self::Val(res)
380                }
381            },
382            (Self::Val(lhs), Self::Base(rhs)) => match rhs {
383                SymbolicFelt::Const(rhs) => {
384                    let res = unsafe { (*lhs.handle).add_const_e(lhs, EF::from_base(rhs)) };
385                    Self::Val(res)
386                }
387                SymbolicFelt::Val(rhs) => {
388                    let res = unsafe { (*lhs.handle).add_e_f(lhs, rhs) };
389                    Self::Val(res)
390                }
391            },
392        }
393    }
394}
395
396impl<N: Field> Mul for SymbolicVar<N> {
397    type Output = Self;
398
399    fn mul(self, rhs: Self) -> Self::Output {
400        match (self, rhs) {
401            (Self::Const(lhs), Self::Const(rhs)) => Self::Const(lhs * rhs),
402            (Self::Val(lhs), Self::Const(rhs)) => {
403                let res = unsafe { (*lhs.handle).mul_const_v(lhs, rhs) };
404                Self::Val(res)
405            }
406            (Self::Const(lhs), Self::Val(rhs)) => {
407                let res = unsafe { (*rhs.handle).mul_v_const(lhs, rhs) };
408                Self::Val(res)
409            }
410            (Self::Val(lhs), Self::Val(rhs)) => {
411                let res = unsafe { (*lhs.handle).mul_v(lhs, rhs) };
412                Self::Val(res)
413            }
414        }
415    }
416}
417
418impl<F: Field> Mul for SymbolicFelt<F> {
419    type Output = Self;
420
421    fn mul(self, rhs: Self) -> Self::Output {
422        match (self, rhs) {
423            (Self::Const(lhs), Self::Const(rhs)) => Self::Const(lhs * rhs),
424            (Self::Val(lhs), Self::Const(rhs)) => {
425                let res = unsafe { (*lhs.handle).mul_const_f(lhs, rhs) };
426                Self::Val(res)
427            }
428            (Self::Const(lhs), Self::Val(rhs)) => {
429                let res = unsafe { (*rhs.handle).mul_f_const(lhs, rhs) };
430                Self::Val(res)
431            }
432            (Self::Val(lhs), Self::Val(rhs)) => {
433                let res = unsafe { (*lhs.handle).mul_f(lhs, rhs) };
434                Self::Val(res)
435            }
436        }
437    }
438}
439
440impl<F: Field, EF: ExtensionField<F>, E: Any> Mul<E> for SymbolicExt<F, EF> {
441    type Output = Self;
442
443    fn mul(self, rhs: E) -> Self::Output {
444        let rhs = rhs.to_operand().symbolic();
445
446        match (self, rhs) {
447            (Self::Const(lhs), Self::Const(rhs)) => Self::Const(lhs * rhs),
448            (Self::Val(lhs), Self::Const(rhs)) => {
449                let res = unsafe { (*lhs.handle).mul_const_e(lhs, rhs) };
450                Self::Val(res)
451            }
452            (Self::Const(lhs), Self::Val(rhs)) => {
453                let res = unsafe { (*rhs.handle).mul_e_const(lhs, rhs) };
454                Self::Val(res)
455            }
456            (Self::Const(lhs), Self::Base(rhs)) => match rhs {
457                SymbolicFelt::Const(rhs) => Self::Const(lhs * rhs),
458                SymbolicFelt::Val(rhs) => {
459                    let ext_handle_ptr =
460                        unsafe { (*rhs.handle).ext_handle_ptr as *mut ExtHandle<F, EF> };
461                    let ext_handle: ManuallyDrop<_> =
462                        unsafe { ManuallyDrop::new(Box::from_raw(ext_handle_ptr)) };
463                    let res = ext_handle.mul_const_e_f(lhs, rhs, ext_handle_ptr);
464                    Self::Val(res)
465                }
466            },
467            (Self::Base(lhs), Self::Const(rhs)) => match lhs {
468                SymbolicFelt::Const(lhs) => Self::Const(EF::from_base(lhs) * rhs),
469                SymbolicFelt::Val(lhs) => {
470                    let ext_handle_ptr =
471                        unsafe { (*lhs.handle).ext_handle_ptr as *mut ExtHandle<F, EF> };
472                    let ext_handle: ManuallyDrop<_> =
473                        unsafe { ManuallyDrop::new(Box::from_raw(ext_handle_ptr)) };
474                    let res = ext_handle.mul_f_const_e(lhs, rhs, ext_handle_ptr);
475                    Self::Val(res)
476                }
477            },
478
479            (Self::Val(lhs), Self::Val(rhs)) => {
480                let res = unsafe { (*lhs.handle).mul_e(lhs, rhs) };
481                Self::Val(res)
482            }
483            (Self::Base(lhs), Self::Base(rhs)) => Self::Base(lhs * rhs),
484            (Self::Base(lhs), Self::Val(rhs)) => match lhs {
485                SymbolicFelt::Const(lhs) => {
486                    let res = unsafe { (*rhs.handle).mul_e_const(EF::from_base(lhs), rhs) };
487                    Self::Val(res)
488                }
489                SymbolicFelt::Val(lhs) => {
490                    let res = unsafe { (*rhs.handle).mul_f_e(lhs, rhs) };
491                    Self::Val(res)
492                }
493            },
494            (Self::Val(lhs), Self::Base(rhs)) => match rhs {
495                SymbolicFelt::Const(rhs) => {
496                    let res = unsafe { (*lhs.handle).mul_const_e(lhs, EF::from_base(rhs)) };
497                    Self::Val(res)
498                }
499                SymbolicFelt::Val(rhs) => {
500                    let res = unsafe { (*lhs.handle).mul_e_f(lhs, rhs) };
501                    Self::Val(res)
502                }
503            },
504        }
505    }
506}
507
508impl<N: Field> Sub for SymbolicVar<N> {
509    type Output = Self;
510
511    fn sub(self, rhs: Self) -> Self::Output {
512        match (self, rhs) {
513            (Self::Const(lhs), Self::Const(rhs)) => Self::Const(lhs - rhs),
514            (Self::Val(lhs), Self::Const(rhs)) => {
515                let res = unsafe { (*lhs.handle).sub_v_const(lhs, rhs) };
516                Self::Val(res)
517            }
518            (Self::Const(lhs), Self::Val(rhs)) => {
519                let res = unsafe { (*rhs.handle).sub_const_v(lhs, rhs) };
520                Self::Val(res)
521            }
522            (Self::Val(lhs), Self::Val(rhs)) => {
523                let res = unsafe { (*lhs.handle).sub_v(lhs, rhs) };
524                Self::Val(res)
525            }
526        }
527    }
528}
529
530impl<F: Field> Sub for SymbolicFelt<F> {
531    type Output = Self;
532
533    fn sub(self, rhs: Self) -> Self::Output {
534        match (self, rhs) {
535            (Self::Const(lhs), Self::Const(rhs)) => Self::Const(lhs - rhs),
536            (Self::Val(lhs), Self::Const(rhs)) => {
537                let res = unsafe { (*lhs.handle).sub_f_const(lhs, rhs) };
538                Self::Val(res)
539            }
540            (Self::Const(lhs), Self::Val(rhs)) => {
541                let res = unsafe { (*rhs.handle).sub_const_f(lhs, rhs) };
542                Self::Val(res)
543            }
544            (Self::Val(lhs), Self::Val(rhs)) => {
545                let res = unsafe { (*lhs.handle).sub_f(lhs, rhs) };
546                Self::Val(res)
547            }
548        }
549    }
550}
551
552impl<F: Field, EF: ExtensionField<F>, E: Any> Sub<E> for SymbolicExt<F, EF> {
553    type Output = Self;
554
555    fn sub(self, rhs: E) -> Self::Output {
556        let rhs = rhs.to_operand().symbolic();
557
558        match (self, rhs) {
559            (Self::Const(lhs), Self::Const(rhs)) => Self::Const(lhs - rhs),
560            (Self::Val(lhs), Self::Const(rhs)) => {
561                let res = unsafe { (*lhs.handle).sub_const_e(lhs, rhs) };
562                Self::Val(res)
563            }
564            (Self::Const(lhs), Self::Val(rhs)) => {
565                let res = unsafe { (*rhs.handle).sub_e_const(lhs, rhs) };
566                Self::Val(res)
567            }
568            (Self::Const(lhs), Self::Base(rhs)) => match rhs {
569                SymbolicFelt::Const(rhs) => Self::Const(lhs - rhs),
570                SymbolicFelt::Val(rhs) => {
571                    let ext_handle_ptr =
572                        unsafe { (*rhs.handle).ext_handle_ptr as *mut ExtHandle<F, EF> };
573                    let ext_handle: ManuallyDrop<_> =
574                        unsafe { ManuallyDrop::new(Box::from_raw(ext_handle_ptr)) };
575                    let res = ext_handle.sub_const_e_f(lhs, rhs, ext_handle_ptr);
576                    Self::Val(res)
577                }
578            },
579            (Self::Base(lhs), Self::Const(rhs)) => match lhs {
580                SymbolicFelt::Const(lhs) => Self::Const(EF::from_base(lhs) - rhs),
581                SymbolicFelt::Val(lhs) => {
582                    let ext_handle_ptr =
583                        unsafe { (*lhs.handle).ext_handle_ptr as *mut ExtHandle<F, EF> };
584                    let ext_handle: ManuallyDrop<_> =
585                        unsafe { ManuallyDrop::new(Box::from_raw(ext_handle_ptr)) };
586                    let res = ext_handle.sub_f_const_e(lhs, rhs, ext_handle_ptr);
587                    Self::Val(res)
588                }
589            },
590
591            (Self::Val(lhs), Self::Val(rhs)) => {
592                let res = unsafe { (*lhs.handle).sub_e(lhs, rhs) };
593                Self::Val(res)
594            }
595            (Self::Base(lhs), Self::Base(rhs)) => Self::Base(lhs - rhs),
596            (Self::Base(lhs), Self::Val(rhs)) => match lhs {
597                SymbolicFelt::Const(lhs) => {
598                    let res = unsafe { (*rhs.handle).sub_e_const(EF::from_base(lhs), rhs) };
599                    Self::Val(res)
600                }
601                SymbolicFelt::Val(lhs) => {
602                    let res = unsafe { (*rhs.handle).sub_f_e(lhs, rhs) };
603                    Self::Val(res)
604                }
605            },
606            (Self::Val(lhs), Self::Base(rhs)) => match rhs {
607                SymbolicFelt::Const(rhs) => {
608                    let res = unsafe { (*lhs.handle).sub_const_e(lhs, EF::from_base(rhs)) };
609                    Self::Val(res)
610                }
611                SymbolicFelt::Val(rhs) => {
612                    let res = unsafe { (*lhs.handle).sub_e_f(lhs, rhs) };
613                    Self::Val(res)
614                }
615            },
616        }
617    }
618}
619
620impl<F: Field> Div for SymbolicFelt<F> {
621    type Output = Self;
622
623    fn div(self, rhs: Self) -> Self::Output {
624        match (self, rhs) {
625            (Self::Const(lhs), Self::Const(rhs)) => Self::Const(lhs / rhs),
626            (Self::Val(lhs), Self::Const(rhs)) => {
627                let res = unsafe { (*lhs.handle).div_f_const(lhs, rhs) };
628                Self::Val(res)
629            }
630            (Self::Const(lhs), Self::Val(rhs)) => {
631                let res = unsafe { (*rhs.handle).div_const_f(lhs, rhs) };
632                Self::Val(res)
633            }
634            (Self::Val(lhs), Self::Val(rhs)) => {
635                let res = unsafe { (*lhs.handle).div_f(lhs, rhs) };
636                Self::Val(res)
637            }
638        }
639    }
640}
641
642impl<F: Field, EF: ExtensionField<F>, E: Any> Div<E> for SymbolicExt<F, EF> {
643    type Output = Self;
644
645    fn div(self, rhs: E) -> Self::Output {
646        let rhs = rhs.to_operand().symbolic();
647
648        match (self, rhs) {
649            (Self::Const(lhs), Self::Const(rhs)) => Self::Const(lhs / rhs),
650            (Self::Val(lhs), Self::Const(rhs)) => {
651                let res = unsafe { (*lhs.handle).div_const_e(lhs, rhs) };
652                Self::Val(res)
653            }
654            (Self::Const(lhs), Self::Val(rhs)) => {
655                let res = unsafe { (*rhs.handle).div_e_const(lhs, rhs) };
656                Self::Val(res)
657            }
658            (Self::Const(lhs), Self::Base(rhs)) => match rhs {
659                SymbolicFelt::Const(rhs) => Self::Const(lhs / EF::from_base(rhs)),
660                SymbolicFelt::Val(rhs) => {
661                    let ext_handle_ptr =
662                        unsafe { (*rhs.handle).ext_handle_ptr as *mut ExtHandle<F, EF> };
663                    let ext_handle: ManuallyDrop<_> =
664                        unsafe { ManuallyDrop::new(Box::from_raw(ext_handle_ptr)) };
665                    let rhs = rhs.inverse();
666                    if let SymbolicFelt::Val(rhs) = rhs {
667                        let res = ext_handle.mul_const_e_f(lhs, rhs, ext_handle_ptr);
668                        Self::Val(res)
669                    } else {
670                        unreachable!()
671                    }
672                }
673            },
674            (Self::Base(lhs), Self::Const(rhs)) => match lhs {
675                SymbolicFelt::Const(lhs) => Self::Const(EF::from_base(lhs) / rhs),
676                SymbolicFelt::Val(lhs) => {
677                    let ext_handle_ptr =
678                        unsafe { (*lhs.handle).ext_handle_ptr as *mut ExtHandle<F, EF> };
679                    let ext_handle: ManuallyDrop<_> =
680                        unsafe { ManuallyDrop::new(Box::from_raw(ext_handle_ptr)) };
681                    let res = ext_handle.div_f_const_e(lhs, rhs, ext_handle_ptr);
682                    Self::Val(res)
683                }
684            },
685
686            (Self::Val(lhs), Self::Val(rhs)) => {
687                let res = unsafe { (*lhs.handle).div_e(lhs, rhs) };
688                Self::Val(res)
689            }
690            (Self::Base(lhs), Self::Base(rhs)) => Self::Base(lhs / rhs),
691            (Self::Base(lhs), Self::Val(rhs)) => match lhs {
692                SymbolicFelt::Const(lhs) => {
693                    let res = unsafe { (*rhs.handle).div_e_const(EF::from_base(lhs), rhs) };
694                    Self::Val(res)
695                }
696                SymbolicFelt::Val(lhs) => {
697                    let res = unsafe { (*rhs.handle).div_f_e(lhs, rhs) };
698                    Self::Val(res)
699                }
700            },
701            (Self::Val(lhs), Self::Base(rhs)) => match rhs {
702                SymbolicFelt::Const(rhs) => {
703                    let res = unsafe { (*lhs.handle).div_const_e(lhs, EF::from_base(rhs)) };
704                    Self::Val(res)
705                }
706                SymbolicFelt::Val(rhs) => {
707                    let res = unsafe { (*lhs.handle).div_e_f(lhs, rhs) };
708                    Self::Val(res)
709                }
710            },
711        }
712    }
713}
714
715impl<N: Field> Neg for SymbolicVar<N> {
716    type Output = Self;
717
718    fn neg(self) -> Self::Output {
719        match self {
720            SymbolicVar::Const(n) => SymbolicVar::Const(-n),
721            SymbolicVar::Val(n) => {
722                let res = unsafe { (*n.handle).neg_v(n) };
723                SymbolicVar::Val(res)
724            }
725        }
726    }
727}
728
729impl<F: Field> Neg for SymbolicFelt<F> {
730    type Output = Self;
731
732    fn neg(self) -> Self::Output {
733        match self {
734            SymbolicFelt::Const(f) => SymbolicFelt::Const(-f),
735            SymbolicFelt::Val(f) => {
736                let res = unsafe { (*f.handle).neg_f(f) };
737                SymbolicFelt::Val(res)
738            }
739        }
740    }
741}
742
743impl<F: Field, EF: ExtensionField<F>> Neg for SymbolicExt<F, EF> {
744    type Output = Self;
745
746    fn neg(self) -> Self::Output {
747        match self {
748            SymbolicExt::Const(ef) => SymbolicExt::Const(-ef),
749            SymbolicExt::Base(f) => SymbolicExt::Base(-f),
750            SymbolicExt::Val(ef) => {
751                let res = unsafe { (*ef.handle).neg_e(ef) };
752                SymbolicExt::Val(res)
753            }
754        }
755    }
756}
757
758// Implement all operations between N, F, EF, and SymbolicVar<N>, SymbolicFelt<F>, SymbolicExt<F,
759// EF>
760
761impl<N: Field> Add<N> for SymbolicVar<N> {
762    type Output = Self;
763
764    fn add(self, rhs: N) -> Self::Output {
765        self + SymbolicVar::from(rhs)
766    }
767}
768
769impl<F: Field> Add<F> for SymbolicFelt<F> {
770    type Output = Self;
771
772    fn add(self, rhs: F) -> Self::Output {
773        self + SymbolicFelt::from(rhs)
774    }
775}
776
777impl<N: Field> Mul<N> for SymbolicVar<N> {
778    type Output = Self;
779
780    fn mul(self, rhs: N) -> Self::Output {
781        self * SymbolicVar::from(rhs)
782    }
783}
784
785impl<F: Field> Mul<F> for SymbolicFelt<F> {
786    type Output = Self;
787
788    fn mul(self, rhs: F) -> Self::Output {
789        self * SymbolicFelt::from(rhs)
790    }
791}
792
793impl<N: Field> Sub<N> for SymbolicVar<N> {
794    type Output = Self;
795
796    fn sub(self, rhs: N) -> Self::Output {
797        self - SymbolicVar::from(rhs)
798    }
799}
800
801impl<F: Field> Sub<F> for SymbolicFelt<F> {
802    type Output = Self;
803
804    fn sub(self, rhs: F) -> Self::Output {
805        self - SymbolicFelt::from(rhs)
806    }
807}
808
809// Implement all operations between SymbolicVar<N>, SymbolicFelt<F>, SymbolicExt<F, EF>, and Var<N>,
810//  Felt<F>, Ext<F, EF>.
811
812impl<N: Field> Add<Var<N>> for SymbolicVar<N> {
813    type Output = SymbolicVar<N>;
814
815    fn add(self, rhs: Var<N>) -> Self::Output {
816        self + SymbolicVar::from(rhs)
817    }
818}
819
820impl<F: Field> Add<Felt<F>> for SymbolicFelt<F> {
821    type Output = SymbolicFelt<F>;
822
823    fn add(self, rhs: Felt<F>) -> Self::Output {
824        self + SymbolicFelt::from(rhs)
825    }
826}
827
828impl<N: Field> Mul<Var<N>> for SymbolicVar<N> {
829    type Output = SymbolicVar<N>;
830
831    fn mul(self, rhs: Var<N>) -> Self::Output {
832        self * SymbolicVar::from(rhs)
833    }
834}
835
836impl<F: Field> Mul<Felt<F>> for SymbolicFelt<F> {
837    type Output = SymbolicFelt<F>;
838
839    fn mul(self, rhs: Felt<F>) -> Self::Output {
840        self * SymbolicFelt::from(rhs)
841    }
842}
843
844impl<N: Field> Sub<Var<N>> for SymbolicVar<N> {
845    type Output = SymbolicVar<N>;
846
847    fn sub(self, rhs: Var<N>) -> Self::Output {
848        self - SymbolicVar::from(rhs)
849    }
850}
851
852impl<F: Field> Sub<Felt<F>> for SymbolicFelt<F> {
853    type Output = SymbolicFelt<F>;
854
855    fn sub(self, rhs: Felt<F>) -> Self::Output {
856        self - SymbolicFelt::from(rhs)
857    }
858}
859
860impl<F: Field> Div<SymbolicFelt<F>> for Felt<F> {
861    type Output = SymbolicFelt<F>;
862
863    fn div(self, rhs: SymbolicFelt<F>) -> Self::Output {
864        SymbolicFelt::<F>::from(self) / rhs
865    }
866}
867
868// Implement operations between constants N, F, EF, and Var<N>, Felt<F>, Ext<F, EF>.
869
870impl<N: Field> Add for Var<N> {
871    type Output = SymbolicVar<N>;
872
873    fn add(self, rhs: Self) -> Self::Output {
874        SymbolicVar::<N>::from(self) + rhs
875    }
876}
877
878impl<N: Field> Add<N> for Var<N> {
879    type Output = SymbolicVar<N>;
880
881    fn add(self, rhs: N) -> Self::Output {
882        SymbolicVar::from(self) + rhs
883    }
884}
885
886impl<F: Field> Add for Felt<F> {
887    type Output = SymbolicFelt<F>;
888
889    fn add(self, rhs: Self) -> Self::Output {
890        SymbolicFelt::<F>::from(self) + rhs
891    }
892}
893
894impl<F: Field> Add<F> for Felt<F> {
895    type Output = SymbolicFelt<F>;
896
897    fn add(self, rhs: F) -> Self::Output {
898        SymbolicFelt::from(self) + rhs
899    }
900}
901
902impl<N: Field> Mul for Var<N> {
903    type Output = SymbolicVar<N>;
904
905    fn mul(self, rhs: Self) -> Self::Output {
906        SymbolicVar::<N>::from(self) * rhs
907    }
908}
909
910impl<N: Field> Mul<N> for Var<N> {
911    type Output = SymbolicVar<N>;
912
913    fn mul(self, rhs: N) -> Self::Output {
914        SymbolicVar::from(self) * rhs
915    }
916}
917
918impl<F: Field> Mul for Felt<F> {
919    type Output = SymbolicFelt<F>;
920
921    fn mul(self, rhs: Self) -> Self::Output {
922        SymbolicFelt::<F>::from(self) * rhs
923    }
924}
925
926impl<F: Field> Mul<F> for Felt<F> {
927    type Output = SymbolicFelt<F>;
928
929    fn mul(self, rhs: F) -> Self::Output {
930        SymbolicFelt::from(self) * rhs
931    }
932}
933
934impl<N: Field> Sub for Var<N> {
935    type Output = SymbolicVar<N>;
936
937    fn sub(self, rhs: Self) -> Self::Output {
938        SymbolicVar::<N>::from(self) - rhs
939    }
940}
941
942impl<N: Field> Sub<N> for Var<N> {
943    type Output = SymbolicVar<N>;
944
945    fn sub(self, rhs: N) -> Self::Output {
946        SymbolicVar::from(self) - rhs
947    }
948}
949
950impl<F: Field> Sub for Felt<F> {
951    type Output = SymbolicFelt<F>;
952
953    fn sub(self, rhs: Self) -> Self::Output {
954        SymbolicFelt::<F>::from(self) - rhs
955    }
956}
957
958impl<F: Field> Sub<F> for Felt<F> {
959    type Output = SymbolicFelt<F>;
960
961    fn sub(self, rhs: F) -> Self::Output {
962        SymbolicFelt::from(self) - rhs
963    }
964}
965
966impl<F: Field, EF: ExtensionField<F>, E: Any> Add<E> for Ext<F, EF> {
967    type Output = SymbolicExt<F, EF>;
968
969    fn add(self, rhs: E) -> Self::Output {
970        let rhs: ExtOperand<F, EF> = rhs.to_operand();
971        let self_sym = self.to_operand().symbolic();
972        self_sym + rhs
973    }
974}
975
976impl<F: Field, EF: ExtensionField<F>, E: Any> Mul<E> for Ext<F, EF> {
977    type Output = SymbolicExt<F, EF>;
978
979    fn mul(self, rhs: E) -> Self::Output {
980        let self_sym = self.to_operand().symbolic();
981        self_sym * rhs
982    }
983}
984
985impl<F: Field, EF: ExtensionField<F>, E: Any> Sub<E> for Ext<F, EF> {
986    type Output = SymbolicExt<F, EF>;
987
988    fn sub(self, rhs: E) -> Self::Output {
989        let self_sym = self.to_operand().symbolic();
990        self_sym - rhs
991    }
992}
993
994impl<F: Field, EF: ExtensionField<F>, E: Any> Div<E> for Ext<F, EF> {
995    type Output = SymbolicExt<F, EF>;
996
997    fn div(self, rhs: E) -> Self::Output {
998        let self_sym = self.to_operand().symbolic();
999        self_sym / rhs
1000    }
1001}
1002
1003impl<F: Field, EF: ExtensionField<F>> Add<SymbolicExt<F, EF>> for Felt<F> {
1004    type Output = SymbolicExt<F, EF>;
1005
1006    fn add(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
1007        let self_sym = self.to_operand().symbolic();
1008        self_sym + rhs
1009    }
1010}
1011
1012impl<F: Field, EF: ExtensionField<F>> Mul<SymbolicExt<F, EF>> for Felt<F> {
1013    type Output = SymbolicExt<F, EF>;
1014
1015    fn mul(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
1016        let self_sym = self.to_operand().symbolic();
1017        self_sym * rhs
1018    }
1019}
1020
1021impl<F: Field, EF: ExtensionField<F>> Sub<SymbolicExt<F, EF>> for Felt<F> {
1022    type Output = SymbolicExt<F, EF>;
1023
1024    fn sub(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
1025        let self_sym = self.to_operand().symbolic();
1026        self_sym - rhs
1027    }
1028}
1029
1030impl<F: Field, EF: ExtensionField<F>> Div<SymbolicExt<F, EF>> for Felt<F> {
1031    type Output = SymbolicExt<F, EF>;
1032
1033    fn div(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
1034        let self_sym = self.to_operand().symbolic();
1035        self_sym / rhs
1036    }
1037}
1038
1039impl<F: Field> Div for Felt<F> {
1040    type Output = SymbolicFelt<F>;
1041
1042    fn div(self, rhs: Self) -> Self::Output {
1043        SymbolicFelt::<F>::from(self) / rhs
1044    }
1045}
1046
1047impl<F: Field> Div<F> for Felt<F> {
1048    type Output = SymbolicFelt<F>;
1049
1050    fn div(self, rhs: F) -> Self::Output {
1051        SymbolicFelt::from(self) / rhs
1052    }
1053}
1054
1055impl<F: Field> Div<Felt<F>> for SymbolicFelt<F> {
1056    type Output = SymbolicFelt<F>;
1057
1058    fn div(self, rhs: Felt<F>) -> Self::Output {
1059        self / SymbolicFelt::from(rhs)
1060    }
1061}
1062
1063impl<F: Field> Div<F> for SymbolicFelt<F> {
1064    type Output = SymbolicFelt<F>;
1065
1066    fn div(self, rhs: F) -> Self::Output {
1067        self / SymbolicFelt::from(rhs)
1068    }
1069}
1070
1071impl<N: Field> Sub<SymbolicVar<N>> for Var<N> {
1072    type Output = SymbolicVar<N>;
1073
1074    fn sub(self, rhs: SymbolicVar<N>) -> Self::Output {
1075        SymbolicVar::<N>::from(self) - rhs
1076    }
1077}
1078
1079impl<N: Field> Add<SymbolicVar<N>> for Var<N> {
1080    type Output = SymbolicVar<N>;
1081
1082    fn add(self, rhs: SymbolicVar<N>) -> Self::Output {
1083        SymbolicVar::<N>::from(self) + rhs
1084    }
1085}
1086
1087impl<N: Field> Mul<usize> for Usize<N> {
1088    type Output = SymbolicVar<N>;
1089
1090    fn mul(self, rhs: usize) -> Self::Output {
1091        match self {
1092            Usize::Const(n) => SymbolicVar::from(N::from_canonical_usize(n * rhs)),
1093            Usize::Var(n) => SymbolicVar::from(n) * N::from_canonical_usize(rhs),
1094        }
1095    }
1096}
1097
1098impl<N: Field> Product for SymbolicVar<N> {
1099    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1100        iter.fold(SymbolicVar::one(), |acc, x| acc * x)
1101    }
1102}
1103
1104impl<N: Field> Sum for SymbolicVar<N> {
1105    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1106        iter.fold(SymbolicVar::zero(), |acc, x| acc + x)
1107    }
1108}
1109
1110impl<N: Field> AddAssign for SymbolicVar<N> {
1111    fn add_assign(&mut self, rhs: Self) {
1112        *self = *self + rhs;
1113    }
1114}
1115
1116impl<N: Field> SubAssign for SymbolicVar<N> {
1117    fn sub_assign(&mut self, rhs: Self) {
1118        *self = *self - rhs;
1119    }
1120}
1121
1122impl<N: Field> MulAssign for SymbolicVar<N> {
1123    fn mul_assign(&mut self, rhs: Self) {
1124        *self = *self * rhs;
1125    }
1126}
1127
1128impl<N: Field> Default for SymbolicVar<N> {
1129    fn default() -> Self {
1130        SymbolicVar::zero()
1131    }
1132}
1133
1134impl<F: Field> Sum for SymbolicFelt<F> {
1135    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1136        iter.fold(SymbolicFelt::zero(), |acc, x| acc + x)
1137    }
1138}
1139
1140impl<F: Field> Product for SymbolicFelt<F> {
1141    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1142        iter.fold(SymbolicFelt::one(), |acc, x| acc * x)
1143    }
1144}
1145
1146impl<F: Field> AddAssign for SymbolicFelt<F> {
1147    fn add_assign(&mut self, rhs: Self) {
1148        *self = *self + rhs;
1149    }
1150}
1151
1152impl<F: Field> SubAssign for SymbolicFelt<F> {
1153    fn sub_assign(&mut self, rhs: Self) {
1154        *self = *self - rhs;
1155    }
1156}
1157
1158impl<F: Field> MulAssign for SymbolicFelt<F> {
1159    fn mul_assign(&mut self, rhs: Self) {
1160        *self = *self * rhs;
1161    }
1162}
1163
1164impl<F: Field> Default for SymbolicFelt<F> {
1165    fn default() -> Self {
1166        SymbolicFelt::zero()
1167    }
1168}
1169
1170impl<F: Field, EF: ExtensionField<F>> Sum for SymbolicExt<F, EF> {
1171    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1172        iter.fold(SymbolicExt::zero(), |acc, x| acc + x)
1173    }
1174}
1175
1176impl<F: Field, EF: ExtensionField<F>> Product for SymbolicExt<F, EF> {
1177    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1178        iter.fold(SymbolicExt::one(), |acc, x| acc * x)
1179    }
1180}
1181
1182impl<F: Field, EF: ExtensionField<F>> Default for SymbolicExt<F, EF> {
1183    fn default() -> Self {
1184        SymbolicExt::zero()
1185    }
1186}
1187
1188impl<F: Field, EF: ExtensionField<F>, E: Any> AddAssign<E> for SymbolicExt<F, EF> {
1189    fn add_assign(&mut self, rhs: E) {
1190        *self = *self + rhs;
1191    }
1192}
1193
1194impl<F: Field, EF: ExtensionField<F>, E: Any> SubAssign<E> for SymbolicExt<F, EF> {
1195    fn sub_assign(&mut self, rhs: E) {
1196        *self = *self - rhs;
1197    }
1198}
1199
1200impl<F: Field, EF: ExtensionField<F>, E: Any> MulAssign<E> for SymbolicExt<F, EF> {
1201    fn mul_assign(&mut self, rhs: E) {
1202        *self = *self * rhs;
1203    }
1204}
1205
1206impl<F: Field, EF: ExtensionField<F>, E: Any> DivAssign<E> for SymbolicExt<F, EF> {
1207    fn div_assign(&mut self, rhs: E) {
1208        *self = *self / rhs;
1209    }
1210}
1211
1212impl<F: Field, EF: ExtensionField<F>> Mul<SymbolicExt<F, EF>> for SymbolicFelt<F> {
1213    type Output = SymbolicExt<F, EF>;
1214
1215    fn mul(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
1216        rhs * self
1217    }
1218}
1219
1220impl<F: Field, EF: ExtensionField<F>, E: Any> ExtensionOperand<F, EF> for E {
1221    fn to_operand(self) -> ExtOperand<F, EF> {
1222        match self.type_id() {
1223            ty if ty == TypeId::of::<F>() => {
1224                // *Safety*: We know that E is a F and we can transmute it to F which implements
1225                // the Copy trait.
1226                let value = unsafe { mem::transmute_copy::<E, F>(&self) };
1227                ExtOperand::<F, EF>::Base(value)
1228            }
1229            ty if ty == TypeId::of::<EF>() => {
1230                // *Safety*: We know that E is a EF and we can transmute it to EF which implements
1231                // the Copy trait.
1232                let value = unsafe { mem::transmute_copy::<E, EF>(&self) };
1233                ExtOperand::<F, EF>::Const(value)
1234            }
1235            ty if ty == TypeId::of::<Felt<F>>() => {
1236                // *Safety*: We know that E is a Felt<F> and we can transmute it to Felt<F> which
1237                // implements the Copy trait.
1238                let value = unsafe { mem::transmute_copy::<E, Felt<F>>(&self) };
1239                ExtOperand::<F, EF>::Felt(value)
1240            }
1241            ty if ty == TypeId::of::<Ext<F, EF>>() => {
1242                // *Safety*: We know that E is a Ext<F, EF> and we can transmute it to Ext<F, EF>
1243                // which implements the Copy trait.
1244                let value = unsafe { mem::transmute_copy::<E, Ext<F, EF>>(&self) };
1245                ExtOperand::<F, EF>::Ext(value)
1246            }
1247            ty if ty == TypeId::of::<SymbolicFelt<F>>() => {
1248                // *Safety*: We know that E is a Symbolic Felt<F> and we can transmute it to
1249                // SymbolicFelt<F> but we need to clone the pointer.
1250                let value_ref = unsafe { mem::transmute::<&E, &SymbolicFelt<F>>(&self) };
1251                let value = *value_ref;
1252                ExtOperand::<F, EF>::SymFelt(value)
1253            }
1254            ty if ty == TypeId::of::<SymbolicExt<F, EF>>() => {
1255                // *Safety*: We know that E is a SymbolicExt<F, EF> and we can transmute it to
1256                // SymbolicExt<F, EF> but we need to clone the pointer.
1257                let value_ref = unsafe { mem::transmute::<&E, &SymbolicExt<F, EF>>(&self) };
1258                let value = *value_ref;
1259                ExtOperand::<F, EF>::Sym(value)
1260            }
1261            ty if ty == TypeId::of::<ExtOperand<F, EF>>() => {
1262                let value_ref = unsafe { mem::transmute::<&E, &ExtOperand<F, EF>>(&self) };
1263                value_ref.clone()
1264            }
1265            _ => unimplemented!("unsupported type {:?}", self.type_id()),
1266        }
1267    }
1268}
1269
1270impl<F: Field> Add<SymbolicFelt<F>> for Felt<F> {
1271    type Output = SymbolicFelt<F>;
1272
1273    fn add(self, rhs: SymbolicFelt<F>) -> Self::Output {
1274        SymbolicFelt::<F>::from(self) + rhs
1275    }
1276}
1277
1278impl<F: Field, EF: ExtensionField<F>> From<Felt<F>> for SymbolicExt<F, EF> {
1279    fn from(value: Felt<F>) -> Self {
1280        value.to_operand().symbolic()
1281    }
1282}
1283
1284impl<F: Field, EF: ExtensionField<F>> Neg for Ext<F, EF> {
1285    type Output = SymbolicExt<F, EF>;
1286    fn neg(self) -> Self::Output {
1287        -SymbolicExt::from(self)
1288    }
1289}
1290
1291impl<F: Field> Neg for Felt<F> {
1292    type Output = SymbolicFelt<F>;
1293
1294    fn neg(self) -> Self::Output {
1295        -SymbolicFelt::from(self)
1296    }
1297}
1298
1299impl<N: Field> Neg for Var<N> {
1300    type Output = SymbolicVar<N>;
1301
1302    fn neg(self) -> Self::Output {
1303        -SymbolicVar::from(self)
1304    }
1305}
1306
1307impl<N: Field> From<usize> for SymbolicUsize<N> {
1308    fn from(n: usize) -> Self {
1309        SymbolicUsize::Const(n)
1310    }
1311}
1312
1313impl<N: Field> From<SymbolicVar<N>> for SymbolicUsize<N> {
1314    fn from(n: SymbolicVar<N>) -> Self {
1315        SymbolicUsize::Var(n)
1316    }
1317}
1318
1319impl<N: Field> From<Var<N>> for SymbolicUsize<N> {
1320    fn from(n: Var<N>) -> Self {
1321        SymbolicUsize::Var(SymbolicVar::from(n))
1322    }
1323}
1324
1325impl<N: Field> Add for SymbolicUsize<N> {
1326    type Output = Self;
1327
1328    fn add(self, rhs: Self) -> Self::Output {
1329        match (self, rhs) {
1330            (SymbolicUsize::Const(a), SymbolicUsize::Const(b)) => SymbolicUsize::Const(a + b),
1331            (SymbolicUsize::Var(a), SymbolicUsize::Const(b)) => {
1332                SymbolicUsize::Var(a + N::from_canonical_usize(b))
1333            }
1334            (SymbolicUsize::Const(a), SymbolicUsize::Var(b)) => {
1335                SymbolicUsize::Var(b + N::from_canonical_usize(a))
1336            }
1337            (SymbolicUsize::Var(a), SymbolicUsize::Var(b)) => SymbolicUsize::Var(a + b),
1338        }
1339    }
1340}
1341
1342impl<N: Field> Sub for SymbolicUsize<N> {
1343    type Output = Self;
1344
1345    fn sub(self, rhs: Self) -> Self::Output {
1346        match (self, rhs) {
1347            (SymbolicUsize::Const(a), SymbolicUsize::Const(b)) => SymbolicUsize::Const(a - b),
1348            (SymbolicUsize::Var(a), SymbolicUsize::Const(b)) => {
1349                SymbolicUsize::Var(a - N::from_canonical_usize(b))
1350            }
1351            (SymbolicUsize::Const(a), SymbolicUsize::Var(b)) => {
1352                SymbolicUsize::Var(SymbolicVar::from(N::from_canonical_usize(a)) - b)
1353            }
1354            (SymbolicUsize::Var(a), SymbolicUsize::Var(b)) => SymbolicUsize::Var(a - b),
1355        }
1356    }
1357}
1358
1359impl<N: Field> Add<usize> for SymbolicUsize<N> {
1360    type Output = Self;
1361
1362    fn add(self, rhs: usize) -> Self::Output {
1363        match self {
1364            SymbolicUsize::Const(a) => SymbolicUsize::Const(a + rhs),
1365            SymbolicUsize::Var(a) => SymbolicUsize::Var(a + N::from_canonical_usize(rhs)),
1366        }
1367    }
1368}
1369
1370impl<N: Field> Sub<usize> for SymbolicUsize<N> {
1371    type Output = Self;
1372
1373    fn sub(self, rhs: usize) -> Self::Output {
1374        match self {
1375            SymbolicUsize::Const(a) => SymbolicUsize::Const(a - rhs),
1376            SymbolicUsize::Var(a) => SymbolicUsize::Var(a - N::from_canonical_usize(rhs)),
1377        }
1378    }
1379}
1380
1381impl<N: Field> From<Usize<N>> for SymbolicUsize<N> {
1382    fn from(n: Usize<N>) -> Self {
1383        match n {
1384            Usize::Const(n) => SymbolicUsize::Const(n),
1385            Usize::Var(n) => SymbolicUsize::Var(SymbolicVar::from(n)),
1386        }
1387    }
1388}
1389
1390impl<N: Field> Add<Usize<N>> for SymbolicUsize<N> {
1391    type Output = SymbolicUsize<N>;
1392
1393    fn add(self, rhs: Usize<N>) -> Self::Output {
1394        self + Self::from(rhs)
1395    }
1396}
1397
1398impl<N: Field> Sub<Usize<N>> for SymbolicUsize<N> {
1399    type Output = SymbolicUsize<N>;
1400
1401    fn sub(self, rhs: Usize<N>) -> Self::Output {
1402        self - Self::from(rhs)
1403    }
1404}
1405
1406impl<N: Field> Add<usize> for Usize<N> {
1407    type Output = SymbolicUsize<N>;
1408
1409    fn add(self, rhs: usize) -> Self::Output {
1410        SymbolicUsize::from(self) + rhs
1411    }
1412}
1413
1414impl<N: Field> Sub<usize> for Usize<N> {
1415    type Output = SymbolicUsize<N>;
1416
1417    fn sub(self, rhs: usize) -> Self::Output {
1418        SymbolicUsize::from(self) - rhs
1419    }
1420}
1421
1422impl<N: Field> Add<Usize<N>> for Usize<N> {
1423    type Output = SymbolicUsize<N>;
1424
1425    fn add(self, rhs: Usize<N>) -> Self::Output {
1426        SymbolicUsize::from(self) + rhs
1427    }
1428}
1429
1430impl<N: Field> Sub<Usize<N>> for Usize<N> {
1431    type Output = SymbolicUsize<N>;
1432
1433    fn sub(self, rhs: Usize<N>) -> Self::Output {
1434        SymbolicUsize::from(self) - rhs
1435    }
1436}
1437
1438impl<F: Field> MulAssign<Felt<F>> for SymbolicFelt<F> {
1439    fn mul_assign(&mut self, rhs: Felt<F>) {
1440        *self = *self * Self::from(rhs);
1441    }
1442}
1443
1444impl<F: Field> Mul<SymbolicFelt<F>> for Felt<F> {
1445    type Output = SymbolicFelt<F>;
1446
1447    fn mul(self, rhs: SymbolicFelt<F>) -> Self::Output {
1448        SymbolicFelt::<F>::from(self) * rhs
1449    }
1450}
1451
1452impl<N: Field> Mul<SymbolicVar<N>> for Var<N> {
1453    type Output = SymbolicVar<N>;
1454
1455    fn mul(self, rhs: SymbolicVar<N>) -> Self::Output {
1456        SymbolicVar::<N>::from(self) * rhs
1457    }
1458}
1459
1460impl<N: Field> Sub<Usize<N>> for SymbolicVar<N> {
1461    type Output = SymbolicVar<N>;
1462
1463    fn sub(self, rhs: Usize<N>) -> Self::Output {
1464        match rhs {
1465            Usize::Const(n) => self - N::from_canonical_usize(n),
1466            Usize::Var(n) => self - n,
1467        }
1468    }
1469}
1470
1471impl<N: Field> Add<Usize<N>> for SymbolicVar<N> {
1472    type Output = SymbolicVar<N>;
1473
1474    fn add(self, rhs: Usize<N>) -> Self::Output {
1475        match rhs {
1476            Usize::Const(n) => self + N::from_canonical_usize(n),
1477            Usize::Var(n) => self + n,
1478        }
1479    }
1480}
1481
1482impl<N: Field> Add<Usize<N>> for Var<N> {
1483    type Output = SymbolicVar<N>;
1484
1485    fn add(self, rhs: Usize<N>) -> Self::Output {
1486        SymbolicVar::<N>::from(self) + rhs
1487    }
1488}
1489
1490impl<N: Field> Sub<Usize<N>> for Var<N> {
1491    type Output = SymbolicVar<N>;
1492
1493    fn sub(self, rhs: Usize<N>) -> Self::Output {
1494        SymbolicVar::<N>::from(self) - rhs
1495    }
1496}
1497
1498impl<N: Field> Sub<SymbolicVar<N>> for Usize<N> {
1499    type Output = SymbolicVar<N>;
1500
1501    fn sub(self, rhs: SymbolicVar<N>) -> Self::Output {
1502        match self {
1503            Usize::Const(n) => SymbolicVar::from(N::from_canonical_usize(n)) - rhs,
1504            Usize::Var(n) => SymbolicVar::<N>::from(n) - rhs,
1505        }
1506    }
1507}
1508
1509impl<N: Field> Add<SymbolicVar<N>> for Usize<N> {
1510    type Output = SymbolicVar<N>;
1511
1512    fn add(self, rhs: SymbolicVar<N>) -> Self::Output {
1513        match self {
1514            Usize::Const(n) => SymbolicVar::from(N::from_canonical_usize(n)) + rhs,
1515            Usize::Var(n) => SymbolicVar::<N>::from(n) + rhs,
1516        }
1517    }
1518}
1519
1520impl<N: Field> Add<Var<N>> for Usize<N> {
1521    type Output = SymbolicVar<N>;
1522
1523    fn add(self, rhs: Var<N>) -> Self::Output {
1524        self + SymbolicVar::<N>::from(rhs)
1525    }
1526}
1527
1528impl<N: Field> Sub<Var<N>> for Usize<N> {
1529    type Output = SymbolicVar<N>;
1530
1531    fn sub(self, rhs: Var<N>) -> Self::Output {
1532        self - SymbolicVar::<N>::from(rhs)
1533    }
1534}
1535
1536impl<N: Field> From<Usize<N>> for SymbolicVar<N> {
1537    fn from(value: Usize<N>) -> Self {
1538        match value {
1539            Usize::Const(n) => SymbolicVar::from(N::from_canonical_usize(n)),
1540            Usize::Var(n) => SymbolicVar::from(n),
1541        }
1542    }
1543}