From 4a6e18649131102a33cc532c797cbeec992a82a2 Mon Sep 17 00:00:00 2001 From: Alon Haramati Date: Sun, 16 Jun 2024 11:13:22 +0300 Subject: [PATCH] Add lookup final boundary constraints. --- crates/prover/src/core/air/air_ext.rs | 13 ++- crates/prover/src/core/air/mod.rs | 9 +- crates/prover/src/core/fields/mod.rs | 11 ++ crates/prover/src/core/mod.rs | 26 ++++- crates/prover/src/core/prover/mod.rs | 15 ++- .../src/examples/fibonacci/component.rs | 4 +- crates/prover/src/examples/fibonacci/mod.rs | 9 +- .../src/examples/wide_fibonacci/component.rs | 38 ++++++- .../wide_fibonacci/constraint_eval.rs | 104 +++++++++++++++++- .../prover/src/examples/wide_fibonacci/mod.rs | 8 +- .../src/examples/wide_fibonacci/simd.rs | 4 +- 11 files changed, 224 insertions(+), 17 deletions(-) diff --git a/crates/prover/src/core/air/air_ext.rs b/crates/prover/src/core/air/air_ext.rs index e9f3e7f74..e85bc5d42 100644 --- a/crates/prover/src/core/air/air_ext.rs +++ b/crates/prover/src/core/air/air_ext.rs @@ -9,7 +9,7 @@ use crate::core::pcs::{CommitmentTreeProver, TreeVec}; use crate::core::poly::circle::SecureCirclePoly; use crate::core::vcs::blake2_merkle::Blake2sMerkleHasher; use crate::core::vcs::ops::MerkleOps; -use crate::core::{ColumnVec, ComponentVec, InteractionElements}; +use crate::core::{ColumnVec, ComponentVec, InteractionElements, LookupValues}; pub trait AirExt: Air { fn composition_log_degree_bound(&self) -> u32 { @@ -55,6 +55,7 @@ pub trait AirExt: Air { mask_values: &ComponentVec>, random_coeff: SecureField, interaction_elements: &InteractionElements, + lookup_values: &LookupValues, ) -> SecureField { let mut evaluation_accumulator = PointEvaluationAccumulator::new(random_coeff); zip_eq(self.components(), &mask_values.0).for_each(|(component, mask)| { @@ -63,6 +64,7 @@ pub trait AirExt: Air { mask, &mut evaluation_accumulator, interaction_elements, + lookup_values, ) }); evaluation_accumulator.finalize() @@ -127,6 +129,7 @@ pub trait AirProverExt: AirProver { random_coeff: SecureField, component_traces: &[ComponentTrace<'_, B>], interaction_elements: &InteractionElements, + lookup_values: &LookupValues, ) -> SecureCirclePoly { let total_constraints: usize = self .prover_components() @@ -143,10 +146,18 @@ pub trait AirProverExt: AirProver { trace, &mut accumulator, interaction_elements, + lookup_values, ) }); accumulator.finalize() } + + fn lookup_values(&self, component_traces: &[ComponentTrace<'_, B>]) -> LookupValues { + let mut values = LookupValues::default(); + zip_eq(self.prover_components(), component_traces) + .for_each(|(component, trace)| values.extend(component.lookup_values(trace))); + values + } } impl> AirProverExt for A {} diff --git a/crates/prover/src/core/air/mod.rs b/crates/prover/src/core/air/mod.rs index 199a35aa6..f0b507962 100644 --- a/crates/prover/src/core/air/mod.rs +++ b/crates/prover/src/core/air/mod.rs @@ -7,7 +7,7 @@ use super::fields::qm31::SecureField; use super::pcs::TreeVec; use super::poly::circle::{CircleEvaluation, CirclePoly}; use super::poly::BitReversedOrder; -use super::{ColumnVec, InteractionElements}; +use super::{ColumnVec, InteractionElements, LookupValues}; pub mod accumulation; mod air_ext; @@ -74,6 +74,7 @@ pub trait Component { mask: &ColumnVec>, evaluation_accumulator: &mut PointEvaluationAccumulator, interaction_elements: &InteractionElements, + lookup_values: &LookupValues, ); } @@ -93,7 +94,13 @@ pub trait ComponentProver: Component { trace: &ComponentTrace<'_, B>, evaluation_accumulator: &mut DomainEvaluationAccumulator, interaction_elements: &InteractionElements, + lookup_values: &LookupValues, ); + + /// Returns the values needed to evaluate the components lookup boundary constraints. + fn lookup_values(&self, _trace: &ComponentTrace<'_, B>) -> LookupValues { + LookupValues::default() + } } /// A component trace is a set of polynomials for each column on that component. diff --git a/crates/prover/src/core/fields/mod.rs b/crates/prover/src/core/fields/mod.rs index fbeefbb94..beca755cb 100644 --- a/crates/prover/src/core/fields/mod.rs +++ b/crates/prover/src/core/fields/mod.rs @@ -406,6 +406,17 @@ macro_rules! impl_extension_field { } } + impl TryInto for $field_name { + type Error = (); + + fn try_into(self) -> Result { + if self.1 != <$extended_field_name>::zero() { + return Err(()); + } + self.0.try_into().map_err(|_| ()) + } + } + impl AddAssign for $field_name { fn add_assign(&mut self, rhs: M31) { *self = *self + rhs; diff --git a/crates/prover/src/core/mod.rs b/crates/prover/src/core/mod.rs index 499738c18..256ce9067 100644 --- a/crates/prover/src/core/mod.rs +++ b/crates/prover/src/core/mod.rs @@ -1,6 +1,8 @@ use std::collections::BTreeMap; use std::ops::{Deref, DerefMut, Index}; +use fields::m31::BaseField; + use self::fields::qm31::SecureField; pub mod air; @@ -61,7 +63,7 @@ impl DerefMut for ComponentVec { } } -#[derive(Default)] +#[derive(Default, Debug)] pub struct InteractionElements(BTreeMap); impl InteractionElements { @@ -82,3 +84,25 @@ impl Index<&str> for InteractionElements { &self.0[index] } } + +#[derive(Default, Debug)] +pub struct LookupValues(BTreeMap); + +impl LookupValues { + pub fn new(values: BTreeMap) -> Self { + Self(values) + } + + pub fn extend(&mut self, other: Self) { + self.0.extend(other.0); + } +} + +impl Index<&str> for LookupValues { + type Output = BaseField; + + fn index(&self, index: &str) -> &Self::Output { + // TODO(AlonH): Return an error if the key is not found. + &self.0[index] + } +} diff --git a/crates/prover/src/core/prover/mod.rs b/crates/prover/src/core/prover/mod.rs index 24b8ecd25..71071ae83 100644 --- a/crates/prover/src/core/prover/mod.rs +++ b/crates/prover/src/core/prover/mod.rs @@ -10,7 +10,7 @@ use super::pcs::{CommitmentSchemeProof, TreeVec}; use super::poly::circle::{CanonicCoset, SecureCirclePoly, MAX_CIRCLE_DOMAIN_LOG_SIZE}; use super::poly::twiddles::TwiddleTree; use super::proof_of_work::ProofOfWorkVerificationError; -use super::{ColumnVec, InteractionElements}; +use super::{ColumnVec, InteractionElements, LookupValues}; use crate::core::air::{Air, AirExt, AirProverExt}; use crate::core::backend::CpuBackend; use crate::core::channel::{Blake2sChannel, Channel as ChannelTrait}; @@ -39,6 +39,7 @@ pub const N_QUERIES: usize = 3; #[derive(Debug)] pub struct StarkProof { pub commitments: TreeVec<::Hash>, + pub lookup_values: LookupValues, pub commitment_scheme_proof: CommitmentSchemeProof, } @@ -96,10 +97,13 @@ pub fn generate_proof>( let random_coeff = channel.draw_felt(); let span = span!(Level::INFO, "Composition generation").entered(); + let component_traces = air.component_traces(&commitment_scheme.trees); + let lookup_values = air.lookup_values(&component_traces); let composition_polynomial_poly = air.compute_composition_polynomial( random_coeff, - &air.component_traces(&commitment_scheme.trees), + &component_traces, interaction_elements, + &lookup_values, ); span.exit(); @@ -131,6 +135,7 @@ pub fn generate_proof>( &trace_oods_values, random_coeff, interaction_elements, + &lookup_values, ) { return Err(ProvingError::ConstraintsNotSatisfied); @@ -138,6 +143,7 @@ pub fn generate_proof>( Ok(StarkProof { commitments: commitment_scheme.roots(), + lookup_values, commitment_scheme_proof, }) } @@ -235,6 +241,7 @@ pub fn verify( &trace_oods_values, random_coeff, &interaction_elements, + &proof.lookup_values, ) { return Err(VerificationError::OodsNotMatching); @@ -357,7 +364,7 @@ mod tests { use crate::core::poly::BitReversedOrder; use crate::core::prover::{prove, ProvingError}; use crate::core::test_utils::test_channel; - use crate::core::{ColumnVec, InteractionElements}; + use crate::core::{ColumnVec, InteractionElements, LookupValues}; use crate::qm31; struct TestAir> { @@ -435,6 +442,7 @@ mod tests { _mask: &crate::core::ColumnVec>, evaluation_accumulator: &mut PointEvaluationAccumulator, _interaction_elements: &InteractionElements, + _lookup_values: &LookupValues, ) { evaluation_accumulator.accumulate(qm31!(0, 0, 0, 1)) } @@ -456,6 +464,7 @@ mod tests { _trace: &ComponentTrace<'_, CpuBackend>, _evaluation_accumulator: &mut DomainEvaluationAccumulator, _interaction_elements: &InteractionElements, + _lookup_values: &LookupValues, ) { // Does nothing. } diff --git a/crates/prover/src/examples/fibonacci/component.rs b/crates/prover/src/examples/fibonacci/component.rs index 068a3aeb3..6a6b2b062 100644 --- a/crates/prover/src/examples/fibonacci/component.rs +++ b/crates/prover/src/examples/fibonacci/component.rs @@ -15,7 +15,7 @@ use crate::core::pcs::TreeVec; use crate::core::poly::circle::{CanonicCoset, CircleEvaluation}; use crate::core::poly::BitReversedOrder; use crate::core::utils::bit_reverse_index; -use crate::core::{ColumnVec, InteractionElements}; +use crate::core::{ColumnVec, InteractionElements, LookupValues}; pub struct FibonacciComponent { pub log_size: u32, @@ -113,6 +113,7 @@ impl Component for FibonacciComponent { mask: &ColumnVec>, evaluation_accumulator: &mut PointEvaluationAccumulator, _interaction_elements: &InteractionElements, + _lookup_values: &LookupValues, ) { evaluation_accumulator.accumulate( self.step_constraint_eval_quotient_by_mask(point, &mask[0][..].try_into().unwrap()), @@ -142,6 +143,7 @@ impl ComponentProver for FibonacciComponent { trace: &ComponentTrace<'_, CpuBackend>, evaluation_accumulator: &mut DomainEvaluationAccumulator, _interaction_elements: &InteractionElements, + _lookup_values: &LookupValues, ) { let poly = &trace.polys[0][0]; let trace_domain = CanonicCoset::new(self.log_size); diff --git a/crates/prover/src/examples/fibonacci/mod.rs b/crates/prover/src/examples/fibonacci/mod.rs index 940f979b2..bc1038aca 100644 --- a/crates/prover/src/examples/fibonacci/mod.rs +++ b/crates/prover/src/examples/fibonacci/mod.rs @@ -110,7 +110,6 @@ impl MultiFibonacci { #[cfg(test)] mod tests { use std::assert_matches::assert_matches; - use std::collections::BTreeMap; use std::iter::zip; use itertools::Itertools; @@ -129,7 +128,7 @@ mod tests { use crate::core::prover::VerificationError; use crate::core::queries::Queries; use crate::core::utils::bit_reverse; - use crate::core::InteractionElements; + use crate::core::{InteractionElements, LookupValues}; use crate::{m31, qm31}; pub fn generate_test_queries(n_queries: usize, trace_length: usize) -> Vec { @@ -159,7 +158,8 @@ mod tests { let composition_polynomial_poly = fib.air.compute_composition_polynomial( random_coeff, &component_traces, - &InteractionElements::new(BTreeMap::new()), + &InteractionElements::default(), + &LookupValues::default(), ); // Evaluate this polynomial at another point out of the evaluation domain and compare to @@ -181,7 +181,8 @@ mod tests { point, &mask_values, &mut evaluation_accumulator, - &InteractionElements::new(BTreeMap::new()), + &InteractionElements::default(), + &LookupValues::default(), ); let oods_value = evaluation_accumulator.finalize(); diff --git a/crates/prover/src/examples/wide_fibonacci/component.rs b/crates/prover/src/examples/wide_fibonacci/component.rs index 26d6f5737..a7247ee1f 100644 --- a/crates/prover/src/examples/wide_fibonacci/component.rs +++ b/crates/prover/src/examples/wide_fibonacci/component.rs @@ -15,7 +15,7 @@ use crate::core::pcs::TreeVec; use crate::core::poly::circle::{CanonicCoset, CircleEvaluation, SecureCirclePoly}; use crate::core::poly::BitReversedOrder; use crate::core::utils::shifted_secure_combination; -use crate::core::{ColumnVec, InteractionElements}; +use crate::core::{ColumnVec, InteractionElements, LookupValues}; use crate::examples::wide_fibonacci::trace_gen::write_lookup_column; pub const LOG_N_COLUMNS: usize = 8; @@ -23,6 +23,10 @@ pub const N_COLUMNS: usize = 1 << LOG_N_COLUMNS; pub const ALPHA_ID: &str = "wide_fibonacci_alpha"; pub const Z_ID: &str = "wide_fibonacci_z"; +pub const LOOKUP_VALUE_0_ID: &str = "wide_fibonacci_0"; +pub const LOOKUP_VALUE_1_ID: &str = "wide_fibonacci_1"; +pub const LOOKUP_VALUE_N_MINUS_2_ID: &str = "wide_fibonacci_n-2"; +pub const LOOKUP_VALUE_N_MINUS_1_ID: &str = "wide_fibonacci_n-1"; /// Component that computes 2^`self.log_n_instances` instances of fibonacci sequences of size /// 2^`self.log_fibonacci_size`. The numbers are computes over [N_COLUMNS] trace columns. The @@ -48,6 +52,28 @@ impl WideFibComponent { N_COLUMNS } + fn evaluate_trace_boundary_constraints_at_point( + &self, + point: CirclePoint, + mask: &ColumnVec>, + evaluation_accumulator: &mut PointEvaluationAccumulator, + constraint_zero_domain: Coset, + lookup_values: &LookupValues, + ) { + let numerator = mask[0][0] - lookup_values[LOOKUP_VALUE_0_ID]; + let denom = point_vanishing(constraint_zero_domain.at(0), point); + evaluation_accumulator.accumulate(numerator / denom); + let numerator = mask[1][0] - lookup_values[LOOKUP_VALUE_1_ID]; + evaluation_accumulator.accumulate(numerator / denom); + + let numerator = mask[self.n_columns() - 2][0] - lookup_values[LOOKUP_VALUE_N_MINUS_2_ID]; + let denom = point_vanishing(constraint_zero_domain.at(0), point); + evaluation_accumulator.accumulate(numerator / denom); + let numerator = mask[self.n_columns() - 1][0] - lookup_values[LOOKUP_VALUE_N_MINUS_1_ID]; + let denom = point_vanishing(constraint_zero_domain.at(0), point); + evaluation_accumulator.accumulate(numerator / denom); + } + fn evaluate_trace_step_constraints_at_point( &self, point: CirclePoint, @@ -129,7 +155,7 @@ impl Air for WideFibAir { impl Component for WideFibComponent { fn n_constraints(&self) -> usize { - self.n_columns() + self.n_columns() + 4 } fn max_constraint_log_degree_bound(&self) -> u32 { @@ -168,8 +194,16 @@ impl Component for WideFibComponent { mask: &ColumnVec>, evaluation_accumulator: &mut PointEvaluationAccumulator, interaction_elements: &InteractionElements, + lookup_values: &LookupValues, ) { let constraint_zero_domain = CanonicCoset::new(self.log_column_size()).coset; + self.evaluate_trace_boundary_constraints_at_point( + point, + mask, + evaluation_accumulator, + constraint_zero_domain, + lookup_values, + ); self.evaluate_lookup_step_constraints_at_point( point, mask, diff --git a/crates/prover/src/examples/wide_fibonacci/constraint_eval.rs b/crates/prover/src/examples/wide_fibonacci/constraint_eval.rs index 9691b8ecb..472e055a9 100644 --- a/crates/prover/src/examples/wide_fibonacci/constraint_eval.rs +++ b/crates/prover/src/examples/wide_fibonacci/constraint_eval.rs @@ -3,7 +3,10 @@ use std::collections::BTreeMap; use itertools::{zip_eq, Itertools}; use num_traits::Zero; -use super::component::{Input, WideFibAir, WideFibComponent, ALPHA_ID, Z_ID}; +use super::component::{ + Input, WideFibAir, WideFibComponent, ALPHA_ID, LOOKUP_VALUE_0_ID, LOOKUP_VALUE_1_ID, + LOOKUP_VALUE_N_MINUS_1_ID, LOOKUP_VALUE_N_MINUS_2_ID, Z_ID, +}; use super::trace_gen::write_trace_row; use crate::core::air::accumulation::{ColumnAccumulator, DomainEvaluationAccumulator}; use crate::core::air::{ @@ -23,7 +26,7 @@ use crate::core::poly::BitReversedOrder; use crate::core::utils::{ bit_reverse, previous_bit_reversed_circle_domain_index, shifted_secure_combination, }; -use crate::core::{ColumnVec, InteractionElements}; +use crate::core::{ColumnVec, InteractionElements, LookupValues}; use crate::examples::wide_fibonacci::component::LOG_N_COLUMNS; // TODO(AlonH): Rename file to `cpu.rs`. @@ -58,6 +61,59 @@ impl AirProver for WideFibAir { } impl WideFibComponent { + fn evaluate_trace_boundary_constraints( + &self, + trace_evals: &TreeVec>>, + trace_eval_domain: CircleDomain, + zero_domain: Coset, + accum: &mut ColumnAccumulator<'_, CpuBackend>, + lookup_values: &LookupValues, + ) { + let max_constraint_degree = self.max_constraint_log_degree_bound(); + let mut first_point_denoms = vec![]; + let mut last_point_denoms = vec![]; + for point in trace_eval_domain.iter() { + first_point_denoms.push(point_vanishing(zero_domain.at(0), point)); + last_point_denoms.push(point_vanishing(zero_domain.at(zero_domain.size()), point)); + } + bit_reverse(&mut first_point_denoms); + bit_reverse(&mut last_point_denoms); + let mut first_point_denom_inverses = vec![BaseField::zero(); 1 << (max_constraint_degree)]; + let mut last_point_denom_inverses = vec![BaseField::zero(); 1 << (max_constraint_degree)]; + BaseField::batch_inverse(&first_point_denoms, &mut first_point_denom_inverses); + BaseField::batch_inverse(&last_point_denoms, &mut last_point_denom_inverses); + let mut first_point_numerators = vec![SecureField::zero(); 1 << (max_constraint_degree)]; + let mut last_point_numerators = vec![SecureField::zero(); 1 << (max_constraint_degree)]; + + #[allow(clippy::needless_range_loop)] + for i in 0..trace_eval_domain.size() { + first_point_numerators[i] = accum.random_coeff_powers[self.n_columns() + 3] + * (trace_evals[0][0][i] - lookup_values[LOOKUP_VALUE_0_ID]) + + accum.random_coeff_powers[self.n_columns() + 2] + * (trace_evals[0][1][i] - lookup_values[LOOKUP_VALUE_1_ID]); + last_point_numerators[i] = accum.random_coeff_powers[self.n_columns() + 1] + * (trace_evals[0][self.n_columns() - 2][i] + - lookup_values[LOOKUP_VALUE_N_MINUS_2_ID]) + + accum.random_coeff_powers[self.n_columns()] + * (trace_evals[0][self.n_columns() - 1][i] + - lookup_values[LOOKUP_VALUE_N_MINUS_1_ID]); + } + for (i, (num, denom_inverse)) in first_point_numerators + .iter() + .zip(first_point_denom_inverses.iter()) + .enumerate() + { + accum.accumulate(i, *num * *denom_inverse); + } + for (i, (num, denom_inverse)) in last_point_numerators + .iter() + .zip(last_point_denom_inverses.iter()) + .enumerate() + { + accum.accumulate(i, *num * *denom_inverse); + } + } + fn evaluate_trace_step_constraints( &self, trace_evals: &TreeVec>>, @@ -196,6 +252,7 @@ impl ComponentProver for WideFibComponent { trace: &ComponentTrace<'_, CpuBackend>, evaluation_accumulator: &mut DomainEvaluationAccumulator, interaction_elements: &InteractionElements, + lookup_values: &LookupValues, ) { let max_constraint_degree = self.max_constraint_log_degree_bound(); let trace_eval_domain = CanonicCoset::new(max_constraint_degree).circle_domain(); @@ -204,6 +261,13 @@ impl ComponentProver for WideFibComponent { let [mut accum] = evaluation_accumulator.columns([(max_constraint_degree, self.n_constraints())]); + self.evaluate_trace_boundary_constraints( + trace_evals, + trace_eval_domain, + zero_domain, + &mut accum, + lookup_values, + ); self.evaluate_trace_step_constraints( trace_evals, trace_eval_domain, @@ -225,6 +289,42 @@ impl ComponentProver for WideFibComponent { interaction_elements, ) } + + fn lookup_values(&self, trace: &ComponentTrace<'_, CpuBackend>) -> LookupValues { + let domain = CanonicCoset::new(self.log_column_size()); + let trace_poly = &trace.polys[0]; + let values = BTreeMap::from_iter([ + ( + LOOKUP_VALUE_0_ID.to_string(), + trace_poly[0] + .eval_at_point(domain.at(0).into_ef()) + .try_into() + .unwrap(), + ), + ( + LOOKUP_VALUE_1_ID.to_string(), + trace_poly[1] + .eval_at_point(domain.at(0).into_ef()) + .try_into() + .unwrap(), + ), + ( + LOOKUP_VALUE_N_MINUS_2_ID.to_string(), + trace_poly[self.n_columns() - 2] + .eval_at_point(domain.at(domain.size()).into_ef()) + .try_into() + .unwrap(), + ), + ( + LOOKUP_VALUE_N_MINUS_1_ID.to_string(), + trace_poly[self.n_columns() - 1] + .eval_at_point(domain.at(domain.size()).into_ef()) + .try_into() + .unwrap(), + ), + ]); + LookupValues::new(values) + } } /// Generates the trace for the wide Fibonacci example. diff --git a/crates/prover/src/examples/wide_fibonacci/mod.rs b/crates/prover/src/examples/wide_fibonacci/mod.rs index 4e1ea77c6..befc6ec0e 100644 --- a/crates/prover/src/examples/wide_fibonacci/mod.rs +++ b/crates/prover/src/examples/wide_fibonacci/mod.rs @@ -192,7 +192,13 @@ mod tests { ]), }; - wide_fib.evaluate_constraint_quotients_on_domain(&trace, &mut acc, &interaction_elements); + let lookup_values = wide_fib.lookup_values(&trace); + wide_fib.evaluate_constraint_quotients_on_domain( + &trace, + &mut acc, + &interaction_elements, + &lookup_values, + ); let res = acc.finalize(); let poly = res.0[0].clone(); diff --git a/crates/prover/src/examples/wide_fibonacci/simd.rs b/crates/prover/src/examples/wide_fibonacci/simd.rs index 7305dbe76..87b7d16fd 100644 --- a/crates/prover/src/examples/wide_fibonacci/simd.rs +++ b/crates/prover/src/examples/wide_fibonacci/simd.rs @@ -23,7 +23,7 @@ use crate::core::fields::{FieldExpOps, FieldOps}; use crate::core::pcs::TreeVec; use crate::core::poly::circle::{CanonicCoset, CircleEvaluation}; use crate::core::poly::BitReversedOrder; -use crate::core::{ColumnVec, InteractionElements}; +use crate::core::{ColumnVec, InteractionElements, LookupValues}; use crate::examples::wide_fibonacci::component::{ALPHA_ID, N_COLUMNS, Z_ID}; // TODO(AlonH): Remove this once the Cpu and Simd implementations are aligned. @@ -116,6 +116,7 @@ impl Component for SimdWideFibComponent { mask: &ColumnVec>, evaluation_accumulator: &mut PointEvaluationAccumulator, _interaction_elements: &InteractionElements, + _lookup_values: &LookupValues, ) { let constraint_zero_domain = CanonicCoset::new(self.log_column_size()).coset; let denom = coset_vanishing(constraint_zero_domain, point); @@ -176,6 +177,7 @@ impl ComponentProver for SimdWideFibComponent { trace: &ComponentTrace<'_, SimdBackend>, evaluation_accumulator: &mut DomainEvaluationAccumulator, _interaction_elements: &InteractionElements, + _lookup_values: &LookupValues, ) { assert_eq!(trace.polys[0].len(), self.n_columns()); // TODO(spapini): Steal evaluation from commitment.