use core::marker::PhantomData;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum BaseEntry {
Preprocessed { offset: usize },
Main { offset: usize },
Periodic,
Public,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ExtEntry {
Permutation { offset: usize },
Challenge,
PermutationValue,
}
#[derive(Copy, Clone, Debug)]
pub struct SymbolicVariable<F> {
pub entry: BaseEntry,
pub index: usize,
pub(crate) _phantom: PhantomData<F>,
}
impl<F> SymbolicVariable<F> {
pub const fn new(entry: BaseEntry, index: usize) -> Self {
Self {
entry,
index,
_phantom: PhantomData,
}
}
pub const fn degree_multiple(&self) -> usize {
match self.entry {
BaseEntry::Preprocessed { .. }
| BaseEntry::Main { .. }
| BaseEntry::Periodic => 1,
BaseEntry::Public => 0,
}
}
}
#[derive(Copy, Clone, Debug)]
pub struct SymbolicVariableExt<F, EF> {
pub entry: ExtEntry,
pub index: usize,
pub(crate) _phantom: PhantomData<(F, EF)>,
}
impl<F, EF> SymbolicVariableExt<F, EF> {
pub const fn new(entry: ExtEntry, index: usize) -> Self {
Self {
entry,
index,
_phantom: PhantomData,
}
}
pub const fn degree_multiple(&self) -> usize {
match self.entry {
ExtEntry::Permutation { .. } => 1,
ExtEntry::Challenge | ExtEntry::PermutationValue => 0,
}
}
}
#[cfg(test)]
mod tests {
use p3_baby_bear::BabyBear;
use p3_field::extension::BinomialExtensionField;
use super::*;
type F = BabyBear;
type EF = BinomialExtensionField<F, 4>;
#[test]
fn symbolic_variable_new_main() {
let var = SymbolicVariable::<F>::new(BaseEntry::Main { offset: 1 }, 3);
assert_eq!(var.entry, BaseEntry::Main { offset: 1 });
assert_eq!(var.index, 3);
}
#[test]
fn symbolic_variable_new_preprocessed() {
let var = SymbolicVariable::<F>::new(BaseEntry::Preprocessed { offset: 0 }, 5);
assert_eq!(var.entry, BaseEntry::Preprocessed { offset: 0 });
assert_eq!(var.index, 5);
}
#[test]
fn symbolic_variable_new_public() {
let var = SymbolicVariable::<F>::new(BaseEntry::Public, 2);
assert_eq!(var.entry, BaseEntry::Public);
assert_eq!(var.index, 2);
}
#[test]
fn symbolic_variable_degree_multiple_main() {
let var = SymbolicVariable::<F>::new(BaseEntry::Main { offset: 0 }, 0);
assert_eq!(var.degree_multiple(), 1);
}
#[test]
fn symbolic_variable_degree_multiple_preprocessed() {
let var = SymbolicVariable::<F>::new(BaseEntry::Preprocessed { offset: 0 }, 0);
assert_eq!(var.degree_multiple(), 1);
}
#[test]
fn symbolic_variable_degree_multiple_public() {
let var = SymbolicVariable::<F>::new(BaseEntry::Public, 0);
assert_eq!(var.degree_multiple(), 0);
}
#[test]
fn symbolic_variable_ext_new_permutation() {
let var = SymbolicVariableExt::<F, EF>::new(ExtEntry::Permutation { offset: 1 }, 7);
assert_eq!(var.entry, ExtEntry::Permutation { offset: 1 });
assert_eq!(var.index, 7);
}
#[test]
fn symbolic_variable_ext_new_challenge() {
let var = SymbolicVariableExt::<F, EF>::new(ExtEntry::Challenge, 4);
assert_eq!(var.entry, ExtEntry::Challenge);
assert_eq!(var.index, 4);
}
#[test]
fn symbolic_variable_ext_degree_multiple_permutation() {
let var = SymbolicVariableExt::<F, EF>::new(ExtEntry::Permutation { offset: 0 }, 0);
assert_eq!(var.degree_multiple(), 1);
}
#[test]
fn symbolic_variable_ext_degree_multiple_challenge() {
let var = SymbolicVariableExt::<F, EF>::new(ExtEntry::Challenge, 0);
assert_eq!(var.degree_multiple(), 0);
}
}