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