Sitelet https://github.com/PECOS-packages/PECOS/pull/1028
Skip to content

Validate Heisenberg programs at construction and index outcomes by symbol - #1028

Merged
ciaranra merged 3 commits into
devfrom
stab-active-symbol-outcomes
Oct 6, 2026
Merged

ciaranra merged 3 commits into
devfrom
stab-active-symbol-outcomes

Conversation

@ciaranra

@ciaranra ciaranra commented Oct 4, 2026

Copy link
Copy Markdown
Member

Summary

This prepares HeisenbergProgram (from #954) for reordering passes. It does not reorder anything itself.

A rewrite pass needs to change the order of operations without changing what the program computes. Two things in the phase-1 executor depended on operations staying in compiled order:

  • Sign evaluation: measurement outcomes were appended in execution order, but AffineSign::evaluate reads them by measurement symbol. Once a measurement moves, later signs read the wrong outcome. Example: in X q0; PZ q0; MZ q1; MZ q0, moving MZ q1 ahead of the hidden reset measurement is legal. The final MZ q0 then returned 1 instead of 0.
  • Records: visible records were also appended in execution order instead of by record ordinal.

Changes

  • Validity is checked once, when a program is built.
    • HeisenbergProgram::with_operations(self, operations) -> Result<Self, ProgramError> is the only way to obtain a program. compile goes through it, and future rewrite passes will too.
    • It checks causality: no operation's sign reads a measurement symbol before the measurement that produces it.
    • It checks that every measurement symbol and record ordinal is produced exactly once.
    • It checks that every index the program holds is in range: noise symbols, channel symbol spans, detector and observable ordinals, and Pauli factor qubits.
    • It checks that noise tables are well formed: each channel is nonempty, each probability is finite and nonnegative, the total is finite and positive, and each alternative has two bits per qubit.
    • Each failure has its own ProgramError variant, naming the operation, channel or index involved. compile panics if its own output fails the check, since that can only be a builder bug.
  • execute trusts a valid program. It stores outcomes at measurements[symbol] and records at records[ordinal] in plain Vec<bool>s, and does no per-shot checks.
  • AffineSign::evaluate keeps its signature. Its slice is documented as indexed by symbol, which equals execution position in compiled order.
  • Docs: the type and README docs now describe programs that may come from a rewrite, not only from compile.

Results for compiled programs are unchanged. An independent comparison against the previous executor gave identical ShotResults, including peak width, on 8,000 shots over random circuits with resets, rotations and noise.

Test plan

  • New joint-distribution oracle (test-only). It enumerates measurement branches through the production executor's forcing hook. It keys outcomes by symbol and records by ordinal, including hidden reset symbols, and can also sum over every noise-channel alternative. It is checked against analytic distributions: sin^2(theta/2) readouts and a correlated two-qubit Pauli channel with hand-computed weights.
  • Reordering tests:
    • the hidden-reset swap above;
    • records staying in ordinal order;
    • a correlated swap that also shows why per-step conditional probabilities cannot judge a reordered program;
    • every topological order of two small programs whose only ordering constraint comes from a reset outcome;
    • 360 random legal orders over 60 random circuits, all equal in distribution to compiled order (334 reorder measurements).
  • Exact ProgramError assertions for every validation rule, distinct messages for every variant, and a check that compile output validates across 240 random circuits.
  • Mutation checks: each validation rule, symbol- and ordinal-indexed storage, and the reorder dependency edges each make a test fail when removed. The one survivor is removing the check from compile, which no test can expose while the builder is correct; the random-circuit validity test is the guard there.
  • cargo test -p pecos-stab-active debug and release (64 passed); cargo clippy -p pecos-stab-active --all-targets --all-features -- -D warnings; cargo fmt --check; just lint

@ciaranra
ciaranra merged commit 623ea16 into dev Oct 6, 2026
20 checks passed
@ciaranra
ciaranra deleted the stab-active-symbol-outcomes branch October 6, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant