@@ -25,17 +25,13 @@ pub struct ValueTarget {
2525}
2626
2727impl ValueTarget {
28- pub fn zero < F : RichField + Extendable < D > , const D : usize > (
29- builder : & mut CircuitBuilder < F , D > ,
30- ) -> Self {
28+ pub fn zero ( builder : & mut CircuitBuilder < F , D > ) -> Self {
3129 Self {
3230 elements : [ builder. zero ( ) ; VALUE_SIZE ] ,
3331 }
3432 }
3533
36- pub fn one < F : RichField + Extendable < D > , const D : usize > (
37- builder : & mut CircuitBuilder < F , D > ,
38- ) -> Self {
34+ pub fn one ( builder : & mut CircuitBuilder < F , D > ) -> Self {
3935 Self {
4036 elements : array:: from_fn ( |i| {
4137 if i == 0 {
@@ -81,27 +77,6 @@ impl StatementTarget {
8177 . collect ( ) ,
8278 }
8379 }
84- pub fn to_flattened ( & self ) -> Vec < Target > {
85- self . predicate
86- . iter ( )
87- . chain ( self . args . iter ( ) . flatten ( ) )
88- . cloned ( )
89- . collect ( )
90- }
91-
92- pub fn from_flattened ( v : Vec < Target > ) -> Self {
93- let num_args = ( v. len ( ) - Params :: predicate_size ( ) ) / STATEMENT_ARG_F_LEN ;
94- assert_eq ! (
95- v. len( ) ,
96- Params :: predicate_size( ) + num_args * STATEMENT_ARG_F_LEN
97- ) ;
98- let predicate: [ Target ; Params :: predicate_size ( ) ] = array:: from_fn ( |i| v[ i] ) ;
99- let args = ( 0 ..num_args)
100- . map ( |i| array:: from_fn ( |j| v[ Params :: predicate_size ( ) + i * STATEMENT_ARG_F_LEN + j] ) )
101- . collect ( ) ;
102-
103- Self { predicate, args }
104- }
10580
10681 pub fn set_targets (
10782 & self ,
@@ -165,8 +140,42 @@ impl OperationTarget {
165140 builder : & mut CircuitBuilder < F , D > ,
166141 t : NativeOperation ,
167142 ) -> BoolTarget {
143+ let one = builder. one ( ) ;
144+ let op_is_native = builder. is_equal ( self . op_type [ 0 ] , one) ;
168145 let op_code = builder. constant ( F :: from_canonical_u64 ( t as u64 ) ) ;
169- builder. is_equal ( self . op_type [ 1 ] , op_code)
146+ let op_code_matches = builder. is_equal ( self . op_type [ 1 ] , op_code) ;
147+ builder. and ( op_is_native, op_code_matches)
148+ }
149+ }
150+
151+ /// Trait for target structs that may be converted to and from vectors
152+ /// of targets.
153+ pub trait Flattenable {
154+ fn flatten ( & self ) -> Vec < Target > ;
155+ fn from_flattened ( vs : & [ Target ] ) -> Self ;
156+ }
157+
158+ impl Flattenable for StatementTarget {
159+ fn flatten ( & self ) -> Vec < Target > {
160+ self . predicate
161+ . iter ( )
162+ . chain ( self . args . iter ( ) . flatten ( ) )
163+ . cloned ( )
164+ . collect ( )
165+ }
166+
167+ fn from_flattened ( v : & [ Target ] ) -> Self {
168+ let num_args = ( v. len ( ) - Params :: predicate_size ( ) ) / STATEMENT_ARG_F_LEN ;
169+ assert_eq ! (
170+ v. len( ) ,
171+ Params :: predicate_size( ) + num_args * STATEMENT_ARG_F_LEN
172+ ) ;
173+ let predicate: [ Target ; Params :: predicate_size ( ) ] = array:: from_fn ( |i| v[ i] ) ;
174+ let args = ( 0 ..num_args)
175+ . map ( |i| array:: from_fn ( |j| v[ Params :: predicate_size ( ) + i * STATEMENT_ARG_F_LEN + j] ) )
176+ . collect ( ) ;
177+
178+ Self { predicate, args }
170179 }
171180}
172181
@@ -183,23 +192,24 @@ pub trait CircuitBuilderPod<F: RichField + Extendable<D>, const D: usize> {
183192
184193 // Convenience methods for checking values.
185194 /// Checks whether `xs` is right-padded with 0s so as to represent a `Value`.
186- fn is_value ( & mut self , xs : & [ Target ] ) -> BoolTarget ;
195+ fn statement_arg_is_value ( & mut self , xs : & [ Target ] ) -> BoolTarget ;
187196 /// Checks whether `x < y` if `b` is true. This involves checking
188197 /// that `x` and `y` each consist of two `u32` limbs.
189198 fn assert_less_if ( & mut self , b : BoolTarget , x : ValueTarget , y : ValueTarget ) ;
190199
191- // Convenience methods for randomly accessing vector elements and rows of matrices.
192- fn vector_ref ( & mut self , v : & [ Target ] , i : Target ) -> Target ;
193- fn matrix_row_ref ( & mut self , m : & [ Vec < Target > ] , i : Target ) -> Vec < Target > ;
200+ // Convenience methods for accessing and connecting elements of
201+ // (vectors of) flattenables.
202+ fn vec_ref < T : Flattenable > ( & mut self , ts : & [ T ] , i : Target ) -> T ;
203+ fn select_flattenable < T : Flattenable > ( & mut self , b : BoolTarget , x : & T , y : & T ) -> T ;
204+ fn connect_flattenable < T : Flattenable > ( & mut self , xs : & T , ys : & T ) ;
205+ fn is_equal_flattenable < T : Flattenable > ( & mut self , xs : & T , ys : & T ) -> BoolTarget ;
194206
195207 // Convenience methods for Boolean into-iters.
196208 fn all ( & mut self , xs : impl IntoIterator < Item = BoolTarget > ) -> BoolTarget ;
197209 fn any ( & mut self , xs : impl IntoIterator < Item = BoolTarget > ) -> BoolTarget ;
198210}
199211
200- impl < F : RichField + Extendable < D > , const D : usize > CircuitBuilderPod < F , D >
201- for CircuitBuilder < F , D >
202- {
212+ impl CircuitBuilderPod < F , D > for CircuitBuilder < F , D > {
203213 fn connect_slice ( & mut self , xs : & [ Target ] , ys : & [ Target ] ) {
204214 assert_eq ! ( xs. len( ) , ys. len( ) ) ;
205215 for ( x, y) in xs. iter ( ) . zip ( ys. iter ( ) ) {
@@ -262,7 +272,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderPod<F, D>
262272 } )
263273 }
264274
265- fn is_value ( & mut self , xs : & [ Target ] ) -> BoolTarget {
275+ fn statement_arg_is_value ( & mut self , xs : & [ Target ] ) -> BoolTarget {
266276 let zeros = iter:: repeat ( self . zero ( ) )
267277 . take ( STATEMENT_ARG_F_LEN - VALUE_SIZE )
268278 . collect :: < Vec < _ > > ( ) ;
@@ -306,24 +316,54 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderPod<F, D>
306316 assert_limb_lt ( self , lhs, rhs) ;
307317 }
308318
309- // TODO: Revisit this when we need more than 64 statements.
310- fn vector_ref ( & mut self , v : & [ Target ] , i : Target ) -> Target {
311- self . random_access ( i, v. to_vec ( ) )
319+ fn vec_ref < T : Flattenable > ( & mut self , ts : & [ T ] , i : Target ) -> T {
320+ // TODO: Revisit this when we need more than 64 statements.
321+ let vector_ref = |builder : & mut CircuitBuilder < F , D > , v : & [ Target ] , i| {
322+ assert ! ( v. len( ) <= 64 ) ;
323+ builder. random_access ( i, v. to_vec ( ) )
324+ } ;
325+ let matrix_row_ref = |builder : & mut CircuitBuilder < F , D > , m : & [ Vec < Target > ] , i| {
326+ let num_rows = m. len ( ) ;
327+ let num_columns = m
328+ . get ( 0 )
329+ . map ( |row| {
330+ let row_len = row. len ( ) ;
331+ assert ! ( m. iter( ) . all( |row| row. len( ) == row_len) ) ;
332+ row_len
333+ } )
334+ . unwrap_or ( 0 ) ;
335+ ( 0 ..num_columns)
336+ . map ( |j| {
337+ vector_ref (
338+ builder,
339+ & ( 0 ..num_rows) . map ( |i| m[ i] [ j] ) . collect :: < Vec < _ > > ( ) ,
340+ i,
341+ )
342+ } )
343+ . collect :: < Vec < _ > > ( )
344+ } ;
345+
346+ let flattened_ts = ts. iter ( ) . map ( |t| t. flatten ( ) ) . collect :: < Vec < _ > > ( ) ;
347+ T :: from_flattened ( & matrix_row_ref ( self , & flattened_ts, i) )
312348 }
313349
314- fn matrix_row_ref ( & mut self , m : & [ Vec < Target > ] , i : Target ) -> Vec < Target > {
315- let num_rows = m. len ( ) ;
316- let num_columns = m
317- . get ( 0 )
318- . map ( |row| {
319- let row_len = row. len ( ) ;
320- assert ! ( m. iter( ) . all( |row| row. len( ) == row_len) ) ;
321- row_len
322- } )
323- . unwrap_or ( 0 ) ;
324- ( 0 ..num_columns)
325- . map ( |j| self . vector_ref ( & ( 0 ..num_rows) . map ( |i| m[ i] [ j] ) . collect :: < Vec < _ > > ( ) , i) )
326- . collect ( )
350+ fn select_flattenable < T : Flattenable > ( & mut self , b : BoolTarget , x : & T , y : & T ) -> T {
351+ let flattened_x = x. flatten ( ) ;
352+ let flattened_y = y. flatten ( ) ;
353+
354+ T :: from_flattened (
355+ & iter:: zip ( flattened_x, flattened_y)
356+ . map ( |( x, y) | self . select ( b, x, y) )
357+ . collect :: < Vec < _ > > ( ) ,
358+ )
359+ }
360+
361+ fn connect_flattenable < T : Flattenable > ( & mut self , xs : & T , ys : & T ) {
362+ self . connect_slice ( & xs. flatten ( ) , & ys. flatten ( ) )
363+ }
364+
365+ fn is_equal_flattenable < T : Flattenable > ( & mut self , xs : & T , ys : & T ) -> BoolTarget {
366+ self . is_equal_slice ( & xs. flatten ( ) , & ys. flatten ( ) )
327367 }
328368
329369 fn all ( & mut self , xs : impl IntoIterator < Item = BoolTarget > ) -> BoolTarget {
0 commit comments