use sp1_derive::AlignedBorrow;
use crate::air::Word;
#[derive(AlignedBorrow, Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct MemoryReadCols<T> {
pub access: MemoryAccessCols<T>,
}
#[derive(AlignedBorrow, Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct MemoryWriteCols<T> {
pub prev_value: Word<T>,
pub access: MemoryAccessCols<T>,
}
#[derive(AlignedBorrow, Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct MemoryReadWriteCols<T> {
pub prev_value: Word<T>,
pub access: MemoryAccessCols<T>,
}
#[derive(AlignedBorrow, Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct MemoryAccessCols<T> {
pub value: Word<T>,
pub prev_shard: T,
pub prev_clk: T,
pub compare_clk: T,
pub diff_16bit_limb: T,
pub diff_8bit_limb: T,
}
pub trait MemoryCols<T> {
fn access(&self) -> &MemoryAccessCols<T>;
fn access_mut(&mut self) -> &mut MemoryAccessCols<T>;
fn prev_value(&self) -> &Word<T>;
fn prev_value_mut(&mut self) -> &mut Word<T>;
fn value(&self) -> &Word<T>;
fn value_mut(&mut self) -> &mut Word<T>;
}
impl<T> MemoryCols<T> for MemoryReadCols<T> {
fn access(&self) -> &MemoryAccessCols<T> {
&self.access
}
fn access_mut(&mut self) -> &mut MemoryAccessCols<T> {
&mut self.access
}
fn prev_value(&self) -> &Word<T> {
&self.access.value
}
fn prev_value_mut(&mut self) -> &mut Word<T> {
&mut self.access.value
}
fn value(&self) -> &Word<T> {
&self.access.value
}
fn value_mut(&mut self) -> &mut Word<T> {
&mut self.access.value
}
}
impl<T> MemoryCols<T> for MemoryWriteCols<T> {
fn access(&self) -> &MemoryAccessCols<T> {
&self.access
}
fn access_mut(&mut self) -> &mut MemoryAccessCols<T> {
&mut self.access
}
fn prev_value(&self) -> &Word<T> {
&self.prev_value
}
fn prev_value_mut(&mut self) -> &mut Word<T> {
&mut self.prev_value
}
fn value(&self) -> &Word<T> {
&self.access.value
}
fn value_mut(&mut self) -> &mut Word<T> {
&mut self.access.value
}
}
impl<T> MemoryCols<T> for MemoryReadWriteCols<T> {
fn access(&self) -> &MemoryAccessCols<T> {
&self.access
}
fn access_mut(&mut self) -> &mut MemoryAccessCols<T> {
&mut self.access
}
fn prev_value(&self) -> &Word<T> {
&self.prev_value
}
fn prev_value_mut(&mut self) -> &mut Word<T> {
&mut self.prev_value
}
fn value(&self) -> &Word<T> {
&self.access.value
}
fn value_mut(&mut self) -> &mut Word<T> {
&mut self.access.value
}
}
pub fn value_as_limbs<T: Clone, M: MemoryCols<T>>(memory: &[M]) -> Vec<T> {
memory
.iter()
.flat_map(|m| m.value().clone().into_iter())
.collect()
}