`poly::Evaluator` stores all of the polynomials registered with it in
memory for the duration of its existence. When evaluating an AST, it
additionally caches the rotated polynomials in memory, and then chunks
all of the rotated polynomials for parallel evaluation.
Previously, it stored a polynomial for every unique AST leaf, regardless
of whether that leaf required a rotation or not. This resulted in the
unrotated polynomials being stored twice in memory. However, the chunks
simply refer to slices over cached polynomials, so we can reference the
unrotated polynomials stored in `poly::Evaluator` instead of copies of
them stored in the rotated polynomial `HashMap`. This strictly reduces
memory usage during proving with no effect on correctness.
`BatchVerifier` now manages the entire batch verification process.
Individual proofs are verified on a threadpool, and the resulting MSMs
are then batch-checked as before. The addition of parallelism here
couples with zcash/halo2#608 to make parallelism less fine-grained and
reduce the overhead of multi-threading.
We also set `resolver = "2"` on the workspace; this is the default for
the root package in Rust 2021, but as we use a virtual workspace we need
to explicitly set it instead.
There are two existing patterns for constructing a gate from a set of
constraints with a common selector:
- Create an iterator of constraints, where each constraint includes the
selector:
```
vec![
("foo", selector.clone() * foo),
("bar", selector.clone() * bar),
("baz", selector * bar),
]
```
This requires the user to write O(n) `selector.clone()` calls.
- Create an iterator of constraints, and then map the selector in:
```
vec![
("foo", foo),
("bar", bar),
("baz", bar),
].into_iter().map(move |(name, poly)| (name, selector.clone() * poly))
```
This looks cleaner overall, but the API is not as intuitive, and it
is messier when the constraints are named.
The `Constraints` struct provides a third, clearer API:
```
Constraints::with_selector(
selector,
vec![
("foo", foo),
("bar", bar),
("baz", bar),
],
)
```
This focuses on the structure of the constraints, and handles the
selector application for the user.