use super::{super::super::ProofOptions, Vec, MIN_CYCLE_LENGTH};
use core::cmp;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TransitionConstraintDegree {
base: usize,
cycles: Vec<usize>,
}
impl TransitionConstraintDegree {
pub fn new(degree: usize) -> Self {
assert!(
degree > 0,
"transition constraint degree must be at least one, but was zero"
);
TransitionConstraintDegree {
base: degree,
cycles: vec![],
}
}
pub fn with_cycles(base_degree: usize, cycles: Vec<usize>) -> Self {
assert!(
base_degree > 0,
"transition constraint degree must be at least one, but was zero"
);
for (i, &cycle) in cycles.iter().enumerate() {
assert!(
cycle >= MIN_CYCLE_LENGTH,
"cycle length must be at least {}, but was {} for cycle {}",
MIN_CYCLE_LENGTH,
cycle,
i
);
assert!(
cycle.is_power_of_two(),
"cycle length must be a power of two, but was {} for cycle {}",
cycle,
i
);
}
TransitionConstraintDegree {
base: base_degree,
cycles,
}
}
pub fn get_evaluation_degree(&self, trace_length: usize) -> usize {
let mut result = self.base * (trace_length - 1);
for cycle_length in self.cycles.iter() {
result += (trace_length / cycle_length) * (cycle_length - 1);
}
result
}
pub fn min_blowup_factor(&self) -> usize {
let degree_bound = self.base + self.cycles.len() - 1;
cmp::max(
degree_bound.next_power_of_two(),
ProofOptions::MIN_BLOWUP_FACTOR,
)
}
}