openvm_stark_backend/air_builders/
sub.rs1use std::ops::{Deref, Range};
4
5use p3_air::{AirBuilder, BaseAir};
6use p3_matrix::Matrix;
7
8pub struct SubMatrixRowSlices<M: Matrix<T>, T: Clone + Send + Sync> {
10 inner: M,
11 column_range: Range<usize>,
12 _phantom: std::marker::PhantomData<T>,
13}
14
15impl<M: Matrix<T>, T: Clone + Send + Sync> SubMatrixRowSlices<M, T> {
16 pub const fn new(inner: M, column_range: Range<usize>) -> Self {
17 Self {
18 inner,
19 column_range,
20 _phantom: std::marker::PhantomData,
21 }
22 }
23}
24
25impl<M: Matrix<T>, T: Clone + Send + Sync> Matrix<T> for SubMatrixRowSlices<M, T> {
27 #[inline]
28 fn get(&self, r: usize, c: usize) -> Option<T> {
29 let c = self.column_range.start + c;
30 if c >= self.column_range.end {
31 return None;
32 }
33 self.inner.get(r, c)
34 }
35
36 #[inline]
37 unsafe fn row_subseq_unchecked(
38 &self,
39 r: usize,
40 start: usize,
41 end: usize,
42 ) -> impl IntoIterator<Item = T, IntoIter = impl Iterator<Item = T> + Send + Sync> {
43 let global_start = self.column_range.start + start;
44 let global_end = self.column_range.start + end;
45 self.inner
46 .row_unchecked(r)
47 .into_iter()
48 .skip(global_start)
49 .take(global_end - global_start)
50 }
51
52 #[inline]
53 fn row_slice(&self, r: usize) -> Option<impl Deref<Target = [T]>> {
54 self.inner.row(r).map(|row| {
55 row.into_iter()
56 .skip(self.column_range.start)
57 .take(self.width())
58 .collect::<Vec<_>>()
59 })
60 }
61
62 #[inline]
63 fn width(&self) -> usize {
64 self.column_range.len()
65 }
66
67 #[inline]
68 fn height(&self) -> usize {
69 self.inner.height()
70 }
71}
72
73pub struct SubAirBuilder<'a, AB: AirBuilder, SubAir: BaseAir<T>, T> {
77 inner: &'a mut AB,
78 column_range: Range<usize>,
79 _phantom: std::marker::PhantomData<(SubAir, T)>,
80}
81
82impl<'a, AB: AirBuilder, SubAir: BaseAir<T>, T> SubAirBuilder<'a, AB, SubAir, T> {
83 pub fn new(inner: &'a mut AB, column_range: Range<usize>) -> Self {
84 Self {
85 inner,
86 column_range,
87 _phantom: std::marker::PhantomData,
88 }
89 }
90}
91
92impl<AB: AirBuilder, SubAir: BaseAir<F>, F> AirBuilder for SubAirBuilder<'_, AB, SubAir, F> {
94 type F = AB::F;
95 type Expr = AB::Expr;
96 type Var = AB::Var;
97 type M = SubMatrixRowSlices<AB::M, Self::Var>;
98
99 fn main(&self) -> Self::M {
100 let matrix = self.inner.main();
101
102 SubMatrixRowSlices::new(matrix, self.column_range.clone())
103 }
104
105 fn is_first_row(&self) -> Self::Expr {
106 self.inner.is_first_row()
107 }
108
109 fn is_last_row(&self) -> Self::Expr {
110 self.inner.is_last_row()
111 }
112
113 fn is_transition_window(&self, size: usize) -> Self::Expr {
114 self.inner.is_transition_window(size)
115 }
116
117 fn assert_zero<I: Into<Self::Expr>>(&mut self, x: I) {
118 self.inner.assert_zero(x.into());
119 }
120}