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
37#[derive(Debug, Clone)]
38pub enum ExtOperand<F: Field, EF: ExtensionField<F>> {
39 Base(F),
40 Const(EF),
41 Felt(Felt<F>),
42 Ext(Ext<F, EF>),
43 SymFelt(SymbolicFelt<F>),
44 Sym(SymbolicExt<F, EF>),
45}
46
47impl<F: Field, EF: ExtensionField<F>> ExtOperand<F, EF> {
48 pub fn symbolic(self) -> SymbolicExt<F, EF> {
49 match self {
50 ExtOperand::Base(f) => SymbolicExt::Base(SymbolicFelt::from(f)),
51 ExtOperand::Const(ef) => SymbolicExt::Const(ef),
52 ExtOperand::Felt(f) => SymbolicExt::Base(SymbolicFelt::from(f)),
53 ExtOperand::Ext(e) => SymbolicExt::Val(e),
54 ExtOperand::SymFelt(f) => SymbolicExt::Base(f),
55 ExtOperand::Sym(e) => e,
56 }
57 }
58}
59
60pub trait ExtConst<F: Field, EF: ExtensionField<F>> {
61 fn cons(self) -> SymbolicExt<F, EF>;
62}
63
64impl<F: Field, EF: ExtensionField<F>> ExtConst<F, EF> for EF {
65 fn cons(self) -> SymbolicExt<F, EF> {
66 SymbolicExt::Const(self)
67 }
68}
69
70pub trait ExtensionOperand<F: Field, EF: ExtensionField<F>> {
71 fn to_operand(self) -> ExtOperand<F, EF>;
72}
73
74impl<N: Field> AbstractField for SymbolicVar<N> {
75 type F = N;
76
77 fn zero() -> Self {
78 SymbolicVar::from(N::zero())
79 }
80
81 fn one() -> Self {
82 SymbolicVar::from(N::one())
83 }
84
85 fn two() -> Self {
86 SymbolicVar::from(N::two())
87 }
88
89 fn neg_one() -> Self {
90 SymbolicVar::from(N::neg_one())
91 }
92
93 fn from_f(f: Self::F) -> Self {
94 SymbolicVar::from(f)
95 }
96 fn from_bool(b: bool) -> Self {
97 SymbolicVar::from(N::from_bool(b))
98 }
99 fn from_canonical_u8(n: u8) -> Self {
100 SymbolicVar::from(N::from_canonical_u8(n))
101 }
102 fn from_canonical_u16(n: u16) -> Self {
103 SymbolicVar::from(N::from_canonical_u16(n))
104 }
105 fn from_canonical_u32(n: u32) -> Self {
106 SymbolicVar::from(N::from_canonical_u32(n))
107 }
108 fn from_canonical_u64(n: u64) -> Self {
109 SymbolicVar::from(N::from_canonical_u64(n))
110 }
111 fn from_canonical_usize(n: usize) -> Self {
112 SymbolicVar::from(N::from_canonical_usize(n))
113 }
114
115 fn from_wrapped_u32(n: u32) -> Self {
116 SymbolicVar::from(N::from_wrapped_u32(n))
117 }
118 fn from_wrapped_u64(n: u64) -> Self {
119 SymbolicVar::from(N::from_wrapped_u64(n))
120 }
121
122 fn generator() -> Self {
124 SymbolicVar::from(N::generator())
125 }
126}
127
128impl<F: Field> AbstractField for SymbolicFelt<F> {
129 type F = F;
130
131 fn zero() -> Self {
132 SymbolicFelt::from(F::zero())
133 }
134
135 fn one() -> Self {
136 SymbolicFelt::from(F::one())
137 }
138
139 fn two() -> Self {
140 SymbolicFelt::from(F::two())
141 }
142
143 fn neg_one() -> Self {
144 SymbolicFelt::from(F::neg_one())
145 }
146
147 fn from_f(f: Self::F) -> Self {
148 SymbolicFelt::from(f)
149 }
150 fn from_bool(b: bool) -> Self {
151 SymbolicFelt::from(F::from_bool(b))
152 }
153 fn from_canonical_u8(n: u8) -> Self {
154 SymbolicFelt::from(F::from_canonical_u8(n))
155 }
156 fn from_canonical_u16(n: u16) -> Self {
157 SymbolicFelt::from(F::from_canonical_u16(n))
158 }
159 fn from_canonical_u32(n: u32) -> Self {
160 SymbolicFelt::from(F::from_canonical_u32(n))
161 }
162 fn from_canonical_u64(n: u64) -> Self {
163 SymbolicFelt::from(F::from_canonical_u64(n))
164 }
165 fn from_canonical_usize(n: usize) -> Self {
166 SymbolicFelt::from(F::from_canonical_usize(n))
167 }
168
169 fn from_wrapped_u32(n: u32) -> Self {
170 SymbolicFelt::from(F::from_wrapped_u32(n))
171 }
172 fn from_wrapped_u64(n: u64) -> Self {
173 SymbolicFelt::from(F::from_wrapped_u64(n))
174 }
175
176 fn generator() -> Self {
178 SymbolicFelt::from(F::generator())
179 }
180}
181
182impl<F: Field, EF: ExtensionField<F>> AbstractField for SymbolicExt<F, EF> {
183 type F = EF;
184
185 fn zero() -> Self {
186 SymbolicExt::from_f(EF::zero())
187 }
188
189 fn one() -> Self {
190 SymbolicExt::from_f(EF::one())
191 }
192
193 fn two() -> Self {
194 SymbolicExt::from_f(EF::two())
195 }
196
197 fn neg_one() -> Self {
198 SymbolicExt::from_f(EF::neg_one())
199 }
200
201 fn from_f(f: Self::F) -> Self {
202 SymbolicExt::Const(f)
203 }
204 fn from_bool(b: bool) -> Self {
205 SymbolicExt::from_f(EF::from_bool(b))
206 }
207 fn from_canonical_u8(n: u8) -> Self {
208 SymbolicExt::from_f(EF::from_canonical_u8(n))
209 }
210 fn from_canonical_u16(n: u16) -> Self {
211 SymbolicExt::from_f(EF::from_canonical_u16(n))
212 }
213 fn from_canonical_u32(n: u32) -> Self {
214 SymbolicExt::from_f(EF::from_canonical_u32(n))
215 }
216 fn from_canonical_u64(n: u64) -> Self {
217 SymbolicExt::from_f(EF::from_canonical_u64(n))
218 }
219 fn from_canonical_usize(n: usize) -> Self {
220 SymbolicExt::from_f(EF::from_canonical_usize(n))
221 }
222
223 fn from_wrapped_u32(n: u32) -> Self {
224 SymbolicExt::from_f(EF::from_wrapped_u32(n))
225 }
226 fn from_wrapped_u64(n: u64) -> Self {
227 SymbolicExt::from_f(EF::from_wrapped_u64(n))
228 }
229
230 fn generator() -> Self {
232 SymbolicExt::from_f(EF::generator())
233 }
234}
235
236impl<N: Field> From<N> for SymbolicVar<N> {
239 fn from(n: N) -> Self {
240 SymbolicVar::Const(n)
241 }
242}
243
244impl<F: Field> From<F> for SymbolicFelt<F> {
245 fn from(f: F) -> Self {
246 SymbolicFelt::Const(f)
247 }
248}
249
250impl<F: Field, EF: ExtensionField<F>> From<F> for SymbolicExt<F, EF> {
251 fn from(f: F) -> Self {
252 f.to_operand().symbolic()
253 }
254}
255
256impl<N: Field> From<Var<N>> for SymbolicVar<N> {
259 fn from(v: Var<N>) -> Self {
260 SymbolicVar::Val(v)
261 }
262}
263
264impl<F: Field> From<Felt<F>> for SymbolicFelt<F> {
265 fn from(f: Felt<F>) -> Self {
266 SymbolicFelt::Val(f)
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> Product for SymbolicVar<N> {
1088 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1089 iter.fold(SymbolicVar::one(), |acc, x| acc * x)
1090 }
1091}
1092
1093impl<N: Field> Sum for SymbolicVar<N> {
1094 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1095 iter.fold(SymbolicVar::zero(), |acc, x| acc + x)
1096 }
1097}
1098
1099impl<N: Field> AddAssign for SymbolicVar<N> {
1100 fn add_assign(&mut self, rhs: Self) {
1101 *self = *self + rhs;
1102 }
1103}
1104
1105impl<N: Field> SubAssign for SymbolicVar<N> {
1106 fn sub_assign(&mut self, rhs: Self) {
1107 *self = *self - rhs;
1108 }
1109}
1110
1111impl<N: Field> MulAssign for SymbolicVar<N> {
1112 fn mul_assign(&mut self, rhs: Self) {
1113 *self = *self * rhs;
1114 }
1115}
1116
1117impl<N: Field> Default for SymbolicVar<N> {
1118 fn default() -> Self {
1119 SymbolicVar::zero()
1120 }
1121}
1122
1123impl<F: Field> Sum for SymbolicFelt<F> {
1124 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1125 iter.fold(SymbolicFelt::zero(), |acc, x| acc + x)
1126 }
1127}
1128
1129impl<F: Field> Product for SymbolicFelt<F> {
1130 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1131 iter.fold(SymbolicFelt::one(), |acc, x| acc * x)
1132 }
1133}
1134
1135impl<F: Field> AddAssign for SymbolicFelt<F> {
1136 fn add_assign(&mut self, rhs: Self) {
1137 *self = *self + rhs;
1138 }
1139}
1140
1141impl<F: Field> SubAssign for SymbolicFelt<F> {
1142 fn sub_assign(&mut self, rhs: Self) {
1143 *self = *self - rhs;
1144 }
1145}
1146
1147impl<F: Field> MulAssign for SymbolicFelt<F> {
1148 fn mul_assign(&mut self, rhs: Self) {
1149 *self = *self * rhs;
1150 }
1151}
1152
1153impl<F: Field> Default for SymbolicFelt<F> {
1154 fn default() -> Self {
1155 SymbolicFelt::zero()
1156 }
1157}
1158
1159impl<F: Field, EF: ExtensionField<F>> Sum for SymbolicExt<F, EF> {
1160 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1161 iter.fold(SymbolicExt::zero(), |acc, x| acc + x)
1162 }
1163}
1164
1165impl<F: Field, EF: ExtensionField<F>> Product for SymbolicExt<F, EF> {
1166 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1167 iter.fold(SymbolicExt::one(), |acc, x| acc * x)
1168 }
1169}
1170
1171impl<F: Field, EF: ExtensionField<F>> Default for SymbolicExt<F, EF> {
1172 fn default() -> Self {
1173 SymbolicExt::zero()
1174 }
1175}
1176
1177impl<F: Field, EF: ExtensionField<F>, E: Any> AddAssign<E> for SymbolicExt<F, EF> {
1178 fn add_assign(&mut self, rhs: E) {
1179 *self = *self + rhs;
1180 }
1181}
1182
1183impl<F: Field, EF: ExtensionField<F>, E: Any> SubAssign<E> for SymbolicExt<F, EF> {
1184 fn sub_assign(&mut self, rhs: E) {
1185 *self = *self - rhs;
1186 }
1187}
1188
1189impl<F: Field, EF: ExtensionField<F>, E: Any> MulAssign<E> for SymbolicExt<F, EF> {
1190 fn mul_assign(&mut self, rhs: E) {
1191 *self = *self * rhs;
1192 }
1193}
1194
1195impl<F: Field, EF: ExtensionField<F>, E: Any> DivAssign<E> for SymbolicExt<F, EF> {
1196 fn div_assign(&mut self, rhs: E) {
1197 *self = *self / rhs;
1198 }
1199}
1200
1201impl<F: Field, EF: ExtensionField<F>> Mul<SymbolicExt<F, EF>> for SymbolicFelt<F> {
1202 type Output = SymbolicExt<F, EF>;
1203
1204 fn mul(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
1205 rhs * self
1206 }
1207}
1208
1209impl<F: Field, EF: ExtensionField<F>, E: Any> ExtensionOperand<F, EF> for E {
1210 fn to_operand(self) -> ExtOperand<F, EF> {
1211 match self.type_id() {
1212 ty if ty == TypeId::of::<F>() => {
1213 let value = unsafe { mem::transmute_copy::<E, F>(&self) };
1216 ExtOperand::<F, EF>::Base(value)
1217 }
1218 ty if ty == TypeId::of::<EF>() => {
1219 let value = unsafe { mem::transmute_copy::<E, EF>(&self) };
1222 ExtOperand::<F, EF>::Const(value)
1223 }
1224 ty if ty == TypeId::of::<Felt<F>>() => {
1225 let value = unsafe { mem::transmute_copy::<E, Felt<F>>(&self) };
1228 ExtOperand::<F, EF>::Felt(value)
1229 }
1230 ty if ty == TypeId::of::<Ext<F, EF>>() => {
1231 let value = unsafe { mem::transmute_copy::<E, Ext<F, EF>>(&self) };
1234 ExtOperand::<F, EF>::Ext(value)
1235 }
1236 ty if ty == TypeId::of::<SymbolicFelt<F>>() => {
1237 let value_ref = unsafe { mem::transmute::<&E, &SymbolicFelt<F>>(&self) };
1240 let value = *value_ref;
1241 ExtOperand::<F, EF>::SymFelt(value)
1242 }
1243 ty if ty == TypeId::of::<SymbolicExt<F, EF>>() => {
1244 let value_ref = unsafe { mem::transmute::<&E, &SymbolicExt<F, EF>>(&self) };
1247 let value = *value_ref;
1248 ExtOperand::<F, EF>::Sym(value)
1249 }
1250 ty if ty == TypeId::of::<ExtOperand<F, EF>>() => {
1251 let value_ref = unsafe { mem::transmute::<&E, &ExtOperand<F, EF>>(&self) };
1252 value_ref.clone()
1253 }
1254 _ => unimplemented!("unsupported type {:?}", self.type_id()),
1255 }
1256 }
1257}
1258
1259impl<F: Field> Add<SymbolicFelt<F>> for Felt<F> {
1260 type Output = SymbolicFelt<F>;
1261
1262 fn add(self, rhs: SymbolicFelt<F>) -> Self::Output {
1263 SymbolicFelt::<F>::from(self) + rhs
1264 }
1265}
1266
1267impl<F: Field, EF: ExtensionField<F>> From<Felt<F>> for SymbolicExt<F, EF> {
1268 fn from(value: Felt<F>) -> Self {
1269 value.to_operand().symbolic()
1270 }
1271}
1272
1273impl<F: Field, EF: ExtensionField<F>> Neg for Ext<F, EF> {
1274 type Output = SymbolicExt<F, EF>;
1275 fn neg(self) -> Self::Output {
1276 -SymbolicExt::from(self)
1277 }
1278}
1279
1280impl<F: Field> Neg for Felt<F> {
1281 type Output = SymbolicFelt<F>;
1282
1283 fn neg(self) -> Self::Output {
1284 -SymbolicFelt::from(self)
1285 }
1286}
1287
1288impl<N: Field> Neg for Var<N> {
1289 type Output = SymbolicVar<N>;
1290
1291 fn neg(self) -> Self::Output {
1292 -SymbolicVar::from(self)
1293 }
1294}
1295
1296impl<F: Field> MulAssign<Felt<F>> for SymbolicFelt<F> {
1297 fn mul_assign(&mut self, rhs: Felt<F>) {
1298 *self = *self * Self::from(rhs);
1299 }
1300}
1301
1302impl<F: Field> Mul<SymbolicFelt<F>> for Felt<F> {
1303 type Output = SymbolicFelt<F>;
1304
1305 fn mul(self, rhs: SymbolicFelt<F>) -> Self::Output {
1306 SymbolicFelt::<F>::from(self) * rhs
1307 }
1308}
1309
1310impl<N: Field> Mul<SymbolicVar<N>> for Var<N> {
1311 type Output = SymbolicVar<N>;
1312
1313 fn mul(self, rhs: SymbolicVar<N>) -> Self::Output {
1314 SymbolicVar::<N>::from(self) * rhs
1315 }
1316}