use alloc::vec::Vec;
use miden_air::trace::{Challenges, MainTrace};
use miden_core::{Felt, field::ExtensionField};
use super::super::ace::{AceHints, NUM_ACE_LOGUP_FRACTIONS_EVAL, NUM_ACE_LOGUP_FRACTIONS_READ};
pub struct WiringBusBuilder<'a> {
ace_hints: &'a AceHints,
}
impl<'a> WiringBusBuilder<'a> {
pub(crate) fn new(ace_hints: &'a AceHints) -> Self {
Self { ace_hints }
}
pub fn build_aux_column<E: ExtensionField<Felt>>(
&self,
main_trace: &MainTrace,
challenges: &Challenges<E>,
) -> Vec<E> {
let mut wiring_bus = vec![E::ZERO; main_trace.num_rows()];
let total_divisors = self.ace_hints.build_divisors(main_trace, challenges);
let mut trace_offset = self.ace_hints.offset();
let mut divisors_offset = 0;
for section in self.ace_hints.sections.iter() {
let divisors = &total_divisors[divisors_offset
..divisors_offset + NUM_ACE_LOGUP_FRACTIONS_READ * section.num_vars() as usize];
for (i, divisor_tuple) in divisors.chunks(NUM_ACE_LOGUP_FRACTIONS_READ).enumerate() {
let trace_row = i + trace_offset;
let m_0 = main_trace.chiplet_ace_m_0(trace_row.into());
let m_1 = main_trace.chiplet_ace_m_1(trace_row.into());
let value = divisor_tuple[0] * m_0 + divisor_tuple[1] * m_1;
wiring_bus[trace_row + 1] = wiring_bus[trace_row] + value;
}
trace_offset += section.num_vars() as usize;
divisors_offset += NUM_ACE_LOGUP_FRACTIONS_READ * section.num_vars() as usize;
let divisors = &total_divisors[divisors_offset
..divisors_offset + NUM_ACE_LOGUP_FRACTIONS_EVAL * section.num_evals() as usize];
for (i, divisor_tuple) in divisors.chunks(NUM_ACE_LOGUP_FRACTIONS_EVAL).enumerate() {
let trace_row = i + trace_offset;
let m_0 = main_trace.chiplet_ace_m_0(trace_row.into());
let value = divisor_tuple[0] * m_0 - (divisor_tuple[1] + divisor_tuple[2]);
wiring_bus[trace_row + 1] = wiring_bus[trace_row] + value;
}
trace_offset += section.num_evals() as usize;
divisors_offset += NUM_ACE_LOGUP_FRACTIONS_EVAL * section.num_evals() as usize;
}
assert_eq!(wiring_bus[trace_offset], E::ZERO);
wiring_bus
}
}