Skip to content

Commit

Permalink
feat: add dummy rows to memory trace
Browse files Browse the repository at this point in the history
  • Loading branch information
zmalatrax committed Nov 8, 2024
1 parent 7ec6146 commit 8b4dff4
Showing 1 changed file with 63 additions and 1 deletion.
64 changes: 63 additions & 1 deletion crates/brainfuck_prover/src/components/memory/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,48 @@ impl MemoryTable {
self.table.iter().find(|r| *r == row)
}

/// Sorts in-place the existing [`MemoryTableRow`] rows in the Memory Table by `mp`.
/// Returns a reference to a row in the Memory Table given its index.
///
/// # Arguments
/// * `index` - The [`usize`] index to search for in the table.
///
/// # Returns
/// An `Option` containing a reference to the matching row if found,
/// or `None` if the row does not exist in the table.
pub fn get_row_from_index(&self, index: usize) -> Option<&MemoryTableRow> {
self.table.get(index)
}

/// Sorts in-place the existing [`MemoryTableRow`] rows in the Memory Table by `mp`, then `clk`.
///
/// Having the rows sorted is required to ensure a correct proof generation (such that the
/// constraints can be verified).
pub fn sort(&mut self) {
self.table.sort_by_key(|x| (x.mp, x.clk));
}

/// Fills the jumps in `clk` with dummy rows.
///
/// Required to ensure the correct sorting of the [`MemoryTable`] in the constraints.
pub fn complete_with_dummy_rows(&mut self) {
let mut new_table = Vec::with_capacity(self.table.len());
let mut prev_row = self.get_row_from_index(0).unwrap();

for row in &self.table {
let next_clk = prev_row.clk + BaseField::one();
if row.mp == prev_row.mp && row.clk > next_clk {
let mut clk = next_clk;
while clk < row.clk {
new_table.push(MemoryTableRow::new_dummy(clk, prev_row.mp, prev_row.mv));
clk += BaseField::one();
}
}
new_table.push(row.clone());
prev_row = row;
}
new_table.shrink_to_fit();
self.table = new_table;
}
}

#[cfg(test)]
Expand Down Expand Up @@ -268,4 +306,28 @@ mod tests {

assert_eq!(memory_table, expected_memory_table);
}

#[test]
fn test_complete_wih_dummy_rows() {
let mut memory_table = MemoryTable::new();
let row1 = MemoryTableRow::new(BaseField::zero(), BaseField::zero(), BaseField::zero());
let row2 = MemoryTableRow::new(BaseField::zero(), BaseField::one(), BaseField::zero());
let row3 = MemoryTableRow::new(BaseField::from(5), BaseField::one(), BaseField::one());
memory_table.add_rows(vec![row3.clone(), row1.clone(), row2.clone()]);
memory_table.sort();
memory_table.complete_with_dummy_rows();

let mut expected_memory_table = MemoryTable::new();
expected_memory_table.add_rows(vec![
row1,
row2,
MemoryTableRow::new_dummy(BaseField::from(1), BaseField::one(), BaseField::zero()),
MemoryTableRow::new_dummy(BaseField::from(2), BaseField::one(), BaseField::zero()),
MemoryTableRow::new_dummy(BaseField::from(3), BaseField::one(), BaseField::zero()),
MemoryTableRow::new_dummy(BaseField::from(4), BaseField::one(), BaseField::zero()),
row3,
]);

assert_eq!(memory_table, expected_memory_table);
}
}

0 comments on commit 8b4dff4

Please sign in to comment.