@@ -6,16 +6,13 @@ use std::{
6
6
use itertools:: Itertools ;
7
7
use powdr_ast:: {
8
8
analyzed:: {
9
- AlgebraicExpression as Expression , AlgebraicReferenceThin , PolynomialIdentity ,
10
- PolynomialType ,
9
+ AlgebraicExpression as Expression , AlgebraicReference , PolynomialIdentity , PolynomialType ,
11
10
} ,
12
11
parsed:: visitor:: { AllChildren , Children } ,
13
12
} ;
14
13
use powdr_number:: FieldElement ;
15
14
16
- use crate :: witgen:: {
17
- data_structures:: identity:: Identity , jit:: variable:: MachineCallVariable , FixedData ,
18
- } ;
15
+ use crate :: witgen:: { data_structures:: identity:: Identity , jit:: variable:: MachineCallVariable } ;
19
16
20
17
use super :: { prover_function_heuristics:: ProverFunction , variable:: Variable } ;
21
18
@@ -29,12 +26,9 @@ pub struct IdentityQueue<'a, T: FieldElement> {
29
26
}
30
27
31
28
impl < ' a , T : FieldElement > IdentityQueue < ' a , T > {
32
- pub fn new (
33
- fixed_data : & ' a FixedData < ' a , T > ,
34
- items : impl IntoIterator < Item = QueueItem < ' a , T > > ,
35
- ) -> Self {
29
+ pub fn new ( items : impl IntoIterator < Item = QueueItem < ' a , T > > ) -> Self {
36
30
let queue: BTreeSet < _ > = items. into_iter ( ) . collect ( ) ;
37
- let mut references = ReferencesComputer :: new ( fixed_data ) ;
31
+ let mut references = ReferencesComputer :: default ( ) ;
38
32
let occurrences = Rc :: new (
39
33
queue
40
34
. iter ( )
@@ -154,33 +148,24 @@ pub struct ConstantAssignment<'a, T: FieldElement> {
154
148
}
155
149
156
150
/// Utility to compute the variables that occur in a queue item.
157
- /// Follows intermediate column references and employs caches.
158
- struct ReferencesComputer < ' a , T : FieldElement > {
159
- fixed_data : & ' a FixedData < ' a , T > ,
160
- intermediate_cache : HashMap < AlgebraicReferenceThin , Vec < AlgebraicReferenceThin > > ,
151
+ #[ derive( Default ) ]
152
+ struct ReferencesComputer < ' a > {
161
153
/// A cache to store algebraic references in a polynomial identity, so that it
162
154
/// can be re-used on all rows.
163
- references_per_identity : HashMap < u64 , Vec < AlgebraicReferenceThin > > ,
155
+ references_per_identity : HashMap < u64 , Vec < & ' a AlgebraicReference > > ,
164
156
}
165
157
166
- impl < ' a , T : FieldElement > ReferencesComputer < ' a , T > {
167
- pub fn new ( fixed_data : & ' a FixedData < ' a , T > ) -> Self {
168
- Self {
169
- fixed_data,
170
- intermediate_cache : HashMap :: new ( ) ,
171
- references_per_identity : HashMap :: new ( ) ,
172
- }
173
- }
174
- pub fn references ( & mut self , item : & QueueItem < ' a , T > ) -> Vec < Variable > {
158
+ impl < ' a > ReferencesComputer < ' a > {
159
+ pub fn references < T : FieldElement > ( & mut self , item : & QueueItem < ' a , T > ) -> Vec < Variable > {
175
160
let vars: Box < dyn Iterator < Item = _ > > = match item {
176
161
QueueItem :: Identity ( id, row) => match id {
177
162
Identity :: Polynomial ( poly_id) => Box :: new (
178
163
self . references_in_polynomial_identity ( poly_id)
179
164
. into_iter ( )
180
- . map ( |r| self . reference_to_variable ( & r, * row) ) ,
165
+ . map ( |r| Variable :: from_reference ( r, * row) ) ,
181
166
) ,
182
167
Identity :: BusSend ( bus_send) => Box :: new (
183
- self . variables_in_expression ( & bus_send. selected_payload . selector , * row)
168
+ variables_in_expression ( & bus_send. selected_payload . selector , * row)
184
169
. into_iter ( )
185
170
. chain (
186
171
( 0 ..bus_send. selected_payload . expressions . len ( ) ) . map ( |index| {
@@ -194,18 +179,16 @@ impl<'a, T: FieldElement> ReferencesComputer<'a, T> {
194
179
) ,
195
180
Identity :: Connect ( ..) => Box :: new ( std:: iter:: empty ( ) ) ,
196
181
} ,
197
- QueueItem :: ConstantAssignment ( a) => Box :: new (
198
- self . variables_in_expression ( a. lhs , a. row_offset )
199
- . into_iter ( ) ,
200
- ) ,
182
+ QueueItem :: ConstantAssignment ( a) => {
183
+ Box :: new ( variables_in_expression ( a. lhs , a. row_offset ) . into_iter ( ) )
184
+ }
201
185
QueueItem :: VariableAssignment ( a) => Box :: new (
202
- std:: iter:: once ( a. rhs . clone ( ) )
203
- . chain ( self . variables_in_expression ( a. lhs , a. row_offset ) ) ,
186
+ std:: iter:: once ( a. rhs . clone ( ) ) . chain ( variables_in_expression ( a. lhs , a. row_offset ) ) ,
204
187
) ,
205
188
QueueItem :: ProverFunction ( p, row) => Box :: new (
206
189
p. condition
207
190
. iter ( )
208
- . flat_map ( |c| self . variables_in_expression ( c, * row) )
191
+ . flat_map ( |c| variables_in_expression ( c, * row) )
209
192
. chain (
210
193
p. input_columns
211
194
. iter ( )
@@ -216,79 +199,54 @@ impl<'a, T: FieldElement> ReferencesComputer<'a, T> {
216
199
vars. unique ( ) . collect_vec ( )
217
200
}
218
201
219
- fn variables_in_expression ( & mut self , expression : & Expression < T > , row : i32 ) -> Vec < Variable > {
220
- self . references_in_expression ( expression)
221
- . iter ( )
222
- . map ( |r| {
223
- let name = self . fixed_data . column_name ( & r. poly_id ) . to_string ( ) ;
224
- Variable :: from_reference ( & r. with_name ( name) , row)
225
- } )
226
- . collect ( )
227
- }
228
-
229
- /// Turns AlgebraicReferenceThin to Variable, by including the row offset.
230
- fn reference_to_variable ( & self , reference : & AlgebraicReferenceThin , row : i32 ) -> Variable {
231
- let name = self . fixed_data . column_name ( & reference. poly_id ) . to_string ( ) ;
232
- Variable :: from_reference ( & reference. with_name ( name) , row)
233
- }
234
-
235
- fn references_in_polynomial_identity (
202
+ fn references_in_polynomial_identity < T : FieldElement > (
236
203
& mut self ,
237
- identity : & PolynomialIdentity < T > ,
238
- ) -> Vec < AlgebraicReferenceThin > {
204
+ identity : & ' a PolynomialIdentity < T > ,
205
+ ) -> Vec < & ' a AlgebraicReference > {
239
206
// Clippy suggests to use `entry()...or_insert_with()`,
240
207
// but the code does not work, since we need `&mut self` in
241
208
// self.references_in_expression.
242
209
#[ allow( clippy:: map_entry) ]
243
210
if !self . references_per_identity . contains_key ( & identity. id ) {
244
211
let mut result = BTreeSet :: new ( ) ;
245
212
for e in identity. children ( ) {
246
- result. extend ( self . references_in_expression ( e) ) ;
213
+ result. extend ( references_in_expression ( e) ) ;
247
214
}
248
215
self . references_per_identity
249
216
. insert ( identity. id , result. into_iter ( ) . collect_vec ( ) ) ;
250
217
}
251
218
self . references_per_identity [ & identity. id ] . clone ( )
252
219
}
220
+ }
253
221
254
- /// Returns all references to witness column in the expression, including indirect
255
- /// references through intermediate columns.
256
- fn references_in_expression (
257
- & mut self ,
258
- expression : & Expression < T > ,
259
- ) -> Vec < AlgebraicReferenceThin > {
260
- let mut references = BTreeSet :: new ( ) ;
261
- for e in expression. all_children ( ) {
262
- match e {
263
- Expression :: Reference ( r ) => match r . poly_id . ptype {
264
- PolynomialType :: Constant => { }
265
- PolynomialType :: Committed = > {
266
- references . insert ( r . into ( ) ) ;
267
- }
268
- PolynomialType :: Intermediate => references
269
- . extend ( self . references_in_intermediate ( & r . into ( ) ) . iter ( ) . cloned ( ) ) ,
270
- } ,
271
- Expression :: PublicReference ( _ ) | Expression :: Challenge ( _ ) => {
272
- // TODO we need to introduce a variable type for those.
222
+ fn variables_in_expression < T : FieldElement > ( expression : & Expression < T > , row : i32 ) -> Vec < Variable > {
223
+ references_in_expression ( expression )
224
+ . iter ( )
225
+ . map ( |r| Variable :: from_reference ( r , row ) )
226
+ . collect ( )
227
+ }
228
+
229
+ /// Returns all references to witness column in the expression, including indirect
230
+ /// references through intermediate columns.
231
+ fn references_in_expression < T : FieldElement > (
232
+ expression : & Expression < T > ,
233
+ ) -> Vec < & AlgebraicReference > {
234
+ let mut references = BTreeSet :: new ( ) ;
235
+ for e in expression . all_children ( ) {
236
+ match e {
237
+ Expression :: Reference ( r ) => match r . poly_id . ptype {
238
+ PolynomialType :: Constant => { }
239
+ PolynomialType :: Committed | PolynomialType :: Intermediate => {
240
+ references . insert ( r ) ;
273
241
}
274
- Expression :: Number ( _ )
275
- | Expression :: BinaryOperation ( .. )
276
- | Expression :: UnaryOperation ( .. ) => { }
242
+ } ,
243
+ Expression :: PublicReference ( _ ) | Expression :: Challenge ( _ ) => {
244
+ // TODO we need to introduce a variable type for those.
277
245
}
246
+ Expression :: Number ( _)
247
+ | Expression :: BinaryOperation ( ..)
248
+ | Expression :: UnaryOperation ( ..) => { }
278
249
}
279
- references. into_iter ( ) . collect ( )
280
- }
281
-
282
- fn references_in_intermediate (
283
- & mut self ,
284
- intermediate : & AlgebraicReferenceThin ,
285
- ) -> & Vec < AlgebraicReferenceThin > {
286
- if !self . intermediate_cache . contains_key ( intermediate) {
287
- let definition = & self . fixed_data . intermediate_definitions [ intermediate] ;
288
- let references = self . references_in_expression ( definition) ;
289
- self . intermediate_cache
290
- . insert ( intermediate. clone ( ) , references. clone ( ) ) ;
291
- }
292
- & self . intermediate_cache [ intermediate]
293
250
}
251
+ references. into_iter ( ) . collect ( )
294
252
}
0 commit comments