From bb4412656acaae79d23d8f3b0bd42fa7ce90bcce Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 2 Jul 2024 18:48:35 +0200 Subject: [PATCH] Create row struct (#1510) --- executor/src/witgen/block_processor.rs | 2 +- .../src/witgen/data_structures/column_map.rs | 29 +- .../data_structures/finalizable_data.rs | 6 +- executor/src/witgen/generator.rs | 6 +- executor/src/witgen/machines/block_machine.rs | 21 +- executor/src/witgen/processor.rs | 28 +- executor/src/witgen/query_processor.rs | 2 +- executor/src/witgen/rows.rs | 332 +++++++++--------- executor/src/witgen/vm_processor.rs | 25 +- 9 files changed, 243 insertions(+), 208 deletions(-) diff --git a/executor/src/witgen/block_processor.rs b/executor/src/witgen/block_processor.rs index f3da0b3ec..b40eb7713 100644 --- a/executor/src/witgen/block_processor.rs +++ b/executor/src/witgen/block_processor.rs @@ -208,7 +208,7 @@ mod tests { for &(i, name, expected) in asserted_values.iter() { let poly_id = poly_ids[name]; - let actual: T = data[i][&poly_id].value_or_zero(); + let actual: T = data[i].value_or_zero(&poly_id); assert_eq!(actual, T::from(expected)); } }, diff --git a/executor/src/witgen/data_structures/column_map.rs b/executor/src/witgen/data_structures/column_map.rs index e90aedb2b..576082b03 100644 --- a/executor/src/witgen/data_structures/column_map.rs +++ b/executor/src/witgen/data_structures/column_map.rs @@ -62,7 +62,7 @@ impl ColumnMap { let mut values: Vec = (0..len).map(|_| V::default()).collect(); for (poly, value) in items { values[poly.id as usize] = value; - assert_eq!(poly.ptype, T::P_TYPE); + debug_assert_eq!(poly.ptype, T::P_TYPE); } ColumnMap { @@ -90,17 +90,40 @@ impl ColumnMap { self.values.iter() } + pub fn values_into_iter(self) -> impl Iterator { + self.values.into_iter() + } + + pub fn values_iter_mut(&mut self) -> impl Iterator { + self.values.iter_mut() + } + pub fn len(&self) -> usize { self.values.len() } } +impl Default for ColumnMap { + fn default() -> Self { + ColumnMap { + values: Vec::new(), + _ptype: PhantomData, + } + } +} + +impl PartialEq for ColumnMap { + fn eq(&self, other: &Self) -> bool { + self.values == other.values + } +} + impl Index<&PolyID> for ColumnMap { type Output = V; #[inline] fn index(&self, poly_id: &PolyID) -> &Self::Output { - assert!(poly_id.ptype == T::P_TYPE); + debug_assert!(poly_id.ptype == T::P_TYPE); &self.values[poly_id.id as usize] } } @@ -108,7 +131,7 @@ impl Index<&PolyID> for ColumnMap { impl IndexMut<&PolyID> for ColumnMap { #[inline] fn index_mut(&mut self, poly_id: &PolyID) -> &mut Self::Output { - assert!(poly_id.ptype == T::P_TYPE); + debug_assert!(poly_id.ptype == T::P_TYPE); &mut self.values[poly_id.id as usize] } } diff --git a/executor/src/witgen/data_structures/finalizable_data.rs b/executor/src/witgen/data_structures/finalizable_data.rs index cdfd1443d..f659eb704 100644 --- a/executor/src/witgen/data_structures/finalizable_data.rs +++ b/executor/src/witgen/data_structures/finalizable_data.rs @@ -7,7 +7,7 @@ use bit_vec::BitVec; use powdr_ast::analyzed::PolyID; use powdr_number::FieldElement; -use crate::witgen::rows::{finalize_row, Row}; +use crate::witgen::rows::Row; /// A row entry in [FinalizableData]. #[derive(Clone)] @@ -125,8 +125,8 @@ impl<'a, T: FieldElement> FinalizableData<'a, T> { } pub fn finalize(&mut self, i: usize) -> bool { - if let Entry::InProgress(row) = &self.data[i] { - self.data[i] = Entry::Finalized(finalize_row(row, &self.column_ids)); + if let Entry::InProgress(row) = &mut self.data[i] { + self.data[i] = Entry::Finalized(row.finalize(&self.column_ids)); true } else { false diff --git a/executor/src/witgen/generator.rs b/executor/src/witgen/generator.rs index a877beeb8..e1637e3c5 100644 --- a/executor/src/witgen/generator.rs +++ b/executor/src/witgen/generator.rs @@ -5,7 +5,6 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use crate::witgen::data_structures::finalizable_data::FinalizableData; use crate::witgen::machines::profiling::{record_end, record_start}; use crate::witgen::processor::OuterQuery; -use crate::witgen::rows::merge_row_with; use crate::witgen::EvalValue; use crate::Identity; @@ -216,7 +215,8 @@ impl<'a, T: FieldElement> Generator<'a, T> { is_main_run: bool, ) -> ProcessResult<'a, T> { log::trace!( - "Running main machine from row {row_offset} with the following initial values in the first row:\n{}", first_row.render_values(false, None) + "Running main machine from row {row_offset} with the following initial values in the first row:\n{}", + first_row.render_values(false, None, self.fixed_data) ); let data = FinalizableData::with_initial_rows_in_progress( &self.witnesses, @@ -244,6 +244,6 @@ impl<'a, T: FieldElement> Generator<'a, T> { assert_eq!(self.data.len() as DegreeType, self.fixed_data.degree + 1); let last_row = self.data.pop().unwrap(); - merge_row_with(&mut self.data[0], &last_row).unwrap(); + self.data[0].merge_with(&last_row).unwrap(); } } diff --git a/executor/src/witgen/machines/block_machine.rs b/executor/src/witgen/machines/block_machine.rs index 512d6e053..0bbe3d7c8 100644 --- a/executor/src/witgen/machines/block_machine.rs +++ b/executor/src/witgen/machines/block_machine.rs @@ -8,7 +8,7 @@ use crate::witgen::block_processor::BlockProcessor; use crate::witgen::data_structures::finalizable_data::FinalizableData; use crate::witgen::identity_processor::IdentityProcessor; use crate::witgen::processor::{OuterQuery, Processor}; -use crate::witgen::rows::{merge_row_with, Row, RowIndex, RowPair, UnknownStrategy}; +use crate::witgen::rows::{Row, RowIndex, RowPair, UnknownStrategy}; use crate::witgen::sequence_iterator::{ DefaultSequenceIterator, ProcessingSequenceCache, ProcessingSequenceIterator, }; @@ -644,15 +644,16 @@ impl<'a, T: FieldElement> BlockMachine<'a, T> { // 1. Ignore the first row of the next block: new_block.pop(); // 2. Merge the last row of the previous block - merge_row_with( - new_block.get_mut(0).unwrap(), - self.get_row(self.last_row_index()), - ) - .map_err(|_| { - EvalError::Generic( - "Block machine overwrites existing value with different value!".to_string(), - ) - })?; + + new_block + .get_mut(0) + .unwrap() + .merge_with(self.get_row(self.last_row_index())) + .map_err(|_| { + EvalError::Generic( + "Block machine overwrites existing value with different value!".to_string(), + ) + })?; // 3. Remove the last row of the previous block from data self.data.pop(); diff --git a/executor/src/witgen/processor.rs b/executor/src/witgen/processor.rs index 8a5b84fa9..08ff0a88f 100644 --- a/executor/src/witgen/processor.rs +++ b/executor/src/witgen/processor.rs @@ -4,11 +4,9 @@ use powdr_ast::analyzed::PolynomialType; use powdr_ast::analyzed::{AlgebraicExpression as Expression, AlgebraicReference, PolyID}; use powdr_number::{DegreeType, FieldElement}; -use crate::witgen::rows::set_cell_unknown; use crate::witgen::{query_processor::QueryProcessor, util::try_to_simple_poly, Constraint}; use crate::Identity; -use super::rows::value_is_known; use super::{ affine_expression::AffineExpression, data_structures::{ @@ -225,14 +223,22 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback> Processor<'a, 'b, 'c, T, Known values in current row (local: {row_index}, global {global_row_index}): {} ", - self.data[row_index].render_values(false, Some(self.witness_cols)) + self.data[row_index].render_values( + false, + Some(self.witness_cols), + self.fixed_data, + ) ); if identity.contains_next_ref() { error += &format!( "Known values in next row (local: {}, global {}):\n{}\n", row_index + 1, global_row_index + 1, - self.data[row_index + 1].render_values(false, Some(self.witness_cols)) + self.data[row_index + 1].render_values( + false, + Some(self.witness_cols), + self.fixed_data, + ) ); } error += &format!(" => Error: {e}"); @@ -319,7 +325,7 @@ Known values in current row (local: {row_index}, global {global_row_index}): pub fn set_inputs_if_unset(&mut self, row_index: usize) -> bool { let mut input_updates = EvalValue::complete(vec![]); for (poly_id, value) in self.inputs.iter() { - if !value_is_known(&self.data[row_index], poly_id) { + if !self.data[row_index].value_is_known(poly_id) { input_updates.combine(EvalValue::complete(vec![( &self.fixed_data.witness_cols[poly_id].poly, Constraint::Assignment(*value), @@ -335,7 +341,7 @@ Known values in current row (local: {row_index}, global {global_row_index}): self.fixed_data.column_name(poly_id) ); for row_index in start_row..row_index { - set_cell_unknown(&mut self.data[row_index], poly_id); + self.data[row_index].set_cell_unknown(poly_id); } } } @@ -514,8 +520,14 @@ Known values in current row (local: {row_index}, global {global_row_index}): .process_identity(identity, &row_pair) .is_err() { - log::debug!("Previous {:?}", &self.data[row_index - 1]); - log::debug!("Proposed {:?}", proposed_row); + log::debug!( + "Previous {}", + self.data[row_index - 1].render_values(true, None, self.fixed_data) + ); + log::debug!( + "Proposed {:?}", + proposed_row.render_values(true, None, self.fixed_data) + ); log::debug!("Failed on identity: {}", identity); return false; diff --git a/executor/src/witgen/query_processor.rs b/executor/src/witgen/query_processor.rs index fd97d1662..9b53b8628 100644 --- a/executor/src/witgen/query_processor.rs +++ b/executor/src/witgen/query_processor.rs @@ -34,7 +34,7 @@ impl<'a, 'b, T: FieldElement, QueryCallback: super::QueryCallback> ) -> Option> { let column = &self.fixed_data.witness_cols[poly_id]; - if rows.get_value(&column.poly).is_none() { + if !rows.value_is_known(&column.poly) { Some(self.process_witness_query(column.query.unwrap(), &column.poly, rows)) } else { None diff --git a/executor/src/witgen/rows.rs b/executor/src/witgen/rows.rs index 42c95c445..4d2f2105d 100644 --- a/executor/src/witgen/rows.rs +++ b/executor/src/witgen/rows.rs @@ -1,6 +1,6 @@ use std::{ collections::HashSet, - fmt::Debug, + fmt::Display, ops::{Add, Sub}, }; @@ -105,16 +105,17 @@ impl Sub for RowIndex { } } -impl std::fmt::Display for RowIndex { +impl Display for RowIndex { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.index) } } -#[derive(Clone, PartialEq, Debug)] +#[derive(Default, Clone, PartialEq)] enum CellValue { Known(T), RangeConstraint(RangeConstraint), + #[default] Unknown, } @@ -123,217 +124,209 @@ impl CellValue { matches!(self, CellValue::Known(_)) } - pub fn unwrap_or_default(&self) -> T { + /// Returns the value if known, otherwise zero. + pub fn unwrap_or_zero(&self) -> T { match self { CellValue::Known(v) => *v, _ => Default::default(), } } - /// Returns the new combined range constraint or new value for this cell. + /// Returns Some(value) if known, otherwise None. + pub fn value(&self) -> Option { + match self { + CellValue::Known(v) => Some(*v), + _ => None, + } + } + + /// Updates the cell with the new combined range constraint or new value for this cell. /// /// # Panics /// Panics if the update is not an improvement. - pub fn update_with(&self, c: &Constraint) -> Self { - match (self, c) { + pub fn apply_update(&mut self, c: &Constraint) { + match (&self, c) { (CellValue::Known(_), _) => { // Note that this is a problem even if the value that was set is the same, // because we would return that progress was made when it wasn't. panic!("Value was already set."); } - (_, Constraint::Assignment(v)) => CellValue::Known(*v), + (_, Constraint::Assignment(v)) => { + *self = CellValue::Known(*v); + } (CellValue::RangeConstraint(current), Constraint::RangeConstraint(c)) => { let new = c.conjunction(current); assert!(new != *current, "Range constraint was already set"); log::trace!(" (the conjunction is {})", new); - CellValue::RangeConstraint(new) + *self = CellValue::RangeConstraint(new) } (CellValue::Unknown, Constraint::RangeConstraint(c)) => { - CellValue::RangeConstraint(c.clone()) + *self = CellValue::RangeConstraint(c.clone()) } } } } -impl From> for Option { - fn from(val: CellValue) -> Self { - match val { - CellValue::Known(v) => Some(v), - _ => None, +impl Display for CellValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CellValue::Known(v) => write!(f, "{v}"), + CellValue::RangeConstraint(rc) => write!(f, "? (range constraint: {rc})"), + CellValue::Unknown => write!(f, "?"), } } } -/// A single cell, holding an optional value and range constraint. -#[derive(Clone)] -pub struct Cell<'a, T: FieldElement> { - /// The column name, for debugging purposes. - name: &'a str, - value: CellValue, +#[derive(Clone, PartialEq)] +pub struct Row<'a, T: FieldElement> { + values: WitnessColumnMap>, + // TODO remove this. + names: Vec<&'a str>, } -impl<'a, T: FieldElement> Cell<'a, T> { - /// Applies the new range constraint or new value to this cell. - /// - /// # Panics - /// Panics if the update is not an improvement. - pub fn apply_update(&mut self, c: &Constraint) { - self.value = self.value.update_with(c); +impl<'a, T: FieldElement> Row<'a, T> { + pub fn value_or_zero(&self, poly_id: &PolyID) -> T { + self.values[poly_id].unwrap_or_zero() } - /// Returns the value if it is known or zero if it is unknown. - pub fn value_or_zero(&self) -> T { - self.value.unwrap_or_default() + pub fn value(&self, poly_id: &PolyID) -> Option { + self.values[poly_id].value() } -} -impl Debug for Cell<'_, T> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let debug_str = match &self.value { - CellValue::Known(v) => format!("{} = {}", self.name, v), - CellValue::RangeConstraint(rc) => { - format!("{} = ? (range constraint: {})", self.name, rc) - } - CellValue::Unknown => format!("{} = ?", self.name), - }; - f.write_str(&debug_str) + pub fn range_constraint(&self, poly_id: &PolyID) -> Option> { + match &self.values[poly_id] { + CellValue::RangeConstraint(c) => Some(c.clone()), + _ => None, + } } -} -pub type Row<'a, T> = WitnessColumnMap>; - -/// Merges two rows, updating the first. -/// Range constraints from the second row are ignored. -pub fn merge_row_with<'a, T: FieldElement>( - row: &mut Row<'a, T>, - other: &Row<'a, T>, -) -> Result<(), ()> { - // First check for conflicts, otherwise we would have to roll back changes. - if row - .values() - .zip(other.values()) - .any(|(cell1, cell2)| match (&cell1.value, &cell2.value) { - (CellValue::Known(v1), CellValue::Known(v2)) => v1 != v2, - _ => false, - }) - { - return Err(()); - }; - *row = WitnessColumnMap::from(row.values().zip(other.values()).map(|(cell1, cell2)| { - match (&cell1.value, &cell2.value) { - (CellValue::Known(_), _) => cell1.clone(), - _ => cell2.clone(), - } - })); - Ok(()) -} + /// Merges two rows, updating the first. + /// Range constraints from the second row are ignored. + pub fn merge_with(&mut self, other: &Row<'a, T>) -> Result<(), ()> { + // First check for conflicts, otherwise we would have to roll back changes. + if self + .values + .values() + .zip(other.values.values()) + .any(|(cell1, cell2)| match (&cell1, &cell2) { + (CellValue::Known(v1), CellValue::Known(v2)) => v1 != v2, + _ => false, + }) + { + return Err(()); + }; -// TODO will be impl method of row later. -pub fn value_is_known(row: &Row<'_, T>, poly_id: &PolyID) -> bool { - row[poly_id].value.is_known() -} + self.values + .values_iter_mut() + .zip(other.values.values()) + .for_each(|(cell1, cell2)| match (&cell1, &cell2) { + (CellValue::Known(_), _) => {} + _ => *cell1 = cell2.clone(), + }); + Ok(()) + } -// TODO will be impl method of row later. -pub fn set_cell_unknown(row: &mut Row<'_, T>, poly_id: &PolyID) { - row[poly_id].value = CellValue::Unknown; -} + pub fn value_is_known(&self, poly_id: &PolyID) -> bool { + self.values[poly_id].is_known() + } -// TODO will be impl method of row later. -/// Returns true if the values and known constraints are equal for the two rows. -pub fn rows_are_equal(row1: &Row<'_, T>, row2: &Row<'_, T>) -> bool { - row1.values() - .zip(row2.values()) - .all(|(cell1, cell2)| cell1.value == cell2.value) -} + pub fn set_cell_unknown(&mut self, poly_id: &PolyID) { + self.values[poly_id] = CellValue::Unknown; + } -// TODO will be impl method of row later. -// TODO we need to get rid of column_ids and ensure that the vector is already in that shape. -pub fn finalize_row<'a, T: FieldElement>( - row: &Row<'_, T>, - column_ids: impl IntoIterator, -) -> FinalizedRow { - let (values, know_cells) = column_ids - .into_iter() - .map(|c| (row[c].value.unwrap_or_default(), row[c].value.is_known())) - .unzip(); - FinalizedRow::new(values, know_cells) -} + pub fn apply_update(&mut self, poly_id: &PolyID, constr: &Constraint) { + self.values[poly_id].apply_update(constr); + } -impl Debug for Row<'_, T> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Row:\n{}", self.render_values(true, None)) + pub fn finalize(&self, column_ids: &[PolyID]) -> FinalizedRow { + let (values, known_cells) = column_ids + .iter() + .map(|poly_id| { + // TODO avoid these accesses. + let cell = &self.values[poly_id]; + (cell.unwrap_or_zero(), cell.is_known()) + }) + .unzip(); + FinalizedRow::new(values, known_cells) } } impl<'a, T: FieldElement> Row<'a, T> { /// Creates a "fresh" row, i.e., one that is empty but initialized with the global range constraints. pub fn fresh(fixed_data: &'a FixedData<'a, T>, row: RowIndex) -> Row<'a, T> { - WitnessColumnMap::from( + // TODO this instance could be computed exactly once (per column set) and then cloned. + // TODO and we could copy in the external witnesses later on + // TODO we should really only have a subset of the columns. + let values = WitnessColumnMap::from( fixed_data .global_range_constraints() .witness_constraints .iter() - .map(|(poly_id, range_constraint)| { - let name = fixed_data.column_name(&poly_id); - let value = match ( - fixed_data.external_witness(row.into(), &poly_id), - range_constraint.as_ref(), - ) { - (Some(external_witness), _) => CellValue::Known(external_witness), - (None, Some(range_constraint)) => { - CellValue::RangeConstraint(range_constraint.clone()) - } - (None, None) => CellValue::Unknown, - }; - Cell { name, value } + .map(|(poly_id, rc)| { + if let Some(external_witness) = + fixed_data.external_witness(row.into(), &poly_id) + { + CellValue::Known(external_witness) + } else if let Some(rc) = rc { + CellValue::RangeConstraint(rc.clone()) + } else { + CellValue::Unknown + } }), - ) + ); + Self { + values, + names: vec![], + } } /// Builds a string representing the current row - pub fn render(&self, title: &str, include_unknown: bool, cols: &HashSet) -> String { + pub fn render( + &self, + title: &str, + include_unknown: bool, + cols: &HashSet, + fixed_data: &FixedData<'_, T>, + ) -> String { format!( "{}:\n{}\n---------------------", title, - self.render_values(include_unknown, Some(cols)) + self.render_values(include_unknown, Some(cols), fixed_data) ) } /// Builds a string listing all values, one by row. Nonzero entries are /// first, then zero, then unknown (if `include_unknown == true`). - pub fn render_values(&self, include_unknown: bool, cols: Option<&HashSet>) -> String { - let mut cells = self + pub fn render_values( + &self, + include_unknown: bool, + cols: Option<&HashSet>, + fixed_data: &FixedData<'_, T>, + ) -> String { + self.values .iter() - .filter(|(_, cell)| cell.value.is_known() || include_unknown) + .filter(|(_, cell)| cell.is_known() || include_unknown) .filter(|(col, _)| cols.map(|cols| cols.contains(col)).unwrap_or(true)) - .collect::>(); - - // Nonzero first, then zero, then unknown - cells.sort_by_key(|(i, cell)| { - ( - match cell.value { - CellValue::Known(v) if v.is_zero() => 1, - CellValue::Known(_) => 0, - _ => 2, - }, - *i, - ) - }); - - cells - .into_iter() - .map(|(_, cell)| format!(" {cell:?}")) + // Nonzero first, then zero, then unknown + .sorted_by_key(|(i, cell)| { + ( + match cell { + CellValue::Known(v) if v.is_zero() => 1, + CellValue::Known(_) => 0, + _ => 2, + }, + *i, + ) + }) + .map(|(poly_id, cell)| format!(" {} = {cell}", fixed_data.column_name(&poly_id))) .join("\n") } } impl From> for WitnessColumnMap { /// Builds a map from polynomial ID to value. Unknown values are set to zero. - fn from(val: Row) -> Self { - WitnessColumnMap::from( - val.into_iter() - .map(|(_, cell)| cell.value.unwrap_or_default()), - ) + fn from(row: Row) -> Self { + WitnessColumnMap::from(row.values.values_into_iter().map(|c| c.unwrap_or_zero())) } } @@ -376,13 +369,13 @@ impl<'row, 'a, T: FieldElement> RowUpdater<'row, 'a, T> { ); } } - self.get_cell_mut(poly).apply_update(c); + self.get_row_mut(poly.next).apply_update(&poly.poly_id, c); } - fn get_cell_mut<'b>(&'b mut self, poly: &AlgebraicReference) -> &'b mut Cell<'a, T> { - match poly.next { - false => &mut self.current[&poly.poly_id], - true => &mut self.next[&poly.poly_id], + fn get_row_mut<'b>(&'b mut self, next: bool) -> &'b mut Row<'a, T> { + match next { + false => self.current, + true => self.next, } } @@ -445,26 +438,34 @@ impl<'row, 'a, T: FieldElement> RowPair<'row, 'a, T> { } } - /// Gets the cell corresponding to the given polynomial reference. - /// - /// # Panics - /// Panics if the next row is accessed but the row pair has been constructed with - /// [RowPair::from_single_row]. - fn get_cell(&self, poly: &AlgebraicReference) -> &Cell { - match (poly.next, self.next.as_ref()) { - (false, _) => &self.current[&poly.poly_id], - (true, Some(next)) => &next[&poly.poly_id], - (true, None) => panic!("Tried to access next row, but it is not available."), + pub fn value_is_known(&self, poly: &AlgebraicReference) -> bool { + self.get_row_mut(poly.next).value_is_known(&poly.poly_id) + } + + fn get_row_mut(&self, next: bool) -> &Row<'a, T> { + match next { + false => self.current, + true => self + .next + .unwrap_or_else(|| panic!("Tried to access next row, but it is not available.")), + } + } + + fn get_row(&self, next: bool) -> &Row<'a, T> { + match next { + false => self.current, + true => self + .next + .unwrap_or_else(|| panic!("Tried to access next row, but it is not available.")), } } pub fn get_value(&self, poly: &AlgebraicReference) -> Option { - match self.get_cell(poly).value { - CellValue::Known(value) => Some(value), - _ => match self.unknown_strategy { - UnknownStrategy::Zero => Some(T::zero()), - UnknownStrategy::Unknown => None, - }, + let row = self.get_row(poly.next); + if self.unknown_strategy == UnknownStrategy::Zero { + Some(row.value_or_zero(&poly.poly_id)) + } else { + row.value(&poly.poly_id) } } @@ -492,9 +493,6 @@ impl WitnessColumnEvaluator for RowPair<'_, '_, T> { impl RangeConstraintSet<&AlgebraicReference, T> for RowPair<'_, '_, T> { fn range_constraint(&self, poly: &AlgebraicReference) -> Option> { - match self.get_cell(poly).value { - CellValue::RangeConstraint(ref c) => Some(c.clone()), - _ => None, - } + self.get_row(poly.next).range_constraint(&poly.poly_id) } } diff --git a/executor/src/witgen/vm_processor.rs b/executor/src/witgen/vm_processor.rs index a0623b265..4b928e89b 100644 --- a/executor/src/witgen/vm_processor.rs +++ b/executor/src/witgen/vm_processor.rs @@ -14,7 +14,7 @@ use crate::Identity; use super::data_structures::finalizable_data::FinalizableData; use super::processor::{OuterQuery, Processor}; -use super::rows::{rows_are_equal, Row, RowIndex, UnknownStrategy}; +use super::rows::{Row, RowIndex, UnknownStrategy}; use super::{Constraints, EvalError, EvalValue, FixedData, MutableState, QueryCallback}; /// Maximal period checked during loop detection. @@ -219,12 +219,8 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback> VmProcessor<'a, 'b, 'c, T let row = row_index as usize; (1..MAX_PERIOD).find(|&period| { - (1..=period).all(|i| { - rows_are_equal( - self.processor.row(row - i - period), - self.processor.row(row - i), - ) - }) + (1..=period) + .all(|i| self.processor.row(row - i - period) == self.processor.row(row - i)) }) } @@ -297,7 +293,8 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback> VmProcessor<'a, 'b, 'c, T row_index as DegreeType + self.row_offset ), true, - &self.witnesses + &self.witnesses, + self.fixed_data, ) ); @@ -442,7 +439,8 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback> VmProcessor<'a, 'b, 'c, T self.processor.row(row_index).render( &format!("Current row ({row_index})"), false, - &self.witnesses + &self.witnesses, + self.fixed_data, ) ); log::debug!( @@ -450,7 +448,8 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback> VmProcessor<'a, 'b, 'c, T self.processor.row(row_index + 1).render( &format!("Next row ({})", row_index + 1), false, - &self.witnesses + &self.witnesses, + self.fixed_data, ) ); log::debug!("Set RUST_LOG=trace to understand why these values were chosen."); @@ -478,7 +477,8 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback> VmProcessor<'a, 'b, 'c, T self.processor.row(row_index).render( &format!("Current row ({row_index})"), true, - &self.witnesses + &self.witnesses, + self.fixed_data, ) ); log::debug!( @@ -486,7 +486,8 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback> VmProcessor<'a, 'b, 'c, T self.processor.row(row_index + 1).render( &format!("Next row ({})", row_index + 1), true, - &self.witnesses + &self.witnesses, + self.fixed_data, ) ); log::debug!("\nSet RUST_LOG=trace to understand why these values were (not) chosen.");