Fixes#844
This PR adds a new machine to the STD: `WriteOnceMemory`. This can be
used in our RISC-V machine for bootloader inputs (#1203).
Most of the issues mentioned in the issue were fixed in the meantime or
had a simple workaround (like defining `let LATCH = 1`). The only
remaining issues were in the machine detection, which I fixed here.
I also re-factor two existing tests.
With this PR, we remember the mapping from Lookup / Permutation Identity
to Machine. This is cleaner, lets us save some work when calling a
machine and allows us to fail earlier if no machine can answer the call
(at machine extraction time, rather than runtime.
Changes:
- `Machine::process_plookup()`: Instead of passing in `right` and
`kind`, machines now only receive an `IdentityId`. If the machine needs
to access any of the expressions, references to it have to be stored
with the machine.
- `Machine::identities()`: New function that lets us ask the machine for
which identities it feels respondible.
- The `Machines` struct now stores the mapping from `IdentityId` to
machine index, allowing us to replace the loop of trying all machines
with a simple call to `Machines::call()`.
- The identity kind is now also stored in `Identity::id`. Previously,
this only stored a `usize` which is not necessarily unique. As mentioned
above, this change could be merged as part of a separate PR.
#### Benchmark Results:
```
executor-benchmark/keccak
time: [8.7242 s 8.9755 s 9.3876 s]
change: [-4.7814% +0.8652% +7.4252%] (p = 0.79 > 0.05)
No change in performance detected.
executor-benchmark/many_chunks_chunk_0
time: [38.731 s 39.313 s 40.081 s]
change: [-5.6906% -3.9986% -1.8421%] (p = 0.00 < 0.05)
Performance has improved.
```
This PR changes that `Identity` IDs are now globally unique, by doing to
things:
1. When dispensing IDs, we now have only one ID counter, instead of one
per type.
2. Fixed a bug in the condenser, where it would previously assign the
same ID when evaluating a `|| -> constr[]`.
- change AffineExpression to an enum of Constant|OneVar|ManyVars
- remove "cleaning" logic and keep coefficients ordered and clean
- rewrite of ExpressionEvaluator::evaluate_binary_operation to shortcut on Err when possible