sp1_stark/air/machine.rs
1use p3_air::BaseAir;
2use p3_field::Field;
3use p3_matrix::dense::RowMajorMatrix;
4
5use crate::{septic_digest::SepticDigest, MachineRecord};
6
7pub use sp1_derive::MachineAir;
8
9use super::InteractionScope;
10
11// TODO: add Id type and also fn id()
12
13#[macro_export]
14/// Macro to get the name of a chip.
15macro_rules! chip_name {
16 ($chip:ident, $field:ty) => {
17 <$chip as MachineAir<$field>>::name(&$chip {})
18 };
19}
20
21/// An AIR that is part of a multi table AIR arithmetization.
22pub trait MachineAir<F: Field>: BaseAir<F> + 'static + Send + Sync {
23 /// The execution record containing events for producing the air trace.
24 type Record: MachineRecord;
25
26 /// The program that defines the control flow of the machine.
27 type Program: MachineProgram<F>;
28
29 /// A unique identifier for this AIR as part of a machine.
30 fn name(&self) -> String;
31
32 /// The number of rows in the trace
33 fn num_rows(&self, _input: &Self::Record) -> Option<usize> {
34 None
35 }
36
37 /// Generate the trace for a given execution record.
38 ///
39 /// - `input` is the execution record containing the events to be written to the trace.
40 /// - `output` is the execution record containing events that the `MachineAir` can add to the
41 /// record such as byte lookup requests.
42 fn generate_trace(&self, input: &Self::Record, output: &mut Self::Record) -> RowMajorMatrix<F>;
43
44 /// Generate the dependencies for a given execution record.
45 fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) {
46 self.generate_trace(input, output);
47 }
48
49 /// Whether this execution record contains events for this air.
50 fn included(&self, shard: &Self::Record) -> bool;
51
52 /// The width of the preprocessed trace.
53 fn preprocessed_width(&self) -> usize {
54 0
55 }
56
57 /// The number of rows in the preprocessed trace
58 fn preprocessed_num_rows(&self, _program: &Self::Program, _instrs_len: usize) -> Option<usize> {
59 None
60 }
61
62 /// Generate the preprocessed trace given a specific program.
63 fn generate_preprocessed_trace(&self, _program: &Self::Program) -> Option<RowMajorMatrix<F>> {
64 None
65 }
66
67 /// Specifies whether it's trace should be part of either the global or local commit.
68 fn commit_scope(&self) -> InteractionScope {
69 InteractionScope::Local
70 }
71
72 /// Specifies whether the air only uses the local row, and not the next row.
73 fn local_only(&self) -> bool {
74 false
75 }
76}
77
78/// A program that defines the control flow of a machine through a program counter.
79pub trait MachineProgram<F>: Send + Sync {
80 /// Gets the starting program counter.
81 fn pc_start(&self) -> F;
82 /// Gets the initial global cumulative sum.
83 fn initial_global_cumulative_sum(&self) -> SepticDigest<F>;
84}