use super::{ColMatrix, Felt, FieldElement, LookupTableRow};
#[derive(Debug, Clone)]
pub struct CycleRangeChecks {
memory: Option<RangeCheckRequest>,
stack: Option<RangeCheckRequest>,
}
impl CycleRangeChecks {
pub fn new_from_memory(values: &[u16; 2]) -> Self {
Self {
stack: None,
memory: Some(RangeCheckRequest::Memory([Felt::from(values[0]), Felt::from(values[1])])),
}
}
pub fn new_from_stack(values: &[u16; 4]) -> Self {
Self {
memory: None,
stack: Some(RangeCheckRequest::Stack([
Felt::from(values[0]),
Felt::from(values[1]),
Felt::from(values[2]),
Felt::from(values[3]),
])),
}
}
pub fn add_memory_checks(&mut self, values: &[u16]) {
debug_assert_eq!(self.memory, None);
self.memory =
Some(RangeCheckRequest::Memory([Felt::from(values[0]), Felt::from(values[1])]));
}
pub fn to_stack_value<E: FieldElement<BaseField = Felt>>(
&self,
main_trace: &MainTrace,
alphas: &[E],
) -> E {
let mut value = E::ONE;
if let Some(stack_checks) = &self.stack {
value *= stack_checks.to_value(main_trace, alphas);
}
value
}
fn to_mem_value<E: FieldElement<BaseField = Felt>>(
&self,
main_trace: &MainTrace,
alphas: &[E],
) -> E {
let mut value = E::ONE;
if let Some(mem_checks) = &self.memory {
value = mem_checks.to_value(main_trace, alphas)
}
value
}
}
impl LookupTableRow for CycleRangeChecks {
fn to_value<E: FieldElement<BaseField = Felt>>(
&self,
main_trace: &MainTrace,
alphas: &[E],
) -> E {
let stack_value = self.to_stack_value(main_trace, alphas);
let mem_value = self.to_mem_value(main_trace, alphas);
if stack_value != E::ONE {
stack_value * mem_value
} else {
mem_value
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum RangeCheckRequest {
Memory([Felt; 2]),
Stack([Felt; 4]),
}
impl LookupTableRow for RangeCheckRequest {
fn to_value<E: FieldElement<BaseField = Felt>>(
&self,
_main_trace: &MainTrace,
alphas: &[E],
) -> E {
let alpha: E = alphas[0];
let mut value = E::ONE;
let values_iter = match self {
Self::Memory(values) => values.iter(),
Self::Stack(values) => values.iter(),
};
for &rc_value in values_iter {
value *= alpha + rc_value.into();
}
value
}
}