Enforce Gate angle arity at construction and DAG mutation - #701
Conversation
4bff01b to
da077f0
Compare
|
Rebased onto current That mattered: an earlier PR in this same convention arc (#681) looked ready at 77 green checks and turned out to have twelve stale pinned constants, because its ticks predated a convention change. Re-verifying rather than trusting the existing green. Merged cleanly, no conflicts. Verified on the new base:
No interaction with the new phase-exactness conformance tests or the pinned correctness harness. |
Root cause of the Idle findingsThe two Idle-related review findings (duration snapping to zero, and every idle-noise circuit misclassifying as non-Clifford) both trace to a single change in this PR, at pub fn angle_arity(self) -> usize {
- pecos_core::gate_type::GateType::from(self).angle_arity()
+ if self == Self::Idle {
+ 1
+ } else {
+ pecos_core::gate_type::GateType::from(self).angle_arity()
+ }
}
The divergence is in The Consequence for sequencingThe special case cannot simply be deleted here. Removing it makes Idle arity 0, which then fails validation for a Proposed order:
That removes both findings at the source rather than handling Idle specially in each angle consumer, and keeps each PR to one idea. Note that |
…ebase # Conflicts: # exp/pecos-neo/src/adapter.rs # exp/pecos-neo/src/circuit.rs # exp/pecos-neo/src/command.rs # exp/pecos-neo/src/engines.rs # exp/pecos-neo/src/extensible/queue_validation.rs # exp/pecos-neo/src/lib.rs # exp/pecos-neo/src/runner.rs # python/pecos-rslib-exp/src/sim_neo_bindings.rs
Native gates with missing or surplus angles can otherwise reach consumers that discard data or panic.
Gateconstructors check native angle arity, and DAG insertion and transactional mutation validate their payloads before storing them. Rejected DAG updates preserve the original gate and its wiring and measurement identities.Scope:
Gate::gate_typeandGate::anglesremain public. Struct literals and mutation of owned gates can still create malformed values. This is enforcement at constructors and circuit boundaries, not a type invariant that makes invalid states unrepresentable. Encapsulating both fields and providing atomic replacement is separate work.An adversarial review of this PR produced twelve findings, four of them high severity, including panics on input that
devaccepted. All twelve are addressed here:CommandQueue::push, builders andFromIteratorinfallible. Reuse command validation at fallible execution and conversion boundaries. Add fallible shot methods to the program runner, quantum-engine adapter and importance runner; existing convenience methods delegate to them.Unitary::Namedwith a checked payload whose gate-type field is private.Unitary::try_namedandUnitaryRep::try_gateshare the fixed-unitary and angle checks. Direct invalid construction and payload mutation are compile errors.TODO(dynamic-angles)documentation.gate_mutand Rustsim_neo(circuit)documentation and restorecommand_queue_to_gates's must-use annotation. Rust Tick/DAG inputs require explicit fallible conversion to a command queue.Verification (using
eval "$(uv run --frozen pecos env)"):pecos-core,pecos-quantum,pecos-simulators,pecos-engines,pecos-qasm,pecos-qec): release 5,520 passed / 9 ignored; debug 5,524 passed / 9 ignored. The difference is four existing debug-only simulator contract tests.cargo test -p pecos-neo --release: 1,374 passed, none ignored.cargo clippy --workspace --all-targets --all-features -- -D warnings: passed.cargo fmt --all -- --check: passed.The execution regressions demonstrate infallible duplicate-CX queue construction followed by a structured execution/conversion error; lossless integer Idle storage with explicit rejection of inexact core conversion; Idle duration preservation under every snapping policy; duration-independent Clifford classification; and checked/compile-time rejection of invalid Named payloads.