sp1_recursion_core/
builder.rs1use std::iter::once;
2
3use p3_air::AirBuilderWithPublicValues;
4use p3_field::AbstractField;
5use sp1_stark::{
6 air::{AirInteraction, BaseAirBuilder, InteractionScope, MachineAirBuilder},
7 InteractionKind,
8};
9
10use crate::{air::Block, Address};
11
12pub trait SP1RecursionAirBuilder: MachineAirBuilder + RecursionAirBuilder {}
14
15impl<AB: AirBuilderWithPublicValues + RecursionAirBuilder> SP1RecursionAirBuilder for AB {}
16impl<AB: BaseAirBuilder> RecursionAirBuilder for AB {}
17
18pub trait RecursionAirBuilder: BaseAirBuilder {
19 fn send_single<E: Into<Self::Expr>>(
20 &mut self,
21 addr: Address<E>,
22 val: E,
23 mult: impl Into<Self::Expr>,
24 ) {
25 let mut padded_value = core::array::from_fn(|_| Self::Expr::zero());
26 padded_value[0] = val.into();
27 self.send_block(Address(addr.0.into()), Block(padded_value), mult)
28 }
29
30 fn send_block<E: Into<Self::Expr>>(
31 &mut self,
32 addr: Address<E>,
33 val: Block<E>,
34 mult: impl Into<Self::Expr>,
35 ) {
36 self.send(
37 AirInteraction::new(
38 once(addr.0).chain(val).map(Into::into).collect(),
39 mult.into(),
40 InteractionKind::Memory,
41 ),
42 InteractionScope::Local,
43 );
44 }
45
46 fn receive_single<E: Into<Self::Expr>>(
47 &mut self,
48 addr: Address<E>,
49 val: E,
50 mult: impl Into<Self::Expr>,
51 ) {
52 let mut padded_value = core::array::from_fn(|_| Self::Expr::zero());
53 padded_value[0] = val.into();
54 self.receive_block(Address(addr.0.into()), Block(padded_value), mult)
55 }
56
57 fn receive_block<E: Into<Self::Expr>>(
58 &mut self,
59 addr: Address<E>,
60 val: Block<E>,
61 mult: impl Into<Self::Expr>,
62 ) {
63 self.receive(
64 AirInteraction::new(
65 once(addr.0).chain(val).map(Into::into).collect(),
66 mult.into(),
67 InteractionKind::Memory,
68 ),
69 InteractionScope::Local,
70 );
71 }
72}