use miden_crypto::stark::air::{AirBuilder, LiftedAirBuilder};
use crate::{
MainTraceRow,
constraints::{
op_flags::OpFlags,
tagging::{
TaggingAirBuilderExt,
ids::{TAG_STACK_GENERAL_BASE, TAG_STACK_GENERAL_COUNT},
},
},
};
pub const NUM_CONSTRAINTS: usize = TAG_STACK_GENERAL_COUNT;
const STACK_GENERAL_NAMES: [&str; NUM_CONSTRAINTS] = [
"stack.general.transition.0",
"stack.general.transition.1",
"stack.general.transition.2",
"stack.general.transition.3",
"stack.general.transition.4",
"stack.general.transition.5",
"stack.general.transition.6",
"stack.general.transition.7",
"stack.general.transition.8",
"stack.general.transition.9",
"stack.general.transition.10",
"stack.general.transition.11",
"stack.general.transition.12",
"stack.general.transition.13",
"stack.general.transition.14",
"stack.general.transition.15",
];
pub fn enforce_main<AB>(
builder: &mut AB,
local: &MainTraceRow<AB::Var>,
next: &MainTraceRow<AB::Var>,
op_flags: &OpFlags<AB::Expr>,
) where
AB: LiftedAirBuilder,
{
{
let flag_sum = op_flags.no_shift_at(0) + op_flags.left_shift_at(1);
let expected = op_flags.no_shift_at(0) * local.stack[0].clone().into()
+ op_flags.left_shift_at(1) * local.stack[1].clone().into();
let actual: AB::Expr = next.stack[0].clone().into();
builder.tagged(TAG_STACK_GENERAL_BASE, STACK_GENERAL_NAMES[0], |builder| {
builder.when_transition().assert_zero(actual * flag_sum - expected);
});
}
for (i, &namespace) in STACK_GENERAL_NAMES.iter().enumerate().take(15).skip(1) {
let flag_sum = op_flags.no_shift_at(i)
+ op_flags.left_shift_at(i + 1)
+ op_flags.right_shift_at(i - 1);
let expected = op_flags.no_shift_at(i) * local.stack[i].clone().into()
+ op_flags.left_shift_at(i + 1) * local.stack[i + 1].clone().into()
+ op_flags.right_shift_at(i - 1) * local.stack[i - 1].clone().into();
let actual: AB::Expr = next.stack[i].clone().into();
let id = TAG_STACK_GENERAL_BASE + i;
builder.tagged(id, namespace, |builder| {
builder.when_transition().assert_zero(actual * flag_sum - expected);
});
}
{
let flag_sum = op_flags.no_shift_at(15) + op_flags.right_shift_at(14);
let expected = op_flags.no_shift_at(15) * local.stack[15].clone().into()
+ op_flags.right_shift_at(14) * local.stack[14].clone().into();
let actual: AB::Expr = next.stack[15].clone().into();
builder.tagged(TAG_STACK_GENERAL_BASE + 15, STACK_GENERAL_NAMES[15], |builder| {
builder.when_transition().assert_zero(actual * flag_sum - expected);
});
}
}