- Python: qudit, qudit_check, wasmq (an envelope's bytes, a path or an example's name), wasmq_verify (with the envelope, run again byte for byte) and wasmq_examples, the extension module running an envelope on wai-wasmq's own interpreter (no compiler in the wheel); Service.wasmq and Service.qudit run them on a service. Tests: both kinds run and verified here, a qudit run equal to `wai-quantum qudit run`'s bits and a wasmQ/1 job equal to `wai-quantum run`'s byte for byte, and both run on a service built from this checkout. - npm (wai-web, quantum_engine): QuantumEngine.qudit and QuantumEngine.wasmq (the interpreter, the only engine on wasm32), engine_qudit_check, engine_wasmq_verify, engine_wasmq_examples and engine_wasmq_example. The smoke test runs every example in Node, each sealed, held to its form and run again, a fault sealed and W013 refused. - Quantum Studio: the "Qudits" and "wasmQ" panes (closed until opened), in the browser and in the desktop app (its qudit, qudit_check, wasmq, wasmq_verify and wasmq_examples commands): the qudit counts by digits, amplitudes as integers, bounds, the seal checked and the request run again; an example envelope or a .wai file opened there, its outcome, calls, fuel, counts and energy, its seal and form checked and the envelope run again; a refusal with its code. The browser e2e drives each. - quantum-wasmq §11.9 and quantum-sim §9.10 name every surface. Tested on the build hosts: wai-web for wasm32-unknown-unknown and the npm smoke test in Node 26 (macOS arm64); the Python package's wheel (maturin 1.15.0), clippy -D warnings and pytest (95 passed, the widgets' node test skipped there) on Linux x86_64; the Studio's browser e2e (macOS arm64, STUDIO_SKIP_SERVICE=1), every qudit and wasmQ check passing. Co-Authored-By: Claude Opus 5.5 <[email protected]>
1068 lines
55 KiB
Markdown
1068 lines
55 KiB
Markdown
# WAI Extension: Quantum-Circuit Simulation
|
||
|
||
> Status: Draft. A quantum computation shipped as **instructions**, not
|
||
> outcomes: the wire carries a compact gate op-log (a `WQC` container),
|
||
> the sink **classically simulates** it in a fixed-point complex floor,
|
||
> and the reconstructed statevector hashes identically on every machine.
|
||
> Conformance is **statevector-equivalence** (and, for measured circuits,
|
||
> **shot-histogram-equivalence**). Two capabilities share the container
|
||
> layout, the gate IR and the arithmetic: `wai.quantum.circuit2` (magic
|
||
> `WQC2`), for new content, and `wai.quantum.circuit` (magic `WQC1`), frozen
|
||
> so that existing content reproduces bit for bit. Reference impl: the
|
||
> `quantum` feature of `wai-quantum` (`wai_quantum::quantum`), which `wai-rs`
|
||
> forwards and re-exports as `wai::quantum`; corpus: `quantum-conformance/`.
|
||
Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
|
||
|
||
## 1. Scope and model
|
||
|
||
A quantum-circuit object is a **quantum circuit**: a qubit count and an ordered
|
||
list of gates. The sink reconstructs the resulting quantum state by simulating
|
||
the circuit from `|0…0⟩` in a fixed-point complex floor — every amplitude is a
|
||
complex fixed-point number (`re, im` as `i64` at scale `2^FRAC`), every gate an
|
||
integer matrix–vector update with a pinned rounding rule. It is lever 3
|
||
(instructions-at-the-sink) applied to computation: the wire carries the
|
||
*circuit*, the sink reconstructs the *state*.
|
||
|
||
Two capabilities carry such an object. They differ only in the magic, the
|
||
contract (§2.1), the phase table the gates read (§3.1, §3.2) and how strictly a
|
||
reader holds the container (§2):
|
||
|
||
| capability | magic | contract `ext` | phase table | for |
|
||
|---|---|---|---|---|
|
||
| `wai.quantum.circuit2` | `WQC2` | `wai.quantum.circuit2/1` | correctly rounded (§3.2) | new content |
|
||
| `wai.quantum.circuit` | `WQC1` | `wai.quantum.circuit/1` | frozen (§3.1) | existing content, which reproduces bit for bit |
|
||
|
||
Below, **circuit2** and **circuit/1** name the two. Writers SHOULD NOT emit new
|
||
circuit/1 content: its phase table deviates from the ideal phases for `k ≥ 8` and
|
||
applies none for `k ≥ 19` (§3.1). A sink that reconstructs circuit/1 content
|
||
reads it exactly as this text states, so that the content keeps its hashes and
|
||
its receipts keep verifying. §8 says why the correction is a capability of its
|
||
own.
|
||
|
||
The design rule that governs the whole extension: **WAI's value is
|
||
determinism** — byte-identical reconstruction, "conformance is a hash." Real
|
||
quantum **hardware** is the enemy of that: NISQ noise and stochastic
|
||
measurement are not reproducible across devices. So this extension does
|
||
**not** use, require, or emulate a QPU, and delivers **no** quantum speedup.
|
||
It makes a quantum *computation* a transportable, deterministic, receiptable
|
||
object — nothing more, and it says so plainly.
|
||
|
||
In scope: the container, the gate IR, the deterministic reconstruct
|
||
contract, the **statevector-equivalence** and **shot-histogram-equivalence**
|
||
conformance criteria, the quantum-information-theoretic fidelity metric, and
|
||
the receipt profile. §9 states registers of qudits (2, 3, 4 or 6 levels) in the same
|
||
floor, run as a job of the engine rather than carried in a container.
|
||
|
||
Out of scope: quantum hardware or any device backend; a compression codec
|
||
for arbitrary media (this is not one); variational-quantum-circuit /
|
||
"quantum AI" **priors** whose measurement is stochastic — those are at best a
|
||
float/behavioral capability that can never back `intent=replicate`, so they
|
||
do not belong in this exact-reconstruction extension (§7).
|
||
|
||
Relationship to the core spec: mirrors worlds / score / film. The
|
||
reconstruct runs in the deterministic floor; `media` takes the informational
|
||
value `"quantum"`; the envelope's capability names which of the two applies.
|
||
Both capabilities have the replicate class `StandardDefined` (WAI's own
|
||
deterministic floor) and the fidelity tier `Lossless` (the simulation analog —
|
||
the reconstruction is byte-exact).
|
||
|
||
## 2. Container (`WQC`)
|
||
|
||
```
|
||
magic | u16 n_sections | n_sections × (u8 kind, u32 off, u32 len) | sections
|
||
```
|
||
|
||
The magic names the capability: `WQC1` is circuit/1 and `WQC2` is circuit2. The
|
||
layout is otherwise identical. All integers in the container are little-endian.
|
||
|
||
The sections blob starts immediately after the table, at byte
|
||
`6 + 9·n_sections`, and `off` is relative to it: a section occupies the bytes
|
||
from `blob + off` to `blob + off + len`. A reader computes these bounds without
|
||
overflow (in arithmetic wider than 32 bits, or with checked operations) and
|
||
refuses a table or a section, of any kind, that runs past the end of the payload.
|
||
|
||
| kind | section | required |
|
||
|---|---|---|
|
||
| `0x01` | contract (canonical JSON, §2.1) | REQUIRED |
|
||
| `0x02` | gate op-log (§2.2) | REQUIRED |
|
||
| `0x03` | measurement (canonical JSON, §2.3) | OPTIONAL |
|
||
|
||
Unknown section kinds MUST be ignored (forward-compatible). A known kind that
|
||
appears more than once MUST be refused: two readers could otherwise read
|
||
different sections of one payload. The reference writer emits the contract, the
|
||
op-log and the measurement, if any, in that order and contiguous from offset 0,
|
||
and no other section.
|
||
|
||
**JSON in a section.** The contract and the measurement are I-JSON texts
|
||
([RFC 7493](https://www.rfc-editor.org/rfc/rfc7493)), and a reader decides each
|
||
of these rules from the section's bytes:
|
||
|
||
- The section is UTF-8 and holds one JSON value
|
||
([RFC 8259](https://www.rfc-editor.org/rfc/rfc8259)), with only space, tab,
|
||
line feed and carriage return around its tokens. A byte-order mark is not
|
||
whitespace.
|
||
- No object names a member twice. Names are compared after their escapes are
|
||
decoded, so `"a"` and `"\u0061"` are the same name.
|
||
- No name or string holds a surrogate code point or a noncharacter (U+FDD0 to
|
||
U+FDEF, and the last two code points of every plane), written raw or as an
|
||
escape. An escaped surrogate pair stands for the one character it encodes.
|
||
- No number has a magnitude of 2^1024 − 2^970 or more. These are exactly the
|
||
numbers that round to an infinite IEEE 754 double, rounding to nearest with
|
||
ties to even. A reader decides the rule exactly, on the literal's digits: its
|
||
significant digits and its decimal exponent against the 309 digits of
|
||
2^1024 − 2^970, however many digits or zeros the literal is written with. A
|
||
float parser decides it only where it rounds correctly at every length and
|
||
every exponent. A number that rounds to zero is in range.
|
||
- Arrays and objects nest at most 127 deep, the outermost counted as the first.
|
||
|
||
RFC 7493 also asks a sender to keep a number within a double's precision and an
|
||
integer within ±(2^53 − 1). A reader here does not hold what it receives to that:
|
||
it reads an integer exactly, so `seed` and `shots` (§2.3) span the whole `u64`
|
||
range. Where a rule asks for an *unsigned JSON integer*, it means a number
|
||
written with no sign, fraction or exponent, whose value is in the range the rule
|
||
names: `-0`, `2.0` and `2e0` are not one.
|
||
|
||
A section that breaks one of these rules is a contract refusal for the contract
|
||
and a malformed one for the measurement. A section that breaks several is
|
||
refused with that class whichever of them a reader meets first; readers may name
|
||
different rules for it, and only the class is specified.
|
||
|
||
A reader refuses a payload that breaks a rule of this section or of §2.1–§2.3.
|
||
It checks in this order and refuses with the class of the first rule broken:
|
||
|
||
1. The payload is at least 6 bytes and starts with `WQC1` or `WQC2`; else
|
||
**malformed**.
|
||
2. The section table and every section, of a known kind or not, lie within the
|
||
payload; no known kind repeats; the contract and the op-log are present.
|
||
Else **malformed**.
|
||
3. The contract (§2.1); else **contract**, except that an `n_qubits` that is
|
||
not an unsigned integer of at most 255 is **malformed**.
|
||
4. The op-log parses (§2.2); else **malformed**.
|
||
5. The circuit keeps the rules of its capability (§2.2); else **invalid**.
|
||
6. The measurement, if present (§2.3); else **malformed**.
|
||
|
||
The corpus's `reject/` tree holds at least one payload for each refusal of this
|
||
section and of §2.1–§2.3 that a payload can carry, and `reject.json` names each
|
||
one's class. The two limits it cannot carry bind a writer instead: the wire
|
||
counts a gate's controls in a `u8` and a circuit's ops in a `u32`. Its `accept/`
|
||
tree holds payloads at the edges of the same rules that a reader MUST accept,
|
||
and `accept.json` gives how each one reads: its capability, `n_qubits`, op count,
|
||
`circuit_hash` and measurement.
|
||
|
||
### 2.1 Contract
|
||
|
||
The canonical contract bytes, used for writing and for `circuit_hash` (§4.1),
|
||
have no whitespace and these members in this order. `N` is `n_qubits` in
|
||
decimal, `0` to `255`, with no sign, leading zero, fraction or exponent:
|
||
|
||
- circuit/1:
|
||
`{"ext":"wai.quantum.circuit/1","n_qubits":N,"numeric":"wai.det.fixed64","frac":30,"gateset":"cliffordT+dyadicP"}`
|
||
- circuit2:
|
||
`{"ext":"wai.quantum.circuit2/1","n_qubits":N,"numeric":"wai.det.amp64","frac":30,"gateset":"cliffordT+dyadicP.rn"}`
|
||
|
||
A writer writes the canonical contract of its capability.
|
||
|
||
`ext` is `<capability>/<contract revision>`: `wai.quantum.circuit2/1` is revision
|
||
1 of the circuit2 capability, not a version "2.1". `frac` is the amplitude
|
||
fixed-point scale (`FRAC`, 30 in both). `gateset` names the reconstruction's gate
|
||
algebra (§3); circuit2's string differs from circuit/1's because its constants
|
||
differ. `numeric` names the arithmetic:
|
||
|
||
- `wai.det.amp64`: complex amplitudes, `re` and `im` each an `i64` at scale
|
||
`2^frac`. A product of two components is computed exactly and rounded as
|
||
`(a·b + 2^(frac−1)) >> frac`, with an arithmetic shift (round half up); sums
|
||
are exact (§3.0).
|
||
- `wai.det.fixed64`, inside a circuit/1 contract, means the same: the §3.0
|
||
arithmetic at frac 30, with products rounded half up. Those bytes are inside
|
||
every circuit/1 `circuit_hash`, so they stay. It does not mean the Q32.32
|
||
floor, with products rounded toward −∞, that
|
||
[interactive-worlds](interactive-worlds.md) §6.2 names `wai.det.fixed64`.
|
||
|
||
Reading a circuit/1 contract. The section MUST be an I-JSON object (§2), else
|
||
contract.
|
||
Its `ext`, `numeric` and `gateset` MUST be the strings of the template above and
|
||
its `frac` the JSON integer `30` (`30.0` is not); a member that is missing or
|
||
carries another value is a contract refusal, so a circuit2 contract in a `WQC1`
|
||
container is refused. Then `n_qubits` MUST be an unsigned JSON integer of at most
|
||
255, else malformed. Member order, whitespace and further members are free;
|
||
`circuit_hash` covers the canonical bytes, not the received ones (§4.1).
|
||
|
||
Reading a circuit2 contract. The section MUST be an I-JSON object (§2), else contract,
|
||
whose `n_qubits` is an unsigned JSON integer of at most 255, else malformed. Its
|
||
bytes MUST then equal the canonical circuit2 contract for that `n_qubits`, else
|
||
contract: no whitespace, no other member order and no further member, and a
|
||
circuit/1 contract in a `WQC2` container is refused.
|
||
|
||
### 2.2 Gate op-log
|
||
|
||
`u32 n_ops`, then per op:
|
||
|
||
```
|
||
u8 opcode | u8 n_ctrl | u8 target | u16 param | n_ctrl × u8 control
|
||
```
|
||
|
||
The op is a **controlled-1-qubit gate**: the base gate `opcode` is applied to
|
||
`target` iff every qubit in `control` is set. `param` carries the dyadic index
|
||
`k` for `P(k)`. Opcodes:
|
||
|
||
| opcode | gate | | opcode | gate |
|
||
|---|---|---|---|---|
|
||
| 0 | `I` | | 5 | `S` |
|
||
| 1 | `X` | | 6 | `S†` |
|
||
| 2 | `Y` | | 7 | `T` |
|
||
| 3 | `Z` | | 8 | `T†` |
|
||
| 4 | `H` | | 9 | `P(k) = diag(1, e^{2πi/2^k})` |
|
||
|
||
`CX`/`CZ`/`CP(k)` are these with `n_ctrl = 1`; `CCX` (Toffoli) with
|
||
`n_ctrl = 2`; `SWAP` is three `CX`.
|
||
|
||
Parsing, in both capabilities: every op lies within the section and its opcode is
|
||
at most 9, else malformed. In circuit2 the section MUST end exactly after the
|
||
`n_ops`-th op, else malformed; in circuit/1 bytes after it are ignored and are
|
||
not part of the circuit. `n_ops` is the payload's claim: every op takes at least
|
||
5 bytes, so a section of `len` bytes holds at most `⌊(len − 4)/5⌋` ops, and a
|
||
reader reserves no more than that.
|
||
|
||
The rules of the circuit, refused as invalid:
|
||
|
||
- in both capabilities, a target is `< n_qubits`; a control is `< n_qubits` and
|
||
`≠ target`; a gate has at most 255 controls (the wire counts them in a `u8`,
|
||
so this binds a writer); `P(k)` has `1 ≤ k ≤ 32`; a circuit has at most
|
||
`2^32 − 1` ops;
|
||
- in circuit2 also, a gate's controls are pairwise distinct, so there are at
|
||
most 254, and `param` is 0 for opcodes 0–8.
|
||
|
||
circuit/1 keeps the rules it had: a repeated control is the same condition
|
||
twice, and opcodes 0–8 ignore `param`.
|
||
|
||
### 2.3 Measurement (optional)
|
||
|
||
```json
|
||
{"seed":12648430,"shots":100000,"basis":"computational"}
|
||
```
|
||
|
||
Pins a computational-basis sampling for shot-histogram-equivalence (§4.2); the
|
||
example is the corpus's bell measurement.
|
||
`seed` and `shots` are unsigned 64-bit integers.
|
||
|
||
- circuit2: the section MUST be exactly
|
||
`{"seed":S,"shots":N,"basis":"computational"}`, with `S` and `N` in decimal
|
||
with no sign, leading zero, fraction, exponent or whitespace; else malformed.
|
||
- circuit/1: the section MUST be I-JSON (§2), else malformed. A `seed` or `shots` that
|
||
is missing or is not an unsigned integer in the `u64` range reads as 0, and
|
||
`basis` is not read. The reference writer writes the circuit2 form.
|
||
|
||
## 3. Reconstruct contract
|
||
|
||
### 3.0 Arithmetic, for both capabilities
|
||
|
||
An implementer needs all of this, with the phase table of §3.1 or §3.2, to
|
||
reproduce a statevector.
|
||
|
||
- **Amplitude.** `(re, im)`, each an `i64` at scale `2^30`; `2^30` is 1. A unit
|
||
below means `2^−30`.
|
||
- **Product.** `fx(a, b) = (a·b + 2^29) >> 30`, with `a·b` exact (signed 128-bit
|
||
arithmetic holds it) and `>>` an arithmetic shift, that is floor division by
|
||
`2^30`.
|
||
- **Complex product.** `(a·b).re = fx(a.re, b.re) − fx(a.im, b.im)` and
|
||
`(a·b).im = fx(a.re, b.im) + fx(a.im, b.re)`. Each product is rounded
|
||
separately; the sums are exact.
|
||
- **Initial state.** `2^n` amplitudes, `amps[0] = (2^30, 0)` and every other
|
||
`(0, 0)`. Qubit `q` is bit `q` of the basis index, qubit 0 the least
|
||
significant.
|
||
- **A gate** (base, controls `C`, target `t`, param), for every index `i` with
|
||
bit `t` clear and every bit of `C` set, with `j = i | 2^t`, sets
|
||
|
||
```
|
||
a_i' = m00·a_i + m01·a_j a_j' = m10·a_i + m11·a_j
|
||
```
|
||
|
||
from the values before the gate, each product a complex product and each sum
|
||
exact. Gates apply in op-log order.
|
||
- **Matrices.** With `P(k)` the capability's phase table (§3.1 or §3.2),
|
||
`h = re P(3)`, `1 = (2^30, 0)` and `i = (0, 2^30)`:
|
||
|
||
| opcode | gate | `m00` | `m01` | `m10` | `m11` |
|
||
|---|---|---|---|---|---|
|
||
| 0 | `I` | `1` | `0` | `0` | `1` |
|
||
| 1 | `X` | `0` | `1` | `1` | `0` |
|
||
| 2 | `Y` | `0` | `−i` | `i` | `0` |
|
||
| 3 | `Z` | `1` | `0` | `0` | `−1` |
|
||
| 4 | `H` | `(h, 0)` | `(h, 0)` | `(h, 0)` | `(−h, 0)` |
|
||
| 5 | `S` | `1` | `0` | `0` | `i` |
|
||
| 6 | `S†` | `1` | `0` | `0` | `−i` |
|
||
| 7 | `T` | `1` | `0` | `0` | `P(3)` |
|
||
| 8 | `T†` | `1` | `0` | `0` | `conj P(3)` |
|
||
| 9 | `P(k)` | `1` | `0` | `0` | `P(k)` |
|
||
|
||
- The capability selects the table and nothing else, and only `H`, `T`, `T†`
|
||
and `P(k)` read it.
|
||
- `fx(±2^30, x) = ±x` and `fx(0, x) = 0` exactly, so a product with a matrix
|
||
entry of `0`, `±1` or `±i` is exact. An implementation may skip such products
|
||
(a diagonal gate need touch only `a_j`) without changing a bit.
|
||
|
||
The canonical reconstructed quantity is the amplitude vector serialized as
|
||
`re_le(i64) ‖ im_le(i64)` per amplitude, in index order.
|
||
|
||
`cliffordT+dyadicP` and `cliffordT+dyadicP.rn` are universal (Clifford+T is
|
||
dense in `SU(2^n)`). In circuit2, `P(k)` gives the controlled-phase ladder of
|
||
the QFT ("quantum FFT"), transported as a circuit (`H` + controlled-`P(k)` +
|
||
swaps) and reconstructed byte-exact; the circuit/1 table does not (§3.1). No float runs on the decode: the phase tables are
|
||
integer constants.
|
||
|
||
### 3.1 The circuit/1 phase table (frozen)
|
||
|
||
`P1(1) = (−2^30, 0)` and `P1(2) = (0, 2^30)`. For `k = 3..32`, with
|
||
`c = re P1(k−1)`:
|
||
|
||
```
|
||
re P1(k) = isqrt(⌊(2^30 + c) / 2⌋ · 2^30)
|
||
im P1(k) = isqrt(⌊(2^30 − c) / 2⌋ · 2^30)
|
||
```
|
||
|
||
`isqrt` is the floor square root. Both halves are non-negative, so truncating
|
||
division and floor division agree. `H` uses `h = re P1(3) = 759250124`, `T` is
|
||
`P1(3)` and `T†` is `conj P1(3)`.
|
||
|
||
The table is the one every circuit/1 file, hash and receipt was made with, and it
|
||
is kept bit for bit. Its literal values (Appendix B.1) are normative by equality,
|
||
and so is its digest, BLAKE3 over `i64le(re) ‖ i64le(im)` for `k = 1..32`
|
||
(512 bytes, no domain prefix):
|
||
`3fa9805ff96feb819a1cf371fedcd3b5228f93eddf933d0edcf401cbf8c28466`.
|
||
|
||
Its floors compound. The stored values deviate from `2^30·e^{2πi/2^k}`, in units:
|
||
|
||
- `re P1(k)` is low by up to 1.3 units for every `k ≥ 3`;
|
||
- `im P1(k)` is within 2.2 units for `k ≤ 7`, then too large: +9.52 (`k = 8`),
|
||
+21.1 (9), +49.0 (10), +90.5 (11), +124.3 (12), +224.4 (13), +112.2 (14),
|
||
+1355.6 (15), +677.3 (16), +5283.2 (17, about 10% of the angle) and +7032.1
|
||
(18, about 27%);
|
||
- `im P1(19..32) = 0`: these entries apply no phase at all, a deviation of the
|
||
whole angle, from −12868 units at `k = 19` to −1.57 at `k = 32`.
|
||
|
||
A QFT on `n` qubits uses `P(2..n)`, so in circuit/1 a QFT on 8 or more qubits
|
||
applies phases that are off by more than 9 units, and one on 19 or more applies
|
||
none for its smallest rotations.
|
||
|
||
### 3.2 The circuit2 phase table
|
||
|
||
`P2(1) = (−2^30, 0)` and `P2(2) = (0, 2^30)`, both exact. For `k = 3..32`:
|
||
|
||
```
|
||
P2(k) = ( ⌊2^30·cos(2π/2^k) + ½⌋ , ⌊2^30·sin(2π/2^k) + ½⌋ )
|
||
```
|
||
|
||
the integers nearest to the ideal values. For `k ≥ 3` every ideal value is
|
||
irrational, so none is a half-integer and the nearest integer is unique. The
|
||
closest any ideal value comes to a half-integer is 0.00456 unit, at `im P2(22)`,
|
||
so any computation of the ideal values accurate to better than that rounds to the
|
||
same table. `H` uses `h = re P2(3) = 759250125`, `T` is `P2(3)` and `T†` is
|
||
`conj P2(3)`; `re P2(3) = im P2(3)`.
|
||
|
||
The literal values (Appendix B.2) are normative by equality, and an
|
||
implementation carries them as constants; it need not compute them. Their digest,
|
||
computed as for circuit/1, is
|
||
`d34cb793715348e7c92db027c0bc3dddb6008f5730470bafaed978ea7fb23510`.
|
||
|
||
**The circuit2 table gives the QFT**: every rotation `P(2..32)` of the
|
||
controlled-phase ladder is within half a unit per component of its ideal value.
|
||
§5 states what that leaves of the error.
|
||
|
||
*Derivation (informative).* An exact-integer procedure certifies the table with no
|
||
floating point. At scale `2^62` it keeps an enclosure
|
||
`c_lo ≤ 2^62·cos(2π/2^k) ≤ c_hi` and `s_lo ≤ 2^62·sin(2π/2^k) ≤ s_hi`, starting
|
||
from `(cos, sin)(π/2) = (0, 1)`, which is exact, and halves the angle with
|
||
`cos(θ/2) = √((1 + cos θ)/2)` and `sin(θ/2) = sin θ / (2 cos(θ/2))`, which has no
|
||
cancellation, rounding every bound outward:
|
||
|
||
```
|
||
S = 2^62
|
||
ceil_isqrt(x) = r if r·r = x, else r + 1, where r = isqrt(x)
|
||
R(x) = (x + 2^31) >> 32 -- scale 2^62 to 2^30, half up
|
||
(c_lo, c_hi, s_lo, s_hi) = (0, 0, S, S)
|
||
for k in 3..=32:
|
||
c_lo' = isqrt(((S + c_lo)·S) >> 1)
|
||
c_hi' = ceil_isqrt(⌈(S + c_hi)·S / 2⌉)
|
||
s_lo' = ⌊s_lo·S / (2·c_hi')⌋
|
||
s_hi' = ⌈s_hi·S / (2·c_lo')⌉
|
||
require R(c_lo') = R(c_hi') = re P2(k)
|
||
require R(s_lo') = R(s_hi') = im P2(k)
|
||
require |(x mod 2^32) − 2^31| > 2^20 for x in {c_lo', c_hi', s_lo', s_hi'}
|
||
(c_lo, c_hi, s_lo, s_hi) = (c_lo', c_hi', s_lo', s_hi')
|
||
```
|
||
|
||
Every step keeps a true enclosure, and when both ends of an enclosure round to
|
||
the same integer, that integer is the correctly rounded value. Every product
|
||
fits 125 bits, every enclosure is at most 3 units of `2^−62` wide, and no end
|
||
comes within 19,590,902 units of `2^−62` of a tie. The reference implementation
|
||
runs this procedure as a test, and the corpus referee runs it independently.
|
||
|
||
## 4. Conformance
|
||
|
||
### 4.1 statevector-equivalence
|
||
|
||
> Given the same circuit under the same capability, a conforming sink MUST
|
||
> reconstruct the identical fixed-point statevector, hence the identical
|
||
> BLAKE3 — on every machine, no tolerance parameter.
|
||
|
||
```
|
||
statevector_hash = BLAKE3("wai:quantum-statevector\x01"
|
||
‖ u8 n_qubits ‖ u32le frac
|
||
‖ per amplitude, in index order: i64le re ‖ i64le im)
|
||
circuit_hash = BLAKE3("wai:quantum-circuit\x01"
|
||
‖ canonical contract (§2.1) of the capability for n_qubits
|
||
‖ canonical op-log)
|
||
```
|
||
|
||
The canonical op-log is the §2.2 encoding of the circuit's ops: `u32le n_ops`,
|
||
then each op, and nothing after. For circuit2 the canonical contract and op-log
|
||
are the bytes received, since the reader requires them. For circuit/1 the
|
||
contract is the re-rendered template, however the received one was formatted,
|
||
and bytes after the last op are not part of the op-log.
|
||
|
||
`circuit_hash` is the identity of the circuit, and its contract names the
|
||
capability, so it binds the capability and its phase table: the same ops under
|
||
circuit/1 and circuit2 have different circuit hashes. `statevector_hash` hashes
|
||
the amplitudes alone and names no capability: the two capabilities give the same
|
||
statevector, and so the same hash, for a circuit in which no gate that reads the
|
||
table acts on a nonzero amplitude (one of `X` gates only, say). A run is
|
||
therefore identified by its `circuit_hash`, and each sink's `statevector_hash`
|
||
is the verifiable result.
|
||
|
||
### 4.2 shot-histogram-equivalence (measured circuits)
|
||
|
||
For a circuit with a §2.3 measurement, a conforming sink MUST sample the
|
||
computational-basis outcome as follows, producing an identical per-basis-state
|
||
count vector:
|
||
|
||
- The weight of basis state `i` is `w_i = re_i² + im_i²`, exact; `W` is their
|
||
sum, and `cum_i` the sum of `w_0..w_i`. The weights are not normalised.
|
||
- `splitmix64` with state `s`, starting at `seed`, all arithmetic mod `2^64`:
|
||
`s ← s + 0x9E3779B97F4A7C15`; `z ← s`;
|
||
`z ← (z ⊕ (z >> 30))·0xBF58476D1CE4E5B9`;
|
||
`z ← (z ⊕ (z >> 27))·0x94D049BB133111EB`; the draw is `z ⊕ (z >> 31)`.
|
||
- Each of the `shots` shots draws `x`, takes `r = x mod W`, and counts the first
|
||
basis state `i` with `cum_i > r`. If `W` is 0, every count is 0.
|
||
|
||
```
|
||
histogram_hash = BLAKE3("wai:quantum-histogram\x01"
|
||
‖ u8 n_qubits ‖ u64le seed ‖ u64le shots
|
||
‖ per basis state, in index order: u64le count)
|
||
```
|
||
|
||
`seed`, `shots` and every count are `u64le`; `n_qubits` is a `u8` prefix. The
|
||
histogram depends only on the statevector and the measurement, so it names no
|
||
capability either.
|
||
|
||
## 5. Fidelity and size (honest)
|
||
|
||
Two honesties the format states rather than implies:
|
||
|
||
1. **The reconstruction is exact; the model it reconstructs is an
|
||
approximation.** The statevector is byte-identical across sinks
|
||
(statevector-equivalence), but it is a *fixed-point* approximation of the
|
||
ideal complex-amplitude unitary evolution. This is the same call as
|
||
`wai.video.int_motion`: byte-exact reconstruction of a defined-lossy quantity.
|
||
The tier is therefore `Lossless` in the *simulation* sense (like world
|
||
replay), and the error bound is part of the contract, not a hidden claim.
|
||
Per capability:
|
||
|
||
- **circuit2.** Every table constant is within ½ unit of its ideal value,
|
||
which §3.2 proves, and every product within ½ unit of the exact product.
|
||
One gate applied to a pair of amplitudes whose squared moduli sum to at
|
||
most 1 therefore lands within 2 units per component of the ideal gate
|
||
applied to the same pair: each component takes at most two rounded
|
||
products, ½ unit each, and the constants' error of ½ unit each meets
|
||
components whose squares sum to at most 1, which gives `1 + √2/2 ≈ 1.71`.
|
||
The worst measured on random normalised pairs is under 1.5 units. Errors
|
||
accumulate roughly linearly in the number of gates. Some table entries have
|
||
a modulus slightly above 1, by at most 0.3603 unit (`||P2(k)|² − 1|` is at
|
||
most 0.73 unit), so a long run of one phase drifts the norm upward, at the
|
||
order of the product rounding: `P2(19)` applied `2^18` times to `|1⟩`, a
|
||
half turn, ends at modulus 1.0000189 and within `10^−5` rad of the half
|
||
turn. The resolution of `2^−30` is a floor no rounding removes:
|
||
`P2(26..32)` carry imaginary parts of 101 down to 2, so `P2(32)` is correct
|
||
to the nearest unit (ideal 1.5708, stored 2) and 27% off in relative angle.
|
||
A finer resolution needs a new capability.
|
||
- **circuit/1.** The same arithmetic with the constants of §3.1, which are
|
||
off by up to 12868 units, and `P1(19..32)` apply no phase. The bound above
|
||
does not hold: one `P1(k)` errs by as much as its constant does. `P1(19)`
|
||
applied `2^18` times to `|1⟩` ends at exactly `(1073479680, 0)`: each step
|
||
loses a unit and none rotates.
|
||
|
||
A QFT on `n` qubits needs `P(2..n)`, so a 26-qubit QFT needs `P(19..26)` and
|
||
is circuit2-only.
|
||
|
||
2. **The state is exponential; the circuit is not.** A statevector is
|
||
`2^n` amplitudes × 16 bytes — the reconstruction is heavy and grows
|
||
exponentially. The *transportable* object is the circuit op-log, which is
|
||
linear in gate count (the reference corpus's QFT-5 circuit is 261 bytes as
|
||
circuit/1 and 263 as circuit2, and reconstructs a 32-amplitude state; a
|
||
26-qubit QFT is still a few kilobytes and reconstructs ~1 GiB). The win is
|
||
exactly WAI's thesis — the wire carries instructions, the sink
|
||
reconstructs — and it is *why* the receipt matters: because reconstruction
|
||
cost is exponential, an energy-metered, byte-exact, signed record of the
|
||
computation is a genuinely novel artifact.
|
||
|
||
This extension is a way to make a quantum computation portable and verifiable.
|
||
It is not a media codec and it is not a route to quantum advantage.
|
||
|
||
## 6. Receipt (JWP profile)
|
||
|
||
The receipt (`wai-quantum/src/quantum_receipt.rs`, feature `quantum_receipt`,
|
||
which `wai-rs` forwards under the same name) is the artifact this whole extension
|
||
exists to make possible. Its
|
||
design principle: **separate the two halves of the reconstruction's cost so each
|
||
is trusted the way it honestly can be.**
|
||
|
||
| field | what it is | how it is trusted |
|
||
|---|---|---|
|
||
| `circuit_hash` | identity — the `WQC` circuit's hash, which names its capability | re-checkable |
|
||
| `statevector_hash` | the byte-exact reconstruction result | **re-checkable** (re-simulate) |
|
||
| `measurement` | optional `{seed, shots, histogram_hash}` | re-checkable |
|
||
| `work_amp_updates` | `n_ops · 2^n` — the exponential reconstruction cost | **verified by recomputation** |
|
||
| `joules_micro` | measured marginal CPU energy the sink spent; `null` beside `energy_unmetered`, the reason, for a run nobody measured ([quantum-ops](quantum-ops.md) §3.5), and in a receipt sealed before that form, `0`, the unmetered marker, read as unmetered (legacy), never as zero joules | **attested by signature** |
|
||
| `energy_provenance` and its evidence (optional; [energy-measurement](energy-measurement.md) §2.8) | how `joules_micro` was acquired | **attested by signature**, not re-measurable |
|
||
|
||
`work_amp_updates` is *portable-exact*: anyone recomputes it from `(n_ops,
|
||
n_qubits)` and it grows exponentially in qubits, so a sink cannot inflate or
|
||
deflate the stated cost. `joules_micro` is *measured-attested*: only the signer
|
||
can vouch for what its own silicon drew, and the same holds for the class that
|
||
labels it and for the values of any report about it (energy-measurement §6). One Ed25519 signature,
|
||
verified strictly by the rule every quantum receipt is ([quantum-providers](quantum-providers.md)
|
||
§8.2 *The signature, strictly*), covers all of it
|
||
over a Merkle root of the leaf hashes (`circuit`, `statevector`, `[histogram]`) —
|
||
the worlds / provenance / film receipt shape reused, `parent_receipt_hash`
|
||
chaining a derivation exactly as they do.
|
||
|
||
The receipt format is the same for both capabilities. A receipt names its
|
||
capability through `circuit_hash`, whose contract names it (§4.1).
|
||
|
||
Two verification depths:
|
||
|
||
- `verify()` — Merkle root recomputes, `work == n_ops · 2^n`, signature valid by that rule.
|
||
- `verify_reconstruction(circuit)` — the strong, portable check: **independently
|
||
re-simulate the circuit** and confirm it reproduces the receipt's
|
||
`circuit_hash`, `statevector_hash`, shape, and histogram, *then* that the
|
||
receipt verifies. A receipt claiming a statevector the circuit does not
|
||
reconstruct to is rejected on any machine. (The measured `joules_micro` stays
|
||
attested-only — re-simulation checks the *result and cost*, never the signer's
|
||
energy draw.)
|
||
|
||
`verify_reconstruction` re-simulates the circuit under its own capability: the
|
||
circuit as decoded from its container, whose magic names it. A receipt sealed
|
||
under one capability therefore does not verify against the same ops under the
|
||
other. A receipt sealed before circuit2 existed (by `wai-quantum` 0.3.x) is a
|
||
circuit/1 receipt: re-verify it with its `WQC1` file, or with the circuit built
|
||
in circuit/1 (`Gateset::V1`). The reference's `gateset_of` reports under which
|
||
capability a circuit's ops match a receipt's `circuit_hash`; it explains a failed
|
||
reconstruction and decides nothing.
|
||
|
||
`to_json()` / `from_json()` give the portable, sorted-key JSON an out-of-band
|
||
verifier reads. `wai_quantum_meter <circuit.wqc> [receipt.json]` fills the
|
||
energy honestly: it samples the CPU power the open-source `macmon` reader
|
||
reports (no elevated privileges), brackets a reconstruction burst against an idle
|
||
baseline, and writes the marginal microjoules — never a fabricated number; where
|
||
no reader is present, or the reported power does not move in both brackets
|
||
([energy-measurement](energy-measurement.md) §3.1), or the §4 ratio cannot
|
||
support a figure, it emits an UNMETERED receipt in the unmetered form
|
||
([quantum-ops](quantum-ops.md) §3.5: `joules_micro` `null` beside `energy_unmetered`, the
|
||
meter's reason, inside the signature), never a figure of zero joules, with the exact work
|
||
intact. A receipt sealed before that form carries the unmetered marker `0`
|
||
([energy-measurement](energy-measurement.md) §2) and is read as unmetered (legacy).
|
||
`POST /verify` renders either as `"joules_micro": null` with `"unmetered"` saying why. Beside a
|
||
figure the meter writes a measurement report (energy-measurement §6). A figure is sealed with its acquisition class as a
|
||
`quantum_energy::Labelled` receipt ([energy-measurement](energy-measurement.md)
|
||
§2.8): `ModelBased`, inside the signature, because the samples are a power the
|
||
reader reports from a channel it selects, not a counter the meter reads and shows
|
||
live ([energy-measurement](energy-measurement.md) §3.1). It is
|
||
verified with `Labelled::verify` / `Labelled::verify_reconstruction`. The
|
||
`wai-quantum verify` CLI and the HTTP handler's `POST /verify` accept a receipt
|
||
in any form (`quantum_energy::MaybeLabelled`) and restate its class. A receipt
|
||
sealed without a label keeps its legacy bytes and its figure is unlabelled. The
|
||
meter decodes the circuit from its container, so the receipt binds the capability
|
||
the file names. A representative run on the reference QFT-5 vector, at a revision
|
||
that labelled the same reported power `OnChipCounter`: **≈43 µJ per
|
||
reconstruction, `work_amp_updates = 672`** (21 ops × 2⁵), sealed and
|
||
self-verified.
|
||
|
||
Because a quantum computation carries no speedup here, this is exactly the value
|
||
the standard adds: an energy-accounted, byte-exact, signed record whose *result*
|
||
and *cost* anyone can re-check, and whose *energy* the signer attests.
|
||
|
||
## 7. Quantum information theory as the conformance metric
|
||
|
||
The exact path above conforms by **byte identity**, so state fidelity is
|
||
`1` by construction — but the reference exposes the
|
||
quantum-information-theoretic metric explicitly, `fidelity_fx(a, b) =
|
||
|⟨a|b⟩|²` in the fixed-point floor (`0` for orthogonal states, `≈ ONE` for
|
||
equal). It serves two roles: a **diagnostic** here (how close an *approximate*
|
||
or float simulation lands to the byte-exact reference), and the **conformance
|
||
metric** for the future path this extension deliberately excludes — a
|
||
variational-quantum-circuit / "quantum AI" prior whose measurement is
|
||
stochastic. Such a prior is `NeuralFloat`/`Behavioral`: it MUST NOT back
|
||
`intent=replicate`, and would conform by a declared fidelity floor, exactly as
|
||
`wai.semantic.*` conforms by a CLIP-similarity threshold. Naming the metric now
|
||
fixes the axis before that capability is ever registered.
|
||
|
||
## 8. Versions
|
||
|
||
**Why circuit2 is a capability of its own.** The circuit/1 table comes from a
|
||
recurrence whose floors compound (§3.1). Correcting it under the same string
|
||
would change the payload format of a registered capability, which SPEC §8
|
||
forbids: once a capability string is registered, its payload format is fixed
|
||
forever, and a later change never widens an existing string. It would also
|
||
change the reconstruction, the `circuit_hash` and every receipt of the content
|
||
made with it. So the corrected table is a new capability, `wai.quantum.circuit2`,
|
||
with a magic of its own, and circuit/1 stays as it was.
|
||
|
||
**What a reader that predates circuit2 does.** It requires the magic `WQC1`, so
|
||
it refuses a `WQC2` payload at the magic, before it reads anything else. It does
|
||
not advertise `wai.quantum.circuit2`, so an envelope that names that capability
|
||
is inert to it (SPEC §4). It recomputes `circuit_hash` with the circuit/1
|
||
contract, so a circuit2 receipt does not verify there. Each of these fails
|
||
closed: no older reader reconstructs circuit2 content with the circuit/1 table.
|
||
|
||
**Payloads this revision makes non-conforming.** This revision states reader
|
||
rules for circuit/1 that enforce its registration as it was made (SPEC §8): the
|
||
contract's values (§2.1), the range of `n_qubits`, sections within the payload,
|
||
and one section of each known kind (§2). Earlier reference readers accepted
|
||
payloads that break them, and a reader of this revision refuses:
|
||
|
||
- a `WQC1` contract whose `ext`, `numeric`, `frac` or `gateset` is missing or
|
||
carries another value, a circuit2 contract among them;
|
||
- an `n_qubits` that is not an unsigned integer of at most 255 (an earlier
|
||
reader read 258 as 2);
|
||
- a known section kind that appears more than once (an earlier reader kept the
|
||
last);
|
||
- a section whose bounds overflow (an earlier reader could wrap on a 32-bit
|
||
target);
|
||
- a contract or measurement that repeats a member name within one object (an
|
||
earlier reader kept the last), or that holds a noncharacter in a name or a
|
||
string;
|
||
- a contract or measurement holding a number of magnitude 2^1024 − 2^970 or
|
||
more that an earlier reader accepted. Earlier readers left the range to their
|
||
float parser, so depending on how they were built they accepted some such
|
||
numbers, and refused some numbers below the limit that a reader of this
|
||
revision accepts.
|
||
|
||
The other rules of §2 refuse what earlier reference readers refused.
|
||
|
||
No file written by any reference version is affected: every reference writer
|
||
wrote the canonical contract, one section of each kind, and sections within the
|
||
payload. The reference implementation adds circuit2 in `wai-quantum` 0.4.0, where
|
||
a circuit built in code is circuit2 unless it is built as circuit/1.
|
||
|
||
## 9. Qudits
|
||
|
||
A register of **qudits** generalises the qubit: each of its `n` digits has `d`
|
||
levels. The Pauli group becomes the Weyl–Heisenberg group (the shift `X` and
|
||
the clock `Z`), the Hadamard becomes the Fourier transform over `Z_d`, and
|
||
`CNOT` becomes addition modulo `d`. This section states a register's
|
||
arithmetic, its constants, what each gate adds to the error, its measurement,
|
||
and the job that runs it (`wai.quantum.qudit/1`). It adds no capability: no
|
||
container carries a register, nothing in §2 to §8 changes, and a sink that
|
||
reads `WQC` needs none of it. Reference implementation: `quantum_qudit` (the
|
||
library) and `engine::qudit` (the job) in `wai-quantum`, and `wai-quantum
|
||
qudit`; corpus: `quantum-conformance/qudit/`.
|
||
|
||
The rule of §1 holds here: the same integers on every machine, every constant a
|
||
stated number, and the error a stated bound.
|
||
|
||
### 9.1 The register
|
||
|
||
- **Dimensions.** `d` is 2, 3, 4 or 6: the dimensions whose roots of unity
|
||
have degree at most two over the rationals (`φ(d) ≤ 2`), so that every
|
||
coordinate of a root is `0`, `±1`, `±1/2` or `±√3/2` (§9.2). Every other
|
||
dimension is refused; none is given roots from a float or a series. (8 and 12
|
||
would take the same construction, their coordinates `±√2/2` and `±√3/2`, and
|
||
are not built.)
|
||
- **Amplitudes.** `d^n` amplitudes, each as in §3.0: `(re, im)`, `i64` at
|
||
scale `2^30`. Qudit `q` is digit `q` of the base-`d` index, qudit 0 the least
|
||
significant. The initial state has `amps[0] = (2^30, 0)` and every other
|
||
`(0, 0)`.
|
||
- **Fibres.** For a gate on qudit `q`, a fibre is the `d` amplitudes at
|
||
indices `i₀ + j·d^q` for `j = 0 … d − 1`, where `i₀` has digit `q` equal to 0;
|
||
amplitude `j` of the fibre is the one at level `j`.
|
||
|
||
At `d = 2` the register is circuit2's state vector, and its gates are circuit2's
|
||
(§9.3).
|
||
|
||
### 9.2 The constants
|
||
|
||
**The roots.** `ω_d^k = e^{2πik/d}` is `12k/d` twelfths of a turn, whose
|
||
coordinates are:
|
||
|
||
| twelfths | 0 | 2 | 3 | 4 | 6 | 8 | 9 | 10 |
|
||
|---|---|---|---|---|---|---|---|---|
|
||
| `(cos, sin)` | `(1, 0)` | `(1/2, √3/2)` | `(0, 1)` | `(−1/2, √3/2)` | `(−1, 0)` | `(−1/2, −√3/2)` | `(0, −1)` | `(1/2, −√3/2)` |
|
||
|
||
Each coordinate is `s·√(p/q)` for a sign `s` and whole `p`, `q`: `1` is
|
||
`√(1/1)`, `1/2` is `√(1/4)` and `√3/2` is `√(3/4)`. The Fourier gate's entry
|
||
`ω_d^m/√d` has the coordinates `s·√(p/(q·d))`.
|
||
|
||
**The fixed point of `s·√(p/q)`** is `s·c`, with
|
||
|
||
```
|
||
f = ⌊√⌊p·2^60 / q⌋⌋ (= ⌊2^30·√(p/q)⌋)
|
||
c = f + 1 when 4·p·2^60 ≥ (2f + 1)²·q, else f
|
||
```
|
||
|
||
in whole numbers: `c` is the nearest whole number to `2^30·√(p/q)`, and every
|
||
machine finds the same one. It is **exact** (the fixed point holds the number
|
||
itself) when `c²·q = p·2^60`: so `0`, `±1` and `±1/2` are exact. Every other
|
||
constant is irrational, so it is **correctly rounded**: within half a unit
|
||
(`2^−31`) of its number, and never a tie. These are all of them:
|
||
|
||
| constant | `p/q` | at `2^30` | the number at `2^30` | error, units |
|
||
|---|---|---|---|---|
|
||
| `√3/2` | 3/4 | 929887697 | 929887696.6898 | +0.3102 |
|
||
| `1/√2` | 1/2 | 759250125 | 759250124.9940 | +0.0060 |
|
||
| `1/√3` | 1/3 | 619925131 | 619925131.1266 | −0.1266 |
|
||
| `1/(2√3)` | 1/12 | 309962566 | 309962565.5633 | +0.4367 |
|
||
| `1/√6` | 1/6 | 438353264 | 438353264.0476 | −0.0476 |
|
||
| `1/(2√6)` | 1/24 | 219176632 | 219176632.0238 | −0.0238 |
|
||
| `√2/4` | 1/8 | 379625062 | 379625062.4970 | −0.4970 |
|
||
|
||
So: every root of `d = 2` (`±1`) and `d = 4` (`±1`, `±i`) is exact, as are the
|
||
real parts of the roots of `d = 3` and `d = 6`; their imaginary parts are
|
||
`±929887697`. `F_4`'s entries (`±1/2`, `±i/2`) are exact. `F_2`'s are
|
||
`±759250125`, which is circuit2's `re P(3)`. `F_3`'s are `619925131` and
|
||
`(−309962566, ±536870912)`; `F_6`'s are `±438353264` and
|
||
`(±219176632, ±379625062)`. A first version of the reference took `√3/2` and
|
||
`1/√3` as floors (929887696 and 619925130, the second a floor of a floor and
|
||
1.13 units low) and called them exact; this text replaces it.
|
||
|
||
**The constants' digest** of `d` is BLAKE3 over `"wai:qudit-constants\x01" ‖
|
||
u8 d`, then `ω_d^k` for `k = 0 … d − 1`, then the Fourier entries `ω_d^m/√d`
|
||
for `m = 0 … d − 1`, each as `i64le re ‖ i64le im`:
|
||
|
||
| `d` | constants' digest |
|
||
|---|---|
|
||
| 2 | `fa5e6bc7fe53b14b4e5917caeb9b8028ae316c7f619bdd5c292565c9360b9dbf` |
|
||
| 3 | `2f4a3854c397f95e152396701355baab1c14f1ba5a735c0d34378fd71b571d72` |
|
||
| 4 | `0bc240d517a49c6052b02e972d0592f8b21b342c782f8770f845cc88e61045a3` |
|
||
| 6 | `15f24f2b6546ea838e9360b122e4172c4574097c6fabc61cea0980c920596715` |
|
||
|
||
### 9.3 The gates and their arithmetic
|
||
|
||
Products and sums are §3.0's: each real product `fx(a, b)` rounded half up,
|
||
each complex product four of them, every sum exact. A gate reads the amplitudes
|
||
as they were before it.
|
||
|
||
| gate | takes | does |
|
||
|---|---|---|
|
||
| `shift` | `power` `a`, `0 ≤ a < d` | in every fibre, the amplitude at level `j` moves to level `(j + a) mod d` |
|
||
| `clock` | `power` `b`, `0 ≤ b < d` | in every fibre, the amplitude at level `j` is multiplied by `ω^{b·j}` |
|
||
| `phase` | `powers` `k₀ … k_{d−1}`, each `0 ≤ k_j < d` | in every fibre, the amplitude at level `j` is multiplied by `ω^{k_j}` |
|
||
| `fourier` | `power` `p`, `0 ≤ p ≤ 3` | `p = 0`: nothing. `p = 2`: in every fibre, the amplitude at level `j` moves to level `(−j) mod d`. `p = 1`: in every fibre, `a'_k = Σ_j F_{kj}·a_j` with `F_{kj}` the Fourier entry of `m = jk mod d`. `p = 3`: the same with `m = (−jk) mod d`, `F†` |
|
||
| `csum` | qudits `c ≠ t`, `power` `a`, `0 ≤ a < d` | the amplitude at an index whose digits `c` and `t` are `x` and `y` moves to the index whose digit `t` is `(y + a·x) mod d`, the others unchanged |
|
||
|
||
`F²` is the reflection, applied as the permutation it is; applying `F` twice
|
||
gives the reflection within its bound, not exactly. A multiplication by `ω^0 =
|
||
(2^30, 0)` leaves an amplitude as it was, so a gate whose every entry is 1 (a
|
||
power of 0, or every `k_j = 0`) changes nothing, and an implementation may skip
|
||
it.
|
||
|
||
At `d = 2`, `fourier` is circuit2's `H` (its entries are `(±h, 0)` with `h = re
|
||
P(3)`, and the sum is §3.0's `m00·a_i + m01·a_j`), `shift` is `X`, `clock` is
|
||
`Z` and `csum` is `CNOT`: a program of them gives circuit2's amplitudes on any
|
||
state, bit for bit. At `d = 4`, `F` is the two-qubit Fourier transform (`H` on
|
||
the high qubit, a controlled `P(2)` from the low one, `H` on the low one, a
|
||
swap), and the two give the same integers on every basis state. At `d = 6`, `F`
|
||
is `F_2 ⊗ F_3` under the Chinese-remainder relabelling of the levels (`n = (3n₁
|
||
+ 2n₂) mod 6` in, `k ≡ k₁ (mod 2)` and `k ≡ k₂ (mod 3)` out), exactly in the
|
||
constants' own numbers.
|
||
|
||
### 9.4 What a gate adds to the error
|
||
|
||
A register's amplitudes are the same integers everywhere, and differ from the
|
||
ideal state by what the arithmetic rounds. Of each gate, two numbers:
|
||
|
||
- `r`, the most rounded products in one coordinate of one output amplitude. A
|
||
product with a coordinate `0` or `±1` is exact (§3.0); every other is
|
||
rounded, by at most half a unit. For `clock` and `phase`, `r` is the most, over
|
||
their entries, of the coordinates of an entry that are neither `0` nor `±1`;
|
||
for `fourier` with `p = 1` or `3`, the most, over the output levels `k`, of
|
||
that count summed over `j`; for a permutation, 0.
|
||
- `κ`, a bound on the operator norm of the gate's matrix as held less the
|
||
ideal one, in units: each irrational coordinate is off by at most half a unit.
|
||
For `clock` and `phase`, `κ = ½·√m`, `m` the most irrational coordinates of
|
||
any entry; for `fourier` with `p = 1` or `3`, `κ = ½·√m`, `m` the irrational
|
||
coordinates of all `d²` entries (a Frobenius bound); for a permutation, 0.
|
||
|
||
| `d` | `F`, `F†`: `r` | `F`, `F†`: `κ` | `clock`, `phase` with a root other than `±1` | otherwise |
|
||
|---|---|---|---|---|
|
||
| 2 | 2 | 1 | | 0, 0 |
|
||
| 3 | 5 | 1.5 | `r = 2`, `κ = ½` | 0, 0 |
|
||
| 4 | 4 | 0 | | 0, 0 |
|
||
| 6 | 10 | `½·√52 ≈ 3.606` | `r = 2`, `κ = ½` | 0, 0 |
|
||
|
||
`shift`, `csum`, `F²` and the identity add nothing, and so does a `clock` or
|
||
`phase` whose roots are all `±1` or `±i` (every one at `d = 2` and `d = 4`;
|
||
`clock` with `b = 3` at `d = 6`). A program of such gates is the ideal state
|
||
exactly.
|
||
|
||
**The state's bound.** On `N = d^n` amplitudes, from `E = 0`, each gate in turn
|
||
sets
|
||
|
||
```
|
||
E ← E·(1 + κ·2^−30) + κ + (r/2)·√(2N)
|
||
```
|
||
|
||
in units of `2^−30`, and the final `E` bounds the 2-norm distance between the
|
||
computed state and the ideal one: the ideal unitary carries the error so far
|
||
unchanged, the matrix as held adds `κ` times the state's norm (at most
|
||
`1 + E·2^−30`), and each of the `2N` coordinates takes at most `r` roundings of
|
||
half a unit. It is computed in IEEE-754 binary64, every operation rounded to
|
||
nearest, in this order: `√(2N)` once; then `((E·(1 + κ·2^−30)) + κ) + ((0.5·r)
|
||
·√(2N))` for each gate, `κ` itself `0.5·√m`. So it is the same double on every
|
||
machine. On random programs of every gate, on 1 to 3 qudits of every dimension
|
||
and random states, the largest distance measured is 0.79 of the bound.
|
||
|
||
**The outcomes' bound.** With `e = E·2^−30`, the law the counts are drawn from
|
||
(§9.5) is within total variation `2e(2 + e)` of the ideal outcome distribution
|
||
while `2e + e² < 1/17`; past that the bound is 1, and says nothing. In doubles,
|
||
`e = E/2^30`, the test is `(2·e) + (e·e) < 1/17` (the double nearest `1/17`),
|
||
and the bound `(2·e)·(2 + e)`. The
|
||
computed weights' law is within `e(2 + e)` of the ideal one, since
|
||
`Σ|p̃ᵢ − pᵢ| ≤ |1 − S| + e(2 + e)` with `S = ‖ã‖² ∈ [(1 − e)², (1 + e)²]`.
|
||
Reducing a 64-bit draw modulo the weights' sum `W` adds at most
|
||
`min(R, W − R)/2^64 ≤ |S − 1| ≤ 2e + e²`, where `R = 2^64 mod W`, while
|
||
`|S − 1| < 1/17` keeps `⌊2^64/W⌋` at 15 or 16.
|
||
|
||
### 9.5 Measurement
|
||
|
||
Every qudit is read at the end, in the computational basis, as §4.2 reads a
|
||
qubit register: the weight of basis state `i` is `wᵢ = reᵢ² + imᵢ²`, exact, `W`
|
||
their sum and `cumᵢ` the sum of `w₀ … wᵢ`; `splitmix64` from `seed` gives one
|
||
`x` a shot, `r = x mod W`, and the shot's outcome is the first `i` with `cumᵢ >
|
||
r`. With `shots` 0, or `W` 0, nothing is drawn. An implementation may sort the
|
||
draws and walk the weights once: each shot's outcome is the same.
|
||
|
||
An outcome is written as the qudits' digits, the highest-numbered qudit first
|
||
(qudit 0 is the last character), each digit `0` to `d − 1`. `counts` lists the
|
||
outcomes drawn, the most frequent first and then by their text, at most 65536
|
||
of them; `distinct_outcomes` is how many there were, and `omitted_shots` the
|
||
shots of those not listed.
|
||
|
||
### 9.6 The state's digest
|
||
|
||
```
|
||
state_blake3 = BLAKE3("wai:qudit-state\x01" ‖ u8 d ‖ u8 n
|
||
‖ per amplitude, in index order: i64le re ‖ i64le im)
|
||
```
|
||
|
||
and `norm2` is `⌊Σ (reᵢ² + imᵢ²) / 2^30⌋`, which stays near `2^30`.
|
||
|
||
### 9.7 The job: `wai.quantum.qudit/1`
|
||
|
||
A request is a JSON object:
|
||
|
||
| member | | |
|
||
|---|---|---|
|
||
| `d` | required | 2, 3, 4 or 6 |
|
||
| `qudits` | required | a whole number, at least 1 |
|
||
| `gates` | required | a list, each `{"gate", "qudits"}` and a `power` (`shift`, `clock`, `fourier`, `csum`; 1 when left out) or `powers` (`phase`, required): `qudits` holds one qudit, or for `csum` two different ones, the control then the target |
|
||
| `shots` | optional | a whole number; 1024 when left out |
|
||
| `seed` | optional | a whole number from 0 to `2^53 − 1`; 1 when left out |
|
||
| `amplitudes` | optional | a list of outcomes, each `n` digits as §9.5 writes them |
|
||
|
||
A whole number is a JSON number with no fractional part from 0 to `2^53 − 1`,
|
||
read by its value (`1`, `1.0` and `1e0` are one). A request is checked in this
|
||
order, and the first rule that fails is the refusal (the
|
||
job layer's codes, `wai-quantum/docs/job-refusals.md`):
|
||
|
||
1. the request is an object, with no member but these (`J090`);
|
||
2. `d` is a whole number (`J090`), and 2, 3, 4 or 6 (`J091`);
|
||
3. `qudits` is a whole number of at least 1 (`J090`), and `d^qudits` is at most
|
||
`2^24` (`J092`);
|
||
4. `gates` is a list (`J090`) of at most 65536 (`J092`), and each gate in turn
|
||
reads: its `gate` one of the five, no member its gate does not take, its
|
||
`qudits` in the register, a `csum`'s two different, each power in its range
|
||
and `phase` with exactly `d` powers (`J090`);
|
||
5. `shots` is a whole number (`J090`) of at most 10^6 (`J092`);
|
||
6. `seed` is a whole number from 0 to `2^53 − 1` (`J090`);
|
||
7. `amplitudes` is a list (`J090`) of at most 64 (`J092`), each `n` digits
|
||
below `d` (`J090`);
|
||
8. the work is at most `2^32` (`J092`).
|
||
|
||
**The work** is what the job touches: each gate's (`N` for a permutation or a
|
||
`clock` or `phase`; `N·d` for `fourier` with `p = 1` or `3`; nothing for a gate
|
||
that changes nothing: a power of 0, or a `phase` of `ω^0` at every level), and
|
||
`2N + shots` for the draws and the digest.
|
||
|
||
**The answer** to a run holds, in this order: `answer` (`"run"`), `d`,
|
||
`qudits`, `gates` (how many), `shots`, `seed`, `counts`, `distinct_outcomes`
|
||
and `omitted_shots` (§9.5), `outcomes` (a sentence: how an outcome is
|
||
written), `amplitudes` when the request asks (each by its digits, `{"re",
|
||
"im"}`, the integers at `2^−30`), `state` (`blake3`, `amplitudes` (that is,
|
||
`N`) and `norm2`, §9.6), `constants` (`blake3`, §9.2), `work`, and `accuracy`:
|
||
`class` `bit-exact`, `bound` (`E·2^−30`), `bound_units` (`E`), `outcomes` (the
|
||
outcomes' bound) and a `note`. A host names the engine and the schema
|
||
(`engine`, `schema`: `wai.quantum.qudit/1`, `wai-quantum/schemas/qudit.v1.json`),
|
||
writes its word on the run's energy in `energy` (a reading, or `unmetered` with
|
||
the reason; never 0 for unmetered), and seals the request and the result as
|
||
every job is sealed ([quantum-providers.md §8.2](quantum-providers.md), the
|
||
receipt `wai.quantum.receipt/2`), so `wai-quantum verify` checks it as any
|
||
job's. **Checking one** (`wai-quantum qudit check`) verifies the receipt, runs
|
||
the request again and holds every member of the result but `receipt`,
|
||
`energy` and `engine` to the one given; it is verified when the signature holds
|
||
and nothing differs.
|
||
|
||
### 9.8 The ceiling, measured
|
||
|
||
A register holds at most `2^24` amplitudes: 24 qubits, 15 qutrits, 12 ququarts,
|
||
or 9 qudits of six levels. Its state is 256 MiB of amplitudes, which a 32-bit
|
||
host holds as one allocation. A job does at most `2^32` units of work, about a
|
||
minute of the largest register's Fourier gates on wasm32. Measured on the
|
||
reference build host (an arm64 workstation of 32 cores, shared) on 2026-11-10
|
||
by `engine::qudit`'s `measure_the_ceiling`, a release build natively and the
|
||
same test compiled to `wasm32-wasip2` and run by wasmtime 50.0.1 on the same
|
||
host:
|
||
|
||
| | native (aarch64), two runs | wasm32-wasip2 |
|
||
|---|---|---|
|
||
| a Fourier gate, per amplitude touched | 1.95–2.77 ns | 9.6–11.5 ns |
|
||
| a `clock`, per amplitude | 1.91–3.06 ns | 11.4–11.7 ns |
|
||
| a `shift` or `csum`, per amplitude | under 2 ns | under 5 ns |
|
||
| the largest job (127 Fourier gates on 24 qubits, work `2^32`) | 9.6 s and 10.1 s | 49.9 s |
|
||
| memory at its end | 277 MiB resident | 275 MiB linear memory |
|
||
|
||
A gate's time is the difference between a job of four of them and a job of none,
|
||
so the cheapest gates' figures are within the noise of a shared host (one run
|
||
gave a negative time for a `shift` at `d = 4`). The figures are for scale; the
|
||
limits are the contract, and they are the same on every host.
|
||
|
||
### 9.9 Conformance
|
||
|
||
`quantum-conformance/qudit/vectors.json` holds each dimension's constants (its
|
||
roots and Fourier entries at `2^30`, and their digest), 29 vectors (every gate
|
||
and power on every dimension, from one qudit to 14 qubits, each with the answer
|
||
a conforming host gives, every member of §9.7's answer but those a host adds),
|
||
and 35 requests a conforming host refuses, each with its code. A column of each
|
||
Fourier gate is among the vectors, every entry times an amplitude of exactly 1,
|
||
so a change of one unit to any constant changes some vector's state. Every
|
||
vector's answer is the same bytes on arm64 macOS, x86_64 Linux and
|
||
wasm32-wasip2 (CI, `wai-quantum-qudit.yml`), and
|
||
`quantum-conformance/tools/qudit_referee.py` recomputes all of it from this
|
||
section alone, in Python, in whole numbers and doubles, and moves every
|
||
constant by one unit to see a vector's state move.
|
||
|
||
### 9.10 What is not here
|
||
|
||
- **No noise and no measurement in the middle.** Every qudit is read once, at
|
||
the end.
|
||
- **No other dimension**, and no mixed register (a qubit beside a qutrit).
|
||
- **No energy reading but the job service's.** Every surface runs a qudit job and
|
||
checks one: the command line (`wai-quantum qudit run`, `check`), both MCP servers
|
||
(`run_qudit`), the job service (`POST /v1/qudit`, run as a job in a worker), the
|
||
Python package (`qudit`, `qudit_check`), the npm package (`QuantumEngine.qudit`,
|
||
`engine_qudit_check`), the Studio and the desktop app. The job service writes
|
||
its worker's reading in `energy`, or the unmetered form with the reason; every
|
||
other host writes the unmetered form with its reason.
|
||
- **No device.** Nothing here has run on a three-level machine. A register is
|
||
the ideal circuit's state, computed exactly as stated; it says nothing of how
|
||
a device's levels would behave.
|
||
|
||
## Appendix A — One floor, one more kind of state
|
||
|
||
statevector-equivalence is replay-equivalence with the world state replaced by
|
||
a quantum amplitude vector, and the deterministic floor extended from real
|
||
fixed-point (`Fx`) to complex fixed-point (`Amp`). The same discipline that
|
||
makes a world replay, a mix sum, an actuator buzz, a film frame and a Gaussian
|
||
cloud reconstruct now makes a quantum state reconstruct — one floor, one more
|
||
cargo class, one verification. The state is heavy and the model approximate;
|
||
the *reconstruction* of it is exact and auditable, and that — not a quantum
|
||
speedup WAI does not claim — is the honest thing the standard adds.
|
||
|
||
## Appendix B — The phase tables
|
||
|
||
`P(k)` as `(re, im)` at scale `2^30`, for `k = 1..32`, with each table's digest:
|
||
BLAKE3 over `i64le(re) ‖ i64le(im)` for `k = 1..32`, 512 bytes, no domain prefix.
|
||
The tables and digests below are rendered from the reference implementation's
|
||
constants (`PHASE_V1`, `PHASE_V2`) by `wai_quantum_vectors appendix`, and a test
|
||
fails when this text differs from what the constants render. B.1 is circuit/1's
|
||
table (§3.1) and B.2 is circuit2's (§3.2).
|
||
|
||
<!-- generated: wai_quantum_vectors appendix; do not edit by hand -->
|
||
|
||
### B.1 `wai.quantum.circuit`
|
||
|
||
| k | re P(k) | im P(k) |
|
||
|---:|---:|---:|
|
||
| 1 | -1073741824 | 0 |
|
||
| 2 | 0 | 1073741824 |
|
||
| 3 | 759250124 | 759250124 |
|
||
| 4 | 992008094 | 410903207 |
|
||
| 5 | 1053110175 | 209476638 |
|
||
| 6 | 1068571463 | 105245102 |
|
||
| 7 | 1072448454 | 52686012 |
|
||
| 8 | 1073418432 | 26350953 |
|
||
| 9 | 1073660972 | 13176485 |
|
||
| 10 | 1073721610 | 6588405 |
|
||
| 11 | 1073736770 | 3294284 |
|
||
| 12 | 1073740560 | 1647223 |
|
||
| 13 | 1073741507 | 823774 |
|
||
| 14 | 1073741744 | 411887 |
|
||
| 15 | 1073741803 | 207243 |
|
||
| 16 | 1073741818 | 103621 |
|
||
| 17 | 1073741822 | 56755 |
|
||
| 18 | 1073741823 | 32768 |
|
||
| 19 | 1073741823 | 0 |
|
||
| 20 | 1073741823 | 0 |
|
||
| 21 | 1073741823 | 0 |
|
||
| 22 | 1073741823 | 0 |
|
||
| 23 | 1073741823 | 0 |
|
||
| 24 | 1073741823 | 0 |
|
||
| 25 | 1073741823 | 0 |
|
||
| 26 | 1073741823 | 0 |
|
||
| 27 | 1073741823 | 0 |
|
||
| 28 | 1073741823 | 0 |
|
||
| 29 | 1073741823 | 0 |
|
||
| 30 | 1073741823 | 0 |
|
||
| 31 | 1073741823 | 0 |
|
||
| 32 | 1073741823 | 0 |
|
||
|
||
Digest: `3fa9805ff96feb819a1cf371fedcd3b5228f93eddf933d0edcf401cbf8c28466`
|
||
|
||
### B.2 `wai.quantum.circuit2`
|
||
|
||
| k | re P(k) | im P(k) |
|
||
|---:|---:|---:|
|
||
| 1 | -1073741824 | 0 |
|
||
| 2 | 0 | 1073741824 |
|
||
| 3 | 759250125 | 759250125 |
|
||
| 4 | 992008094 | 410903207 |
|
||
| 5 | 1053110176 | 209476638 |
|
||
| 6 | 1068571464 | 105245103 |
|
||
| 7 | 1072448455 | 52686014 |
|
||
| 8 | 1073418433 | 26350943 |
|
||
| 9 | 1073660973 | 13176464 |
|
||
| 10 | 1073721611 | 6588356 |
|
||
| 11 | 1073736771 | 3294193 |
|
||
| 12 | 1073740561 | 1647099 |
|
||
| 13 | 1073741508 | 823550 |
|
||
| 14 | 1073741745 | 411775 |
|
||
| 15 | 1073741804 | 205887 |
|
||
| 16 | 1073741819 | 102944 |
|
||
| 17 | 1073741823 | 51472 |
|
||
| 18 | 1073741824 | 25736 |
|
||
| 19 | 1073741824 | 12868 |
|
||
| 20 | 1073741824 | 6434 |
|
||
| 21 | 1073741824 | 3217 |
|
||
| 22 | 1073741824 | 1608 |
|
||
| 23 | 1073741824 | 804 |
|
||
| 24 | 1073741824 | 402 |
|
||
| 25 | 1073741824 | 201 |
|
||
| 26 | 1073741824 | 101 |
|
||
| 27 | 1073741824 | 50 |
|
||
| 28 | 1073741824 | 25 |
|
||
| 29 | 1073741824 | 13 |
|
||
| 30 | 1073741824 | 6 |
|
||
| 31 | 1073741824 | 3 |
|
||
| 32 | 1073741824 | 2 |
|
||
|
||
Digest: `d34cb793715348e7c92db027c0bc3dddb6008f5730470bafaed978ea7fb23510`
|
||
|
||
<!-- end generated -->
|