zisk-pil 1.3.2-alpha

PIL2 definitions for the ZisK zkVM
//! Main row helpers defined beside the autogenerated `MainTraceRow` without touching
//! `traces.rs`: the air's ids and the steps a row packs. The compact *indexed* packing of
//! the same row lives in [`crate::main_indexed`].

use proofman_fields::Goldilocks;

use crate::{MainTrace, MainTraceRow};

/// Re-export so the emulator / main SM can bound generic fills on `zisk_pil::IndexedFill`.
pub use proofman_common::trace::IndexedFill;

// Derived from the autogenerated `MainTrace` alias, so they track the pilout — not hardcoded.
pub const MAIN_AIRGROUP_ID: usize = MainTrace::<()>::AIRGROUP_ID;
pub const MAIN_AIR_ID: usize = MainTrace::<()>::AIR_ID;

/// Execution steps packed into one Main row — `lanes_x_row` in main.pil.
///
/// Read off the generated row instead of being restated here, so it cannot drift from the
/// PIL: `flag` and `pc` are consecutive `[F; lanes_x_row]` columns of a `#[repr(C)]` struct
/// whose element is field-sized, so the gap between them is exactly one lane array.
pub const MAIN_LANES: usize = (std::mem::offset_of!(MainTraceRow<Goldilocks>, pc)
    - std::mem::offset_of!(MainTraceRow<Goldilocks>, flag))
    / std::mem::size_of::<Goldilocks>();

/// Execution steps one Main segment covers: every row of the air carries [`MAIN_LANES`] of
/// them. Segments are planned, chunked and range-checked in steps, not in rows.
pub const MAIN_STEPS_PER_SEGMENT: usize = MainTrace::<()>::NUM_ROWS * MAIN_LANES;

// The Main witness fill splits the trace into equal row ranges, one per minimal-trace chunk,
// which only tiles the air when the row count is a power of two.
const _: () = assert!(
    MainTrace::<()>::NUM_ROWS.is_power_of_two(),
    "MainTrace::NUM_ROWS must be a power of two",
);

#[cfg(test)]
mod tests {
    use super::*;
    use crate::MainTraceRowOps;

    #[test]
    fn main_lanes_matches_the_generated_row() {
        // `MAIN_LANES` is read off the row's memory layout; this pins it against the array
        // length the pil-helpers actually generated.
        let row = MainTraceRow::<Goldilocks>::default();
        assert_eq!(MAIN_LANES, row.pc.len());
        assert_eq!(MAIN_LANES, MainTraceRowOps::get_all_flag(&row).len());
    }
}