mirror of
https://github.com/powdr-labs/powdr.git
synced 2026-04-20 03:03:25 -04:00
Get rid of dummy blocks in BlockMachines
This commit is contained in:
@@ -8,7 +8,7 @@ use powdr_number::FieldElement;
|
||||
use super::{
|
||||
data_structures::finalizable_data::FinalizableData,
|
||||
processor::{OuterQuery, Processor},
|
||||
rows::UnknownStrategy,
|
||||
rows::{RowIndex, UnknownStrategy},
|
||||
sequence_iterator::{Action, ProcessingSequenceIterator, SequenceStep},
|
||||
EvalError, EvalValue, FixedData, IncompleteCause, MutableState, QueryCallback,
|
||||
};
|
||||
@@ -27,7 +27,7 @@ pub struct BlockProcessor<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> {
|
||||
|
||||
impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> BlockProcessor<'a, 'b, 'c, T, Q> {
|
||||
pub fn new(
|
||||
row_offset: u64,
|
||||
row_offset: RowIndex,
|
||||
data: FinalizableData<'a, T>,
|
||||
mutable_state: &'c mut MutableState<'a, 'b, T, Q>,
|
||||
identities: &'c [&'a Identity<Expression<T>>],
|
||||
@@ -105,12 +105,11 @@ mod tests {
|
||||
use crate::{
|
||||
constant_evaluator::generate,
|
||||
witgen::{
|
||||
data_structures::column_map::FixedColumnMap,
|
||||
data_structures::finalizable_data::FinalizableData,
|
||||
data_structures::{column_map::FixedColumnMap, finalizable_data::FinalizableData},
|
||||
global_constraints::GlobalConstraints,
|
||||
identity_processor::Machines,
|
||||
machines::FixedLookup,
|
||||
rows::RowFactory,
|
||||
rows::{RowFactory, RowIndex},
|
||||
sequence_iterator::{DefaultSequenceIterator, ProcessingSequenceIterator},
|
||||
unused_query_callback, FixedData, MutableState, QueryCallback,
|
||||
},
|
||||
@@ -161,7 +160,8 @@ mod tests {
|
||||
.collect();
|
||||
let data = FinalizableData::with_initial_rows_in_progress(
|
||||
&columns,
|
||||
(0..fixed_data.degree).map(|i| row_factory.fresh_row(i)),
|
||||
(0..fixed_data.degree)
|
||||
.map(|i| row_factory.fresh_row(RowIndex::from_degree(i, fixed_data.degree))),
|
||||
);
|
||||
|
||||
let mut mutable_state = MutableState {
|
||||
@@ -169,7 +169,7 @@ mod tests {
|
||||
machines: Machines::from(machines.iter_mut()),
|
||||
query_callback: &mut query_callback,
|
||||
};
|
||||
let row_offset = 0;
|
||||
let row_offset = RowIndex::from_degree(0, fixed_data.degree);
|
||||
let identities = analyzed.identities.iter().collect::<Vec<_>>();
|
||||
let witness_cols = fixed_data.witness_cols.keys().collect();
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ use super::block_processor::BlockProcessor;
|
||||
use super::data_structures::column_map::WitnessColumnMap;
|
||||
use super::global_constraints::GlobalConstraints;
|
||||
use super::machines::{FixedLookup, Machine};
|
||||
use super::rows::{Row, RowFactory};
|
||||
use super::rows::{Row, RowFactory, RowIndex};
|
||||
use super::sequence_iterator::{DefaultSequenceIterator, ProcessingSequenceIterator};
|
||||
use super::vm_processor::VmProcessor;
|
||||
use super::{EvalResult, FixedData, MutableState, QueryCallback};
|
||||
@@ -174,8 +174,8 @@ impl<'a, T: FieldElement> Generator<'a, T> {
|
||||
let data = FinalizableData::with_initial_rows_in_progress(
|
||||
&self.witnesses,
|
||||
[
|
||||
row_factory.fresh_row(self.fixed_data.degree - 1),
|
||||
row_factory.fresh_row(0),
|
||||
row_factory.fresh_row(RowIndex::from_i64(-1, self.fixed_data.degree)),
|
||||
row_factory.fresh_row(RowIndex::from_i64(0, self.fixed_data.degree)),
|
||||
]
|
||||
.into_iter(),
|
||||
);
|
||||
@@ -190,7 +190,7 @@ impl<'a, T: FieldElement> Generator<'a, T> {
|
||||
.filter_map(|identity| identity.contains_next_ref().then_some(*identity))
|
||||
.collect::<Vec<_>>();
|
||||
let mut processor = BlockProcessor::new(
|
||||
self.fixed_data.degree - 1,
|
||||
RowIndex::from_i64(-1, self.fixed_data.degree),
|
||||
data,
|
||||
mutable_state,
|
||||
&identities_with_next_reference,
|
||||
@@ -223,7 +223,7 @@ impl<'a, T: FieldElement> Generator<'a, T> {
|
||||
[first_row].into_iter(),
|
||||
);
|
||||
let mut processor = VmProcessor::new(
|
||||
row_offset,
|
||||
RowIndex::from_degree(row_offset, self.fixed_data.degree),
|
||||
self.fixed_data,
|
||||
&self.identities,
|
||||
&self.witnesses,
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::witgen::data_structures::finalizable_data::FinalizableData;
|
||||
use crate::witgen::global_constraints::GlobalConstraints;
|
||||
use crate::witgen::identity_processor::IdentityProcessor;
|
||||
use crate::witgen::processor::OuterQuery;
|
||||
use crate::witgen::rows::{CellValue, RowFactory, RowPair, UnknownStrategy};
|
||||
use crate::witgen::rows::{CellValue, Row, RowFactory, RowIndex, RowPair, UnknownStrategy};
|
||||
use crate::witgen::sequence_iterator::{ProcessingSequenceCache, ProcessingSequenceIterator};
|
||||
use crate::witgen::util::try_to_simple_poly;
|
||||
use crate::witgen::{machines::Machine, EvalError, EvalValue, IncompleteCause};
|
||||
@@ -114,12 +114,15 @@ impl<'a, T: FieldElement> BlockMachine<'a, T> {
|
||||
.map(|(block_size, connecting_rhs)| {
|
||||
assert!(block_size <= fixed_data.degree as usize);
|
||||
let row_factory = RowFactory::new(fixed_data, global_range_constraints.clone());
|
||||
// Start out with a block filled with unknown values so that we do not have to deal with wrap-around
|
||||
// when storing machine witness data.
|
||||
// This will be filled with the default block in `take_witness_col_values`
|
||||
// Because block shapes are not always rectangular, we add the last block to the data at the
|
||||
// beginning. It starts out with unknown values. Should the first block decide to write to
|
||||
// rows < 0, they will be writen to this block.
|
||||
// In `take_witness_col_values()`, this block will be removed and its values will be used to
|
||||
// construct the "default" block used to fill up unused rows.
|
||||
let start_index = RowIndex::from_i64(-(block_size as i64), fixed_data.degree);
|
||||
let data = FinalizableData::with_initial_rows_in_progress(
|
||||
witness_cols,
|
||||
(0..block_size).map(|i| row_factory.fresh_row(i as DegreeType)),
|
||||
(0..block_size).map(|i| row_factory.fresh_row(start_index + i)),
|
||||
);
|
||||
BlockMachine {
|
||||
name,
|
||||
@@ -192,7 +195,7 @@ impl<'a, T: FieldElement> Machine<'a, T> for BlockMachine<'a, T> {
|
||||
if !self.connecting_rhs.contains(right) || kind != IdentityKind::Plookup {
|
||||
return None;
|
||||
}
|
||||
let previous_len = self.rows() as usize;
|
||||
let previous_len = self.data.len();
|
||||
Some({
|
||||
let result = self.process_plookup_internal(mutable_state, left, right);
|
||||
if let Ok(assignments) = &result {
|
||||
@@ -231,25 +234,38 @@ impl<'a, T: FieldElement> Machine<'a, T> for BlockMachine<'a, T> {
|
||||
.map(|(v, known)| known.then_some(v))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Remove the "last" block added to the beginning of self.data.
|
||||
// It contains the values the first block wrote to it and otherwise unknown values.
|
||||
let dummy_block = values.drain(0..self.block_size).collect::<Vec<_>>();
|
||||
|
||||
// For all constraints to be satisfied, unused cells have to be filled with valid values.
|
||||
// We do this, we construct a default block, by repeating the first input to the block machine.
|
||||
values.resize(self.fixed_data.degree as usize, None);
|
||||
|
||||
let second_block_values = values.iter().skip(self.block_size).take(self.block_size);
|
||||
|
||||
// The first block is a dummy block (filled mostly with None), the second block is the first block
|
||||
// resulting of an actual evaluation.
|
||||
// However, if the block machine already sets some registers in the last row of the previous block,
|
||||
// they will be set in the "dummy block". In this case, we want to use these values.
|
||||
// As a result, the default block consists of values of the first block if they are set, otherwise
|
||||
// the values of the second block.
|
||||
// Use the block as the default block. However, it needs to be merged with the dummy block,
|
||||
// to handle blocks of non-rectangular shape.
|
||||
// For example, let's say, the situation might look like this (block size = 3 in this example):
|
||||
// Row Latch C1 C2 C3
|
||||
// -3 0
|
||||
// -2 0
|
||||
// -1 1 X <- This value belongs to the first block
|
||||
// 0 0 X X X
|
||||
// 1 0 X X X
|
||||
// 2 1 X X X <- This value belongs to the second block
|
||||
//
|
||||
// The following code constructs the default block as follows:
|
||||
// - All values will come from rows 0-2, EXCEPT
|
||||
// - In the last row, the value of C3 is whatever value was written to the dummy block
|
||||
//
|
||||
// Constructed like this, we can repeat the default block forever.
|
||||
//
|
||||
// TODO: Determine the row-extend per column
|
||||
let default_block = values
|
||||
.iter()
|
||||
.take(self.block_size)
|
||||
.zip(second_block_values)
|
||||
.map(|(first_block, second_block)| {
|
||||
first_block.or(*second_block).unwrap_or_default()
|
||||
let first_block_values = values.iter().take(self.block_size);
|
||||
let default_block = dummy_block
|
||||
.into_iter()
|
||||
.zip(first_block_values)
|
||||
.map(|(dummy_block, first_block)| {
|
||||
dummy_block.or(*first_block).unwrap_or_default()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -292,8 +308,20 @@ impl<'a, T: FieldElement> BlockMachine<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the current number of rows *not counting the dummy block* inserted at the beginning
|
||||
/// (with row numbers (-block_size..0)).
|
||||
fn rows(&self) -> DegreeType {
|
||||
self.data.len() as DegreeType
|
||||
(self.data.len() - self.block_size) as DegreeType
|
||||
}
|
||||
|
||||
fn last_row_index(&self) -> RowIndex {
|
||||
RowIndex::from_i64(self.rows() as i64 - 1, self.fixed_data.degree)
|
||||
}
|
||||
|
||||
fn get_row(&self, row: RowIndex) -> &Row<'a, T> {
|
||||
// The first block is a dummy block corresponding to rows (-block_size, 0),
|
||||
// so we have to add the block size to the row index.
|
||||
&self.data[(row + self.block_size).into()]
|
||||
}
|
||||
|
||||
fn process_plookup_internal<'b, Q: QueryCallback<T>>(
|
||||
@@ -314,16 +342,16 @@ impl<'a, T: FieldElement> BlockMachine<'a, T> {
|
||||
if left.iter().all(|v| v.is_constant()) && self.rows() > 0 {
|
||||
// All values on the left hand side are known, check if this is a query
|
||||
// to the last row.
|
||||
let row = self.rows() - 1;
|
||||
let row_index = self.last_row_index();
|
||||
|
||||
let current = &self.data[row as usize];
|
||||
let current = &self.get_row(row_index);
|
||||
// We don't have the next row, because it would be the first row of the next block.
|
||||
// We'll use a fresh row instead.
|
||||
let next = self.row_factory.fresh_row(row + 1);
|
||||
let next = self.row_factory.fresh_row(row_index + 1);
|
||||
let row_pair = RowPair::new(
|
||||
current,
|
||||
&next,
|
||||
row,
|
||||
row_index,
|
||||
self.fixed_data,
|
||||
UnknownStrategy::Unknown,
|
||||
);
|
||||
@@ -400,13 +428,12 @@ impl<'a, T: FieldElement> BlockMachine<'a, T> {
|
||||
sequence_iterator: &mut ProcessingSequenceIterator,
|
||||
) -> Result<ProcessResult<'a, T>, EvalError<T>> {
|
||||
// We start at the last row of the previous block.
|
||||
let row_offset = self.rows() - 1;
|
||||
let row_offset = self.last_row_index();
|
||||
// Make the block two rows larger than the block size, it includes the last row of the previous block
|
||||
// and the first row of the next block.
|
||||
let block = FinalizableData::with_initial_rows_in_progress(
|
||||
&self.witness_cols,
|
||||
(0..(self.block_size + 2))
|
||||
.map(|i| self.row_factory.fresh_row(i as DegreeType + row_offset)),
|
||||
(0..(self.block_size + 2)).map(|i| self.row_factory.fresh_row(row_offset + i)),
|
||||
);
|
||||
let mut processor = BlockProcessor::new(
|
||||
row_offset,
|
||||
@@ -439,9 +466,8 @@ 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
|
||||
let last_row_index = self.rows() as usize - 1;
|
||||
let updated_last_row = new_block.get_mut(0).unwrap();
|
||||
for (poly_id, existing_value) in self.data[last_row_index].iter() {
|
||||
for (poly_id, existing_value) in self.get_row(self.last_row_index()).iter() {
|
||||
if let CellValue::Known(v) = existing_value.value {
|
||||
if updated_last_row[&poly_id].value.is_known()
|
||||
&& updated_last_row[&poly_id].value != existing_value.value
|
||||
|
||||
@@ -13,7 +13,7 @@ use super::{
|
||||
affine_expression::AffineExpression,
|
||||
data_structures::{column_map::WitnessColumnMap, finalizable_data::FinalizableData},
|
||||
identity_processor::IdentityProcessor,
|
||||
rows::{CellValue, Row, RowPair, RowUpdater, UnknownStrategy},
|
||||
rows::{CellValue, Row, RowIndex, RowPair, RowUpdater, UnknownStrategy},
|
||||
Constraints, EvalError, EvalValue, FixedData, MutableState, QueryCallback,
|
||||
};
|
||||
|
||||
@@ -53,7 +53,7 @@ pub struct IdentityResult {
|
||||
/// - `'c`: The duration of this Processor's lifetime (e.g. the reference to the identity processor)
|
||||
pub struct Processor<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> {
|
||||
/// The global index of the first row of [Processor::data].
|
||||
row_offset: u64,
|
||||
row_offset: RowIndex,
|
||||
/// The rows that are being processed.
|
||||
data: FinalizableData<'a, T>,
|
||||
/// The mutable state
|
||||
@@ -72,7 +72,7 @@ pub struct Processor<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> {
|
||||
|
||||
impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> Processor<'a, 'b, 'c, T, Q> {
|
||||
pub fn new(
|
||||
row_offset: u64,
|
||||
row_offset: RowIndex,
|
||||
data: FinalizableData<'a, T>,
|
||||
mutable_state: &'c mut MutableState<'a, 'b, T, Q>,
|
||||
fixed_data: &'a FixedData<'a, T>,
|
||||
@@ -129,7 +129,7 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> Processor<'a, 'b, 'c, T,
|
||||
pub fn latch_value(&self, row_index: usize) -> Option<bool> {
|
||||
let row_pair = RowPair::from_single_row(
|
||||
&self.data[row_index],
|
||||
row_index as u64 + self.row_offset,
|
||||
self.row_offset + row_index as u64,
|
||||
self.fixed_data,
|
||||
UnknownStrategy::Unknown,
|
||||
);
|
||||
@@ -377,7 +377,7 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> Processor<'a, 'b, 'c, T,
|
||||
RowPair::new(
|
||||
&self.data[row_index - 1],
|
||||
proposed_row,
|
||||
row_index as DegreeType + self.row_offset - 1,
|
||||
self.row_offset + (row_index - 1) as DegreeType,
|
||||
self.fixed_data,
|
||||
UnknownStrategy::Zero,
|
||||
)
|
||||
@@ -387,7 +387,7 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> Processor<'a, 'b, 'c, T,
|
||||
// Because we never access the next row, we can use [RowPair::from_single_row] here.
|
||||
false => RowPair::from_single_row(
|
||||
proposed_row,
|
||||
row_index as DegreeType + self.row_offset,
|
||||
self.row_offset + row_index as DegreeType,
|
||||
self.fixed_data,
|
||||
UnknownStrategy::Zero,
|
||||
),
|
||||
|
||||
@@ -8,7 +8,10 @@ use powdr_ast::analyzed::{
|
||||
use powdr_number::{DegreeType, FieldElement};
|
||||
use powdr_pil_analyzer::evaluator::{self, Custom, EvalError, SymbolLookup, Value};
|
||||
|
||||
use super::{rows::RowPair, Constraint, EvalResult, EvalValue, FixedData, IncompleteCause};
|
||||
use super::{
|
||||
rows::{RowIndex, RowPair},
|
||||
Constraint, EvalResult, EvalValue, FixedData, IncompleteCause,
|
||||
};
|
||||
|
||||
/// Computes value updates that result from a query.
|
||||
pub struct QueryProcessor<'a, 'b, T: FieldElement, QueryCallback: Send + Sync> {
|
||||
@@ -81,7 +84,7 @@ impl<'a, 'b, T: FieldElement, QueryCallback: super::QueryCallback<T>>
|
||||
rows: &RowPair<T>,
|
||||
) -> Result<String, EvalError> {
|
||||
let arguments = vec![Rc::new(Value::Integer(num_bigint::BigInt::from(
|
||||
rows.current_row_index,
|
||||
u64::from(rows.current_row_index),
|
||||
)))];
|
||||
let symbols = Symbols {
|
||||
fixed_data: self.fixed_data,
|
||||
@@ -141,12 +144,13 @@ impl<'a, T: FieldElement> SymbolLookup<'a, T, Reference<'a>> for Symbols<'a, T>
|
||||
};
|
||||
Ok(Value::FieldElement(match function.poly_id.ptype {
|
||||
PolynomialType::Committed | PolynomialType::Intermediate => {
|
||||
let next = self
|
||||
.rows
|
||||
.is_row_number_next(DegreeType::try_from(row).unwrap())
|
||||
.map_err(|_| {
|
||||
EvalError::OutOfBounds(format!("Referenced row outside of window: {row}"))
|
||||
})?;
|
||||
let row_index = RowIndex::from_degree(
|
||||
DegreeType::try_from(row).unwrap(),
|
||||
self.fixed_data.degree,
|
||||
);
|
||||
let next = self.rows.is_row_number_next(row_index).map_err(|_| {
|
||||
EvalError::OutOfBounds(format!("Referenced row outside of window: {row}"))
|
||||
})?;
|
||||
let poly_ref = AlgebraicReference {
|
||||
name: function.name.to_string(),
|
||||
poly_id: function.poly_id,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
use std::{collections::HashSet, fmt::Debug};
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
fmt::Debug,
|
||||
ops::{Add, Sub},
|
||||
};
|
||||
|
||||
use itertools::Itertools;
|
||||
use powdr_ast::analyzed::{AlgebraicExpression as Expression, AlgebraicReference, PolyID};
|
||||
@@ -16,6 +20,86 @@ use super::{
|
||||
FixedData,
|
||||
};
|
||||
|
||||
/// A small wrapper around a row index, which knows the total number of rows.
|
||||
/// When converted to DegreeType or usize, it will be reduced modulo the number of rows
|
||||
/// (handling negative indices as well).
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RowIndex {
|
||||
index: i64,
|
||||
num_rows: DegreeType,
|
||||
}
|
||||
|
||||
impl From<RowIndex> for DegreeType {
|
||||
fn from(row_index: RowIndex) -> Self {
|
||||
// Ensure that 0 <= index < num_rows
|
||||
if row_index.index >= 0 {
|
||||
(row_index.index as DegreeType) % row_index.num_rows
|
||||
} else {
|
||||
assert!(row_index.index > -(row_index.num_rows as i64));
|
||||
row_index.num_rows - (-row_index.index as DegreeType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RowIndex> for usize {
|
||||
fn from(row_index: RowIndex) -> Self {
|
||||
DegreeType::from(row_index).try_into().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl RowIndex {
|
||||
pub fn from_i64(index: i64, num_rows: DegreeType) -> Self {
|
||||
Self { index, num_rows }
|
||||
}
|
||||
|
||||
pub fn from_degree(index: DegreeType, num_rows: DegreeType) -> Self {
|
||||
Self {
|
||||
index: index.try_into().unwrap(),
|
||||
num_rows,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Add<T> for RowIndex
|
||||
where
|
||||
i64: TryFrom<T>,
|
||||
<i64 as TryFrom<T>>::Error: std::fmt::Debug,
|
||||
{
|
||||
type Output = RowIndex;
|
||||
|
||||
fn add(self, rhs: T) -> RowIndex {
|
||||
RowIndex {
|
||||
index: self.index + i64::try_from(rhs).unwrap(),
|
||||
num_rows: self.num_rows,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<RowIndex> for RowIndex {
|
||||
type Output = i64;
|
||||
|
||||
fn sub(self, rhs: RowIndex) -> i64 {
|
||||
assert_eq!(self.num_rows, rhs.num_rows);
|
||||
let num_rows = i64::try_from(self.num_rows).unwrap();
|
||||
let lhs = i64::try_from(DegreeType::from(self)).unwrap();
|
||||
let rhs = i64::try_from(DegreeType::from(rhs)).unwrap();
|
||||
let diff = lhs - rhs;
|
||||
if diff <= -num_rows / 2 {
|
||||
diff + num_rows
|
||||
} else if diff >= num_rows / 2 {
|
||||
diff - num_rows
|
||||
} else {
|
||||
diff
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for RowIndex {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.index)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub enum CellValue<T: FieldElement> {
|
||||
Known(T),
|
||||
@@ -165,7 +249,7 @@ impl<'a, T: FieldElement> RowFactory<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fresh_row(&self, row: DegreeType) -> Row<'a, T> {
|
||||
pub fn fresh_row(&self, row: RowIndex) -> Row<'a, T> {
|
||||
WitnessColumnMap::from(
|
||||
self.global_range_constraints
|
||||
.witness_constraints
|
||||
@@ -173,7 +257,7 @@ impl<'a, T: FieldElement> RowFactory<'a, T> {
|
||||
.map(|(poly_id, range_constraint)| {
|
||||
let name = self.fixed_data.column_name(&poly_id);
|
||||
let value = match (
|
||||
self.fixed_data.external_witness(row, &poly_id),
|
||||
self.fixed_data.external_witness(row.into(), &poly_id),
|
||||
range_constraint.as_ref(),
|
||||
) {
|
||||
(Some(external_witness), _) => CellValue::Known(external_witness),
|
||||
@@ -202,14 +286,14 @@ impl<T: FieldElement> From<Row<'_, T>> for WitnessColumnMap<T> {
|
||||
pub struct RowUpdater<'row, 'a, T: FieldElement> {
|
||||
current: &'row mut Row<'a, T>,
|
||||
next: &'row mut Row<'a, T>,
|
||||
current_row_index: DegreeType,
|
||||
current_row_index: RowIndex,
|
||||
}
|
||||
|
||||
impl<'row, 'a, T: FieldElement> RowUpdater<'row, 'a, T> {
|
||||
pub fn new(
|
||||
current: &'row mut Row<'a, T>,
|
||||
next: &'row mut Row<'a, T>,
|
||||
current_row_index: DegreeType,
|
||||
current_row_index: RowIndex,
|
||||
) -> Self {
|
||||
Self {
|
||||
current,
|
||||
@@ -247,7 +331,7 @@ impl<'row, 'a, T: FieldElement> RowUpdater<'row, 'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn row_number(&self, poly: &AlgebraicReference) -> DegreeType {
|
||||
fn row_number(&self, poly: &AlgebraicReference) -> RowIndex {
|
||||
match poly.next {
|
||||
false => self.current_row_index,
|
||||
true => self.current_row_index + 1,
|
||||
@@ -268,7 +352,7 @@ pub enum UnknownStrategy {
|
||||
pub struct RowPair<'row, 'a, T: FieldElement> {
|
||||
pub current: &'row Row<'a, T>,
|
||||
pub next: Option<&'row Row<'a, T>>,
|
||||
pub current_row_index: DegreeType,
|
||||
pub current_row_index: RowIndex,
|
||||
fixed_data: &'a FixedData<'a, T>,
|
||||
unknown_strategy: UnknownStrategy,
|
||||
}
|
||||
@@ -277,7 +361,7 @@ impl<'row, 'a, T: FieldElement> RowPair<'row, 'a, T> {
|
||||
pub fn new(
|
||||
current: &'row Row<'a, T>,
|
||||
next: &'row Row<'a, T>,
|
||||
current_row_index: DegreeType,
|
||||
current_row_index: RowIndex,
|
||||
fixed_data: &'a FixedData<'a, T>,
|
||||
unknown_strategy: UnknownStrategy,
|
||||
) -> Self {
|
||||
@@ -293,7 +377,7 @@ impl<'row, 'a, T: FieldElement> RowPair<'row, 'a, T> {
|
||||
/// Creates a new row pair from a single row, setting the next row to None.
|
||||
pub fn from_single_row(
|
||||
current: &'row Row<'a, T>,
|
||||
current_row_index: DegreeType,
|
||||
current_row_index: RowIndex,
|
||||
fixed_data: &'a FixedData<'a, T>,
|
||||
unknown_strategy: UnknownStrategy,
|
||||
) -> Self {
|
||||
@@ -335,7 +419,7 @@ impl<'row, 'a, T: FieldElement> RowPair<'row, 'a, T> {
|
||||
pub fn evaluate<'b>(&self, expr: &'b Expression<T>) -> AffineResult<&'b AlgebraicReference, T> {
|
||||
ExpressionEvaluator::new(SymoblicWitnessEvaluator::new(
|
||||
self.fixed_data,
|
||||
self.current_row_index,
|
||||
self.current_row_index.into(),
|
||||
self,
|
||||
))
|
||||
.evaluate(expr)
|
||||
@@ -343,7 +427,7 @@ impl<'row, 'a, T: FieldElement> RowPair<'row, 'a, T> {
|
||||
|
||||
/// Returns Ok(true) if the given row number references the "next" row,
|
||||
/// Ok(false) if it references the "current" row and Err if it is out of range.
|
||||
pub fn is_row_number_next(&self, row_number: DegreeType) -> Result<bool, ()> {
|
||||
pub fn is_row_number_next(&self, row_number: RowIndex) -> Result<bool, ()> {
|
||||
match row_number - self.current_row_index {
|
||||
0 => Ok(false),
|
||||
1 => Ok(true),
|
||||
|
||||
@@ -15,7 +15,7 @@ use crate::witgen::IncompleteCause;
|
||||
use super::data_structures::finalizable_data::FinalizableData;
|
||||
use super::processor::{OuterQuery, Processor};
|
||||
|
||||
use super::rows::{Row, RowFactory, UnknownStrategy};
|
||||
use super::rows::{Row, RowFactory, RowIndex, UnknownStrategy};
|
||||
use super::{Constraints, EvalError, EvalValue, FixedData, MutableState, QueryCallback};
|
||||
|
||||
/// Maximal period checked during loop detection.
|
||||
@@ -64,7 +64,7 @@ pub struct VmProcessor<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> {
|
||||
|
||||
impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> VmProcessor<'a, 'b, 'c, T, Q> {
|
||||
pub fn new(
|
||||
row_offset: DegreeType,
|
||||
row_offset: RowIndex,
|
||||
fixed_data: &'a FixedData<'a, T>,
|
||||
identities: &[&'a Identity<Expression<T>>],
|
||||
witnesses: &'c HashSet<PolyID>,
|
||||
@@ -86,7 +86,7 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> VmProcessor<'a, 'b, 'c, T
|
||||
);
|
||||
|
||||
VmProcessor {
|
||||
row_offset,
|
||||
row_offset: row_offset.into(),
|
||||
witnesses: witnesses.clone(),
|
||||
fixed_data,
|
||||
identities_with_next_ref: identities_with_next,
|
||||
@@ -238,7 +238,8 @@ impl<'a, 'b, 'c, T: FieldElement, Q: QueryCallback<T>> VmProcessor<'a, 'b, 'c, T
|
||||
if row_index == self.processor.len() as DegreeType - 1 {
|
||||
self.processor.set_row(
|
||||
self.processor.len(),
|
||||
self.row_factory.fresh_row(row_index + 1),
|
||||
self.row_factory
|
||||
.fresh_row(RowIndex::from_degree(row_index, self.fixed_data.degree) + 1),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user