@@ -11,25 +11,23 @@ use crate::{MyAir, witness::AirWitness};
1111pub struct AirTable < EF : Field , A > {
1212 pub air : A ,
1313 pub n_constraints : usize ,
14-
15- _phantom : std:: marker:: PhantomData < EF > ,
14+ _phantom : PhantomData < EF > ,
1615}
1716
1817impl < EF : ExtensionField < PF < EF > > , A : MyAir < EF > > AirTable < EF , A > {
1918 pub fn new ( air : A ) -> Self {
2019 let symbolic_constraints = get_symbolic_constraints ( & air, 0 , 0 ) ;
2120 let n_constraints = symbolic_constraints. len ( ) ;
22- let constraint_degree = Iterator :: max (
23- symbolic_constraints
24- . iter ( )
25- . map ( p3_uni_stark:: SymbolicExpression :: degree_multiple) ,
26- )
27- . unwrap ( ) ;
21+ let constraint_degree = symbolic_constraints
22+ . iter ( )
23+ . map ( p3_uni_stark:: SymbolicExpression :: degree_multiple)
24+ . max ( )
25+ . unwrap ( ) ;
2826 assert_eq ! ( constraint_degree, air. degree( ) ) ;
2927 Self {
3028 air,
3129 n_constraints,
32- _phantom : std :: marker :: PhantomData ,
30+ _phantom : PhantomData ,
3331 }
3432 }
3533
@@ -45,15 +43,43 @@ impl<EF: ExtensionField<PF<EF>>, A: MyAir<EF>> AirTable<EF, A> {
4543 A : MyAir < EF > ,
4644 EF : ExtensionField < IF > ,
4745 {
48- if witness. n_columns ( ) != self . n_columns ( ) {
46+ let width = self . air . width ( ) ;
47+ let rows = witness. n_rows ( ) ;
48+
49+ if witness. n_columns ( ) != width {
4950 return Err ( "Invalid number of columns" . to_string ( ) ) ;
5051 }
51- let handle_errors = |row : usize , constraint_checker : & mut ConstraintChecker < ' _ , IF , EF > | {
52- if !constraint_checker. errors . is_empty ( ) {
52+
53+ // Erased-type dispatch to the concrete ConstraintChecker expected by `air.eval`.
54+ let eval_erased = |checker : & mut ConstraintChecker < ' _ , IF , EF > | unsafe {
55+ if TypeId :: of :: < IF > ( ) == TypeId :: of :: < EF > ( ) {
56+ self . air
57+ . eval ( transmute :: < _ , & mut ConstraintChecker < ' _ , EF , EF > > ( checker) ) ;
58+ } else {
59+ assert_eq ! ( TypeId :: of:: <IF >( ) , TypeId :: of:: <PF <EF >>( ) ) ;
60+ self . air
61+ . eval ( transmute :: < _ , & mut ConstraintChecker < ' _ , PF < EF > , EF > > (
62+ checker,
63+ ) ) ;
64+ }
65+ } ;
66+
67+ // Common per-row runner.
68+ let run_row = |row : usize , slice : Vec < IF > | -> Result < ( ) , String > {
69+ let mut checker = ConstraintChecker {
70+ main : RowMajorMatrixView :: new ( & slice, width) ,
71+ constraint_index : 0 ,
72+ errors : Vec :: new ( ) ,
73+ field : PhantomData ,
74+ } ;
75+
76+ eval_erased ( & mut checker) ;
77+
78+ if !checker. errors . is_empty ( ) {
5379 return Err ( format ! (
5480 "Trace is not valid at row {}: contraints not respected: {}" ,
5581 row,
56- constraint_checker
82+ checker
5783 . errors
5884 . iter( )
5985 . map( std:: string:: ToString :: to_string)
@@ -63,69 +89,22 @@ impl<EF: ExtensionField<PF<EF>>, A: MyAir<EF>> AirTable<EF, A> {
6389 }
6490 Ok ( ( ) )
6591 } ;
92+
6693 if self . air . structured ( ) {
67- for row in 0 ..witness. n_rows ( ) - 1 {
68- let up = ( 0 ..self . n_columns ( ) )
69- . map ( |j| witness[ j] [ row] )
70- . collect :: < Vec < _ > > ( ) ;
71- let down = ( 0 ..self . n_columns ( ) )
72- . map ( |j| witness[ j] [ row + 1 ] )
73- . collect :: < Vec < _ > > ( ) ;
74- let up_and_down = [ up, down] . concat ( ) ;
75- let mut constraints_checker = ConstraintChecker :: < IF , EF > {
76- main : RowMajorMatrixView :: new ( & up_and_down, self . air . width ( ) ) ,
77- constraint_index : 0 ,
78- errors : Vec :: new ( ) ,
79- field : PhantomData ,
80- } ;
81- if TypeId :: of :: < IF > ( ) == TypeId :: of :: < EF > ( ) {
82- unsafe {
83- self . air
84- . eval ( transmute :: < _ , & mut ConstraintChecker < ' _ , EF , EF > > (
85- & mut constraints_checker,
86- ) ) ;
87- }
88- } else {
89- assert_eq ! ( TypeId :: of:: <IF >( ) , TypeId :: of:: <PF <EF >>( ) ) ;
90- unsafe {
91- self . air
92- . eval ( transmute :: < _ , & mut ConstraintChecker < ' _ , PF < EF > , EF > > (
93- & mut constraints_checker,
94- ) ) ;
95- }
96- }
97- handle_errors ( row, & mut constraints_checker) ?;
94+ // same semantics as original: panics if rows == 0 due to `rows - 1`
95+ for row in 0 ..rows - 1 {
96+ let mut up_and_down = Vec :: with_capacity ( width * 2 ) ;
97+ up_and_down. extend ( ( 0 ..width) . map ( |j| witness[ j] [ row] ) ) ;
98+ up_and_down. extend ( ( 0 ..width) . map ( |j| witness[ j] [ row + 1 ] ) ) ;
99+ run_row ( row, up_and_down) ?;
98100 }
99101 } else {
100- for row in 0 ..witness. n_rows ( ) {
101- let up = ( 0 ..self . n_columns ( ) )
102- . map ( |j| witness[ j] [ row] )
103- . collect :: < Vec < _ > > ( ) ;
104- let mut constraints_checker = ConstraintChecker {
105- main : RowMajorMatrixView :: new ( & up, self . air . width ( ) ) ,
106- constraint_index : 0 ,
107- errors : Vec :: new ( ) ,
108- field : PhantomData ,
109- } ;
110- if TypeId :: of :: < IF > ( ) == TypeId :: of :: < EF > ( ) {
111- unsafe {
112- self . air
113- . eval ( transmute :: < _ , & mut ConstraintChecker < ' _ , EF , EF > > (
114- & mut constraints_checker,
115- ) ) ;
116- }
117- } else {
118- assert_eq ! ( TypeId :: of:: <IF >( ) , TypeId :: of:: <PF <EF >>( ) ) ;
119- unsafe {
120- self . air
121- . eval ( transmute :: < _ , & mut ConstraintChecker < ' _ , PF < EF > , EF > > (
122- & mut constraints_checker,
123- ) ) ;
124- }
125- }
126- handle_errors ( row, & mut constraints_checker) ?;
102+ for row in 0 ..rows {
103+ let up = ( 0 ..width) . map ( |j| witness[ j] [ row] ) . collect ( ) ;
104+ run_row ( row, up) ?;
127105 }
128106 }
107+
129108 Ok ( ( ) )
130109 }
131110}
0 commit comments