diff --git a/o1vm/src/mips/mod.rs b/o1vm/src/mips/mod.rs index b9b0855756..7a5be219f1 100644 --- a/o1vm/src/mips/mod.rs +++ b/o1vm/src/mips/mod.rs @@ -20,6 +20,7 @@ pub mod constraints; pub mod folding; pub mod interpreter; pub mod registers; +pub mod singlestep; #[cfg(test)] pub mod tests; pub mod trace; diff --git a/o1vm/src/mips/singlestep.rs b/o1vm/src/mips/singlestep.rs new file mode 100644 index 0000000000..9f009aa7c8 --- /dev/null +++ b/o1vm/src/mips/singlestep.rs @@ -0,0 +1,116 @@ +// Amalgamation of the different MIPS circuits into a "single" circuit. + +use super::column; + +pub trait SingleStepper { + type S; + + type Position; + + type Instruction; + + type Variable: Clone + + std::ops::Add + + std::ops::Sub + + std::ops::Mul + + std::fmt::Debug + + ark_ff::Zero + + ark_ff::One; + + type State = S; + + /// Helpers + + fn alloc_scratch(state: Self::State) -> (Self::Position, Self::State); + + fn variable(state: &Self::State, column: Self::Position) -> Self::Variable; + + fn add_constraint(state: Self::State, assert_equals_zero: Self::Variable) -> Self::State; + + // ABORTS + fn check_is_zero(assert_equals_zero: &Self::Variable); + + fn assert_is_zero(state: Self::State, assert_equals_zero: Self::Variable) -> Self::State { + Self::check_is_zero(&assert_equals_zero); + self.add_constraint(assert_equals_zero) + } + + // ABORTS + fn check_equal(x: &Self::Variable, y: &Self::Variable); + + fn assert_equal(state: Self::State, x: Self::Variable, y: Self::Variable) -> Self::State { + Self::check_equal(&x, &y); + self.add_constraint(x - y) + } + + // ABORTS + fn check_boolean(x: &Self::Variable); + + fn assert_boolean(state: Self::State, x: Self::Variable) { + Self::check_boolean(&x); + self.add_constraint(x.clone() * x.clone() - x); // polynomial with roots {0, 1} + } + + fn add_lookup(state: Self::State, lookup: Lookup) -> Self::State; + + // compared to original, this is divided by 4. + fn instruction_counter(state: &Self::State) -> Self::Variable; + + fn increase_instruction_counter(state: Self::State) -> Self::State; + + /// Actual stepper + + fn step(state: Self::State, instructions: &Vec) -> Self::State; +} + +/// A simple example + +#[derive( + Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, EnumCount, EnumIter +)] +pub enum ExampleRegister { + A, + B, + C, + D, + Lo, + Hi, + Ip, + NextIp, +} + +pub type ExamplePosition = column::ColumnAlias; + +pub type ExampleVariable = ark_bn254::Bn254; + +const SCRATCH_SIZE: usize = 64; + +pub struct ExampleRegisterBank { + a: T, + b: T, + c: T, + d: T, + lo: T, + hi: T, + ip: T, + next_ip: T, +} + +#[derive( + Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd +)] +pub enum ExampleInstruction { + Div(ExampleRegister, ExampleRegister), + ShiftLeftLogicalVariable(ExampleRegister, ExampleRegister), + JumpRegister(ExampleRegister), + Load8(ExampleRegister, ExampleRegister, u32), + SyscallExitGroup, +} + +pub struct ExampleS { + registers: ExampleRegisterBank, + memory: Vec<(u32, Vec)>, + halt: bool, + scratch_state_idx: usize, + scratch_state: [V; SCRATCH_SIZE], +} \ No newline at end of file