sp1_recursion_core/air/
multi_builder.rs

1use p3_air::{
2    AirBuilder, AirBuilderWithPublicValues, ExtensionBuilder, FilteredAirBuilder,
3    PermutationAirBuilder,
4};
5use sp1_stark::air::{InteractionScope, MessageBuilder};
6
7/// The MultiBuilder is used for the multi table.  It is used to create a virtual builder for one of
8/// the sub tables in the multi table.
9pub struct MultiBuilder<'a, AB: AirBuilder> {
10    inner: FilteredAirBuilder<'a, AB>,
11
12    /// These fields are used to determine whether a row is is the first or last row of the
13    /// subtable, which requires hinting from the parent table.
14    is_first_row: AB::Expr,
15    is_last_row: AB::Expr,
16
17    next_condition: AB::Expr,
18}
19
20impl<'a, AB: AirBuilder> MultiBuilder<'a, AB> {
21    pub fn new(
22        builder: &'a mut AB,
23        local_condition: AB::Expr,
24        is_first_row: AB::Expr,
25        is_last_row: AB::Expr,
26        next_condition: AB::Expr,
27    ) -> Self {
28        let inner = builder.when(local_condition.clone());
29        Self { inner, is_first_row, is_last_row, next_condition }
30    }
31}
32
33impl<AB: AirBuilder> AirBuilder for MultiBuilder<'_, AB> {
34    type F = AB::F;
35    type Expr = AB::Expr;
36    type Var = AB::Var;
37    type M = AB::M;
38
39    fn main(&self) -> Self::M {
40        self.inner.main()
41    }
42
43    fn is_first_row(&self) -> Self::Expr {
44        self.is_first_row.clone()
45    }
46
47    fn is_last_row(&self) -> Self::Expr {
48        self.is_last_row.clone()
49    }
50
51    fn is_transition_window(&self, size: usize) -> Self::Expr {
52        self.next_condition.clone() * self.inner.is_transition_window(size)
53    }
54
55    fn assert_zero<I: Into<Self::Expr>>(&mut self, x: I) {
56        self.inner.assert_zero(x.into());
57    }
58}
59
60impl<AB: ExtensionBuilder> ExtensionBuilder for MultiBuilder<'_, AB> {
61    type EF = AB::EF;
62    type VarEF = AB::VarEF;
63    type ExprEF = AB::ExprEF;
64
65    fn assert_zero_ext<I>(&mut self, x: I)
66    where
67        I: Into<Self::ExprEF>,
68    {
69        self.inner.assert_zero_ext(x.into());
70    }
71}
72
73impl<AB: PermutationAirBuilder> PermutationAirBuilder for MultiBuilder<'_, AB> {
74    type MP = AB::MP;
75
76    type RandomVar = AB::RandomVar;
77
78    fn permutation(&self) -> Self::MP {
79        self.inner.permutation()
80    }
81
82    fn permutation_randomness(&self) -> &[Self::RandomVar] {
83        self.inner.permutation_randomness()
84    }
85}
86
87impl<AB: AirBuilder + MessageBuilder<M>, M> MessageBuilder<M> for MultiBuilder<'_, AB> {
88    fn send(&mut self, message: M, scope: InteractionScope) {
89        self.inner.send(message, scope);
90    }
91
92    fn receive(&mut self, message: M, scope: InteractionScope) {
93        self.inner.receive(message, scope);
94    }
95}
96
97impl<AB: AirBuilder + AirBuilderWithPublicValues> AirBuilderWithPublicValues
98    for MultiBuilder<'_, AB>
99{
100    type PublicVar = AB::PublicVar;
101
102    fn public_values(&self) -> &[Self::PublicVar] {
103        self.inner.public_values()
104    }
105}