@@ -495,6 +495,7 @@ pub fn constrain_rw_counter<F: Field>(
495495 cb : & mut BaseConstraintBuilder < F > ,
496496 meta : & mut VirtualCells < ' _ , F > ,
497497 is_last_col : Column < Advice > ,
498+ is_first : Expression < F > ,
498499 is_rw_type : Expression < F > ,
499500 is_row_end : Expression < F > ,
500501 is_memory_copy : Expression < F > ,
@@ -503,7 +504,9 @@ pub fn constrain_rw_counter<F: Field>(
503504) {
504505 // Decrement rwc_inc_left for the next row, when an RW operation happens.
505506 let rwc_diff = is_rw_type. expr ( ) * is_row_end. expr ( ) ;
506- let new_value = meta. query_advice ( rwc_inc_left, CURRENT ) - rwc_diff;
507+ let cur_rwc_inc_left = meta. query_advice ( rwc_inc_left, CURRENT ) ;
508+ let new_value = cur_rwc_inc_left. clone ( ) - rwc_diff;
509+
507510 let is_last = meta. query_advice ( is_last_col, CURRENT ) ;
508511 let is_last_two = meta. query_advice ( is_last_col, NEXT_ROW ) ;
509512
@@ -528,7 +531,7 @@ pub fn constrain_rw_counter<F: Field>(
528531 // normal case( `rwc_inc_left` decrease by 1 or 0 for consecutive read steps--> write step
529532 // --> read step -->write step ...).
530533 cb. condition (
531- is_memory_copy * not:: expr ( is_last_two) * not:: expr ( is_last. clone ( ) ) ,
534+ is_memory_copy. clone ( ) * not:: expr ( is_last_two. clone ( ) ) * not:: expr ( is_last. clone ( ) ) ,
532535 |cb| {
533536 cb. require_equal (
534537 "rwc_inc_left[2] == rwc_inc_left[0] - rwc_diff, or 0 at the end" ,
@@ -538,6 +541,23 @@ pub fn constrain_rw_counter<F: Field>(
538541 } ,
539542 ) ;
540543
544+ // the last row is write row.
545+ cb. condition ( is_memory_copy. clone ( ) * is_last. clone ( ) , |cb| {
546+ cb. require_equal (
547+ "constrain last rwc_inc_left == 1 " ,
548+ cur_rwc_inc_left,
549+ 1 . expr ( ) ,
550+ ) ;
551+ } ) ;
552+ // second(write) step's rwc_inc_left is half of the first.
553+ cb. condition ( is_memory_copy * is_first, |cb| {
554+ cb. require_equal (
555+ "rwc_inc_left[0] == 2 * rwc_inc_left[1] " ,
556+ meta. query_advice ( rwc_inc_left, CURRENT ) ,
557+ 2 . expr ( ) * meta. query_advice ( rwc_inc_left, NEXT_ROW ) ,
558+ ) ;
559+ } ) ;
560+
541561 // Maintain rw_counter based on rwc_inc_left. Their sum remains constant in all cases.
542562 cb. condition ( not:: expr ( is_last. expr ( ) ) , |cb| {
543563 cb. require_equal (
0 commit comments