pub mod columns;
use miden_crypto::stark::air::AirBuilder;
use crate::{
MainCols, MidenAirBuilder,
constraints::{constants::F_1, op_flags::OpFlags, utils::BoolNot},
};
pub fn enforce_main<AB>(
builder: &mut AB,
local: &MainCols<AB::Var>,
next: &MainCols<AB::Var>,
op_flags: &OpFlags<AB::Expr>,
) where
AB: MidenAirBuilder,
{
{
builder.when_first_row().assert_zero(local.system.clk);
builder.when_transition().assert_eq(next.system.clk, local.system.clk + F_1);
}
let f_call = op_flags.call();
let f_syscall = op_flags.syscall();
let f_dyncall = op_flags.dyncall();
let f_end = op_flags.end();
{
let ctx = local.system.ctx;
let ctx_next = next.system.ctx;
let clk = local.system.clk;
let call_dyncall_flag = f_call.clone() + f_dyncall.clone();
let change_ctx_flag =
f_call.clone() + f_syscall.clone() + f_dyncall.clone() + f_end.clone();
let default_flag = change_ctx_flag.not();
let builder = &mut builder.when_transition();
builder.when(call_dyncall_flag).assert_eq(ctx_next, clk + F_1);
builder.when(f_syscall).assert_zero(ctx_next);
builder.when(default_flag).assert_eq(ctx_next, ctx);
}
{
let f_load = f_call + f_dyncall;
let f_preserve = (f_load.clone() + f_end).not();
let builder = &mut builder.when_transition();
{
let builder = &mut builder.when(f_load);
for i in 0..4 {
builder.assert_eq(next.system.fn_hash[i], local.decoder.hasher_state[i]);
}
}
{
let builder = &mut builder.when(f_preserve);
for i in 0..4 {
builder.assert_eq(next.system.fn_hash[i], local.system.fn_hash[i]);
}
}
}
}