use alloc::vec;
use alloc::vec::Vec;
use crate::field::extension::Extendable;
use crate::field::packable::Packable;
use crate::field::packed::PackedField;
use crate::gates::gate::Gate;
use crate::gates::util::StridedConstraintConsumer;
use crate::hash::hash_types::RichField;
use crate::plonk::vars::{EvaluationVarsBaseBatch, EvaluationVarsBasePacked};
pub trait PackedEvaluableBase<F: RichField + Extendable<D>, const D: usize>: Gate<F, D> {
fn eval_unfiltered_base_packed<P: PackedField<Scalar = F>>(
&self,
vars_base: EvaluationVarsBasePacked<P>,
yield_constr: StridedConstraintConsumer<P>,
);
fn eval_unfiltered_base_batch_packed(&self, vars_batch: EvaluationVarsBaseBatch<F>) -> Vec<F> {
let mut res = vec![F::ZERO; vars_batch.len() * self.num_constraints()];
let (vars_packed_iter, vars_leftovers_iter) = vars_batch.pack::<<F as Packable>::Packing>();
let leftovers_start = vars_batch.len() - vars_leftovers_iter.len();
for (i, vars_packed) in vars_packed_iter.enumerate() {
self.eval_unfiltered_base_packed(
vars_packed,
StridedConstraintConsumer::new(
&mut res[..],
vars_batch.len(),
<F as Packable>::Packing::WIDTH * i,
),
);
}
for (i, vars_leftovers) in vars_leftovers_iter.enumerate() {
self.eval_unfiltered_base_packed(
vars_leftovers,
StridedConstraintConsumer::new(&mut res[..], vars_batch.len(), leftovers_start + i),
);
}
res
}
}