@@ -88,7 +88,7 @@ namespace nil {
88
88
const plonk_assignment_table<FieldType> &assignments) const {
89
89
math::expression_evaluator<VariableType> evaluator (
90
90
*this ,
91
- [&assignments, row_index](const VariableType &var) {
91
+ [&assignments, row_index](const VariableType &var) -> const typename VariableType::assignment_type& {
92
92
std::size_t rows_amount = assignments.rows_amount ();
93
93
switch (var.type ) {
94
94
case VariableType::column_type::witness:
@@ -100,8 +100,8 @@ namespace nil {
100
100
case VariableType::column_type::selector:
101
101
return assignments.selector (var.index )[(rows_amount + row_index + var.rotation ) % rows_amount];
102
102
default :
103
- BOOST_ASSERT_MSG ( false , " Invalid column type" ) ;
104
- return VariableType::assignment_type::zero ();
103
+ std::cerr << " Invalid column type" << std::endl ;
104
+ abort ();
105
105
}
106
106
});
107
107
@@ -110,38 +110,33 @@ namespace nil {
110
110
111
111
math::polynomial<typename VariableType::assignment_type>
112
112
evaluate (const plonk_polynomial_table<FieldType> &assignments,
113
- std::shared_ptr<math::evaluation_domain<FieldType>>
114
- domain) const {
115
- using polynomial_type = math::polynomial< typename VariableType::assignment_type >;
116
- using polynomial_variable_type = plonk_variable<polynomial_type>;
117
- math::expression_variable_type_converter<VariableType, polynomial_variable_type> converter;
118
-
119
- math::expression_evaluator<polynomial_variable_type> evaluator (
120
- converter. convert (* this ),
121
- [&domain, &assignments]( const VariableType &var) {
122
- polynomial_type assignment ;
123
- switch (var. type ) {
124
- case VariableType::column_type::witness:
125
- assignment = assignments. witness ( var. index );
126
- break ;
127
- case VariableType::column_type::public_input:
128
- assignment = assignments.public_input (var. index );
129
- break ;
130
- case VariableType::column_type::constant:
131
- assignment = assignments. constant (var. index );
132
- break ;
133
- case VariableType::column_type::selector:
134
- assignment = assignments. selector (var. index );
135
- break ;
136
- default :
137
- BOOST_ASSERT_MSG ( false , " Invalid column type " );
113
+ std::shared_ptr<math::evaluation_domain<FieldType>> domain) const {
114
+ using polynomial_type = math::polynomial< typename VariableType::assignment_type>;
115
+ using polynomial_variable_type = plonk_variable<polynomial_type >;
116
+
117
+ // Convert scalar values to polynomials inside the expression.
118
+ math::expression_variable_type_converter<VariableType, polynomial_variable_type> converter;
119
+ auto converted_expression = converter. convert (* this );
120
+
121
+ // For each variable with a rotation pre-compute its value.
122
+ std::unordered_map<polynomial_variable_type, polynomial_type> rotated_variable_values ;
123
+
124
+ math::expression_for_each_variable_visitor<polynomial_variable_type> visitor (
125
+ [&rotated_variable_values, &assignments, &domain]( const polynomial_variable_type& var) {
126
+ if (var. rotation == 0 )
127
+ return ;
128
+ rotated_variable_values[var] = assignments.get_variable_value (var, domain );
129
+ }) ;
130
+ visitor. visit (converted_expression);
131
+
132
+ math::expression_evaluator<polynomial_variable_type> evaluator (
133
+ converted_expression,
134
+ [&domain, & assignments, &rotated_variable_values]
135
+ ( const VariableType &var) -> const polynomial_type& {
136
+ if (var. rotation == 0 ) {
137
+ return assignments. get_variable_value_without_rotation (var, domain );
138
138
}
139
-
140
- if (var.rotation != 0 ) {
141
- assignment =
142
- math::polynomial_shift (assignment, domain->get_domain_element (var.rotation ));
143
- }
144
- return assignment;
139
+ return rotated_variable_values[var];
145
140
});
146
141
return evaluator.evaluate ();
147
142
}
@@ -152,46 +147,43 @@ namespace nil {
152
147
using polynomial_dfs_type = math::polynomial_dfs<typename VariableType::assignment_type>;
153
148
using polynomial_dfs_variable_type = plonk_variable<polynomial_dfs_type>;
154
149
150
+ // Convert scalar values to polynomials inside the expression.
155
151
math::expression_variable_type_converter<variable_type, polynomial_dfs_variable_type> converter (
156
152
[&assignments](const typename VariableType::assignment_type& coeff) {
157
153
polynomial_dfs_type (0 , assignments.rows_amount (), coeff);
158
154
});
159
- math::expression_evaluator<polynomial_dfs_variable_type> evaluator (
160
- converter.convert (*this ),
161
- [&domain, &assignments](const polynomial_dfs_variable_type &var) {
162
- polynomial_dfs_type assignment;
163
- switch (var.type ) {
164
- case VariableType::column_type::witness:
165
- assignment = assignments.witness (var.index );
166
- break ;
167
- case VariableType::column_type::public_input:
168
- assignment = assignments.public_input (var.index );
169
- break ;
170
- case VariableType::column_type::constant:
171
- assignment = assignments.constant (var.index );
172
- break ;
173
- case VariableType::column_type::selector:
174
- assignment = assignments.selector (var.index );
175
- break ;
176
- default :
177
- BOOST_ASSERT_MSG (false , " Invalid column type" );
178
- }
179
155
180
- if (var.rotation != 0 ) {
181
- assignment = math::polynomial_shift (assignment, var.rotation , domain->m );
156
+ auto converted_expression = converter.convert (*this );
157
+
158
+ // For each variable with a rotation pre-compute its value.
159
+ std::unordered_map<polynomial_dfs_variable_type, polynomial_dfs_type> rotated_variable_values;
160
+
161
+ math::expression_for_each_variable_visitor<polynomial_dfs_variable_type> visitor (
162
+ [&rotated_variable_values, &assignments, &domain](const polynomial_dfs_variable_type& var) {
163
+ if (var.rotation == 0 )
164
+ return ;
165
+ rotated_variable_values[var] = assignments.get_variable_value (var, domain);
166
+ });
167
+ visitor.visit (converted_expression);
168
+
169
+ math::expression_evaluator<polynomial_dfs_variable_type> evaluator (
170
+ converted_expression,
171
+ [&domain, &assignments, &rotated_variable_values]
172
+ (const polynomial_dfs_variable_type &var) -> const polynomial_dfs_type& {
173
+ if (var.rotation == 0 ) {
174
+ return assignments.get_variable_value_without_rotation (var, domain);
182
175
}
183
- return assignment ;
176
+ return rotated_variable_values[var] ;
184
177
}
185
178
);
186
179
187
180
return evaluator.evaluate ();
188
181
}
189
182
190
- typename VariableType::assignment_type
191
- evaluate (detail::plonk_evaluation_map<VariableType> &assignments) const {
183
+ typename VariableType::assignment_type evaluate (detail::plonk_evaluation_map<VariableType> &assignments) const {
192
184
math::expression_evaluator<VariableType> evaluator (
193
185
*this ,
194
- [&assignments](const VariableType &var) {
186
+ [&assignments](const VariableType &var) -> const typename VariableType::assignment_type& {
195
187
std::tuple<std::size_t , int , typename VariableType::column_type> key =
196
188
std::make_tuple (var.index , var.rotation , var.type );
197
189
0 commit comments