p3_uni_stark/
check_constraints.rs
1use alloc::vec::Vec;
2
3use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues};
4use p3_field::Field;
5use p3_matrix::dense::{RowMajorMatrix, RowMajorMatrixView};
6use p3_matrix::stack::VerticalPair;
7use p3_matrix::Matrix;
8use tracing::instrument;
9
10#[instrument(name = "check constraints", skip_all)]
11pub(crate) fn check_constraints<F, A>(air: &A, main: &RowMajorMatrix<F>, public_values: &Vec<F>)
12where
13 F: Field,
14 A: for<'a> Air<DebugConstraintBuilder<'a, F>>,
15{
16 let height = main.height();
17
18 (0..height).for_each(|i| {
19 let i_next = (i + 1) % height;
20
21 let local = main.row_slice(i);
22 let next = main.row_slice(i_next);
23 let main = VerticalPair::new(
24 RowMajorMatrixView::new_row(&*local),
25 RowMajorMatrixView::new_row(&*next),
26 );
27
28 let mut builder = DebugConstraintBuilder {
29 row_index: i,
30 main,
31 public_values,
32 is_first_row: F::from_bool(i == 0),
33 is_last_row: F::from_bool(i == height - 1),
34 is_transition: F::from_bool(i != height - 1),
35 };
36
37 air.eval(&mut builder);
38 });
39}
40
41#[derive(Debug)]
44pub struct DebugConstraintBuilder<'a, F: Field> {
45 row_index: usize,
46 main: VerticalPair<RowMajorMatrixView<'a, F>, RowMajorMatrixView<'a, F>>,
47 public_values: &'a [F],
48 is_first_row: F,
49 is_last_row: F,
50 is_transition: F,
51}
52
53impl<'a, F> AirBuilder for DebugConstraintBuilder<'a, F>
54where
55 F: Field,
56{
57 type F = F;
58 type Expr = F;
59 type Var = F;
60 type M = VerticalPair<RowMajorMatrixView<'a, F>, RowMajorMatrixView<'a, F>>;
61
62 fn main(&self) -> Self::M {
63 self.main
64 }
65
66 fn is_first_row(&self) -> Self::Expr {
67 self.is_first_row
68 }
69
70 fn is_last_row(&self) -> Self::Expr {
71 self.is_last_row
72 }
73
74 fn is_transition_window(&self, size: usize) -> Self::Expr {
75 if size == 2 {
76 self.is_transition
77 } else {
78 panic!("only supports a window size of 2")
79 }
80 }
81
82 fn assert_zero<I: Into<Self::Expr>>(&mut self, x: I) {
83 assert_eq!(
84 x.into(),
85 F::ZERO,
86 "constraints had nonzero value on row {}",
87 self.row_index
88 );
89 }
90
91 fn assert_eq<I1: Into<Self::Expr>, I2: Into<Self::Expr>>(&mut self, x: I1, y: I2) {
92 let x = x.into();
93 let y = y.into();
94 assert_eq!(
95 x, y,
96 "values didn't match on row {}: {} != {}",
97 self.row_index, x, y
98 );
99 }
100}
101
102impl<F: Field> AirBuilderWithPublicValues for DebugConstraintBuilder<'_, F> {
103 type PublicVar = Self::F;
104
105 fn public_values(&self) -> &[Self::F] {
106 self.public_values
107 }
108}