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 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 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 fn generator() -> Self {
238 SymbolicExt::from_f(EF::generator())
239 }
240}
241
242impl<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
262impl<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
282impl<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
758impl<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
809impl<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
868impl<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 let value = unsafe { mem::transmute_copy::<E, F>(&self) };
1227 ExtOperand::<F, EF>::Base(value)
1228 }
1229 ty if ty == TypeId::of::<EF>() => {
1230 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 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 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 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 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}