use super::{build_trace_from_ops, Felt, FieldElement, Trace, NUM_RAND_ROWS, ONE, ZERO};
use miden_air::trace::{
chiplets::hasher::HASH_CYCLE_LEN, range::B_RANGE_COL_IDX, AUX_TRACE_RAND_ELEMENTS,
};
use test_utils::rand::rand_array;
use vm_core::{ExtensionOf, Operation};
#[test]
fn b_range_trace_stack() {
let stack = [1, 255];
let operations = vec![Operation::U32add];
let mut trace = build_trace_from_ops(operations, &stack);
let rand_elements = rand_array::<Felt, AUX_TRACE_RAND_ELEMENTS>();
let alpha = rand_elements[0];
let aux_columns = trace.build_aux_segment(&[], &rand_elements).unwrap();
let b_range = aux_columns.get_column(B_RANGE_COL_IDX);
assert_eq!(trace.length(), b_range.len());
assert_eq!(ONE, b_range[0]);
assert_eq!(ONE, b_range[1]);
let lookups = alpha.inv().mul_base(Felt::new(3)) + (alpha - Felt::new(256)).inv();
let mut expected = b_range[1] - lookups;
assert_eq!(expected, b_range[2]);
let len_16bit = 44 + 1;
let values_start = trace.length() - len_16bit - NUM_RAND_ROWS;
assert_eq!(expected, b_range[values_start]);
expected += alpha.inv().mul_base(Felt::new(3));
assert_eq!(expected, b_range[values_start + 1]);
assert_eq!(expected, b_range[values_start + 2]);
assert_eq!(expected, b_range[values_start + 3]);
assert_eq!(expected, b_range[values_start + 4]);
expected += (alpha - Felt::new(256)).inv();
assert_eq!(expected, b_range[values_start + 5]);
let last_row = b_range.len() - NUM_RAND_ROWS - 1;
assert_eq!(ONE, b_range[last_row]);
}
#[test]
#[allow(clippy::needless_range_loop)]
fn b_range_trace_mem() {
let stack = [0, 1, 2, 3, 4, 0];
let operations = vec![
Operation::MStoreW,
Operation::Drop,
Operation::Drop,
Operation::Drop,
Operation::Drop,
Operation::MLoadW,
];
let mut trace = build_trace_from_ops(operations, &stack);
let rand_elements = rand_array::<Felt, AUX_TRACE_RAND_ELEMENTS>();
let alpha = rand_elements[0];
let aux_columns = trace.build_aux_segment(&[], &rand_elements).unwrap();
let b_range = aux_columns.get_column(B_RANGE_COL_IDX);
assert_eq!(trace.length(), b_range.len());
let memory_start = HASH_CYCLE_LEN;
let len_16bit = 40 + 1;
let values_start = trace.length() - len_16bit - NUM_RAND_ROWS;
let mut expected = ONE;
for row in 0..memory_start {
assert_eq!(expected, b_range[row]);
}
let (d0_store, d1_store) = (ZERO, ZERO);
let (d0_load, d1_load) = (Felt::new(4), ZERO);
expected -= (alpha - d0_store).inv() + (alpha - d1_store).inv();
assert_eq!(expected, b_range[memory_start + 1]);
expected -= (alpha - d0_load).inv() + (alpha - d1_load).inv();
assert_eq!(expected, b_range[memory_start + 2]);
for row in memory_start + 2..=values_start {
assert_eq!(expected, b_range[row]);
}
expected += alpha.inv().mul_base(Felt::new(3));
assert_eq!(expected, b_range[values_start + 1]);
assert_eq!(expected, b_range[values_start + 2]);
expected += (alpha - d0_load).inv();
assert_eq!(expected, b_range[values_start + 3]);
assert_eq!(expected, ONE);
for i in (values_start + 3)..(b_range.len() - NUM_RAND_ROWS) {
assert_eq!(ONE, b_range[i]);
}
}