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