11use core:: borrow:: Borrow ;
2- use p3_air:: { Air , AirBuilder , BaseAir } ;
2+ use p3_air:: { Air , AirBuilder , AirBuilderWithPublicValues , BaseAir } ;
33use p3_field:: FieldAlgebra ;
44use p3_matrix:: Matrix ;
55
6- use bf_stark:: air:: { BaseAirBuilder , BfAirBuilder } ;
6+ use bf_stark:: {
7+ air:: { BaseAirBuilder , BfAirBuilder } ,
8+ PublicValues , PROOF_NUM_PV_ELTS ,
9+ } ;
710
811use crate :: {
912 air:: { BfCoreAirBuilder , MemoryAirBuilder , U8AirBuilder } ,
@@ -21,7 +24,7 @@ impl<F> BaseAir<F> for CpuChip {
2124
2225impl < AB > Air < AB > for CpuChip
2326where
24- AB : BfCoreAirBuilder ,
27+ AB : BfCoreAirBuilder + AirBuilderWithPublicValues ,
2528 AB :: Var : Sized ,
2629{
2730 #[ inline( never) ]
3134 let local: & CpuCols < AB :: Var > = ( * local) . borrow ( ) ;
3235 let next: & CpuCols < AB :: Var > = ( * next) . borrow ( ) ;
3336
37+ let public_values_slice: [ AB :: PublicVar ; PROOF_NUM_PV_ELTS ] =
38+ core:: array:: from_fn ( |i| builder. public_values ( ) [ i] ) ;
39+ let public_values: & PublicValues < AB :: PublicVar > = public_values_slice. as_slice ( ) . borrow ( ) ;
40+
3441 let clk =
3542 AB :: Expr :: from_canonical_u32 ( 1u32 << 16 ) * local. clk_8bit_limb + local. clk_16bit_limb ;
3643
4754 self . eval_clk ( builder, local, next, clk. clone ( ) ) ;
4855
4956 // Check that the pc is updated correctly.
50- self . eval_pc ( builder, local, next) ;
57+ self . eval_pc ( builder, local, next, public_values ) ;
5158
5259 // Check that the is_real flag is correct.
5360 self . eval_is_real ( builder, local, next) ;
@@ -128,6 +135,7 @@ impl CpuChip {
128135 builder : & mut AB ,
129136 local : & CpuCols < AB :: Var > ,
130137 next : & CpuCols < AB :: Var > ,
138+ public_values : & PublicValues < AB :: PublicVar > ,
131139 ) {
132140 builder. when_transition ( ) . when ( next. is_real ) . assert_eq ( local. next_pc , next. pc ) ;
133141
@@ -136,6 +144,19 @@ impl CpuChip {
136144 . when ( local. is_real )
137145 . when_not ( local. is_jump )
138146 . assert_eq ( local. next_pc , local. pc + AB :: Expr :: from_canonical_u32 ( 1 ) ) ;
147+
148+ // Verify the public value's next pc. We need to handle two cases:
149+ // 1. The last real row is a transition row.
150+ // 2. The last real row is the last row.
151+
152+ // If the last real row is a transition row, verify the public value's next pc.
153+ builder
154+ . when_transition ( )
155+ . when ( local. is_real - next. is_real )
156+ . assert_eq ( public_values. next_pc , local. next_pc ) ;
157+
158+ // If the last real row is the last row, verify the public value's next pc.
159+ builder. when_last_row ( ) . when ( local. is_real ) . assert_eq ( public_values. next_pc , local. next_pc ) ;
139160 }
140161
141162 /// Constraints related to the is_real column.
0 commit comments