use core::marker::PhantomData;
use core::ops::{Add, Mul, Sub};
use p3_field::Field;
use crate::symbolic_expression::SymbolicExpression;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum Entry {
Preprocessed { offset: usize },
Main { offset: usize },
Permutation { offset: usize },
Public,
Challenge,
}
#[derive(Copy, Clone, Debug)]
pub struct SymbolicVariable<F: Field> {
pub entry: Entry,
pub index: usize,
pub(crate) _phantom: PhantomData<F>,
}
impl<F: Field> SymbolicVariable<F> {
pub const fn new(entry: Entry, index: usize) -> Self {
Self {
entry,
index,
_phantom: PhantomData,
}
}
pub const fn degree_multiple(&self) -> usize {
match self.entry {
Entry::Preprocessed { .. } | Entry::Main { .. } | Entry::Permutation { .. } => 1,
Entry::Public | Entry::Challenge => 0,
}
}
}
impl<F: Field> From<SymbolicVariable<F>> for SymbolicExpression<F> {
fn from(value: SymbolicVariable<F>) -> Self {
SymbolicExpression::Variable(value)
}
}
impl<F: Field> Add for SymbolicVariable<F> {
type Output = SymbolicExpression<F>;
fn add(self, rhs: Self) -> Self::Output {
SymbolicExpression::from(self) + SymbolicExpression::from(rhs)
}
}
impl<F: Field> Add<F> for SymbolicVariable<F> {
type Output = SymbolicExpression<F>;
fn add(self, rhs: F) -> Self::Output {
SymbolicExpression::from(self) + SymbolicExpression::from(rhs)
}
}
impl<F: Field> Add<SymbolicExpression<F>> for SymbolicVariable<F> {
type Output = SymbolicExpression<F>;
fn add(self, rhs: SymbolicExpression<F>) -> Self::Output {
SymbolicExpression::from(self) + rhs
}
}
impl<F: Field> Add<SymbolicVariable<F>> for SymbolicExpression<F> {
type Output = Self;
fn add(self, rhs: SymbolicVariable<F>) -> Self::Output {
self + Self::from(rhs)
}
}
impl<F: Field> Sub for SymbolicVariable<F> {
type Output = SymbolicExpression<F>;
fn sub(self, rhs: Self) -> Self::Output {
SymbolicExpression::from(self) - SymbolicExpression::from(rhs)
}
}
impl<F: Field> Sub<F> for SymbolicVariable<F> {
type Output = SymbolicExpression<F>;
fn sub(self, rhs: F) -> Self::Output {
SymbolicExpression::from(self) - SymbolicExpression::from(rhs)
}
}
impl<F: Field> Sub<SymbolicExpression<F>> for SymbolicVariable<F> {
type Output = SymbolicExpression<F>;
fn sub(self, rhs: SymbolicExpression<F>) -> Self::Output {
SymbolicExpression::from(self) - rhs
}
}
impl<F: Field> Sub<SymbolicVariable<F>> for SymbolicExpression<F> {
type Output = Self;
fn sub(self, rhs: SymbolicVariable<F>) -> Self::Output {
self - Self::from(rhs)
}
}
impl<F: Field> Mul for SymbolicVariable<F> {
type Output = SymbolicExpression<F>;
fn mul(self, rhs: Self) -> Self::Output {
SymbolicExpression::from(self) * SymbolicExpression::from(rhs)
}
}
impl<F: Field> Mul<F> for SymbolicVariable<F> {
type Output = SymbolicExpression<F>;
fn mul(self, rhs: F) -> Self::Output {
SymbolicExpression::from(self) * SymbolicExpression::from(rhs)
}
}
impl<F: Field> Mul<SymbolicExpression<F>> for SymbolicVariable<F> {
type Output = SymbolicExpression<F>;
fn mul(self, rhs: SymbolicExpression<F>) -> Self::Output {
SymbolicExpression::from(self) * rhs
}
}
impl<F: Field> Mul<SymbolicVariable<F>> for SymbolicExpression<F> {
type Output = Self;
fn mul(self, rhs: SymbolicVariable<F>) -> Self::Output {
self * Self::from(rhs)
}
}