sp1_recursion_core/air/
multi_builder.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use p3_air::{
    AirBuilder, AirBuilderWithPublicValues, ExtensionBuilder, FilteredAirBuilder,
    PermutationAirBuilder,
};
use sp1_stark::air::{InteractionScope, MessageBuilder};

/// The MultiBuilder is used for the multi table.  It is used to create a virtual builder for one of
/// the sub tables in the multi table.
pub struct MultiBuilder<'a, AB: AirBuilder> {
    inner: FilteredAirBuilder<'a, AB>,

    /// These fields are used to determine whether a row is is the first or last row of the
    /// subtable, which requires hinting from the parent table.
    is_first_row: AB::Expr,
    is_last_row: AB::Expr,

    next_condition: AB::Expr,
}

impl<'a, AB: AirBuilder> MultiBuilder<'a, AB> {
    pub fn new(
        builder: &'a mut AB,
        local_condition: AB::Expr,
        is_first_row: AB::Expr,
        is_last_row: AB::Expr,
        next_condition: AB::Expr,
    ) -> Self {
        let inner = builder.when(local_condition.clone());
        Self { inner, is_first_row, is_last_row, next_condition }
    }
}

impl<AB: AirBuilder> AirBuilder for MultiBuilder<'_, AB> {
    type F = AB::F;
    type Expr = AB::Expr;
    type Var = AB::Var;
    type M = AB::M;

    fn main(&self) -> Self::M {
        self.inner.main()
    }

    fn is_first_row(&self) -> Self::Expr {
        self.is_first_row.clone()
    }

    fn is_last_row(&self) -> Self::Expr {
        self.is_last_row.clone()
    }

    fn is_transition_window(&self, size: usize) -> Self::Expr {
        self.next_condition.clone() * self.inner.is_transition_window(size)
    }

    fn assert_zero<I: Into<Self::Expr>>(&mut self, x: I) {
        self.inner.assert_zero(x.into());
    }
}

impl<AB: ExtensionBuilder> ExtensionBuilder for MultiBuilder<'_, AB> {
    type EF = AB::EF;
    type VarEF = AB::VarEF;
    type ExprEF = AB::ExprEF;

    fn assert_zero_ext<I>(&mut self, x: I)
    where
        I: Into<Self::ExprEF>,
    {
        self.inner.assert_zero_ext(x.into());
    }
}

impl<AB: PermutationAirBuilder> PermutationAirBuilder for MultiBuilder<'_, AB> {
    type MP = AB::MP;

    type RandomVar = AB::RandomVar;

    fn permutation(&self) -> Self::MP {
        self.inner.permutation()
    }

    fn permutation_randomness(&self) -> &[Self::RandomVar] {
        self.inner.permutation_randomness()
    }
}

impl<AB: AirBuilder + MessageBuilder<M>, M> MessageBuilder<M> for MultiBuilder<'_, AB> {
    fn send(&mut self, message: M, scope: InteractionScope) {
        self.inner.send(message, scope);
    }

    fn receive(&mut self, message: M, scope: InteractionScope) {
        self.inner.receive(message, scope);
    }
}

impl<AB: AirBuilder + AirBuilderWithPublicValues> AirBuilderWithPublicValues
    for MultiBuilder<'_, AB>
{
    type PublicVar = AB::PublicVar;

    fn public_values(&self) -> &[Self::PublicVar] {
        self.inner.public_values()
    }
}