use crate::logup::LookupTableID;
use ark_ff::PrimeField;
use num_bigint::BigUint;
use o1_utils::FieldHelpers;
use strum_macros::EnumIter;
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, EnumIter)]
pub enum LookupTable {
RangeCheck15,
RangeCheck1BitSigned,
}
impl LookupTableID for LookupTable {
fn to_u32(&self) -> u32 {
match self {
Self::RangeCheck15 => 1,
Self::RangeCheck1BitSigned => 2,
}
}
fn from_u32(value: u32) -> Self {
match value {
1 => Self::RangeCheck15,
2 => Self::RangeCheck1BitSigned,
_ => panic!("Invalid lookup table id"),
}
}
fn is_fixed(&self) -> bool {
true
}
fn runtime_create_column(&self) -> bool {
panic!("No runtime tables specified");
}
fn length(&self) -> usize {
match self {
Self::RangeCheck15 => 1 << 15,
Self::RangeCheck1BitSigned => 3,
}
}
fn ix_by_value<F: PrimeField>(&self, value: &[F]) -> Option<usize> {
let value = value[0];
Some(match self {
Self::RangeCheck15 => TryFrom::try_from(value.to_biguint()).unwrap(),
Self::RangeCheck1BitSigned => {
if value == F::zero() {
0
} else if value == F::one() {
1
} else if value == F::zero() - F::one() {
2
} else {
panic!("Invalid value for rangecheck1abs")
}
}
})
}
fn all_variants() -> Vec<Self> {
vec![Self::RangeCheck15, Self::RangeCheck1BitSigned]
}
}
impl LookupTable {
pub fn entries<F: PrimeField>(&self, domain_d1_size: u64) -> Vec<F> {
assert!(domain_d1_size >= (1 << 15));
match self {
Self::RangeCheck1BitSigned => [F::zero(), F::one(), F::zero() - F::one()]
.into_iter()
.chain((3..domain_d1_size).map(|_| F::one())) .collect(),
Self::RangeCheck15 => (0..domain_d1_size).map(|i| F::from(i)).collect(),
}
}
pub fn is_member<F: PrimeField>(&self, value: F) -> bool {
match self {
Self::RangeCheck1BitSigned => {
value == F::zero() || value == F::one() || value == F::zero() - F::one()
}
Self::RangeCheck15 => value.to_biguint() < BigUint::from(2u128.pow(15)),
}
}
}