open-standards/wai/quantum-conformance/tools/receipt_verify.py
Transaction Science 5475caab2d
Some checks failed
wai-audit collector and player integration / does this change touch it (push) Successful in 22s
wai-quantum command line / does this change touch it (push) Successful in 17s
wai-quantum docs, course and locales / does this change touch it (push) Successful in 17s
WAI operation catalogue / does this change touch it (push) Successful in 28s
wai-quantum editors / does this change touch it (push) Successful in 46s
wai-quantum contract / does this change touch it (push) Successful in 1m1s
wai-quantum extension points / does this change touch it (push) Successful in 20s
wai-quantum error correction and mitigation / does this change touch it (push) Successful in 25s
wai-quantum service / does this change touch it (push) Successful in 18s
wai-quantum studio and desktop / does this change touch it (push) Successful in 15s
wai-quantum OpenQASM reader / does this change touch it (push) Successful in 1m0s
wai-quantum for Python / does this change touch it (push) Successful in 51s
wai-quantum pulse and dynamics / does this change touch it (push) Successful in 56s
wai-quantum for JavaScript / does this change touch it (push) Successful in 1m2s
wai-quantum resource estimation / does this change touch it (push) Successful in 1m6s
wai-quantum other formats / does this change touch it (push) Successful in 1m4s
wai-sink-swift native sink package / does this change touch it (push) Successful in 17s
wai-sink-android native sink library / does this change touch it (push) Successful in 18s
wai-quantum views in agent hosts / does this change touch it (push) Successful in 19s
WAI Studio / does this change touch it (push) Successful in 19s
wai-quantum variational and algorithm library / does this change touch it (push) Successful in 38s
wai-quantum verdicts and repairs / does this change touch it (push) Successful in 32s
wai-quantum service / service energy · linux packages (push) Successful in 2m39s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Failing after 3m50s
wai-quantum pulse and dynamics / the same bits · linux-arm64 (push) Successful in 3m28s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux-arm64, release (push) Successful in 3m42s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Successful in 6m3s
wai-quantum extension points / the registry and the example · linux-arm64 (push) Successful in 7m23s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 15s
wai-quantum wasmQ / does this change touch it (push) Successful in 13s
wai-quantum docs, course and locales / the Studio's words in every locale · linux (push) Successful in 17s
wai-quantum contract / the policy is linked, and the deprecations page reads (push) Successful in 7s
wai-quantum docs, course and locales / the course and the command line's languages · linux (push) Successful in 3m14s
WAI operation catalogue / the catalogue and every door · linux (push) Failing after 3m20s
wai-audit collector and player integration / collector · linux (push) Successful in 5m33s
wai-quantum extension points / the registry under wasm32-wasip2 (wasmtime) (push) Successful in 2m55s
wai-quantum error correction and mitigation / codes, decoders, texts and mitigation · linux, release (push) Successful in 3m8s
wai-quantum OpenQASM reader / corpus under wasm32-wasip2 (wasmtime) (push) Successful in 1m34s
wai-quantum editors / editors · linux (push) Successful in 6m31s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs under wasm32-wasip2 (wasmtime) (push) Successful in 2m1s
wai-quantum studio and desktop / studio · browser (push) Successful in 5m16s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs · linux, release (push) Successful in 3m29s
wai-quantum OpenQASM reader / reader and corpus · linux (push) Successful in 5m49s
wai-quantum contract / API compatibility · linux (push) Successful in 8m40s
wai-quantum other formats / the set under wasm32-wasip2 (wasmtime) (push) Successful in 1m51s
wai-quantum for Python / python · linux (push) Successful in 4m27s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 1m59s
wai-quantum extension points / the registry and the example · linux (push) Successful in 10m22s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux, release (push) Successful in 2m35s
wai-quantum service / service · linux (push) Failing after 10m28s
wai-quantum verdicts and repairs / the intent set and the verdict under wasm32-wasip2 (wasmtime) (push) Successful in 1m44s
wai-quantum for JavaScript / javascript · linux (push) Successful in 7m11s
wai-quantum verdicts and repairs / verdicts, repairs and the intent set · linux (push) Successful in 3m11s
wai-quantum studio and desktop / desktop app · linux (push) Successful in 10m47s
wai-quantum other formats / readers, writers and the set · linux (push) Successful in 6m57s
wai-quantum contract / schemas and the committed tool lists · linux (push) Successful in 13m33s
wai-quantum views in agent hosts / views · a scripted host (push) Successful in 4m42s
wai-quantum views in agent hosts / views · the page and its engine (push) Successful in 6m40s
wai-quantum resource estimation / estimation and calibration · linux, release (push) Successful in 12m3s
WAI Studio / Studio in WebKit · linux (push) Successful in 20m41s
wai-quantum wasmQ / the reference modules rebuild to their modules of record · linux (push) Successful in 41s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Failing after 2m24s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 3m19s
wai-quantum wasmQ / interpreter and vectors under wasm32-wasip2 (wasmtime) (push) Successful in 3m18s
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · linux (push) Successful in 10m32s
wai-quantum docs, course and locales / every command and snippet in the docs · linux (push) Successful in 47m14s
wai-quantum studio and desktop / desktop app · windows (push) Successful in 10m0s
wai-quantum command line / command line · linux (push) Failing after 1h0m4s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 2m9s
wai-quantum editors / editors · macos (push) Successful in 1m43s
wai-quantum command line / command line · macos (push) Successful in 2m44s
wai-quantum pulse and dynamics / the same bits · macos (push) Successful in 1m16s
wai-quantum for Python / python · macos (push) Successful in 2m56s
wai-quantum service / service · macos (push) Successful in 6m52s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 6m6s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Successful in 5m48s
WAI Studio / Studio in Chromium and Firefox · macos (push) Successful in 10m39s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Successful in 13m10s
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · macos (push) Successful in 2m13s
wai-quantum: a provider's result says how many shots its counts are of, and the second receipt verifier reads wasmQ/2
accepted_shots (quantum-providers §5.5, §8.1, §8.3, §8.4). A device may keep another number of
shots than asked (a post-selected or heralded readout discards the shots that fail its test;
some devices run more), and every host refused such counts, so no receipt could record such
a run before the first hardware receipt.
- engine::provider: a stated result whose counts are of another number than its shots
  carries `accepted_shots`, their sum (at least 1); the counts rule holds counts and
  omitted_shots to it when present, to `shots` when not; the distance to the exact
  distribution is over the shots kept. A result without it is of every shot asked, as every
  result before was (hosts refused other sums), so no receipt sealed before changes. The
  earlier form still takes only every shot. job-result.v1.json names the member.
- wai-quantum-qpu: run_compiled_stated takes counts of any sum of at least 1 (run_compiled
  still holds them to the shots); the open protocol's client reads `accepted_shots` from a
  `result` answer and refuses counts that sum to neither it nor the shots.
- §8.3 says a device that reads an ensemble gives no counts. counts_source, execution and
  approximate were checked against a live run's cases: shot records, vendor counts and
  rebuilt probabilities; settings sent or not; a simulator's approximation; and now the shots
  kept. A provider's own conformance vectors (provider-v1.json) still expect every shot.
- Receipts corpus: scripted-sampler-v2-post-selected (a sampler-v2 device that answered 387
  of 400 shots, wai-quantum-qpu/tests/clients.rs) and crafted receipts at the rule's edges
  (kept fewer and more, counts not its sum, of every shot beside one fewer, null).

The second verifier reads wasmQ/2 (quantum-wasmq §11.6). receipt_verify.py read a job whose
result's format is wai.quantum.wasmq.result/2 as no wasmQ job at all; it now holds it to
rules 4, 8, 11, 12 and 30 as that version reads them, and to rule 36, its energy, written from
§11 (one reading, SPEC-GAP [W23], noted: rule 11's accuracy by run's method).
- Corpus: the six wasmQ/2 jobs the command line seals from the second version's envelopes
  (jobs/cli-wasmq2-*, with the energy the build host read: OnChipCounter readings of its
  process), pinned in made.lock.json; twelve crafted from them, each breaking rule 4, 8, 11,
  12 or 36 alone or keeping them (the unmetered form, the stabilizer method at 27 qubits).
- receipt_differential.py: the rules stage holds both verifiers at each bound of rules 4, 8,
  11, 12, 30 and 36 as the second version reads them (the exact method at 26 and 27 qubits;
  the most shots its fresh state leaves under 2^42 and one more; readings at the floor and one
  ppm below, of 0 and of 2^53, an estimate, HwShunt, a reading that says more, each callout's
  figure missing, extra or a reading; the first version's energy and format), and the
  members-of-another-kind stage covers two second-version jobs.
- wasmq_mutants.py: rust-schemata takes several files, numbering across them, and the nightly
  step weakens engine/wasmq2.rs beside engine/wasmq.rs (its rule 36 and rule 1 checks marked).
- quantum-providers §8.4's wasmq_form and quantum-wasmq §11.8 name the second version and its
  jobs in the corpus.

The MCP tool lists carry job-result.v1.json as outputSchema, so docs/local-mcp.json and
docs/service-mcp.json are blessed (WAI_QUANTUM_BLESS=1) with the new member.

Tested on the build host (macOS arm64): wai-quantum --features
full --lib --tests (lib 1587 passed, every integration test, wasmq_verdict's corpus walk
over the new jobs among them); wai-quantum-qpu (lib 107 on macOS, 106 elsewhere as pinned;
clients 20; providers 12) and clippy --all-targets -D warnings; wai-quantum-cli
cargo test --release and the service's mcp:: tests (19); receipts generate.py --check and
--self-test, receipt_verify.py --self-test (846 checks); receipt_differential.py against the
reference: the 413 receipts agree three ways (manifest, reference, second), 31 868 one-member
changes agree, the rules stage's 1467 cases (265 at the bounds of the 36 rules) are as
written by both with the same rules stated, the 261 labelled cases as written; each of the
14 plants caught. Weakenings (wasmq_mutants.py), run here for this version's rules:
the second verifier's for rules 4, 8, 11, 12, 30, 31 and 36, 83, every one caught; the
engine's of engine/wasmq2.rs, 34, 27 caught and 7 listed as equivalent with the reason no
input tells each from the text. The first runs left 17 alive: the engine's 7 equivalents,
and 10 answered here, by cases at each bound they showed unheld (a reading's ppm and window below 0 or with a
fraction, and a window of 1; the result's shots written 64.0; the exact method's work at
2^42 exactly and 8 past it; a second-version envelope of 2^27 bytes and one more) and by
replacing a qubit bound of the Python rule 30's own, which no input could tell. Clippy: no
finding in provider.rs or wasmq2.rs; wai breaking: no unacknowledged break (the corpus's
additions are listed as additions). Rebased on 23e05b143 (the toolchain's release), the tool
lists blessed again and the CLI, service, qpu, provider, wasmQ and corpus checks rerun.

Changelog entry: wai/changes/2026-11-10-quantum-accepted-shots-and-wasmq2-second-verifier.md

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-10 17:20:36 -05:00

5461 lines
299 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""receipt_verify.py: a second, independent verifier of WAI Quantum job receipts.
Written from wai/extensions/quantum-providers.md §8 alone (the working text), and
sharing no code with the engine. Its wasmQ rules (`wasmq_form`) were written from
wai/extensions/quantum-wasmq.md §6.5, which §8.4 names, by a reader who had not seen
the reference; the second version's (§11.6: rules 4, 8, 11, 12 and 30 as that version
reads them, and rule 36, its energy) from §11 there. Outside specifications it relies on: RFC 8785 (JCS), RFC 8032
(Ed25519), the BLAKE3 specification, RFC 8259 (JSON), RFC 6901 (JSON Pointer).
Standard library only, Python 3.9 or later, run as `python3 -I`.
python3 -I receipt_verify.py FILE... one verdict line per file
python3 -I receipt_verify.py --lines FILE one compact job a line, one verdict a line
python3 -I receipt_verify.py --self-test [ES_NUMBER_FILE]
python3 -I receipt_verify.py --wasmq-cases OUT.jsonl [ES_NUMBER_FILE]
python3 -I receipt_verify.py --plant NAME ... a deliberate fault (below), never for use
--wasmq-cases writes every wasmQ case of the self-test whose whole-job verdict the
self-test writes, one JSON object a line, {"name", "raw" (base64 of the job's exact
bytes), "reasons" (sorted, [] when valid)}: what the self-test's author wrote from the
text, not a verdict of this file, for another verifier to be run on. It judges nothing.
The ES_NUMBER_FILE is taken for the self-test's shape and not read.
A verdict line is
{"file", "valid", "reasons": [sorted §8.4 reasons], "key", "form"}
with "key" the receipt's key hex when the receipt is of its form (else null) and
"form" "rfc8785", "first" or null; a provider's result adds
"provider": {"form": "stated"|"earlier", "class", "read_as", "counts_source", "execution"}
and a wasmQ job (its result's format is wai.quantum.wasmq.result/1 or /2) that was judged
(not unreadable, not_a_job or no_receipt) adds, as quantum-wasmq §6.5 says a verifier
states beside the verdict,
"wasmq": {"outcome", "problems": [...], "notes": [...]}
with "outcome" the sealed result's status (null when it is not a string), "problems"
each §6.5 rule the job breaks, one entry a rule ("rule 14: ..."), the first 64 and then
"and N more", and "notes" where the body's unsealed status, method and other members
differ from what is sealed or are missing. Neither changes "valid" or "reasons". A set
is no wasmQ job, and states none for its items.
The exit status is 0 only when every verdict is valid.
The reasons are exactly §8.4's, §8.6's and §8.7's:
unreadable, not_a_job, no_receipt (each reported alone); receipt_form,
digest_mismatch, bad_key, bad_signature; inexact_number; provider_class,
request_provider, request_shots, counts (every provider result); provider_members,
counts_source, execution, compiled_program, cost_confirmation (the stated form);
wasmq_form (a wasmQ job, quantum-wasmq §6.5, whatever its method);
set_items, set_item, set_root (a set, section 8.6);
contract_form, planner_form, planner_route, planner_choice, planner_stable,
planner_kept, contract_class, shadow, stopped (a job under a contract, section 8.7).
--plant NAME exists only to prove that a differential against another verifier
can fail: each plant breaks one rule on purpose, and a verifier run with one is
wrong by design. NAME is one of:
lenient-key accept small-order and mixed-order keys (a library's default)
no-alg skip the alg check
last-duplicate read a duplicated member name, keeping the last, not refusing
no-inexact skip inexact_number
measured-simulator accept class measured on a simulator's stated result
whole-cap cap every whole number at 2^53 − 1, not only a count's value
lax-small-order-r do not refuse an R of small order
no-canonical-spelling refuse an inexact whole number even in its canonical spelling
set-seal-only check a set's seal, and nothing of its items or its root
names-layout-only check compiled.qubit_names against the layouts only, not qasm3
route-unchecked take each route's stated outcome as it stands (section 8.7)
choice-unchecked take the planner's choice as it stands (section 8.7)
distance-unchecked take a shadow's stated distance as it stands (section 8.7)
wasmq-unchecked skip the wasmQ rules (quantum-wasmq §6.5): no wasmq_form, and
the wasmq statement's problems empty (its outcome and notes,
which are no rules, still given)
landscape-unchecked skip an energy-landscape job's rules (quantum-landscape §5.4):
no landscape_form
Without --plant the verifier is exactly §8's (and quantum-wasmq §6.5's, and
quantum-landscape §5.4's).
Its reader's questions of the text, gap by gap, are what §8 now says: where §8
left a choice, it was settled in the text, and this file follows the text. Where
quantum-wasmq §6.5 leaves one, the reading taken is marked SPEC-GAP [Wn]: [W2], [W5], [W9]
to [W14], and [W18] to [W23]. [W1], [W3], [W4], [W6], [W7], [W8], [W15], [W16] and [W17]
are gone: the text now settles them.
"""
import fractions
import hashlib
import json
import math
import re
import struct
import sys
import time
PLANTS_KNOWN = ("lenient-key", "no-alg", "last-duplicate", "no-inexact", "measured-simulator",
"whole-cap", "lax-small-order-r", "no-canonical-spelling", "set-seal-only",
"names-layout-only", "route-unchecked", "choice-unchecked", "distance-unchecked",
"wasmq-unchecked", "landscape-unchecked")
PLANTS = set()
MAX_DEPTH = 127 # §8.2: nesting deeper than 127 is unreadable
MAX_SAFE = 2 ** 53 - 1
# =============================================================== 1. reading (§8.2)
class Unreadable(Exception):
"""The text breaks a rule of reading (§8.2). `detail` is for the self-test only."""
def __init__(self, detail):
Exception.__init__(self, detail)
self.detail = detail
class Num(object):
"""A JSON number: the text as written, and the double it reads as."""
__slots__ = ("text", "value")
def __init__(self, text, value):
self.text = text
self.value = value
def literal_whole(self):
"""§8.2: a whole number written as one (no fraction, no exponent)."""
return not any(c in self.text for c in ".eE")
def __repr__(self):
return "Num(%s)" % self.text
_WS = re.compile(r"[ \t\n\r]*")
_NUMBER = re.compile(r"-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?")
_PLAIN = re.compile(r'[^"\\\x00-\x1f]*')
_HEX4 = re.compile(r"[0-9A-Fa-f]{4}")
_UNESCAPE = {'"': '"', "\\": "\\", "/": "/", "b": "\b", "f": "\f",
"n": "\n", "r": "\r", "t": "\t"}
def _number(text):
# §8.2: the nearest double, ties to even (Python's float() is correctly
# rounded); a magnitude of 2^1024 − 2^970 or more rounds to infinity and is
# unreadable; one too small for any double but zero reads as zero.
value = float(text)
if math.isinf(value):
raise Unreadable("number_overflow")
return Num(text, value)
class _Reader(object):
def __init__(self, text):
self.s = text
self.i = 0
def ws(self):
self.i = _WS.match(self.s, self.i).end()
def value(self, depth):
self.ws()
s, i = self.s, self.i
c = s[i:i + 1]
if c == "{":
return self.obj(depth + 1)
if c == "[":
return self.arr(depth + 1)
if c == '"':
return self.string()
for word, val in (("true", True), ("false", False), ("null", None)):
if s.startswith(word, i):
self.i = i + len(word)
return val
m = _NUMBER.match(s, i)
if m:
self.i = m.end()
return _number(m.group())
raise Unreadable("syntax")
def obj(self, depth):
if depth > MAX_DEPTH: # the outermost counted as the first
raise Unreadable("depth")
self.i += 1
out = {}
self.ws()
if self.s[self.i:self.i + 1] == "}":
self.i += 1
return out
while True:
self.ws()
if self.s[self.i:self.i + 1] != '"':
raise Unreadable("syntax")
key = self.string()
self.ws()
if self.s[self.i:self.i + 1] != ":":
raise Unreadable("syntax")
self.i += 1
value = self.value(depth)
# §8.2: a member named twice, names compared after their escapes are read.
if key in out:
if "last-duplicate" not in PLANTS:
raise Unreadable("duplicate")
del out[key] # PLANT: keep the last
out[key] = value
self.ws()
c = self.s[self.i:self.i + 1]
self.i += 1
if c == "}":
return out
if c != ",":
raise Unreadable("syntax")
def arr(self, depth):
if depth > MAX_DEPTH:
raise Unreadable("depth")
self.i += 1
out = []
self.ws()
if self.s[self.i:self.i + 1] == "]":
self.i += 1
return out
while True:
out.append(self.value(depth))
self.ws()
c = self.s[self.i:self.i + 1]
self.i += 1
if c == "]":
return out
if c != ",":
raise Unreadable("syntax")
def string(self):
s = self.s
i = self.i + 1
parts = []
while True:
m = _PLAIN.match(s, i)
parts.append(m.group())
i = m.end()
c = s[i:i + 1]
if c == '"':
self.i = i + 1
return "".join(parts)
if c != "\\":
# §8.2: an unescaped control character (or the text's end)
raise Unreadable("control" if c else "syntax")
e = s[i + 1:i + 2]
if e in _UNESCAPE:
parts.append(_UNESCAPE[e])
i += 2
continue
if e != "u" or not _HEX4.fullmatch(s, i + 2, i + 6):
raise Unreadable("syntax")
u = int(s[i + 2:i + 6], 16)
i += 6
# §8.2: a high surrogate not followed at once by a low one, or a low alone.
if 0xD800 <= u <= 0xDBFF:
if s[i:i + 2] == "\\u" and _HEX4.fullmatch(s, i + 2, i + 6):
lo = int(s[i + 2:i + 6], 16)
if 0xDC00 <= lo <= 0xDFFF:
parts.append(chr(0x10000 + ((u - 0xD800) << 10) + (lo - 0xDC00)))
i += 6
continue
raise Unreadable("surrogate")
if 0xDC00 <= u <= 0xDFFF:
raise Unreadable("surrogate")
parts.append(chr(u)) # §8.2: a noncharacter is a character like any other
def read_json(raw):
"""§8.2: UTF-8, no byte order mark, one JSON value with whitespace around it."""
if raw.startswith(b"\xef\xbb\xbf"):
raise Unreadable("bom")
try:
text = raw.decode("utf-8") # strict: no overlong forms, no encoded surrogates
except UnicodeDecodeError:
raise Unreadable("utf8")
reader = _Reader(text)
value = reader.value(0)
reader.ws()
if reader.i != len(text):
raise Unreadable("syntax")
return value
def _numbers(value):
stack = [value]
while stack:
v = stack.pop()
if isinstance(v, Num):
yield v
elif isinstance(v, dict):
stack.extend(v.values())
elif isinstance(v, list):
stack.extend(v)
# ===================================================== 2. the two texts (§8.2)
_ESCAPED = re.compile(r'[\x00-\x1f"\\]')
_SHORT_ESCAPE = {'"': '\\"', "\\": "\\\\", "\b": "\\b", "\f": "\\f",
"\n": "\\n", "\r": "\\r", "\t": "\\t"}
def _quote(s):
# §8.2: '"' and '\' escaped, the five short forms, other C0 controls as \u00xx
# (lower case), every other character as its UTF-8 bytes, '/' and U+007F included.
return '"' + _ESCAPED.sub(
lambda m: _SHORT_ESCAPE.get(m.group(), "\\u%04x" % ord(m.group())), s) + '"'
def _digits(x):
"""For a finite x > 0: (s, n) with s the fewest digits that read back as x
(the nearest, a tie to the even last digit: Python's repr) and x = 0.s × 10^n."""
mant, _, exp = repr(x).partition("e")
whole, _, frac = mant.partition(".")
raw = whole + frac
digits = raw.lstrip("0")
lead = len(raw) - len(digits)
return digits.rstrip("0"), len(whole) - lead + int(exp or 0)
def es_number(x):
"""§8.2's canonical number: ECMAScript's Number::toString of the double."""
if x == 0:
return "0"
sign = "-" if x < 0 else ""
d, n = _digits(abs(x))
k = len(d)
if k <= n <= 21:
return sign + d + "0" * (n - k)
if 0 < n <= 21:
return sign + d[:n] + "." + d[n:]
if -6 < n <= 0:
return sign + "0." + "0" * (-n) + d
e = n - 1
return sign + (d if k == 1 else d[0] + "." + d[1:]) + "e" + ("+" if e >= 0 else "-") + str(abs(e))
def first_form_number(num):
"""§8.2's first-form number."""
t = num.text
# §8.2: without a "-" from 0 to 2^64 − 1, or with a "-" from −2^63 to −1, as
# its digits; so "-0" is a double: "-0.0".
if num.literal_whole() and t != "-0":
i = int(t) # at most 309 digits: longer ones are unreadable
if 0 <= i <= 2 ** 64 - 1 or -2 ** 63 <= i <= -1:
return str(i)
x = num.value
if x == 0:
return "-0.0" if math.copysign(1.0, x) < 0 else "0.0"
sign = "-" if x < 0 else ""
d, n = _digits(abs(x))
k = len(d)
if k <= n <= 16:
return sign + d + "0" * (n - k) + ".0"
if 0 < n <= 16:
return sign + d[:n] + "." + d[n:]
if -5 < n <= 0:
return sign + "0." + "0" * (-n) + d
# §8.2: then e, a sign (+ or -), and |n − 1| (1e+16, 1e-7)
e = n - 1
return sign + (d if k == 1 else d[0] + "." + d[1:]) + "e" + ("+" if e >= 0 else "-") + str(abs(e))
def _utf16(s):
return s.encode("utf-16-be")
def text_of(value, canonical):
"""§8.2: the canonical text, or (canonical False) the first form's compact text."""
out = []
_write(value, out, canonical)
return "".join(out)
def _write(v, out, canonical):
if v is None:
out.append("null")
elif v is True:
out.append("true")
elif v is False:
out.append("false")
elif isinstance(v, Num):
out.append(es_number(v.value) if canonical else first_form_number(v))
elif isinstance(v, str):
out.append(_quote(v))
elif isinstance(v, list):
out.append("[")
for j, x in enumerate(v):
if j:
out.append(",")
_write(x, out, canonical)
out.append("]")
else:
out.append("{")
# canonical: names in UTF-16 code-unit order; first form: as the job gives them
for j, k in enumerate(sorted(v, key=_utf16) if canonical else v):
if j:
out.append(",")
out.append(_quote(k))
out.append(":")
_write(v[k], out, canonical)
out.append("}")
# ===================================================================== 3. BLAKE3
_IV = (0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19)
_PERM = (2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8)
_M32 = 0xFFFFFFFF
_CHUNK_START, _CHUNK_END, _PARENT, _ROOT = 1, 2, 4, 8
def _g(v, a, b, c, d, x, y):
v[a] = (v[a] + v[b] + x) & _M32
t = v[d] ^ v[a]
v[d] = ((t >> 16) | (t << 16)) & _M32
v[c] = (v[c] + v[d]) & _M32
t = v[b] ^ v[c]
v[b] = ((t >> 12) | (t << 20)) & _M32
v[a] = (v[a] + v[b] + y) & _M32
t = v[d] ^ v[a]
v[d] = ((t >> 8) | (t << 24)) & _M32
v[c] = (v[c] + v[d]) & _M32
t = v[b] ^ v[c]
v[b] = ((t >> 7) | (t << 25)) & _M32
def _compress(cv, m, counter, block_len, flags):
v = list(cv) + list(_IV[:4]) + [counter & _M32, (counter >> 32) & _M32, block_len, flags]
m = list(m)
for _ in range(7):
_g(v, 0, 4, 8, 12, m[0], m[1])
_g(v, 1, 5, 9, 13, m[2], m[3])
_g(v, 2, 6, 10, 14, m[4], m[5])
_g(v, 3, 7, 11, 15, m[6], m[7])
_g(v, 0, 5, 10, 15, m[8], m[9])
_g(v, 1, 6, 11, 12, m[10], m[11])
_g(v, 2, 7, 8, 13, m[12], m[13])
_g(v, 3, 4, 9, 14, m[14], m[15])
m = [m[p] for p in _PERM]
return [v[i] ^ v[i + 8] for i in range(8)]
def _chunk_cv(chunk, counter, root):
cv = _IV
blocks = max(1, (len(chunk) + 63) // 64)
for b in range(blocks):
block = chunk[64 * b:64 * b + 64]
flags = _CHUNK_START if b == 0 else 0
if b == blocks - 1:
flags |= _CHUNK_END | (_ROOT if root else 0)
cv = _compress(cv, struct.unpack("<16I", block.ljust(64, b"\0")), counter, len(block), flags)
return cv
def _parent_cv(left, right, root):
return _compress(_IV, left + right, 0, 64, _PARENT | (_ROOT if root else 0))
def blake3(data):
"""BLAKE3, hash mode, 32 bytes."""
chunks = max(1, (len(data) + 1023) // 1024)
if chunks == 1:
return struct.pack("<8I", *_chunk_cv(data, 0, True))
stack = []
for i in range(chunks - 1):
cv = _chunk_cv(data[1024 * i:1024 * (i + 1)], i, False)
total = i + 1
while total & 1 == 0:
cv = _parent_cv(stack.pop(), cv, False)
total >>= 1
stack.append(cv)
cv = _chunk_cv(data[1024 * (chunks - 1):], chunks - 1, False)
while len(stack) > 1:
cv = _parent_cv(stack.pop(), cv, False)
return struct.pack("<8I", *_parent_cv(stack.pop(), cv, True))
# ============================================================ 4. Ed25519 (§8.2)
_P = 2 ** 255 - 19
_L = 2 ** 252 + 27742317777372353535851937790883648493
_D = -121665 * pow(121666, _P - 2, _P) % _P
_SQRT_M1 = pow(2, (_P - 1) // 4, _P)
_IDENTITY = (0, 1, 1, 0)
def _add(p, q):
x1, y1, z1, t1 = p
x2, y2, z2, t2 = q
a = (y1 - x1) * (y2 - x2) % _P
b = (y1 + x1) * (y2 + x2) % _P
c = 2 * t1 * t2 * _D % _P
d = 2 * z1 * z2 % _P
e, f, g, h = b - a, d - c, d + c, b + a
return (e * f % _P, g * h % _P, f * g % _P, e * h % _P)
def _mul(k, p):
q = _IDENTITY
while k:
if k & 1:
q = _add(q, p)
p = _add(p, p)
k >>= 1
return q
def _same_point(p, q):
return ((p[0] * q[2] - q[0] * p[2]) % _P == 0
and (p[1] * q[2] - q[1] * p[2]) % _P == 0)
def _decode_point(b):
"""§8.2 (RFC 8032 §5.1.3): the point, or None for y ≥ p, off the curve, or x = 0 signed."""
y = int.from_bytes(b, "little")
sign = y >> 255
y &= (1 << 255) - 1
if y >= _P:
return None
x2 = (y * y - 1) * pow(_D * y * y + 1, _P - 2, _P) % _P
x = pow(x2, (_P + 3) // 8, _P)
if (x * x - x2) % _P:
x = x * _SQRT_M1 % _P
if (x * x - x2) % _P:
return None
if x == 0 and sign:
return None
if x & 1 != sign:
x = _P - x
return (x, y, 1, x * y % _P)
def _encode_point(p):
zi = pow(p[2], _P - 2, _P)
x, y = p[0] * zi % _P, p[1] * zi % _P
return (y | ((x & 1) << 255)).to_bytes(32, "little")
def _small_order(p):
return _same_point(_mul(8, p), _IDENTITY)
_B = _decode_point((4 * pow(5, _P - 2, _P) % _P).to_bytes(32, "little"))
def key_point(key):
"""§8.2: the key A as a point, or None when the strict rules refuse it (bad_key)."""
a = _decode_point(key)
if a is None:
return None
if "lenient-key" in PLANTS: # PLANT: a library's default verify
return a
if _small_order(a) or not _same_point(_mul(_L, a), _IDENTITY):
return None
return a
def signature_holds(a, key, digest, sig):
"""§8.2: R decodes and is not of small order, S < ℓ, and [S]B = R + [k]A."""
r = _decode_point(sig[:32])
if r is None or ("lax-small-order-r" not in PLANTS and _small_order(r)):
return False
s = int.from_bytes(sig[32:], "little")
if s >= _L:
return False
k = int.from_bytes(hashlib.sha512(sig[:32] + key + digest).digest(), "little") % _L
return _same_point(_mul(s, _B), _add(r, _mul(k, a)))
def _ed25519_sign(seed, msg):
"""RFC 8032 §5.1.6, for the self-test only: (public key, signature)."""
h = hashlib.sha512(seed).digest()
a = (int.from_bytes(h[:32], "little") & ((1 << 254) - 8)) | (1 << 254)
public = _encode_point(_mul(a, _B))
r = int.from_bytes(hashlib.sha512(h[32:] + msg).digest(), "little") % _L
r_bytes = _encode_point(_mul(r, _B))
k = int.from_bytes(hashlib.sha512(r_bytes + public + msg).digest(), "little") % _L
return public, r_bytes + ((r + k * a) % _L).to_bytes(32, "little")
# =============================================================== 5. the seal
DOMAIN = b"wai:quantum-service-receipt"
_LOWER_HEX = re.compile(r"[0-9a-f]*")
def seal_digest(form_byte, q, t):
"""§8.2: BLAKE3(d ‖ u64(|Q|) ‖ Q ‖ u64(|T|) ‖ T), d the domain and its form byte."""
return blake3(DOMAIN + bytes([form_byte]) + struct.pack(">Q", len(q)) + q
+ struct.pack(">Q", len(t)) + t)
def _lower_hex(v, length):
return isinstance(v, str) and len(v) == length and _LOWER_HEX.fullmatch(v) is not None
def check_seal(request, receipt, body, reasons):
"""§8.4 receipt_form, digest_mismatch, bad_key, bad_signature, over the request and
the sealed body (a job's result less its receipt; a set's head). Returns (key, form)."""
form = None
if isinstance(receipt, dict):
if "canon" not in receipt:
form = "first"
elif receipt["canon"] == "rfc8785":
form = "rfc8785"
if (form is None
or ("no-alg" not in PLANTS and receipt.get("alg") != "ed25519")
or not _lower_hex(receipt.get("key"), 64)
or not _lower_hex(receipt.get("digest"), 64)
or not _lower_hex(receipt.get("signature"), 128)):
reasons.add("receipt_form") # and the next three are not checked
return None, None
key = bytes.fromhex(receipt["key"])
stated = bytes.fromhex(receipt["digest"])
sig = bytes.fromhex(receipt["signature"])
canonical = form == "rfc8785"
q = text_of(request, canonical).encode("utf-8")
t = text_of(body, canonical).encode("utf-8")
if stated != seal_digest(2 if canonical else 1, q, t):
reasons.add("digest_mismatch")
a = key_point(key)
if a is None:
reasons.add("bad_key") # and the signature is not checked
elif not signature_holds(a, key, stated, sig):
reasons.add("bad_signature") # over the digest the receipt states
return receipt["key"], form
def _first_form_digits(num):
"""§8.2: a whole number the first form seals by its digits (its writer's integer range)."""
if not num.literal_whole() or num.text == "-0":
return False
i = int(num.text)
return 0 <= i <= 2 ** 64 - 1 or -2 ** 63 <= i <= -1
def check_inexact(request, body, form, reasons):
# §8.4 inexact_number: a whole number written as one, in what the receipt seals
# (the request, and the result less its receipt; a set's request and head) and
# sealed as a double, is not a double, and is not the canonical text of the double
# it reads as. A receipt is of the first form when receipt_form is not reported and
# it has no canon; one receipt_form refuses names no form, and its numbers are
# read as a canonical receipt's (every number sealed as its double).
if any(writes_inexact(part, form) for part in (request, body)):
reasons.add("inexact_number")
def writes_inexact(value, form):
"""§8.2, §8.4: whether a value writes a whole number, sealed as a double, that is no
double and not the canonical text of the double it reads as, by a receipt's form."""
if "no-inexact" in PLANTS: # PLANT
return False
first = form == "first"
for n in _numbers(value):
if not n.literal_whole() or (first and _first_form_digits(n)):
continue
if int(n.text) == int(n.value):
continue # the double holds it exactly
# §8.2: its one taken spelling, RFC 8785's for a whole double whose magnitude is
# from 2^53 to under 10^21, a negative with its "-": shortest digits padded with
# zeros (2^60 as 1152921504606847000).
if "no-canonical-spelling" not in PLANTS and n.text == es_number(n.value):
continue
return True
return False
# ======================================================== 6. a provider's result
STEPS = ("mitigation", "twirling", "decoupling", "remapping", "optimisation")
COUNTS_SOURCES = ("shots", "vendor_counts", "probabilities")
BASES = ("rzsxxcz", "prxcz", "gpizz", "prxrzxx")
MAX_LISTED = 65536
_OUTCOME = re.compile(r"[01]*")
_INDEX = re.compile(r"0|[1-9][0-9]*") # §8.4: an index in decimal, with no leading zero
_QASM_INDEX = re.compile(r"\$([0-9]+)") # §8.4: a "$" and one or more decimal digits
_MODEL_NAME = object() # a row's placeholder: the noise model's name
def _row(fields, settings, steps, verbatim):
row = {"stated_by": "client", "sent": {"fields": fields, "settings": settings},
"verbatim": verbatim}
for step in STEPS:
row[step] = steps.get(step, "default")
return row
_CLOUD_TASKS_FIELDS = ["action", "clientToken", "deviceArn", "outputS3Bucket",
"outputS3KeyPrefix", "shots"]
def _any_provenance(provenance):
return True
def _silicon(provenance):
return provenance == "silicon"
def _not_silicon(provenance):
return provenance != "silicon"
# §8.3: each built-in kind's rows as (the provenances it holds for, the counts'
# sources it gives, the execution less its note): cloud-tasks' first row for
# silicon, its second for any other; native-turns' row with noise for any but
# silicon (its model's name a string, not empty), its row without noise for any.
# §8.4: only a kind with rows constrains counts_source, to what the rows that hold
# for its provenance give; http, process and later kinds give any of the three.
_SHOTS, _VENDOR, _PROBABILITIES = ("shots",), ("vendor_counts",), ("probabilities",)
_TASKS = ("shots", "probabilities")
ROWS = {
"sampler-v2": [(_any_provenance, _SHOTS, _row(
["backend", "params", "program_id"],
{"/params/options/dynamical_decoupling/enable": False,
"/params/options/twirling/enable_gates": False,
"/params/options/twirling/enable_measure": False},
{"decoupling": "off", "twirling": "off"}, False))],
"prx-circuits": [(_any_provenance, _VENDOR, _row(["circuits", "shots"], {}, {}, False))],
"native-turns": [
(_any_provenance, _PROBABILITIES, _row(
["backend", "input", "settings", "shots", "type"],
{"/input/gateset": "native", "/settings/error_mitigation/debiasing": False},
{"mitigation": "off"}, False)),
(_not_silicon, _PROBABILITIES, _row(
["backend", "input", "noise", "settings", "shots", "type"],
{"/input/gateset": "native", "/settings/error_mitigation/debiasing": False,
"/noise/model": _MODEL_NAME},
{"mitigation": "off"}, False))],
"cloud-tasks": [
(_silicon, _TASKS, _row(_CLOUD_TASKS_FIELDS, {"verbatim_box": True},
{"remapping": "off", "optimisation": "off"}, True)),
(_not_silicon, _TASKS, _row(_CLOUD_TASKS_FIELDS, {}, {}, False))],
}
def _whole(v):
"""§8.4: a number whose value is whole, however it is written, however large
(only a count's value has a ceiling, and check_counts holds it)."""
if "whole-cap" in PLANTS and isinstance(v, Num) and abs(v.value) > MAX_SAFE:
return False # PLANT
return isinstance(v, Num) and v.value.is_integer()
def _same(a, b):
"""JSON equality, numbers by value (spelling is not sealed)."""
if isinstance(a, Num) or isinstance(b, Num):
return isinstance(a, Num) and isinstance(b, Num) and a.value == b.value
if isinstance(a, bool) or isinstance(b, bool) or a is None or b is None:
return a is b
if isinstance(a, str) or isinstance(b, str):
return isinstance(a, str) and isinstance(b, str) and a == b
if isinstance(a, list) and isinstance(b, list):
return len(a) == len(b) and all(_same(x, y) for x, y in zip(a, b))
if isinstance(a, dict) and isinstance(b, dict):
return set(a) == set(b) and all(_same(a[k], b[k]) for k in a)
return False
def read_class(provenance):
"""§8.4: the class a provenance gives: measured, simulated, or None."""
if provenance == "silicon": # §8.1: silicon exactly; "silicon:…" gives none
return "measured"
if isinstance(provenance, str) and provenance.split(":", 1)[0] in ("simulator", "emulator"):
return "simulated"
return None
def _member(obj, *path):
for name in path:
if not isinstance(obj, dict) or name not in obj:
return None
obj = obj[name]
return obj
def check_class(result, provider, stated, reasons):
# §8.4 provider_class.
accuracy = result.get("accuracy")
cls = accuracy.get("class") if isinstance(accuracy, dict) else None
if not provider:
if cls in ("measured", "simulated"):
reasons.add("provider_class")
return
wanted = read_class(_member(result, "provider", "provenance")) if stated else "measured"
planted = "measured-simulator" in PLANTS and stated and wanted == "simulated" and cls == "measured"
if (wanted is None or cls != wanted) and not planted:
reasons.add("provider_class")
if isinstance(accuracy, dict) and "approximate" in accuracy:
if accuracy["approximate"] is not True or not stated or cls != "simulated":
reasons.add("provider_class")
def check_counts(result, reasons):
# §8.4 counts.
counts = result.get("counts")
shots, omitted, distinct = (result.get(k) for k in ("shots", "omitted_shots", "distinct_outcomes"))
ok = isinstance(counts, dict)
total, widths = 0, set()
if ok:
for outcome, n in counts.items():
if not _OUTCOME.fullmatch(outcome) or not (_whole(n) and 1 <= n.value <= MAX_SAFE):
ok = False
break
widths.add(len(outcome))
total += int(n.value)
ok = ok and len(widths) <= 1
# §8.4: shots a whole number of at least 1; omitted_shots and distinct_outcomes
# whole numbers of at least 0. The counts and omitted_shots sum to accepted_shots, the
# shots the device kept, when the result has that member (a whole number of at least 1,
# whatever its value: null is present), and to shots when it has none (§8.1).
kept = result["accepted_shots"] if "accepted_shots" in result else shots
if (ok and _whole(shots) and shots.value >= 1 and _whole(kept) and kept.value >= 1
and _whole(omitted) and omitted.value >= 0 and _whole(distinct) and distinct.value >= 0):
listed = len(counts)
omitted_n, distinct_n = int(omitted.value), int(distinct.value)
if total + omitted_n != int(kept.value):
ok = False
elif omitted_n == 0:
ok = distinct_n == listed
else:
ok = listed == MAX_LISTED and distinct_n > listed
else:
ok = False
if not ok:
reasons.add("counts")
def qubit_names_hold(names, compiled):
"""§8.4: compiled.qubit_names as given: an object from indices to non-empty strings,
holding every entry of layout and final_layout, written in decimal in full, and
every index qasm3 acts on, when qasm3 is a string."""
if not isinstance(names, dict):
return False
if not all(_INDEX.fullmatch(k) and isinstance(v, str) and v for k, v in names.items()):
return False
# SPEC-GAP: [N32] "in full": the exact digits of the double the entry reads as,
# so 1.0 is "1" and 1e23 is "99999999999999991611392". An entry that is no
# whole number is provider_members' already, and is not looked for here.
for name in ("layout", "final_layout"):
entries = compiled.get(name)
if isinstance(entries, list):
for q in entries:
if _whole(q) and str(int(q.value)) not in names:
return False
qasm3 = compiled.get("qasm3")
if "names-layout-only" not in PLANTS and isinstance(qasm3, str): # PLANT: skip it
# §8.4: each "$" followed by one or more decimal digits names the index those
# digits read as, written with no leading zero; a "$" with no digit names none.
# §8.4: a "$" anywhere in it, followed by the ASCII digits 0 to 9.
for m in _QASM_INDEX.finditer(qasm3):
if (m.group(1).lstrip("0") or "0") not in names:
return False
return True
def check_members(result, reasons):
# §8.4 provider_members: each member, present and of its type.
def text(v):
return isinstance(v, str) and v != ""
def natural(v): # §8.4: a whole number of at least 0
return _whole(v) and v.value >= 0
def naturals(v):
return isinstance(v, list) and all(natural(x) for x in v)
p = result.get("provider")
c = result.get("compiled")
j = result.get("job")
cost = result.get("cost")
energy = result.get("energy")
engine = result.get("engine")
p = p if isinstance(p, dict) else {}
c = c if isinstance(c, dict) else {}
j = j if isinstance(j, dict) else {}
cost = cost if isinstance(cost, dict) else {}
energy = energy if isinstance(energy, dict) else {}
engine = engine if isinstance(engine, dict) else {}
charged = cost.get("charged", 0)
# §8.4: compiled.qubit_names is required of cloud-tasks and prx-circuits when the
# execution is stated by client, and optional otherwise; when given it holds its
# shape. SPEC-GAP: [N31] required on a cloud-tasks simulator too, as §8.4 says,
# though §8.1 names only "a cloud-tasks processor's labels". §8.4: null is
# given, and is no object.
names_needed = (p.get("kind") in ("cloud-tasks", "prx-circuits")
and _member(result, "execution", "stated_by") == "client")
checks = (
all(text(p.get(f)) for f in ("name", "kind", "protocol", "device")),
read_class(p.get("provenance")) is not None,
_lower_hex(p.get("describe"), 64),
_whole(p.get("qubits")) and p["qubits"].value >= 1,
"basis" in p and "basis" in c and _same(p["basis"], c["basis"]),
"calibration" in result and (result["calibration"] is None or isinstance(result["calibration"], str)),
c.get("basis") in BASES if isinstance(c.get("basis"), str) else False,
_lower_hex(c.get("program"), 64),
isinstance(c.get("qasm3"), str),
all(natural(c.get(f)) for f in ("native_gates", "two_qubit_gates", "swaps")),
naturals(c.get("layout")) and naturals(c.get("final_layout")),
isinstance(c.get("checked"), str),
qubit_names_hold(c["qubit_names"], c) if "qubit_names" in c else not names_needed,
text(j.get("id")) and natural(j.get("polls")),
isinstance(_member(result, "ideal", "computed"), bool),
isinstance(cost.get("free"), bool) and isinstance(cost.get("confirmed"), bool),
isinstance(cost.get("estimate"), dict), # §8.1: with `unknown` when none was known
charged is None or (isinstance(charged, dict) and isinstance(charged.get("amount"), str)
and isinstance(charged.get("currency"), str)),
isinstance(energy.get("unmetered"), str),
"service_kwh" not in energy or isinstance(energy.get("service_kwh_is"), str),
result.get("schema") == "wai.quantum.job-result/1",
engine.get("name") == "wai-quantum" and isinstance(engine.get("version"), str),
)
if not all(checks):
reasons.add("provider_members")
def execution_rules_hold(e):
"""§8.3's rules of an execution."""
if not isinstance(e, dict):
return False
if set(e) - set(STEPS + ("stated_by", "verbatim", "sent", "note")):
return False # "and nothing else"
if any(m not in e for m in STEPS + ("stated_by", "verbatim")):
return False
by = e["stated_by"]
# §8.3: client: off, on or default, verbatim true or false, sent given;
# provider: off, on, none or unknown, verbatim true or false, no sent;
# nobody: unknown, verbatim null, no sent.
if by == "client":
allowed, verbatim_ok, sent = ("off", "on", "default"), isinstance(e["verbatim"], bool), True
elif by == "provider":
allowed, verbatim_ok, sent = ("off", "on", "none", "unknown"), isinstance(e["verbatim"], bool), False
elif by == "nobody":
allowed, verbatim_ok, sent = ("unknown",), e["verbatim"] is None, False
else:
return False
if not verbatim_ok or ("sent" in e) != sent:
return False
if not all(isinstance(e[s], str) and e[s] in allowed for s in STEPS):
return False
if "note" in e and not isinstance(e["note"], str):
return False
if e["verbatim"] is True and not (e["remapping"] in ("off", "none")
and e["optimisation"] in ("off", "none")):
return False
if by != "client":
return True
s = e["sent"]
if not isinstance(s, dict) or set(s) != {"fields", "settings"}:
return False
fields, settings = s["fields"], s["settings"]
if not isinstance(fields, list) or not all(isinstance(f, str) for f in fields):
return False
encoded = [f.encode("utf-8") for f in fields]
if any(a >= b for a, b in zip(encoded, encoded[1:])):
return False # each once, in increasing order of their UTF-8 bytes
if not isinstance(settings, dict):
return False
# §8.3: each key of settings either begins with "/", and its first reference
# token (up to the next "/", its ~1 and ~0 read as "/" and "~") is one of the
# fields, the rest of it not read; or is a name, not empty, not beginning "/".
named = set(fields) # a list here would make this quadratic
for k in settings:
if not k.startswith("/"):
if not k:
return False
continue
first = k[1:].split("/", 1)[0].replace("~1", "/").replace("~0", "~")
if first not in named:
return False
if any(e[step] in ("off", "on") for step in STEPS) and not settings:
return False # a step said off or on says by which setting
return True
def _matches_row(e, row):
plain = dict((k, v) for k, v in e.items() if k != "note")
if set(plain) != set(row):
return False
for name, want in row.items():
got = plain[name]
if name != "sent":
if not (got is want if isinstance(want, bool) else got == want):
return False
continue
if not (isinstance(got.get("fields"), list) and got["fields"] == want["fields"]):
return False
have = got.get("settings")
if not isinstance(have, dict) or set(have) != set(want["settings"]):
return False
for k, v in want["settings"].items():
if v is _MODEL_NAME:
if not (isinstance(have[k], str) and have[k]):
return False
elif not (have[k] is v if isinstance(v, bool) else have[k] == v):
return False
return True
def check_stated(result, reasons):
"""§8.4's rules for the stated form beyond provider_members."""
kind = _member(result, "provider", "kind")
kind = kind if isinstance(kind, str) else None
source = result.get("counts_source")
provenance = _member(result, "provider", "provenance")
if not (isinstance(source, str) and source in COUNTS_SOURCES
and (kind not in ROWS or any(holds(provenance) and source in sources
for holds, sources, _ in ROWS[kind]))):
reasons.add("counts_source")
e = result.get("execution")
# §8.4: the rules of §8.3; for a kind with rows, one of the rows that hold for
# its provenance, or stated by nobody; for http and process, stated by provider
# or nobody. A later kind is held to §8.3's rules alone.
if not execution_rules_hold(e):
reasons.add("execution")
elif kind in ROWS and e["stated_by"] != "nobody" and not any(
holds(provenance) and _matches_row(e, row) for holds, _, row in ROWS[kind]):
reasons.add("execution")
elif kind in ("http", "process") and e["stated_by"] not in ("provider", "nobody"):
reasons.add("execution")
# §8.4 compiled_program, when qasm3 is a string and program 64 lower-case hex digits.
c = result.get("compiled")
if (isinstance(c, dict) and isinstance(c.get("qasm3"), str) and _lower_hex(c.get("program"), 64)
and bytes.fromhex(c["program"]) != blake3(c["qasm3"].encode("utf-8"))):
reasons.add("compiled_program")
# §8.4 cost_confirmation: confirmed true on a free run, or false on one that is not;
# or a member confirmed_by (null included) that is not "submit", or "submit" beside a
# confirmed that is not true (§8.1: a provider's own record takes the job's submit as
# the confirmation of a run that is not free, and of no other).
cost = result.get("cost")
if isinstance(cost, dict):
free, confirmed = cost.get("free"), cost.get("confirmed")
if isinstance(free, bool) and isinstance(confirmed, bool) and free is confirmed:
reasons.add("cost_confirmation")
if "confirmed_by" in cost and not (cost["confirmed_by"] == "submit" and confirmed is True):
reasons.add("cost_confirmation")
def check_provider(request, result, reasons):
stated = "counts_source" in result or "execution" in result
check_class(result, True, stated, reasons)
# §8.4 request_provider: provider.name a string equal to the request's provider.
# §8.4, §8.7: or, when the request gives none and its contract allows a provider,
# the one its planner chose.
name, asked = _member(result, "provider", "name"), request.get("provider")
if asked is None and _member(request, "contract", "providers") == "allowed":
choice = _member(result, "planner", "choice")
asked = choice[len("provider:"):] if isinstance(choice, str) and choice.startswith("provider:") else None
if not (isinstance(name, str) and isinstance(asked, str) and name == asked):
reasons.add("request_provider")
# §8.4 request_shots: the request's shots, 1024 when it gives none or null.
want = request.get("shots")
want = Num("1024", 1024.0) if want is None else want
if "shots" not in result or not _same(result["shots"], want):
reasons.add("request_shots")
check_counts(result, reasons)
if stated:
check_members(result, reasons)
check_stated(result, reasons)
def _plain(v):
"""A value as Python's json module writes it, for the verdict line."""
if isinstance(v, Num):
return int(v.value) if v.value.is_integer() and abs(v.value) < 2 ** 63 else v.value
if isinstance(v, dict):
return dict((k, _plain(x)) for k, x in v.items())
if isinstance(v, list):
return [_plain(x) for x in v]
return v
def provider_statement(result):
"""§8.4: for a provider's result, its form, its class as its provenance reads it,
and in the stated form its counts' source and its execution."""
stated = "counts_source" in result or "execution" in result
accuracy = result.get("accuracy")
return {
"form": "stated" if stated else "earlier",
"class": _plain(accuracy.get("class")) if isinstance(accuracy, dict) else None,
"read_as": read_class(_member(result, "provider", "provenance")),
"counts_source": _plain(result.get("counts_source")) if stated else None,
"execution": _plain(result.get("execution")) if stated else None,
}
# ================================================== 6b. a job under a contract (§8.7)
CONTRACT_MEMBERS = ("exactness", "max_cost", "deadline_seconds", "max_joules", "providers")
MEETS = {
"bit-exact": ("bit-exact",),
"exact": ("bit-exact", "exact"),
"single": ("bit-exact", "exact", "single"),
"bounded": ("bit-exact", "exact", "bounded"),
"estimate": ("bit-exact", "exact", "bounded", "estimate"),
"heuristic": ("bit-exact", "exact", "single", "bounded", "estimate", "heuristic"),
"measured": ("measured",),
"simulated": ("simulated",),
}
CLASSES_WANTED = tuple(MEETS) + ("any",)
LADDER = ("bit-exact", "exact", "single", "bounded", "estimate", "heuristic")
LEAVES_OUT = ("time", "amount", "energy", "mitigation", "decoder", "charged", "cancel")
QUESTIONS = ("noise", "counts", "expectations", "amplitudes")
_DECIMAL = re.compile(r"[0-9]+(?:\.[0-9]+)?")
_GPU_METHODS = ("method:statevector_single", "method:cutrank_single")
MAX_SECONDS = 1e12 # §8.7: the most seconds a price may state
MAX_AMOUNT = 64 # §8.7: the most characters an amount may have
# §8.7: each built-in method's rank in auto's order, by question (noise, counts,
# expectations, amplitudes); None where auto does not try it for that question.
AUTO_RANKS = {
"exact": (None, 20, 20, 10),
"statevector": (None, 30, 30, 20),
"statevector_single": (None, 40, 40, 30),
"stabilizer": (20, 10, 10, None),
"pauli": (None, None, 60, None),
"mps": (None, 60, 70, 70),
"stabilizer_rank": (None, None, 50, 50),
"tensor_network": (None, None, None, 60),
"cutrank": (None, 50, None, 40),
"cutrank_single": (None, None, None, None),
"density_matrix": (10, None, None, None),
"trajectories": (30, None, None, None),
"pulse": (None, None, None, None),
}
# §8.7: the classes each built-in method can have; which of two, on a job, by _route_class.
METHOD_CLASSES = {
"exact": ("bit-exact",),
"statevector": ("exact",),
"statevector_single": ("single",),
"stabilizer": ("exact", "estimate"),
"pauli": ("bounded",),
"mps": ("exact", "heuristic"),
"stabilizer_rank": ("exact", "estimate"),
"tensor_network": ("exact",),
"cutrank": ("exact", "single"),
"cutrank_single": ("single",),
"density_matrix": ("exact",),
"trajectories": ("estimate",),
"pulse": ("bounded",),
}
_GPU_NAMES = ("statevector_single", "cutrank_single")
def meets(wanted, got):
"""§8.7's table. `any` takes every class; a class nobody knows meets nothing else."""
return wanted == "any" or (wanted in MEETS and got in MEETS[wanted])
def _is_decimal(s):
"""§8.7: digits, optionally '.' and digits, at most 64 characters."""
return isinstance(s, str) and len(s) <= MAX_AMOUNT and _DECIMAL.fullmatch(s) is not None
def _value_of(v):
return v.value if isinstance(v, Num) else None
def _same_keys(v, keys):
return isinstance(v, dict) and set(v) == set(keys)
def read_contract(c):
"""§8.7: the contract as (exactness, max_cost, deadline, joules, providers), or None
when it is not of its form. Null is absent."""
if not isinstance(c, dict) or any(k not in CONTRACT_MEMBERS for k in c):
return None
exactness = c.get("exactness")
if exactness is not None and exactness not in CLASSES_WANTED:
return None
cost = c.get("max_cost")
if cost is not None:
if not (isinstance(cost, dict) and len(cost) == 2 and _is_decimal(cost.get("amount"))
and isinstance(cost.get("currency"), str) and cost["currency"]):
return None
for k in ("deadline_seconds", "max_joules"):
v = c.get(k)
if v is not None and not (isinstance(v, Num) and v.value > 0):
return None
providers = c.get("providers")
if providers is not None and providers not in ("never", "allowed"):
return None
return {"exactness": exactness, "max_cost": cost,
"deadline": c["deadline_seconds"].value if c.get("deadline_seconds") is not None else None,
"joules": c["max_joules"].value if c.get("max_joules") is not None else None,
"providers": providers}
def _seconds_ok(v):
return isinstance(v, Num) and 0 <= v.value <= MAX_SECONDS
def _price_form(p, local):
"""§8.7: a price. A local route's money is free; seconds and amounts are bounded."""
if not isinstance(p, dict):
return False
m = p.get("money")
if not isinstance(m, dict):
return False
if m.get("free") is False:
if local or not (isinstance(m.get("unknown"), str) or (isinstance(m.get("amount"), str) and isinstance(m.get("currency"), str))):
return False
elif m.get("free") is not True:
return False
if "at_least" in m and m["at_least"] is not True:
return False
if "amount" in m and not (isinstance(m["amount"], str) and len(m["amount"]) <= MAX_AMOUNT):
return False
t = p.get("time")
if not isinstance(t, dict) or not (t.get("seconds") is None or _seconds_ok(t["seconds"])):
return False
e = p.get("energy")
if not isinstance(e, dict) or not (e.get("joules") is None or isinstance(e["joules"], Num)):
return False
if any(k in e and not isinstance(e[k], str) for k in ("watch", "unwatched")) or ("watch" in e and "unwatched" in e):
return False
left = p.get("leaves_out")
if not isinstance(left, list) or any(w not in LEAVES_OUT for w in left):
return False
for k in ("memory_bytes", "work"):
# A method's are whole numbers, and a provider's null: it states neither.
if k not in p or not ((_whole(p[k]) and p[k].value >= 0) if local else p[k] is None):
return False
return True
def _route_form(r):
if not isinstance(r, dict):
return False
name, kind = r.get("route"), r.get("kind")
if not isinstance(name, str):
return False
local = name.startswith("method:") and len(name) > 7 and kind == "local"
if not (local or (name.startswith("provider:") and len(name) > 9 and kind == "provider")):
return False
outcome = r.get("outcome")
if outcome in ("chosen", "met"):
if "rejected" in r:
return False
elif outcome == "rejected":
rej = r.get("rejected")
if not (isinstance(rej, dict) and isinstance(rej.get("code"), str) and isinstance(rej.get("why"), str)):
return False
else:
return False
if "price" not in r:
return False
if r["price"] is not None and not _price_form(r["price"], local):
return False
if local:
if "auto_rank" not in r or not (r["auto_rank"] is None or (_whole(r["auto_rank"]) and r["auto_rank"].value >= 0)):
return False
return isinstance(r.get("class"), str) and isinstance(r.get("host_dependent"), bool)
def _class_of_method(method, cls):
"""§8.7: whether cls is one the built-in method has; any class of another."""
return method not in METHOD_CLASSES or cls in METHOD_CLASSES[method]
def _states_itself(r, request):
"""§8.7: a built-in method has the class its table gives it on this request, and
depends on the host only when it runs on a GPU; a provider's route depends on it."""
name = r["route"]
cls = r["class"]
if not name.startswith("method:"):
# A provider's route has the class its provenance gives.
given = read_class(r.get("provenance"))
return r["host_dependent"] is True and (given is None or cls == given)
m = name[len("method:"):]
if m not in METHOD_CLASSES:
return r["host_dependent"] is True # a method the host registered is its own code
options = request.get("options")
given = lambda k: isinstance(options, dict) and options.get(k) is not None
if m == "stabilizer":
want = "estimate" if request.get("noise") is not None or request.get("target") is not None else "exact"
if cls != want:
return False
if m == "stabilizer_rank" and cls != ("estimate" if given("terms") or given("epsilon") else "exact"):
return False
# Every other method but cut-rank (whose plan says which table fits) has the one
# class its table gives: the first each class it declares meets.
if m not in ("stabilizer", "stabilizer_rank", "cutrank"):
declared = METHOD_CLASSES[m]
worst = declared[0] if len(declared) == 1 else next((c for c in LADDER if all(meets(c, d) for d in declared)), None)
if cls != worst:
return False
return cls in METHOD_CLASSES[m] and r["host_dependent"] is (m in _GPU_NAMES)
def _ran_as_routed(routes, choice, result):
"""§8.7: the route chosen is what ran; for a provider's, the result's provider is the
device and provenance it names, where it names them, and the result's cost is its money."""
r = next((x for x in routes if x["route"] == choice), None)
if r is None or r["kind"] != "provider":
return True
money = _member(r, "price", "money")
cost = result.get("cost")
provider = result.get("provider")
if not (isinstance(money, dict) and isinstance(cost, dict) and isinstance(provider, dict)):
return False
estimate = cost.get("estimate") if isinstance(cost.get("estimate"), dict) else {}
return (all(k not in r or _alike(r[k], provider.get(k)) for k in ("device", "provenance"))
and _alike(cost.get("free"), money.get("free"))
and all(_alike(estimate.get(k), money.get(k)) for k in ("amount", "currency", "unit", "at_least")))
def _alike(a, b):
"""§8.7: two members alike: numbers by value (7 and 7.0, -0 and 0), a boolean only
to a boolean, and null as an absent member."""
if isinstance(a, Num) or isinstance(b, Num):
return isinstance(a, Num) and isinstance(b, Num) and float(a.value) == float(b.value)
if isinstance(a, bool) or isinstance(b, bool):
return isinstance(a, bool) and isinstance(b, bool) and a == b
# Lists and objects member by member, by the same rule.
if isinstance(a, list) or isinstance(b, list):
return isinstance(a, list) and isinstance(b, list) and len(a) == len(b) and all(_alike(x, y) for x, y in zip(a, b))
if isinstance(a, dict) or isinstance(b, dict):
return isinstance(a, dict) and isinstance(b, dict) and all(_alike(a.get(k), b.get(k)) for k in set(a) | set(b))
return a == b
def _planner_form(p):
if not isinstance(p, dict) or p.get("format") != "wai.quantum.planner/1":
return False
if not (p.get("wanted") is None or isinstance(p["wanted"], str)):
return False
if "wanted_from" not in p:
return False
if p["wanted_from"] is None:
if p.get("wanted") is not None:
return False
elif p["wanted_from"] not in ("contract", "named", "auto"):
return False
routes = p.get("routes")
if not isinstance(routes, list) or not routes or not all(_route_form(r) for r in routes):
return False
names = [r["route"] for r in routes]
if len(set(names)) != len(names):
return False
for k in ("named", "auto"):
if not (p.get(k) is None or p[k] in names):
return False
if p.get("question") not in QUESTIONS or p.get("choice") not in names:
return False
host = p.get("host")
if not isinstance(host, dict) or not (_whole(host.get("job_bytes")) and host["job_bytes"].value >= 0):
return False
providers = host.get("providers")
if not isinstance(providers, list) or not all(isinstance(x, str) for x in providers):
return False
return isinstance(p.get("why"), str) and isinstance(p.get("stable"), dict) and isinstance(p.get("kept"), dict)
def _request_names(request):
"""§8.7: provider:<name> for the provider a request names, else method:<name> for a
method other than auto, else None."""
provider = request.get("provider")
if isinstance(provider, str):
return "provider:" + provider
m = request.get("method")
if isinstance(m, str) and m != "auto":
return "method:" + m
return None
def _question(request):
"""§8.7: the question a job asks, from its request alone."""
def listed(k):
v = request.get(k)
return isinstance(v, list) and len(v) > 0
observables, amplitudes = listed("observables"), listed("amplitudes")
shots = request.get("shots")
if isinstance(shots, Num) and shots.literal_whole() and not shots.text.startswith("-") and int(shots.text) <= 2 ** 64 - 1:
shots = int(shots.text)
else:
shots = 1024 if not observables and not amplitudes else 0
if request.get("noise") is not None:
return "noise"
if shots > 0:
return "counts"
if observables and not amplitudes:
return "expectations"
return "amplitudes"
def _fabric(request):
f = request.get("fabric")
if f is None or f == "auto":
return "free"
return "cpu" if f == "cpu" else "placed"
def _auto(routes, request, named):
"""§8.7: the route auto picks, from the routes."""
if named is not None:
return None
if _fabric(request) == "placed":
for r in routes:
if r["route"] == "method:statevector" and r["kind"] == "local" and r["price"] is not None:
return "method:statevector"
return None
best = None
for i, r in enumerate(routes):
if r["kind"] == "local" and r["price"] is not None and r.get("auto_rank") is not None:
key = (r["auto_rank"].value, i)
if best is None or key < best[0]:
best = (key, r["route"])
return best[1] if best else None
def _gate(r, contract, request, named, wanted, from_contract, job_bytes):
"""§8.7's rules, in order: the first that applies, or None."""
name, price = r["route"], r["price"]
is_provider = name.startswith("provider:")
# 1
if named is not None and name != named:
return "not_named"
# 2
if named is None:
fabric = _fabric(request)
if fabric == "cpu" and name in _GPU_METHODS:
return "fabric"
if fabric == "placed" and name != "method:statevector":
return "fabric"
cls = r["class"]
# 3
if cls == "unknown" and price is None:
return "cannot"
# 4
if wanted is not None:
if not meets(wanted, cls) or (from_contract and wanted == "simulated" and r.get("approximate") is True):
return "class"
elif is_provider:
return "class"
# 5
if price is None:
return "cannot"
# 6
memory = _value_of(price["memory_bytes"])
if memory is not None and memory > job_bytes:
return "memory"
# 7
if is_provider and contract["providers"] != "allowed":
return "providers"
# 8
if contract["deadline"] is not None:
seconds = _value_of(price["time"].get("seconds"))
if seconds is None:
return "deadline_unknown"
if seconds > contract["deadline"]:
return "deadline"
# 9
money = price["money"]
if is_provider and money.get("free") is not True:
ceiling = contract["max_cost"]
if ceiling is None:
if named != name:
return "cost_no_ceiling"
else:
amount, currency = money.get("amount"), money.get("currency")
if not (_is_decimal(amount) and isinstance(currency, str)):
return "cost_unknown"
if currency != ceiling["currency"]:
return "cost_currency"
if fractions.Fraction(amount) > fractions.Fraction(ceiling["amount"]):
return "cost"
if money.get("at_least") is True:
return "cost_at_least"
# 10
if contract["joules"] is not None:
joules = _value_of(price["energy"].get("joules"))
if not isinstance(price["energy"].get("watch"), str):
return "energy_unwatched"
if joules is not None and joules > contract["joules"]:
return "energy"
return None
def _order_key(r):
"""§8.7's order: money (free, then an amount in decimals by value, then any other),
time to the nearest millisecond (halves up; a stated one first), local first,
memory, name."""
p = r["price"]
money = p["money"]
if money.get("free") is True:
cost = (0, fractions.Fraction(0))
elif _is_decimal(money.get("amount")):
cost = (1, fractions.Fraction(money["amount"]))
else:
cost = (2, fractions.Fraction(0))
seconds = _value_of(p["time"].get("seconds"))
time = (1, 0) if seconds is None else (0, math.floor(seconds * 1000.0 + 0.5))
return (cost, time, 0 if r["kind"] == "local" else 1, _value_of(p["memory_bytes"]) or 0.0, r["route"].encode("utf-8"))
def _picked(routes, auto, contract, passes):
"""§8.7's choice, of the routes the rules let through."""
let_through = [r for r in routes if passes(r)]
if contract["exactness"] is None and auto is not None:
for r in let_through:
if r["route"] == auto:
return r["route"]
return min(let_through, key=_order_key)["route"] if let_through else None
def _stable_holds(p, routes, contract):
"""§8.7 stable: routes, digest and choice as the routes give them."""
stable = p["stable"]
covered = [r for r in routes if r["kind"] == "local" and r["host_dependent"] is False]
facts = []
for r in covered:
price = r["price"] if isinstance(r["price"], dict) else {}
facts.append({"route": r["route"], "class": r["class"], "seconds": _member(price, "time", "seconds"),
"memory_bytes": price.get("memory_bytes"), "work": price.get("work")})
digest = blake3(text_of({"job_bytes": p["host"]["job_bytes"], "routes": facts}, True).encode("utf-8")).hex()
names = [r["route"] for r in covered]
others = all(_member(r, "rejected", "code") in ("not_named", "fabric", "class") for r in routes if r["host_dependent"] is not False)
choice = p["choice"] in names and others and contract["providers"] != "allowed" and contract["joules"] is None
return stable.get("routes") == names and stable.get("digest") == digest and stable.get("choice") is choice
def _kept_holds(p, contract, result):
"""§8.7 kept: exactly a member for each the contract gives, each of exactly its
members, each as its table says."""
kept = p["kept"]
asked = (("deadline", contract["deadline"] is not None), ("energy", contract["joules"] is not None), ("cost", contract["max_cost"] is not None))
if len(kept) != sum(1 for _, a in asked if a) or any((n in kept) != a for n, a in asked):
return False
if contract["deadline"] is not None:
d = contract["deadline"]
k = kept["deadline"]
if not _same_keys(k, ("seconds", "elapsed_ms", "kept")):
return False
e = k.get("elapsed_ms")
if not (e is None or (_whole(e) and e.value >= 0)):
return False
want = None if e is None else e.value <= d * 1000.0
if _value_of(k.get("seconds")) != d or k.get("kept") is not want:
return False
# A method's time is its result's, where its result states one.
if result.get("method") != "provider" and "elapsed_ms" in result and _value_of(result.get("elapsed_ms")) != _value_of(e):
return False
if contract["joules"] is not None:
j = contract["joules"]
k = kept["energy"]
if not _same_keys(k, ("max_joules", "joules", "kept")):
return False
micro = _value_of(_member(result, "energy", "joules_micro"))
stopped = _value_of(_member(result, "stopped", "joules"))
x = stopped if stopped is not None else (None if micro is None else micro / 1e6)
want = False if stopped is not None else (None if x is None else x <= j)
if _value_of(k.get("max_joules")) != j or _value_of(k.get("joules")) != x or k.get("kept") is not want:
return False
if contract["max_cost"] is not None:
ceiling = contract["max_cost"]
k = kept["cost"]
if not _same_keys(k, ("max_cost", "charged", "kept")) or not _same_keys(k.get("max_cost"), ("amount", "currency")):
return False
charged = _member(result, "cost", "charged")
free = _member(result, "cost", "free")
no_free_member = not (isinstance(result.get("cost"), dict) and "free" in result["cost"])
if charged is not None:
amount = _member(charged, "amount")
if _is_decimal(amount) and _member(charged, "currency") == ceiling["currency"]:
held = fractions.Fraction(amount) <= fractions.Fraction(ceiling["amount"])
else:
held = None
elif no_free_member or free is True:
held = True
else:
held = None
charged_same = k.get("charged") is None if charged is None else _same(k.get("charged"), charged)
if (_member(k, "max_cost", "amount") != ceiling["amount"] or _member(k, "max_cost", "currency") != ceiling["currency"]
or k.get("kept") is not held or not charged_same):
return False
return True
def _list_count(v):
"""§8.7: a count of a list, a whole number written as one from 0 to 2^64 − 1, or 0."""
if isinstance(v, Num) and v.literal_whole() and not v.text.startswith("-"):
n = int(v.text)
return n if n <= 2 ** 64 - 1 else 0
return 0
def split_mad(n):
"""§8.7: E|2B − n| for B binomial (n, 1/2), in doubles in the order written."""
if n == 0:
return 0.0
j = (n - 1) // 2
if j < 4096:
m = 1.0
for i in range(j):
m = m * float(2 * i + 3) / float(2 * i + 2)
return m
jj = float(j)
c = (1.0 - 1.0 / (8.0 * jj) + 1.0 / (128.0 * jj * jj) + 5.0 / (1024.0 * jj * jj * jj)) / math.sqrt(math.pi * jj)
return (2.0 * jj + 1.0) * c
def shadow_distance(a, b, shots):
"""§8.7 distance: the numerator, the denominator, the total variation, the Hellinger
fidelity and the sampling bound, in order, or None when it cannot be taken."""
if not (isinstance(a, dict) and isinstance(b, dict)) or shots <= 0:
return None
s = float(shots)
numerator, root, bound, total = 0, 0.0, 0.0, 0
for k in sorted(set(a) | set(b), key=lambda k: k.encode("utf-8")):
x, y = _list_count(a.get(k)), _list_count(b.get(k))
# Sums of whole numbers exact; each product and quotient a double's.
numerator += abs(x - y)
root += math.sqrt(float(x) * float(y))
total += x + y
bound += split_mad(x + y)
if total > 2 * shots:
return None
denominator = 2 * shots
return (numerator, denominator, float(numerator) / float(denominator), root * root / (s * s), min(1.0, 0.5 * bound / s))
def _whole_value(v):
"""A number whose value is whole and at least 0, as a whole number (at most 2^64 − 1)."""
if isinstance(v, Num) and float(v.value).is_integer() and v.value >= 0:
return min(int(v.value), 2 ** 64 - 1)
return None
def _shadow_count(v):
"""§8.7: a count of a shadow's list, a whole number written as one from 1 to 2^53 − 1."""
if isinstance(v, Num) and v.literal_whole() and not v.text.startswith("-"):
n = int(v.text)
if 1 <= n <= MAX_SAFE:
return n
return None
def _shadow_budget(contract, provider_seconds):
d = contract["deadline"]
if d is None:
return 300.0
if provider_seconds is None:
return d
return max(d - provider_seconds, 0.0)
def _shadow_plan_holds(request, contract, p, result):
"""§8.7: the reasoning's shadow."""
plan = p.get("shadow")
if not isinstance(plan, dict) or "route" not in plan:
return False
route = plan["route"]
if route is None:
return (plan.get("code") in ("budget", "memory", "none") and isinstance(plan.get("why"), str)
and ("tried" not in plan or isinstance(plan["tried"], list)))
if not (isinstance(route, str) and route.startswith("method:") and len(route) > 7):
return False
chosen = next((r for r in p["routes"] if r["route"] == p["choice"]), None)
provider_seconds = _value_of(_member(chosen, "price", "time", "seconds")) if chosen else None
budget = _shadow_budget(contract, provider_seconds)
req = plan.get("request")
price = plan.get("price")
listed = next((r for r in p["routes"] if r["route"] == route), None)
if listed is None or plan.get("class") != listed["class"]:
return False
if not (plan.get("class") in LADDER and _value_of(plan.get("budget_seconds")) == budget
and _price_form(price, True) and _value_of(_member(price, "time", "seconds")) is not None
and _value_of(price["time"]["seconds"]) <= budget):
return False
if not _same_keys(req, ("qasm", "shots", "seed", "method")):
return False
seed = request.get("seed")
seed = int(seed.text) if isinstance(seed, Num) and seed.literal_whole() and not seed.text.startswith("-") else 1
seed = seed if seed <= 2 ** 64 - 1 else 1
want_seed = (seed + 2 ** 32) % 2 ** 53
given = req.get("seed")
return (_same(req.get("qasm"), request.get("qasm")) and isinstance(req.get("qasm"), str)
and _same(req.get("shots"), result.get("shots"))
and isinstance(given, Num) and given.literal_whole() and not given.text.startswith("-") and int(given.text) == want_seed
and req.get("method") == route[len("method:"):])
def _shadow_holds(request, contract, p, result):
"""§8.7 shadow: its plan, its form, what its plan and the job imply, its distance its
counts'."""
s, plan = result["shadow"], p.get("shadow")
if not isinstance(s, dict) or not _shadow_plan_holds(request, contract, p, result):
return False
ran = s.get("ran")
if ran is False:
if not (isinstance(s.get("code"), str) and isinstance(s.get("why"), str)):
return False
return s["code"] == plan.get("code") if plan.get("route") is None else s["code"] == "failed"
if ran is not True or plan.get("route") is None:
return False
shots = _whole_value(result.get("shots"))
counts = s.get("counts")
if not isinstance(counts, dict) or shots is None:
return False
listed = [_shadow_count(v) for v in counts.values()]
omitted = _whole_value(s.get("omitted_shots"))
if any(n is None for n in listed) or omitted is None or sum(listed) + omitted != shots:
return False
if not (_whole(s.get("distinct_outcomes")) and s["distinct_outcomes"].value >= 0):
return False
# Its outcomes are a counts' form: of 0 and 1, as wide as the job's where the
# provider's counts name one; with none omitted, as said.
theirs = result.get("counts")
width = len(next(iter(theirs), "")) if isinstance(theirs, dict) and theirs else len(next(iter(counts), ""))
if any(len(k) != width or set(k) - {"0", "1"} for k in counts) or (omitted == 0 and s["distinct_outcomes"].value != len(counts)):
return False
d = s.get("distance")
if not isinstance(d, dict):
return False
# By value: an omitted_shots of 0 however it is written.
theirs, ours = _value_of(result.get("omitted_shots")), _value_of(s.get("omitted_shots"))
if d.get("computed") is False:
if not isinstance(d.get("why"), str) or (theirs == 0 and ours == 0):
return False
elif d.get("computed") is True:
if "distance-unchecked" not in PLANTS: # PLANT
want = shadow_distance(result.get("counts"), counts, shots)
if want is None or theirs != 0 or ours != 0:
return False
for k, v in zip(("numerator", "denominator", "total_variation", "hellinger_fidelity", "sampling_tvd_bound"), want):
if _value_of(d.get(k)) != float(v):
return False
else:
return False
cls = _member(s, "accuracy", "class")
if not _class_of_method(plan["route"][len("method:"):], cls):
return False
return (s.get("route") == plan["route"] and isinstance(cls, str) and meets(plan.get("class"), cls)
and _same(s.get("request"), plan.get("request")) and _same(s.get("shots"), result.get("shots")))
STOPPED_MEMBERS = ("method", "qubits", "gates", "accuracy", "stopped", "elapsed_ms", "planner", "energy", "engine", "schema", "receipt")
def _stopped_holds(contract, result):
"""§8.7: a run stopped at its ceiling, on a contract that gives one, a reading at or
past it, on a method's run, with no answer."""
s = result["stopped"]
j = contract["joules"]
if not _same_keys(s, ("at", "joules", "max_joules", "elapsed_ms", "read")) or j is None:
return False
x = _value_of(s.get("joules"))
return (s.get("at") == "max_joules" and _value_of(s.get("max_joules")) == j and x is not None and x >= j
and _whole(s.get("elapsed_ms")) and s["elapsed_ms"].value >= 0 and isinstance(s.get("read"), str)
and result.get("method") != "provider" and _member(result, "accuracy", "class") == "none"
and all(k in STOPPED_MEMBERS for k in result)
and (_value_of(_member(result, "energy", "joules_micro")) is None or _value_of(_member(result, "energy", "joules_micro")) >= x * 1e6 - 1.0)
and _value_of(result.get("elapsed_ms")) == _value_of(s.get("elapsed_ms")))
def check_contract(request, result, reasons):
# §8.7. A job with no contract carries neither a reasoning nor a shadow.
given = request.get("contract")
planner = result.get("planner")
if given is None:
if "planner" in result:
reasons.add("planner_form")
if "shadow" in result:
reasons.add("shadow")
if "stopped" in result:
reasons.add("stopped")
return
contract = read_contract(given)
if contract is None:
reasons.add("contract_form")
return
if not _planner_form(planner):
reasons.add("planner_form")
return
if request.get("provider") is not None and contract["providers"] != "allowed":
reasons.add("contract_provider")
routes = planner["routes"]
# The providers the host brought are its provider routes, in their order.
brought = [r["route"][len("provider:"):] for r in routes if r["kind"] == "provider"]
if planner["host"]["providers"] != brought:
reasons.add("planner_form")
return
# What the job names, the question it asks and what auto picks: from the request
# and the routes, never from what the reasoning says of itself.
named = _request_names(request)
if named is None and request.get("target") is not None:
stated = planner.get("named")
named = stated if isinstance(stated, str) and stated.startswith("method:") else None
question = _question(request)
ranks_ok = True
for r in routes:
if r["kind"] == "local" and r["route"][len("method:"):] in AUTO_RANKS:
want = AUTO_RANKS[r["route"][len("method:"):]][QUESTIONS.index(question)]
if _value_of(r["auto_rank"]) != want:
ranks_ok = False
auto = _auto(routes, request, named)
class_of = dict((r["route"], r["class"]) for r in routes)
if contract["exactness"] is not None:
wanted, source = contract["exactness"], "contract"
elif named is not None:
wanted, source = class_of.get(named), "named"
elif auto is not None:
wanted, source = class_of.get(auto), "auto"
else:
wanted, source = None, None
if (planner.get("named") != named or planner.get("question") != question or not ranks_ok
or planner.get("auto") != auto or planner.get("wanted") != wanted or planner["wanted_from"] != source):
reasons.add("planner_form")
return
job_bytes = planner["host"]["job_bytes"].value
from_contract = source == "contract"
def gate(r):
return _gate(r, contract, request, named, wanted, from_contract, job_bytes)
broken = False
chosen = [r["route"] for r in routes if r["outcome"] == "chosen"]
if "route-unchecked" not in PLANTS: # PLANT
for r in routes:
if _member(r, "rejected", "code") != gate(r) or not _states_itself(r, request):
broken = True
if len(chosen) != 1 or chosen[0] != planner["choice"]:
broken = True
if broken:
reasons.add("planner_route")
if result.get("method") == "provider":
name = _member(result, "provider", "name")
ran = "provider:" + name if isinstance(name, str) else None
else:
m = result.get("method")
ran = "method:" + m if isinstance(m, str) else None
if "choice-unchecked" not in PLANTS: # PLANT
if (_picked(routes, auto, contract, lambda r: gate(r) is None) != planner["choice"] or ran != planner["choice"]
or not _ran_as_routed(routes, planner["choice"], result)):
reasons.add("planner_choice")
if not _stable_holds(planner, routes, contract):
reasons.add("planner_stable")
if not _kept_holds(planner, contract, result):
reasons.add("planner_kept")
cls = _member(result, "accuracy", "class")
short = wanted is not None and (not meets(wanted, cls) or (from_contract and wanted == "simulated" and _member(result, "accuracy", "approximate") is True))
# A method's result has a class its method has.
method = result.get("method")
if "stopped" in result:
if not _stopped_holds(contract, result):
reasons.add("stopped")
elif short or (isinstance(method, str) and method != "provider" and not _class_of_method(method, cls)):
reasons.add("contract_class")
# Under a contract a provider's result is of the current form.
if result.get("method") == "provider" and ("counts_source" not in result or "execution" not in result):
reasons.add("contract_form")
is_provider = planner["choice"].startswith("provider:")
if is_provider != ("shadow" in result) or is_provider != ("shadow" in planner) or (is_provider and not _shadow_holds(request, contract, planner, result)):
reasons.add("shadow")
def contract_statement(result):
"""§8.7: what a verifier states of a job under a contract."""
p = result.get("planner")
return {
"choice": _plain(_member(p, "choice")),
"wanted": _plain(_member(p, "wanted")),
"class": _plain(_member(result, "accuracy", "class")),
"stable_choice": _plain(_member(p, "stable", "choice")),
"kept": _plain(_member(p, "kept")),
"shadow_ran": _plain(_member(result, "shadow", "ran")),
"shadow_total_variation": _plain(_member(result, "shadow", "distance", "total_variation")),
}
# ============================================ 7. a wasmQ job (quantum-wasmq §6.5)
#
# Written from wai/extensions/quantum-wasmq.md §6.5 (with §2.2, §6.2 and §6.4 for the
# lists it names), by a reader who had not seen the reference. §8.4's `wasmq_form`
# holds a job to those rules when its result's format is wai.quantum.wasmq.result/1.
# Brought to §6.5 as it now stands (rule 18's call that stopped being one of the calls
# made; the statement of outcome, problems and notes) by a reader who had not seen it;
# and again for rules 20 to 35 (the ties between members: fuel, instances, the envelope's
# size, the calls' count, the least charge and the transcript of a run where no call
# returned) and rules 6, 8, 12, 14 and 18 as they now read, from the text alone.
#
# §6.5: a member is *present* when its object names it, whatever its value, null among
# them ("has no fault", "has a callout", "may have fault" read so). Every test of a
# member here is `name in obj` or `_get`, never `obj.get(name) is None`, so a member
# that is null is there; the statement's notes read the body's members the same way.
WASMQ_FORMAT = "wai.quantum.wasmq.result/1"
WASMQ_PROFILE = "wai.quantum.wasmq/1"
# §6.4: the result's energy, the one sentence it gives.
WASMQ_ENERGY = "the runner reads no energy meter; fuel is the profile's measure of work"
# §6.5 rule 9 (§6.4): the result's members; it may also have `fault`.
WASMQ_RESULT_MEMBERS = frozenset((
"format", "profile", "status", "method", "qubits", "shots", "shots_run", "seed", "counts",
"callouts", "fuel", "modules", "transcript_blake3", "accuracy", "energy", "receipt"))
# §6.2: the reasons a fault names.
WASMQ_FAULT_REASONS = (
"fuel_exhausted", "stack_exhausted", "unreachable", "memory_out_of_bounds",
"table_out_of_bounds", "indirect_call_null", "indirect_call_type", "integer_divide_by_zero",
"integer_overflow", "invalid_conversion_to_integer", "bad_result")
WASMQ_PHASES = ("seed", "prior", "init", "call")
WASMQ_RULES = 35
# quantum-wasmq §11: the second version. Its result's format decides that a job is held to
# §11.6, which reads rules 4, 8, 11, 12 and 30 with the second version's names and adds 36.
WASMQ2_FORMAT = "wai.quantum.wasmq.result/2"
WASMQ2_PROFILE = "wai.quantum.wasmq/2"
WASMQ2_METHODS = ("stabilizer", "exact") # §11.1
WASMQ2_EXACT_MAX_QUBITS = 26 # §11.3, rule 12
# §11.5: a reading's class (energy-measurement §2); an estimate is no reading.
WASMQ2_READINGS = ("CalibratedInstrument", "OnChipCounter", "HwShunt")
WASMQ2_FLOOR_UJ_PPM = 288676 # §11.5: energy-measurement §2.3's floor
WASMQ2_RULES = 36
WASMQ_PROBLEMS_SHOWN = 64 # §6.5: the first 64 problems, then how many more
_ABSENT = object() # a member not present: equal to nothing
def _count(v):
"""§6.5: a number whose value is a whole number from 0 to 2^53 − 1, however it is
written (1, 1.0 and 1e0 are one count; -0 is 0)."""
return isinstance(v, Num) and v.value.is_integer() and 0 <= v.value <= MAX_SAFE
def _count_in(v, low, high):
return _count(v) and low <= v.value <= high
def _n(v):
"""A count's value as an exact integer, so that a sum or a product is exact."""
return int(v.value)
def _or_zero(v):
"""§6.5: a bound read "(0 when that is not a count)"."""
return _n(v) if _count(v) else 0
def _text_is(v, *options):
return isinstance(v, str) and v in options
def _exactly(v, names):
"""§6.5: every one named and no other; a value that is not an object has none."""
return isinstance(v, dict) and set(v) == set(names)
def _obj(v):
"""§6.5: a map that is not an object is read as an empty one, after its own rule."""
return v if isinstance(v, dict) else {}
def _arr(v):
"""§6.5: a list that is not an array is read as an empty one, after its own rule."""
return v if isinstance(v, list) else []
def _get(v, name):
"""§6.5: a member's value when it is present (null among them), else _ABSENT."""
return v[name] if isinstance(v, dict) and name in v else _ABSENT
def is_wasmq(result):
"""§6.5, §11.6: a result whose format is wai.quantum.wasmq.result/1, or /2, is a wasmQ
job's."""
return _text_is(result.get("format"), WASMQ_FORMAT, WASMQ2_FORMAT)
def wasmq_version(result):
"""§11.6: "What a job's result format is decides which version's rules hold it"."""
return 2 if _text_is(result.get("format"), WASMQ2_FORMAT) else 1
def _figure_holds(f):
"""§11.5: a figure is the unmetered form, exactly {"unmetered": why} with why a string
that is not empty; or a reading: joules_micro a count of at least 1, energy_provenance a
reading's class, and energy_uncertainty whose relative_ppm and window_us are counts of at
least 1 and whose relative_ppm times joules_micro is at least 288 676. A reading may say
more."""
if not isinstance(f, dict):
return False
if "unmetered" in f:
return len(f) == 1 and isinstance(f["unmetered"], str) and f["unmetered"] != ""
joules = _get(f, "joules_micro")
if not (_count(joules) and _n(joules) >= 1):
return False
if not _text_is(_get(f, "energy_provenance"), *WASMQ2_READINGS):
return False
u = _obj(_get(f, "energy_uncertainty"))
ppm, window = _get(u, "relative_ppm"), _get(u, "window_us")
if not (_count(ppm) and _n(ppm) >= 1 and _count(window) and _n(window) >= 1):
return False
return _n(joules) * _n(ppm) >= WASMQ2_FLOOR_UJ_PPM
def wasmq_broken(request, result):
"""§6.5: the numbers of the rules a wasmQ job breaks; none when it keeps them all.
C is the request's wasmq, run C's run, r the result and F r's fuel. What decides is
what is sealed (the request, and the result less its receipt), but for rule 9's
`receipt` member and rule 10's canon, which name the receipt itself."""
broken = set()
def rule(number, holds):
if not holds:
broken.add(number)
r = result
body = dict((k, v) for k, v in r.items() if k != "receipt")
c_given = _get(request, "wasmq")
c = _obj(c_given)
program_given, run_given = _get(c, "program"), _get(c, "run")
program, run = _obj(program_given), _obj(run_given)
budgets_given = _get(run, "fuel")
budgets = _obj(budgets_given)
# §6.5: "The budget per_call, per_job or per_instance is that member of run's fuel."
per_call, per_job, per_instance = (_get(budgets, k) for k in ("per_call", "per_job", "per_instance"))
modules_given, callouts_given = _get(c, "modules"), _get(c, "callouts")
modules, callouts = _arr(modules_given), _arr(callouts_given)
externs = [_get(co, "extern") for co in callouts]
f_given = _get(r, "fuel")
f = _obj(f_given)
shots, shots_run, status = _get(r, "shots"), _get(r, "shots_run"), _get(r, "status")
# 1. No number in the request, or in the result less its receipt, has a magnitude
# past 2^53 − 1 (its value, the double it reads as).
rule(1, all(abs(n.value) <= MAX_SAFE for part in (request, body) for n in _numbers(part)))
# 2. The request: exactly wasmq and envelope_blake3, the latter a digest.
rule(2, _exactly(request, ("wasmq", "envelope_blake3"))
and _lower_hex(request["envelope_blake3"], 64))
# 3. C, its program, run and run's fuel: exactly the members §2.2 gives.
rule(3, _exactly(c_given, ("profile", "program", "modules", "callouts", "run"))
and _exactly(program_given, ("blake3", "bytes", "inputs"))
and _exactly(run_given, ("shots", "seed", "method", "state", "fuel"))
and _exactly(budgets_given, ("per_call", "per_job", "per_instance")))
# 4. C's profile: wai.quantum.wasmq/1, or under the second version /2 (§11.6).
version = wasmq_version(r)
rule(4, _text_is(_get(c, "profile"), WASMQ_PROFILE if version == 1 else WASMQ2_PROFILE))
# 5. The program: a digest; 1 to 2^20 bytes; inputs an object of whole numbers.
# SPEC-GAP: [W2] "at most 2^53 − 1 in size": a magnitude; an input may be negative
# (an int[k] input), so it is no count.
inputs = _get(program, "inputs")
rule(5, _lower_hex(_get(program, "blake3"), 64)
and _count_in(_get(program, "bytes"), 1, 2 ** 20)
and isinstance(inputs, dict)
and all(isinstance(v, Num) and v.value.is_integer() and abs(v.value) <= MAX_SAFE
for v in inputs.values()))
# 6. The modules: a non-empty array, each module and each prior of its form, and the
# modules' bytes that are counts adding up to at most 2^19. A module's bytes is a count
# of at least 1 (the sum bounds each from above); a prior's bytes is a count, which
# rule 31 bounds, not this rule.
def prior_holds(p):
return (_exactly(p, ("name", "blake3", "bytes")) and isinstance(p["name"], str)
and _lower_hex(p["blake3"], 64) and _count(p["bytes"]))
def module_holds(m):
return (_exactly(m, ("name", "blake3", "bytes", "priors")) and isinstance(m["name"], str)
and _lower_hex(m["blake3"], 64) and _count(m["bytes"]) and _n(m["bytes"]) >= 1
and isinstance(m["priors"], list) and all(prior_holds(p) for p in m["priors"]))
sizes = [_get(m, "bytes") for m in modules]
rule(6, isinstance(modules_given, list) and len(modules) > 0
and all(module_holds(m) for m in modules)
and sum(_n(b) for b in sizes if _count(b)) <= 2 ** 19)
# 7. The callouts: a non-empty array, each of its form, its module a count less than
# the number of modules; no extern twice; every module's index named by a callout.
def callout_holds(co):
return (_exactly(co, ("extern", "module", "export")) and isinstance(co["extern"], str)
and isinstance(co["export"], str) and _count(co["module"])
and _n(co["module"]) < len(modules))
named = set(_n(_get(co, "module")) for co in callouts if _count(_get(co, "module")))
extern_texts = [e for e in externs if isinstance(e, str)]
rule(7, isinstance(callouts_given, list) and len(callouts) > 0
and all(callout_holds(co) for co in callouts)
and len(set(extern_texts)) == len(extern_texts)
and all(i in named for i in range(len(modules))))
# 8. run: shots 1 to 2^20, a seed, the method, the state, and each budget a count,
# per_call and per_instance each at most 2^39 (rule 30 holds per_job to less).
# §11.6: under the second version run's method is stabilizer or exact.
methods = ("stabilizer",) if version == 1 else WASMQ2_METHODS
rule(8, _count_in(_get(run, "shots"), 1, 2 ** 20) and _count(_get(run, "seed"))
and _text_is(_get(run, "method"), *methods) and _text_is(_get(run, "state"), "shot", "job")
and _count(per_job) and _count_in(per_call, 0, 2 ** 39) and _count_in(per_instance, 0, 2 ** 39))
# 9. r: exactly §6.4's members, and may have fault.
rule(9, set(r) - {"fault"} == WASMQ_RESULT_MEMBERS)
# 10. The receipt is an object whose canon is rfc8785. §6.5: "Only what is sealed (the
# request, and the result less its receipt) and the form of its seal decide it": a
# receipt that is not an object, or of the first form, breaks it.
rule(10, _text_is(_get(_get(r, "receipt"), "canon"), "rfc8785"))
# 11. r's constants, and its method, shots and seed equal to run's (numbers by value).
# §11.6: under the second version, format and profile /2, the accuracy §11.4 gives
# run's method (bit-exact for exact, exact for stabilizer), and nothing of the energy,
# which rule 36 holds.
# SPEC-GAP: [W23] "its accuracy the one §11.4 gives its method": read as run's method,
# which the same rule holds r's to (where they differ the rule fails either way); when
# it is neither of §11.1's methods, §11.4 gives no accuracy, and rule 8 says why: the
# accuracy is then held to nothing.
run_method = _get(run, "method")
exact = version == 2 and _text_is(run_method, "exact")
if version == 1:
constants = (_text_is(_get(r, "format"), WASMQ_FORMAT) and _text_is(_get(r, "profile"), WASMQ_PROFILE)
and _same(_get(r, "accuracy"), {"class": "exact"})
and _same(_get(r, "energy"), {"unmetered": WASMQ_ENERGY}))
else:
accuracy = {"class": "bit-exact" if exact else "exact"}
constants = (_text_is(_get(r, "format"), WASMQ2_FORMAT) and _text_is(_get(r, "profile"), WASMQ2_PROFILE)
and (not _text_is(run_method, *WASMQ2_METHODS) or _same(_get(r, "accuracy"), accuracy)))
rule(11, constants and all(_same(_get(r, k), _get(run, k)) for k in ("method", "shots", "seed")))
# 12. r's qubits a count from 1 to 2^15 (a program declares a qubit at least); its
# transcript_blake3 a digest.
# §11.6: when the method is exact, at most 26 qubits.
rule(12, _count_in(_get(r, "qubits"), 1, 2 ** 15) and _lower_hex(_get(r, "transcript_blake3"), 64)
and not (exact and _count(_get(r, "qubits")) and _n(_get(r, "qubits")) > WASMQ2_EXACT_MAX_QUBITS))
# 13. F: exactly its four members; its budget run's fuel; used at most per_job.
used, instances = _get(f, "used"), _get(f, "instances")
rule(13, _exactly(f_given, ("used", "instances", "budget", "callouts"))
and _same(_get(f, "budget"), budgets_given)
and _count(used) and _n(used) <= _or_zero(per_job))
# 14. F's callouts: an object; each member named by an extern of C's callouts, with
# exactly calls (at least 1), fuel and max (at most per_call and at most its own fuel),
# and fuel a count: rule 20, not this rule, bounds it by its calls and their max.
f_callouts_given = _get(f, "callouts")
f_callouts = _obj(f_callouts_given)
extern_set = set(extern_texts) # a list here would make this quadratic
def entry_holds(name, e):
return (name in extern_set and _exactly(e, ("calls", "fuel", "max"))
and _count(e["calls"]) and _n(e["calls"]) >= 1
and _count(e["max"]) and _n(e["max"]) <= _or_zero(per_call)
and _count(e["fuel"]) and _n(e["max"]) <= _n(e["fuel"]))
rule(14, isinstance(f_callouts_given, dict)
and all(entry_holds(k, v) for k, v in f_callouts.items()))
# 15. F's instances and its callouts' fuel add up to used; their calls to r's callouts.
# SPEC-GAP: [W5] "Each of them is a count": every number the rule names, F's
# instances and used, r's callouts, and each member's fuel and calls.
fuels = [_get(e, "fuel") for e in f_callouts.values()]
calls = [_get(e, "calls") for e in f_callouts.values()]
r_callouts = _get(r, "callouts")
rule(15, all(_count(x) for x in [instances, used, r_callouts] + fuels + calls)
and _n(instances) + sum(_n(x) for x in fuels) == _n(used)
and sum(_n(x) for x in calls) == _n(r_callouts))
# 16. r's modules: as many as C's, each exactly name and blake3, equal to C's at its index.
r_modules_given = _get(r, "modules")
def r_module_holds(i, m):
return (_exactly(m, ("name", "blake3")) and _lower_hex(m["blake3"], 64)
and _same(m["name"], _get(modules[i], "name"))
and _same(m["blake3"], _get(modules[i], "blake3")))
rule(16, isinstance(r_modules_given, list) and len(r_modules_given) == len(modules)
and all(r_module_holds(i, m) for i, m in enumerate(r_modules_given)))
# 17. F's instances at most M × S × per_instance: S, over C's modules, 2 and its priors;
# M 1 for state job "whatever the status", for any other state shots_run, and 1 more
# when status is fault.
s = sum(2 + len(_arr(_get(m, "priors"))) for m in modules)
if _text_is(_get(run, "state"), "job"):
m_factor = 1
else:
m_factor = _or_zero(shots_run) + (1 if _text_is(status, "fault") else 0)
rule(17, _count(instances) and _n(instances) <= m_factor * s * _or_zero(per_instance))
# 18. status ok: no fault, and every shot run; status fault: the fault of §6.2's form.
if _text_is(status, "ok"):
rule(18, "fault" not in r and _count(shots_run) and _count(shots) and _n(shots_run) == _n(shots))
elif _text_is(status, "fault"):
rule(18, _fault_holds(_get(r, "fault"), shots, shots_run, modules, externs,
f_callouts, per_instance))
else:
rule(18, False) # any other status breaks the form
# 19. r's counts: an object of outcomes of 0 and 1 (the empty name among them), all of
# one length, each at least 1, adding up to shots_run.
counts_given = _get(r, "counts")
counts = _obj(counts_given)
rule(19, isinstance(counts_given, dict)
and all(_OUTCOME.fullmatch(k) for k in counts) and len(set(len(k) for k in counts)) <= 1
and all(_count(v) and _n(v) >= 1 for v in counts.values())
and _count(shots_run) and sum(_n(v) for v in counts.values()) == _n(shots_run))
# Rules 20 to 35 tie members to each other. In them *the fault* is r's fault when r's
# status is fault and that is an object, and there is none otherwise; a rule about the
# fault holds when there is none. A *call's fault* is one whose phase is call, a
# *lifecycle fault* "one that has a phase other than call": a phase of null is present
# (§6.5), so a lifecycle fault's; a fault that names no phase is neither.
fault_given = _get(r, "fault")
fault = fault_given if _text_is(status, "fault") and isinstance(fault_given, dict) else None
phase, reason = _get(fault, "phase"), _get(fault, "reason")
fault_fuel, fault_shot = _get(fault, "fuel"), _get(fault, "shot")
call_fault = fault is not None and _text_is(phase, "call")
lifecycle_fault = fault is not None and phase is not _ABSENT and not _text_is(phase, "call")
state_job = _text_is(_get(run, "state"), "job")
# 20. Each member of F's callouts: s 1 when the fault is a call's fault whose callout is
# that member's name, else 0; e the fault's fuel when s is 1 (0 when it is no count),
# else 0. T, its fuel less e (the fuel of its calls that returned), is not less than 0,
# and is from k to k × max, k its calls less s (0 when that is below 0); and when max
# is more than e, T is at least max + k − 1. calls, fuel and max are counts.
def returned_holds(name, member):
stopped = 1 if call_fault and _same(_get(fault, "callout"), name) else 0
calls, fuel, top = _get(member, "calls"), _get(member, "fuel"), _get(member, "max")
if not (_count(calls) and _count(fuel) and _count(top)):
return False
stopped_fuel = _or_zero(fault_fuel) if stopped else 0 # e
returned = _n(fuel) - stopped_fuel # T
returning = max(_n(calls) - stopped, 0) # k
return (returned >= 0 and returning <= returned <= returning * _n(top)
and (_n(top) <= stopped_fuel or returned >= _n(top) + returning - 1))
rule(20, all(returned_holds(name, member) for name, member in f_callouts.items()))
# 21. F's instances is a count of at least W × P + E, the least making the instances took
# outside a stopped call.
# P: over every prior of every one of C's modules, 3 and the prior's bytes (0 when no
# count), and 1 more when the fault is a lifecycle fault in phase seed or init.
# W: r's shots_run (0 when no count), 1 more when there is a call's fault, and with
# state job that or 1, whichever is less.
# E: when the fault is a lifecycle fault, the same sum of 3 and the bytes over the priors
# of each module before the one it names (the first of C's modules with that name),
# and, in phase init, over that module's own; 0 otherwise, and when no module has it.
# SPEC-GAP: [W19] "E ... the same sum, of 3 and its bytes": read as the sum over priors
# alone, without P's 1 more for a fault in seed or init, as "of 3 and its bytes" says.
def passing_of(priors):
return sum(3 + _or_zero(_get(p, "bytes")) for p in priors)
all_priors = [p for m in modules for p in _arr(_get(m, "priors"))]
passing = passing_of(all_priors) + (1 if lifecycle_fault and _text_is(phase, "seed", "init") else 0)
made_whole = _or_zero(shots_run) + (1 if call_fault else 0)
if state_job:
made_whole = min(made_whole, 1)
stopped_priors = [] # the priors E counts: those the stopped set passed whole
if lifecycle_fault:
named = next((i for i, m in enumerate(modules) if _same(_get(fault, "module"), _get(m, "name"))),
None)
if named is not None:
upto = named + 1 if _text_is(phase, "init") else named
stopped_priors = [p for m in modules[:upto] for p in _arr(_get(m, "priors"))]
least_instances = made_whole * passing + passing_of(stopped_priors)
rule(21, _count(instances) and _n(instances) >= least_instances)
# 22. A call's fault's module equals the name of C's module whose index is the module of
# each of C's callouts whose extern is the fault's callout (rule 7 allows one); it
# fails when there is no such callout, or no such module.
def callout_module_name(co):
index = _get(co, "module")
if _count(index) and _n(index) < len(modules):
return _get(modules[_n(index)], "name")
return _ABSENT # no such module: equal to nothing
stopped_in = ([co for co in callouts if _same(_get(co, "extern"), _get(fault, "callout"))]
if call_fault else [])
rule(22, not call_fault
or (len(stopped_in) > 0
and all(_same(_get(fault, "module"), callout_module_name(co)) for co in stopped_in)))
# 23. A fault whose phase is prior has as its module the name of one of C's modules
# whose priors is not empty (a priors that is no array read as an empty one).
rule(23, fault is None or not _text_is(phase, "prior")
or any(len(_arr(_get(m, "priors"))) > 0 and _same(_get(fault, "module"), _get(m, "name"))
for m in modules))
# 24. A fault whose reason is bad_result has the phase call or prior.
rule(24, fault is None or not _text_is(reason, "bad_result") or _text_is(phase, "call", "prior"))
# 25. A lifecycle fault's fuel is a count, and F's instances (a count) is at least it
# added to rule 21's W × P + E.
rule(25, not lifecycle_fault
or (_count(fault_fuel) and _count(instances)
and _n(instances) >= _n(fault_fuel) + least_instances))
# 26. When run's state is job, a lifecycle fault's shot is the count 0.
first_shot = _count_in(fault_shot, 0, 0)
rule(26, not (lifecycle_fault and state_job) or first_shot)
# 27. A lifecycle fault whose shot is the count 0 comes with r's callouts the count 0.
rule(27, not (lifecycle_fault and first_shot) or _count_in(r_callouts, 0, 0))
# 28. A fuel_exhausted fault used its whole limit: with budget call its fuel is a count
# equal to the budget per_call, with instance to per_instance (each 0 when no count);
# with run, F's used is a count equal to the budget per_job (a count), and the fault's
# fuel is a count, less than its own limit: per_call in a call's fault, per_instance in
# a lifecycle fault, each read as 0 when it is not a count ("a fault with no phase has
# no limit here, and breaks rule 18").
# SPEC-GAP: [W18] the rule says what the whole limit is for the budgets call, instance
# and run only; a fault of fuel_exhausted with no budget, a budget of null or of
# another value (rule 18 then fails) is held to nothing here.
budget = _get(fault, "budget")
if fault is None or not _text_is(reason, "fuel_exhausted"):
whole_limit = True
elif _text_is(budget, "call"):
whole_limit = _count(fault_fuel) and _n(fault_fuel) == _or_zero(per_call)
elif _text_is(budget, "instance"):
whole_limit = _count(fault_fuel) and _n(fault_fuel) == _or_zero(per_instance)
elif _text_is(budget, "run"):
# Its own limit: per_call in a call's fault, per_instance in a lifecycle fault, each
# 0 when no count (a budget of null among them); a fault with no phase has none.
# (`limited` is a flag of its own: a budget of null reads as Python's None.)
limited = call_fault or lifecycle_fault
own_limit = per_call if call_fault else per_instance
whole_limit = (_count(used) and _count(per_job) and _n(used) == _n(per_job)
and _count(fault_fuel)
and (not limited or _n(fault_fuel) < _or_zero(own_limit)))
else:
whole_limit = True
rule(28, whole_limit)
# 29. When r's counts has a name, the longest, in characters (Unicode code points), is at
# most 2^20 long, and run's shots (0 when no count) times that length at most 2^28
# (counts read as an empty object when it is no object, after rule 19 has failed).
longest = max((len(name) for name in counts), default=None)
rule(29, longest is None
or (longest <= 2 ** 20 and _or_zero(_get(run, "shots")) * longest <= 2 ** 28))
# 30. The part of a run's work a receipt shows, at most 2^42:
# S × 2·n·w + I × Σ (4096 × (1 + 2p) + b) + 131072 × Σ b + 4097 × K + 8 × the budget
# per_job, S run's shots, n r's qubits, w ⌈n/32⌉ or 1 when that is 0, I 1 for state job
# and S otherwise, each sum over C's modules (p its number of priors, b its bytes), K
# r's callouts; every number that is not a count read as 0.
shots_asked = _or_zero(_get(run, "shots"))
qubits = _or_zero(_get(r, "qubits"))
tableau_words = -(-qubits // 32) or 1
instances_counted = 1 if state_job else shots_asked
code = [_or_zero(_get(m, "bytes")) for m in modules]
instance_work = sum(4096 * (1 + 2 * len(_arr(_get(m, "priors")))) + b for m, b in zip(modules, code))
# §11.6, §11.7: under the exact method a shot's fresh state is S x 2·2^n, not S x 2·n·w
# (2·2^64 stands for a state of more qubits: either is past any bound, and neither is
# made here).
if exact:
fresh = shots_asked * (2 << min(qubits, 64))
else:
fresh = shots_asked * 2 * qubits * tableau_words
work = (fresh + instances_counted * instance_work
+ 131072 * sum(code) + 4097 * _or_zero(r_callouts) + 8 * _or_zero(per_job))
rule(30, work <= 2 ** 42)
# 31. The envelope the contract names is at most 2^27 bytes: 20 bytes of magic and
# lengths; the manifest, §2.1's members in order with no space, 192 bytes and the
# decimal digits of r's qubits and of run's shots and seed (each 0 when no count);
# C in RFC 8785 form; and the frames (the program's bytes, each module's and each
# prior's, each 0 when no count), added.
# SPEC-GAP: [W20] "C in RFC 8785 form": a request with no wasmq member (rule 2 then
# fails) has no C, read as no bytes; any other value of wasmq, an object or not, is
# written in its canonical text (§8.2) and counted in its UTF-8 bytes.
manifest = 192 + sum(len(str(_or_zero(v))) for v in (_get(r, "qubits"), _get(run, "shots"),
_get(run, "seed")))
contract = 0 if c_given is _ABSENT else len(text_of(c_given, True).encode("utf-8"))
frames = (_or_zero(_get(program, "bytes")) + sum(code)
+ sum(_or_zero(_get(p, "bytes")) for p in all_priors))
rule(31, 20 + manifest + contract + frames <= 2 ** 27)
# 32. r's callouts is at most 2^21 × H (each 0 when no count), H r's shots_run and 1 more
# when there is a call's fault: the shots that ran steps.
ran_steps = _or_zero(shots_run) + (1 if call_fault else 0)
rule(32, _or_zero(r_callouts) <= 2 ** 21 * ran_steps)
# 33. Each prior passed whole fits one lifecycle call's limit: 3 and its bytes (0 when no
# count) at most the budget per_instance (0 when no count), for every prior of every
# one of C's modules when W (rule 21) is at least 1, and for each prior E counts
# otherwise.
passed_whole = all_priors if made_whole >= 1 else stopped_priors
rule(33, all(3 + _or_zero(_get(p, "bytes")) <= _or_zero(per_instance) for p in passed_whole))
# 34. A fault's fuel, when it is a count, is at least what its reason shows was charged:
# 1 for every reason but fuel_exhausted, 2 for bad_result, 788 for stack_exhausted.
# SPEC-GAP: [W21] "1 for every reason but fuel_exhausted": read of the reason the fault
# has, whatever its value; one §6.2 does not name, or one not a string (null among
# them), shows 1 (rule 18 fails for it). A fault that has no reason member shows
# nothing, and is held to no least here (rule 18 fails for it).
if fault is None or reason is _ABSENT or _text_is(reason, "fuel_exhausted"):
least_charged = 0
elif _text_is(reason, "bad_result"):
least_charged = 2
elif _text_is(reason, "stack_exhausted"):
least_charged = 788
else:
least_charged = 1
rule(34, not _count(fault_fuel) or _n(fault_fuel) >= least_charged)
# 35. When no call returned (r's callouts the count 0, or the count 1 with a call's
# fault), r's transcript_blake3 is BLAKE3 over the bytes wai:wasmq-transcript\x01 and,
# when there is a fault, the bytes fault, its shot (u64), its reason's UTF-8 bytes and
# its fuel (u64), little-endian (shot and fuel 0 when no count, the reason no bytes
# when it is no string).
# SPEC-GAP: [W22] "\x01" read as the one byte 0x01 (as §8.2 names its domain byte), not
# the four characters; "the bytes fault" as the five ASCII bytes of the word.
if _count(r_callouts) and (_n(r_callouts) == 0 or (_n(r_callouts) == 1 and call_fault)):
transcript = b"wai:wasmq-transcript\x01"
if fault is not None:
transcript += (b"fault" + struct.pack("<Q", _or_zero(fault_shot))
+ (reason.encode("utf-8") if isinstance(reason, str) else b"")
+ struct.pack("<Q", _or_zero(fault_fuel)))
rule(35, _same(_get(r, "transcript_blake3"), blake3(transcript).hex()))
# 36 (§11.6, the second version only). r's energy has exactly the members run and
# callouts; run is a figure; callouts is an object whose members are exactly the names
# of F's callouts, each a figure (§11.5). (Rule 1 holds its numbers with the rest.)
if version == 2:
energy = _get(r, "energy")
figures = _get(energy, "callouts")
rule(36, _exactly(energy, ("run", "callouts")) and _figure_holds(energy["run"])
and isinstance(figures, dict) and set(figures) == set(f_callouts)
and all(_figure_holds(x) for x in figures.values()))
return sorted(broken)
def _fault_holds(fault, shots, shots_run, modules, externs, f_callouts, per_instance):
"""§6.5 rule 18, for a result whose status is fault. `f_callouts` is F's callouts,
read as an empty object when it is not one (rule 14 then fails, and so does this
clause: no member is named in it)."""
required = {"reason", "shot", "phase", "module", "fuel"}
if not (isinstance(fault, dict) and required <= set(fault) <= required | {"callout", "budget"}):
return False
reason, phase = fault["reason"], fault["phase"]
in_call = _text_is(phase, "call")
return (_text_is(reason, *WASMQ_FAULT_REASONS)
and _count(shots_run) and _count(shots) and _n(shots_run) < _n(shots)
and _count(fault["shot"]) and _n(fault["shot"]) == _n(shots_run)
and _text_is(phase, *WASMQ_PHASES)
and any(_same(fault["module"], _get(m, "name")) for m in modules)
# fuel a count, and in a phase other than call (one not among the four
# included) at most per_instance: a call's is held by its callout's max,
# below, and rule 14; rules 20 and 25 hold either within F's used
and _count(fault["fuel"])
and (in_call or _n(fault["fuel"]) <= _or_zero(per_instance))
# a callout exactly in a call (present, whatever its value), one of C's
# externs that names a member of F's callouts whose max is at least the
# fault's fuel: the call that stopped is one of the calls made
and ("callout" in fault) == in_call
and (not in_call or (any(_same(fault["callout"], e) for e in externs)
and _stopped_call_made(fault["callout"], fault["fuel"], f_callouts)))
# a budget exactly for fuel_exhausted: run, or call in a call and instance otherwise
and ("budget" in fault) == _text_is(reason, "fuel_exhausted")
and ("budget" not in fault
or _text_is(fault["budget"], "run", "call" if in_call else "instance")))
def _stopped_call_made(callout, fuel, f_callouts):
"""§6.5 rule 18: the fault's callout names a member of F's callouts whose max is at
least the fault's fuel (a count, checked before this is asked)."""
# SPEC-GAP: [W9] "that is the extern of one of C's callouts that names a member of
# F's callouts whose max is at least the fault's fuel": a callout names a member of
# F's callouts by its extern (F's callouts are keyed by extern, §6.4), so the fault's
# callout is one of C's externs, and F's callouts has a member of that very name whose
# max is a count at least the fault's fuel. "At least" compares counts as "at most"
# and "equals" do (§6.5 names those two only): a max that is no count fails it. The
# fault's module against that callout's module is rule 22's, not this rule's.
entry = _get(f_callouts, callout) if isinstance(callout, str) else _ABSENT
top = _get(entry, "max")
return _count(top) and _n(top) >= _n(fuel)
def check_wasmq(request, result, reasons):
"""§8.4 wasmq_form: a wasmQ job's request or result breaks a rule of quantum-wasmq
§6.5. Returns the numbers of the rules it breaks, none for another job."""
if "wasmq-unchecked" in PLANTS: # PLANT: skip the wasmQ rules
return []
broken = wasmq_broken(request, result) if is_wasmq(result) else []
if broken:
reasons.add("wasmq_form")
return broken
# §6.5: "problems, each rule the job breaks, in words": one entry a rule, in this file's
# words (another verifier's are its own; the words are no part of the verdict).
WASMQ_RULE_WORDS = {
1: "a number in the request, or in the result less its receipt, has a magnitude past 2^53 - 1",
2: "the request is not exactly wasmq and envelope_blake3, envelope_blake3 a digest",
3: "the contract, its program, its run or run's fuel has not exactly the members §2.2 gives",
4: "the contract's profile is not wai.quantum.wasmq/1",
5: "the program's blake3, bytes or inputs break their form",
6: "the contract's modules break their form, or their bytes add up past 2^19",
7: "the contract's callouts break their form, name an extern twice, or leave a module unnamed",
8: "run's shots, seed, method, state or a budget breaks its form",
9: "the result has not exactly the members of §6.4 (and may have fault)",
10: "the receipt is not an object whose canon is rfc8785",
11: "the result's format, profile, accuracy or energy is not §6.4's, or its method, shots "
"or seed is not run's",
12: "the result's qubits is not a count from 1 to 2^15, or its transcript_blake3 is no digest",
13: "the result's fuel has not exactly used, instances, budget and callouts, its budget is "
"not run's fuel, or used is past the budget per_job",
14: "a member of fuel's callouts is no extern of the contract, or its calls, fuel and max "
"break their form or bounds",
15: "fuel's instances and its callouts' fuel do not add up to used, or their calls to the "
"result's callouts",
16: "the result's modules are not the contract's, name and blake3 at each index",
17: "fuel's instances are past M x S x the budget per_instance",
19: "the counts are not an object of outcomes of 0 and 1, of one length, each at least 1, "
"adding up to shots_run",
20: "a member of fuel's callouts has a fuel of its returned calls (its fuel less the "
"stopped call's) below 0, outside 1 to max for each call that returned, or below max "
"and 1 for each other when the most was a returned call's",
21: "fuel's instances are no count of at least W x P + E, the least that making the "
"instances took outside a stopped call",
22: "a call's fault names another module than its callout's, or no callout or module of "
"the contract",
23: "a fault in phase prior names no module of the contract that has a prior",
24: "a fault of bad_result is in another phase than call or prior",
25: "a lifecycle fault's fuel is no count, or with rule 21's W x P + E is past fuel's "
"instances",
26: "with state job, a lifecycle fault's shot is not the count 0",
27: "a lifecycle fault at shot 0 comes with the result's callouts other than the count 0",
28: "a fault of fuel_exhausted did not use its whole limit (call, instance, or the run's "
"per_job used up below the call's own)",
29: "the counts' longest outcome is past 2^20 bits, or run's shots times its length past 2^28",
30: "the work the receipt shows (tableaux, instances, compiling, calls, per_job) is past "
"2^42",
31: "the envelope the contract names (magic and lengths, manifest, contract, frames) is "
"past 2^27 bytes",
32: "the result's callouts are past 2^21 for each shot that ran steps",
33: "a prior passed whole does not fit within per_instance (3 and its bytes)",
34: "a fault's fuel is below what its reason shows was charged (1, 2 for bad_result, 788 "
"for stack_exhausted)",
35: "no call returned, and the transcript_blake3 is not the one such a run gives",
}
# The words of the rules the second version reads with its own names (§11.6), and its 36th.
WASMQ2_RULE_WORDS = {
4: "the contract's profile is not wai.quantum.wasmq/2",
8: "run's shots, seed, method (stabilizer or exact), state or a budget breaks its form",
11: "the result's format or profile is not the second version's, its accuracy not the one its "
"method has, or its method, shots or seed is not run's",
12: "the result's qubits is not a count from 1 to 2^15 (at most 26 by the exact method), or "
"its transcript_blake3 is no digest",
30: "the work the receipt shows (fresh states, instances, compiling, calls, per_job) is past "
"2^42",
36: "the energy is not exactly run and callouts, each a figure: the unmetered form with its "
"reason, or a reading of at least 1 microjoule with its class and its uncertainty, for "
"each callout the run called and no other",
}
def _rule_words(number, result):
if wasmq_version(result) == 2 and number in WASMQ2_RULE_WORDS:
return "rule %d: %s" % (number, WASMQ2_RULE_WORDS[number])
if number != 18:
return "rule %d: %s" % (number, WASMQ_RULE_WORDS[number])
status = _get(result, "status")
if _text_is(status, "ok"):
words = "the status is ok, but the result has a fault, or not every shot ran"
elif _text_is(status, "fault"):
words = ("the status is fault, but the fault breaks §6.2's form or disagrees with the run "
"(its reason, shot, phase, module, fuel, callout or budget)")
else:
words = "the status is neither ok nor fault"
return "rule 18: " + words
def _first_and_more(items, shown=WASMQ_PROBLEMS_SHOWN):
"""§6.5: the first 64, and then how many more."""
# SPEC-GAP: [W11] "the first 64 of them and then how many more": how many more is
# one more entry of the list, "and N more", not a member of its own. One entry a
# rule gives at most 35, so a job never reaches it; the self-test calls it alone.
items = list(items)
if len(items) <= shown:
return items
return items[:shown] + ["and %d more" % (len(items) - shown)]
def _words(v):
"""A value of the body or the result, written for a note."""
return json.dumps(_plain(v), ensure_ascii=False, separators=(",", ":"))
def wasmq_notes(job, result):
"""quantum-wasmq §6.4, §6.5: where the body's unsealed members differ from what is
sealed, or are missing. A note is no part of the verdict."""
# SPEC-GAP: [W12] §6.4: the body's status is done when the result's status is ok and
# fault otherwise, so the body's status is held to that word, "otherwise" taken as
# it stands (a result's status that is absent, or no string, carries fault); its
# method to the result's method, as JSON values are equal (a result with no method
# leaves any method in the body differing). A body member that is null is present
# (§6.5), so it differs; only one the body does not name is missing.
notes = []
status, method = _get(result, "status"), _get(result, "method")
carried = "done" if _text_is(status, "ok") else "fault"
for name, wanted, sealed in (("status", carried, status), ("method", method, method)):
said = _get(job, name)
if said is _ABSENT:
notes.append("the host's unsealed %s is missing" % name)
elif not _same(said, wanted):
note = "the host's unsealed %s says %s; the sealed result %s" % (
name, _words(said), "has none" if sealed is _ABSENT else "says " + _words(sealed))
if name == "status" and not _same(sealed, wanted):
# the sealed word is not the body's (ok carries done): say which it carries
note += ", and the body carries %s for that" % _words(wanted)
notes.append(note)
# SPEC-GAP: [W13] §6.4: "or any other member of the body": nothing sealed answers it,
# so each member beyond the four is noted whatever its value, in the canonical
# text's order of names.
for name in sorted(set(job) - {"request", "result", "status", "method"}, key=_utf16):
notes.append("the body's member %s is the host's word; nothing seals it" % _words(name))
return notes
def wasmq_statement(job, result, broken):
"""quantum-wasmq §6.5, §8.4: what a verifier states beside a wasmQ job's verdict:
outcome, problems and notes. None of it changes the verdict."""
# SPEC-GAP: [W10] "outcome, the sealed result's status": given as that string, and
# as null when the status is absent or no string, so that the outcome is a word.
status = _get(result, "status")
return {
"outcome": status if isinstance(status, str) else None,
"problems": _first_and_more(_rule_words(n, result) for n in broken),
"notes": wasmq_notes(job, result),
}
# ============================= 7b. an energy-landscape job (quantum-landscape §5.4)
#
# Written from wai/extensions/quantum-landscape.md §5.4, whose rules are numbered. §8.4's
# `landscape_form` holds a job to them when its result's protocol or schema is
# wai.quantum.landscape/1. Every rule is read from the job alone: no program is read here.
LANDSCAPE = "wai.quantum.landscape/1"
L_SETTLE = "wai.quantum.landscape/settle"
L_SAMPLE = "wai.quantum.landscape/sample"
L_KERNELS = (L_SETTLE, L_SAMPLE)
L_PARITIES = ("reference", "bit-exact", "statistical", "uncertified")
L_VERDICTS = ("solved", "missed", "failed", "unchecked")
L_MODES = ("settle", "quench", "sample")
L_CAPACITY = ("cells", "couplings", "table_entries", "uncertain_span", "sweeps", "chains_per_call")
L_SIDE = ("field", "field_bound", "cost")
L_FLOOR = (("cells", 32), ("couplings", 992), ("table_entries", 31), ("uncertain_span", 61), ("sweeps", 5000))
L_FLOOR_SIDE = (("field", 40), ("field_bound", 41), ("cost", 8))
L_PROVIDER = "wai.quantum.provider/1"
_L_DIGITS = re.compile(r"[0-9]+")
_L_DECIMAL = re.compile(r"[0-9]+(?:\.[0-9]+)?")
_L_ENERGY = re.compile(r"-?[0-9]+")
_L_HEX16 = re.compile(r"[0-9a-f]{16}")
_L_HEX64 = re.compile(r"[0-9a-f]{64}")
_L_NAME = re.compile(r"[a-z0-9._-]+")
_INF = float("inf")
def is_landscape(result):
"""§5.4: a job whose result's protocol or schema is wai.quantum.landscape/1."""
return result.get("protocol") == LANDSCAPE or result.get("schema") == LANDSCAPE
def _l_given(o, name):
"""§5.4: in the request, a member given as null is absent."""
return o.get(name) if isinstance(o, dict) else None
def _l_value(v):
return v.value if isinstance(v, Num) else None
def _l_whole_in(v, low, high):
return isinstance(v, Num) and v.value.is_integer() and low <= v.value <= high
def _l_text(v):
return isinstance(v, str) and v != ""
def _l_exactly(v, names):
return isinstance(v, dict) and set(v) == set(names)
def _l_seed(v):
"""Rule 3: a whole number from 0 to 2^64 - 1, or a string of 1 to 20 ASCII digits whose
value is at most that; its value, or None."""
if isinstance(v, str):
if len(v) <= 20 and _L_DIGITS.fullmatch(v) and int(v) <= 2 ** 64 - 1:
return int(v)
return None
if isinstance(v, Num) and v.value.is_integer() and 0 <= v.value < 2 ** 64:
return int(v.value)
return None
def _l_temperature(v):
"""Rule 3: a number, or a string [0-9]+(.[0-9]+)? of at most 40 characters, whose value
is 0, or finite and at least 0.000001; its value, or None."""
if isinstance(v, str):
if len(v) > 40 or not _L_DECIMAL.fullmatch(v):
return None
t = float(v)
elif isinstance(v, Num):
t = v.value
else:
return None
return t if math.isfinite(t) and (t == 0 or t >= 1e-6) else None
def _l_request_seed(req):
"""The seed a request asks for: 1 where it gives none; None for one of no form."""
v = _l_given(req, "seed")
return 1 if v is None else _l_seed(v)
def _l_cells(v):
"""Rule 10: a state of 1 to 4096 characters, each +, - or 0, as cells; or None."""
if not isinstance(v, str) or not 1 <= len(v) <= 4096 or any(c not in "+-0" for c in v):
return None
return [1 if c == "+" else -1 if c == "-" else 0 for c in v]
def _l_fnv(cells):
"""§3.2: FNV-1a over the cells, each the byte s + 1."""
h = 0xCBF29CE484222325
for c in cells:
h ^= c + 1
h = (h * 0x100000001B3) & 0xFFFFFFFFFFFFFFFF
return "%016x" % h
def landscape_op(r):
"""Rule 4: the answer's operation, read from its members."""
if "lines" in r:
return "replay"
if "rows" in r and "target" in r:
return "compare"
if "rows" in r:
return "sweep"
if "state" in r:
return "run"
return None
def _l_stated(m, single):
"""Each kernel the member names with the parity it states for it, where the parity is a
string ("" for a kernel that is not one)."""
if not isinstance(m, dict):
return []
if single:
p, k = m.get("parity"), m.get("kernel")
return [(k if isinstance(k, str) else "", p)] if isinstance(p, str) else []
out = []
ks = m.get("kernels")
for k in ks if isinstance(ks, list) else []:
p = k.get("parity") if isinstance(k, dict) else None
if isinstance(p, str):
kk = k.get("kernel")
out.append((kk if isinstance(kk, str) else "", p))
return out
def landscape_broken(request, r):
"""quantum-landscape §5.4: the numbers of the rules a landscape job breaks."""
broken = set()
def rule(n, holds):
if not holds:
broken.add(n)
rec = r.get("receipt")
rule(1, isinstance(rec, dict) and rec.get("canon") == "rfc8785")
eng = r.get("engine")
rule(2, r.get("protocol") == LANDSCAPE and r.get("schema") == LANDSCAPE
and isinstance(eng, dict) and eng.get("name") == "wai-quantum" and isinstance(eng.get("version"), str))
if not isinstance(request, dict):
rule(3, False)
else:
prog = request.get("program")
rule(3, isinstance(prog, str) and len(prog.encode("utf-8")) <= 4194304)
g = lambda k: _l_given(request, k)
rule(3, g("seed") is None or _l_seed(g("seed")) is not None)
rule(3, g("temperature") is None or _l_temperature(g("temperature")) is not None)
rule(3, g("seeds") is None or _l_whole_in(g("seeds"), 1, 100000))
ts = g("temperatures")
rule(3, ts is None or (isinstance(ts, list) and 1 <= len(ts) <= 64 and all(_l_temperature(t) is not None for t in ts)))
rule(3, g("parity") is None or g("parity") in ("bit-exact", "statistical"))
rule(3, g("protocol") is None or g("protocol") == LANDSCAPE)
rule(3, g("provider") is None or _l_text(g("provider")))
rule(5, _l_text(r.get("label")))
_l_provider_rule(request, r, rule)
op = landscape_op(r)
if op is None:
rule(4, False)
return broken
single = op in ("run", "replay")
m = r.get("member")
pairs = _l_stated(m, single)
mid = m.get("id") if isinstance(m, dict) else None
reference = mid == "cpu:reference"
# Rule 6.
required = ("id", "class", "kernel", "parity") if single else ("id", "class", "kernels")
rule(6, isinstance(m, dict) and all(k in m for k in required) and all(k in required or k in ("capacity", "demoted") for k in m))
cls = m.get("class") if isinstance(m, dict) else None
cls = cls if cls in ("cpu", "gpu", "fpga") else None
rule(6, cls is not None)
rule(6, cls is not None and isinstance(mid, str) and len(mid) <= 64 and mid.startswith(cls + ":") and bool(_L_NAME.fullmatch(mid[len(cls) + 1:])))
if single:
rule(6, m.get("kernel") in L_KERNELS if isinstance(m, dict) else False)
rule(6, m.get("parity") in L_PARITIES if isinstance(m, dict) else False)
else:
ks = m.get("kernels") if isinstance(m, dict) else None
rule(6, isinstance(ks, list) and len(ks) > 0
and all(_l_exactly(k, ("kernel", "parity")) and k["kernel"] in L_KERNELS and k["parity"] in L_PARITIES for k in ks)
and len(set(k["kernel"] for k in ks)) == len(ks))
if op == "compare":
rule(6, isinstance(ks, list) and len(ks) == 1 and isinstance(ks[0], dict) and ks[0].get("kernel") == L_SAMPLE)
rule(6, all((p == "reference") == reference for _, p in pairs))
rule(6, all(p != "statistical" or k == L_SAMPLE for k, p in pairs))
# Rule 7.
if isinstance(m, dict) and "demoted" in m:
rule(7, isinstance(m["demoted"], str) and all(p == "uncertified" for _, p in pairs))
# Rule 8.
if isinstance(m, dict) and "capacity" in m:
c = m["capacity"]
rule(8, not reference)
number = lambda v: _l_whole_in(v, 0, _INF)
side = lambda v: isinstance(v, dict) and len(v) > 0 and all(k in L_SIDE and number(x) for k, x in v.items())
rule(8, isinstance(c, dict) and len(c) > 0 and all(side(x) if k in ("at_zero", "above_zero") else (k in L_CAPACITY and number(x)) for k, x in c.items()))
if any(p in ("bit-exact", "statistical") for _, p in pairs):
def under(o, floor):
return any(isinstance(o, dict) and isinstance(o.get(k), Num) and o[k].value < f for k, f in floor)
sub = lambda k: c.get(k) if isinstance(c, dict) else None
rule(8, not under(c, L_FLOOR) and not under(sub("at_zero"), L_FLOOR_SIDE) and not under(sub("above_zero"), L_FLOOR_SIDE))
# Rule 9.
bit_exact = any(p == "bit-exact" for _, p in pairs)
if "audit" in r:
a = r["audit"]
rule(9, bit_exact and isinstance(a, dict) and isinstance(a.get("checked"), list) and len(a["checked"]) > 0)
else:
rule(9, not bit_exact)
if "refusals" in r:
f = r["refusals"]
rule(9, isinstance(f, list) and len(f) > 0 and all(isinstance(x, dict) and isinstance(x.get("member"), str) and isinstance(x.get("why"), str) for x in f))
if op == "run":
_l_run_rule(request, r, m, rule)
elif op == "replay":
_l_replay_rule(request, r, rule)
else:
_l_rows_rule(op, r, pairs, rule)
return broken
def _l_run_rule(request, r, m, rule):
"""Rule 10: a run."""
prog = request.get("program") if isinstance(request, dict) else None
rule(10, isinstance(prog, str) and r.get("program_digest") == blake3(prog.encode("utf-8")).hex())
seed = r.get("seed")
want = _l_request_seed(request)
rule(10, want is not None and isinstance(seed, str) and str(want) == seed)
mode = r.get("mode") if r.get("mode") in L_MODES else None
kernel = m.get("kernel") if isinstance(m, dict) else None
rule(10, mode is not None and kernel == (L_SETTLE if mode == "settle" else L_SAMPLE))
t = _l_value(r.get("temperature"))
rule(10, t is not None and mode is not None and (t > 0 if mode == "sample" else t == 0))
asked = _l_given(request, "temperature")
if asked is not None:
tv = _l_temperature(asked)
rule(10, tv is not None and t is not None and tv == t)
restarts = _l_value(r.get("restarts")) if _l_whole_in(r.get("restarts"), 1, 100000) else None
rule(10, restarts is not None and (mode != "settle" or restarts == 1))
sweeps = _l_value(r.get("sweeps")) if _l_whole_in(r.get("sweeps"), 1, 1000000) else None
rule(10, sweeps is not None)
cells = _l_cells(r.get("state"))
rule(10, cells is not None and _l_value(r.get("variables")) == len(cells))
e = _l_value(r.get("energy"))
energy = e if e is not None and e.is_integer() and -2 ** 63 <= e < 2 ** 63 else None
rule(10, energy is not None)
rule(10, cells is not None and r.get("state_hash") == _l_fnv(cells))
replay = None
if (isinstance(seed, str) and _L_DIGITS.fullmatch(seed) and int(seed) <= 2 ** 64 - 1 and isinstance(prog, str) and mode is not None
and (mode != "sample" or t is not None) and restarts is not None and sweeps is not None and cells is not None and energy is not None):
pb = prog.encode("utf-8")
data = LANDSCAPE.encode() + b"\0" + struct.pack("<Q", len(pb)) + pb + struct.pack("<Q", int(seed)) + mode.encode() + b"\0"
if mode == "sample":
data += struct.pack("<d", t)
data += struct.pack("<Q", int(restarts)) + struct.pack("<I", int(sweeps)) + bytes(c + 1 for c in cells) + struct.pack("<q", int(energy))
replay = blake3(data).hex()
rule(10, replay is not None and r.get("replay") == replay)
j = r.get("joules")
metered = j.get("metered", _ABSENT) if isinstance(j, dict) else _ABSENT
rule(10, isinstance(j, dict) and j.get("kind") == "priced"
and (metered is None or (isinstance(metered, dict) and all(_l_whole_in(metered.get(k), 0, _INF) for k in ("joules_micro", "window_us")))))
verdict = r.get("verdict") if r.get("verdict") in L_VERDICTS else None
rule(10, verdict is not None)
truth = r.get("truth", _ABSENT)
lowest = _l_value(truth.get("lowest")) if isinstance(truth, dict) else None
rule(10, truth is None or (isinstance(truth, dict) and lowest is not None))
reached = r.get("reached", _ABSENT)
if not isinstance(truth, dict) and reached is None:
consistent = verdict != "missed"
elif isinstance(truth, dict) and isinstance(reached, bool):
consistent = (reached == (energy is not None and lowest is not None and e == lowest)) and verdict != "unchecked" \
and (verdict in ("solved", "failed") if reached else verdict in ("missed", "failed"))
else:
consistent = False
rule(10, consistent)
def _l_replay_rule(request, r, rule):
"""Rule 11: a replay."""
given = _l_given(request, "seeds")
want = 20 if given is None else (given.value if _l_whole_in(given, 1, 100000) else None)
rule(11, want is not None and _l_value(r.get("seeds")) == want)
first = _l_request_seed(request)
text = r.get("lines")
holds = False
if isinstance(text, str) and want is not None and first is not None and text.endswith("\n"):
lines = text[:-1].split("\n")
holds = len(lines) == int(want)
width = None
for k, line in enumerate(lines if holds else []):
f = line.split(" ")
if len(f) != 7:
holds = False
break
cells = _l_cells(f[2])
if cells is not None and width is None:
width = len(cells)
if not (f[0] == str((first + k) % 2 ** 64) and _L_HEX16.fullmatch(f[1]) and cells is not None and len(cells) == width
and _L_ENERGY.fullmatch(f[3]) and f[4] in L_VERDICTS and _L_DIGITS.fullmatch(f[5]) and _L_HEX16.fullmatch(f[6])):
holds = False
break
rule(11, holds)
def _l_rows_rule(op, r, pairs, rule):
"""Rule 12: a sweep or a comparison."""
rows = r.get("rows")
ok = isinstance(rows, list) and len(rows) > 0 and all(isinstance(x, dict) for x in rows)
rule(12, ok)
def parity_of(k):
for kk, p in pairs:
if kk == k:
return p
return None
def row_holds(row):
if op == "sweep":
k = row.get("kernel") if isinstance(row.get("kernel"), str) else None
p = parity_of(k) if k is not None else None
mode = row.get("mode") if row.get("mode") in L_MODES else None
return p is not None and row.get("parity") == p and mode is not None and (mode == "settle") == (k == L_SETTLE)
c = row.get("classical")
if c is True:
return "parity" in row and row["parity"] is None
if c is False:
p = parity_of(L_SAMPLE)
return p is not None and row.get("parity") == p
return False
rule(12, ok and all(row_holds(x) for x in rows))
if op == "compare":
rule(12, "target" in r and _l_whole_in(r["target"], -_INF, _INF))
def _l_provider_rule(request, r, rule):
"""Rule 13: a provider's job."""
named = _l_given(request, "provider")
added = [k in r for k in ("provider", "job", "cost")]
if named is None:
rule(13, not any(added))
return
rule(13, all(added))
p = r.get("provider")
prov = p.get("provenance") if isinstance(p, dict) else None
provenance = isinstance(prov, str) and (prov == "silicon" or prov.split(":", 1)[0] in ("simulator", "emulator"))
rule(13, _l_exactly(p, ("name", "kind", "protocol", "device", "provenance", "describe"))
and isinstance(named, str) and p.get("name") == named
and p.get("kind") in ("http", "process") and p.get("protocol") == L_PROVIDER
and _l_text(p.get("device")) and provenance
and isinstance(p.get("describe"), str) and bool(_L_HEX64.fullmatch(p["describe"])))
j = r.get("job")
rule(13, _l_exactly(j, ("id", "polls")) and _l_text(j.get("id")) and _l_whole_in(j.get("polls"), 0, _INF))
c = r.get("cost")
x = c.get("charged", _ABSENT) if isinstance(c, dict) else _ABSENT
charged = x is None or (_l_exactly(x, ("amount", "currency")) and isinstance(x["amount"], str) and bool(_L_DECIMAL.fullmatch(x["amount"])) and _l_text(x["currency"]))
free = c.get("free") if isinstance(c, dict) else None
confirmed = c.get("confirmed") if isinstance(c, dict) else None
rule(13, _l_exactly(c, ("free", "estimate", "charged", "confirmed")) and isinstance(free, bool) and isinstance(confirmed, bool)
and confirmed != free and isinstance(c.get("estimate"), dict) and charged)
def check_landscape(request, result, reasons):
"""§8.4 landscape_form: an energy-landscape job that breaks a rule of quantum-landscape §5.4."""
if not is_landscape(result) or "landscape-unchecked" in PLANTS:
return None
broken = landscape_broken(request, result)
if broken:
reasons.add("landscape_form")
return broken
# ===================================================================== 8. a job
def _verdict(reasons, key=None, form=None):
return {"valid": not reasons, "reasons": sorted(reasons), "key": key, "form": form}
def judge(raw):
"""One job's text to its verdict (without "file")."""
try:
job = read_json(raw)
except Unreadable:
return _verdict(["unreadable"])
if not (isinstance(job, dict) and isinstance(job.get("request"), dict)
and isinstance(job.get("result"), dict)):
return _verdict(["not_a_job"])
# §8.2: only request and result are sealed; nothing else in the body decides (a
# wasmQ job's statement reads the rest for its notes, quantum-wasmq §6.5).
request, result = job["request"], job["result"]
if result.get("format") == SET_FORMAT:
return judge_set(request, result)
return judge_job(request, result, job)
def judge_job(request, result, job=None):
"""§8.4: a job's request and result, already read, to its verdict. `job` is the body
they were read from: a wasmQ job judged from its body states beside its verdict
what quantum-wasmq §6.5 says; a set's item (no body of its own) states nothing."""
provider = result.get("method") == "provider"
broken = None
if "receipt" not in result:
verdict = _verdict(["no_receipt"])
else:
reasons = set()
body = dict((k, v) for k, v in result.items() if k != "receipt")
key, form = check_seal(request, result["receipt"], body, reasons)
check_inexact(request, body, form, reasons)
if provider:
check_provider(request, result, reasons)
else:
check_class(result, False, False, reasons)
check_contract(request, result, reasons)
# §8.4: a wasmQ job's result is held to wasmq_form whatever its method, and to
# the provider rules too when its method is provider.
broken = check_wasmq(request, result, reasons)
# §8.4: an energy-landscape job's to landscape_form (quantum-landscape §5.4).
check_landscape(request, result, reasons)
verdict = _verdict(reasons, key, form)
if provider:
verdict["provider"] = provider_statement(result)
if "planner" in result:
verdict["planner"] = contract_statement(result)
# §8.4, quantum-wasmq §6.5: a judged wasmQ job (not no_receipt, nor reported alone
# before it) states its outcome, its problems and the notes on its unsealed body.
# SPEC-GAP: [W14] a set's item that is a wasmQ job states none: the set's verdict is
# one line, the set (format wai.quantum.set/1) is no wasmQ job, and an item's own
# reasons are folded into set_item.
if broken is not None and job is not None and is_wasmq(result):
verdict["wasmq"] = wasmq_statement(job, result, broken)
return verdict
# ===================================================================== 9. a set (§8.6)
SET_FORMAT = "wai.quantum.set/1"
_MERKLE_LEAF = b"moq-jwp:merkle-leaf\x01"
_MERKLE_NODE = b"moq-jwp:merkle-node\x01"
def judge_set(request, result):
"""§8.6: a set's request and result, already read, to its verdict. The seal is over
the request and the head (the result less items and receipt); the provider rules
do not apply to a head."""
if "receipt" not in result:
return _verdict(["no_receipt"])
reasons = set()
head = dict((k, v) for k, v in result.items() if k not in ("items", "receipt"))
key, form = check_seal(request, result["receipt"], head, reasons)
check_inexact(request, head, form, reasons)
if "set-seal-only" not in PLANTS: # PLANT: nothing of the items or the root
check_set(request, result, reasons)
return _verdict(reasons, key, form)
def _item_formed(i, item):
"""§8.6 set_items, the first sentence: item i's own form. An item is read for its
index, request, result, error and path; anything else it holds is unsealed."""
if not isinstance(item, dict):
return False
index = item.get("index")
if not (_whole(index) and index.value == i and isinstance(item.get("request"), dict)):
return False
# §8.6: exactly one of the members result and error present, whatever its value.
if ("result" in item) == ("error" in item):
return False
if "result" in item and not isinstance(item["result"], dict):
return False
if "error" in item and not isinstance(item["error"], str):
return False
path = item.get("path")
return isinstance(path, list) and all(_lower_hex(h, 64) for h in path)
def _items_given(request, items):
"""§8.6: whether the items are the ones the request gives."""
programs, sweep = request.get("programs"), request.get("sweep") # null is none
base = dict((k, v) for k, v in request.items() if k not in ("programs", "sweep", "dry_run"))
# SPEC-GAP: [N42] "neither" read as: neither a programs that is an array nor a
# sweep that is an object; "both" as: both members there and not null. A programs
# that is no array, or a sweep that is no object, gives no items.
if programs is not None and sweep is not None:
return not items
if isinstance(programs, list):
if len(programs) != len(items):
return False
for program, item in zip(programs, items):
wanted = dict(base)
if isinstance(program, str):
wanted["qasm"] = program
elif isinstance(program, dict):
wanted.update(program) # each member replacing one of the same name
else:
# SPEC-GAP: [N43] a program neither a string nor an object gives no item.
return False
if not _same(item["request"], wanted):
return False
return True
if isinstance(sweep, dict):
# SPEC-GAP: [N44] a sweep value that is no non-empty array: the items are not the
# ones the request gives, whatever they are. An empty sweep's product is 1.
product = 1
for values in sweep.values():
if not (isinstance(values, list) and values):
return False
product *= len(values)
if product > len(items):
return False
if product != len(items):
return False
# §8.6: each item's request less qasm is the request less programs, sweep,
# dry_run and qasm; its qasm a string (the program written out at its point,
# which §8 does not check).
base.pop("qasm", None)
for item in items:
asked = item["request"]
if not isinstance(asked.get("qasm"), str):
return False
if not _same(dict((k, v) for k, v in asked.items() if k != "qasm"), base):
return False
return True
return not items
def item_leaf(item):
"""§8.6: an item's leaf, the canonical form's digest of its request and its result
less its receipt, or of its request and {"error": the error}."""
q = text_of(item["request"], True).encode("utf-8")
if "result" in item:
body = dict((k, v) for k, v in item["result"].items() if k != "receipt")
else:
body = {"error": item["error"]}
return seal_digest(2, q, text_of(body, True).encode("utf-8"))
def _leaf_hash(leaf):
return blake3(_MERKLE_LEAF + leaf)
def _node_hash(left, right):
return blake3(_MERKLE_NODE + left + right)
def merkle_levels(hashes):
"""Each level of the tree from the leaves' hashes up; a level of odd length pairs
its last hash with itself."""
levels = [list(hashes)]
while len(levels[-1]) > 1:
level = levels[-1]
levels.append([_node_hash(level[j], level[j + 1] if j + 1 < len(level) else level[j])
for j in range(0, len(level), 2)])
return levels
def merkle_path(levels, position):
"""The siblings from a leaf up (the self-test makes paths with it)."""
path = []
for level in levels[:-1]:
sibling = position + 1 if position % 2 == 0 else position - 1
path.append(level[sibling] if sibling < len(level) else level[position])
position //= 2
return path
def _halvings(n):
count = 0
while n > 1:
n = (n + 1) // 2
count += 1
return count
def _root_holds(root, items):
"""§8.6 set_root: root is the Merkle root of the leaves, and each path leads to it."""
if not _lower_hex(root, 64) or not items:
return False # (no items is set_items', and not checked here)
hashes = [_leaf_hash(item_leaf(item)) for item in items]
want = bytes.fromhex(root)
if merkle_levels(hashes)[-1][0] != want:
return False
depth = _halvings(len(items))
for position, (item, h) in enumerate(zip(items, hashes)):
# §8.6: a path of any other length does not lead to the root.
if len(item["path"]) != depth:
return False
at = position
for sibling in item["path"]:
other = bytes.fromhex(sibling)
h = _node_hash(h, other) if at % 2 == 0 else _node_hash(other, h)
at //= 2
if h != want:
return False
return True
def check_set(request, result, reasons):
"""§8.6 set_items, set_item, set_root."""
items = result.get("items")
# set_items: a non-empty array of well-formed items; reported so, the next two
# are not checked.
if not (isinstance(items, list) and items
and all(_item_formed(i, it) for i, it in enumerate(items))):
reasons.add("set_items")
return
count = result.get("count")
if not (isinstance(count, Num) and count.value == len(items)) or not _items_given(request, items):
reasons.add("set_items")
if not all(_item_holds(item, result["receipt"]) for item in items):
reasons.add("set_item")
if not _root_holds(result.get("root"), items):
reasons.add("set_root")
def _item_holds(item, set_receipt):
"""§8.6 set_item, for one item."""
if "error" in item:
# §8.6: an item with an error: its request writes no whole number its leaf
# could not seal, as inexact_number reads one in a canonical receipt, whatever
# the set's form, since a leaf is the canonical form's digest.
return not writes_inexact(item["request"], "rfc8785")
item_result = item["result"]
if item_result.get("format") == SET_FORMAT:
return False # an item is one job
verdict = judge_job(item["request"], item_result)
if verdict["reasons"]:
return False
# §8.6: a valid item's receipt names the set's receipt's `key` member as it
# stands; one the set's receipt does not have is another.
set_key = set_receipt.get("key") if isinstance(set_receipt, dict) else None
return isinstance(set_key, str) and verdict["key"] == set_key
def verdict_for(name, raw):
try:
v = judge(raw)
except (RecursionError, MemoryError, Exception) as e:
# Never a traceback. This should not happen; §8.4 has no reason for it.
sys.stderr.write("receipt_verify: internal error on %s (%s): reported as unreadable\n"
% (name, type(e).__name__))
v = {"valid": False, "reasons": ["unreadable"], "key": None, "form": None}
out = {"file": name}
out.update(v)
return out
def _read(path):
try:
with open(path, "rb") as f:
return f.read()
except (OSError, ValueError, MemoryError):
return None
def _usage():
sys.stderr.write("usage: receipt_verify.py [--plant NAME]... (FILE... | --lines FILE)\n"
" receipt_verify.py --self-test [ES_NUMBER_FILE]\n"
" receipt_verify.py --wasmq-cases OUT.jsonl [ES_NUMBER_FILE]\n")
return 2
def main(argv):
if not argv or argv[0] in ("-h", "--help"):
return _usage()
if argv[0] == "--self-test":
return self_test(argv[1:])
if argv[0] == "--wasmq-cases":
return write_wasmq_cases(argv[1:])
verdicts, ok, i = [], True, 0
while i < len(argv):
arg = argv[i]
if arg in ("--plant", "--lines"):
if i + 1 >= len(argv):
return _usage()
value = argv[i + 1]
i += 2
if arg == "--plant":
if value not in PLANTS_KNOWN:
return _usage()
PLANTS.add(value)
sys.stderr.write("receipt_verify: planted fault %s: verdicts are wrong by design\n" % value)
continue
raw = _read(value)
if raw is None:
verdicts.append({"file": value, "valid": False, "reasons": ["unreadable"],
"key": None, "form": None})
continue
lines = raw.split(b"\n")
if lines and lines[-1] == b"":
lines.pop()
if not lines:
sys.stderr.write("receipt_verify: no job in %s\n" % value)
ok = False
for n, line in enumerate(lines, 1):
verdicts.append(verdict_for("%s:%d" % (value, n), line))
else:
i += 1
raw = _read(arg)
if raw is None:
verdicts.append({"file": arg, "valid": False, "reasons": ["unreadable"],
"key": None, "form": None})
else:
verdicts.append(verdict_for(arg, raw))
try:
for v in verdicts:
sys.stdout.write(json.dumps(v) + "\n")
sys.stdout.flush()
except (OSError, ValueError):
return 1
return 0 if ok and all(v["valid"] for v in verdicts) else 1
# =============================================================== 10. self-test
_BLAKE3_VECTORS = ( # BLAKE3's test vectors: byte i is i mod 251
(0, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262"),
(1, "2d3adedff11b61f14c886e35afa036736dcd87a74d27b5c1510225d0f592e213"),
(1023, "10108970eeda3eb932baac1428c7a2163b0e924c9a9e25b35bba72b28f70bd11"),
(1024, "42214739f095a406f3fc83deb889744ac00df831c10daa55189b5d121c855af7"),
(1025, "d00278ae47eb27b34faecf67b4fe263f82d5412916c1ffd97c8cb7fb814b8444"),
(2048, "e776b6028c7cd22a4d0ba182a8bf62205d2ef576467e838ed6f2529b85fba24a"),
)
_BLAKE3_ABC = "6437b3ac38465133ffb63b75273a8db548c558465d79db03fd359c6cd5bd9d85"
_RFC8032_VECTORS = ( # RFC 8032 §7.1 TEST 1, 2, 3
("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60",
"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a", "",
"e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"),
("4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb",
"3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", "72",
"92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00"),
("c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7",
"fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025", "af82",
"6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a"),
)
_SMALL_ORDER = ( # identity, order 2, the two of order 4
"0100000000000000000000000000000000000000000000000000000000000000",
"ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
"0000000000000000000000000000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000000000000000000000000080",
)
_CANONICAL_VECTORS = ( # RFC 8785 §3.2.2, §3.2.3, and numbers
('{"numbers":[333333333.33333329,1E30,4.50,2e-3,0.000000000000000000000000001],'
'"string":"\\u20ac$\\u000F\\u000aA\'\\u0042\\u0022\\u005c\\\\\\"\\/",'
'"literals":[null,true,false]}',
'{"literals":[null,true,false],"numbers":[333333333.3333333,1e+30,4.5,0.002,1e-27],'
'"string":"\u20ac$\\u000f\\nA\'B\\"\\\\\\\\\\"/"}'),
('{"\\u20ac":1,"\\r":2,"\\ufb33":3,"1":4,"\\ud83d\\ude00":5,"\\u0080":6,"\\u00f6":7}',
'{"\\r":2,"1":4,"\u0080":6,"\u00f6":7,"\u20ac":1,"\U0001f600":5,"\ufb33":3}'),
('[-0, 0.0, 1.0, 1e21, 1e-7, 123e-9, 5e-324, 1e-400, 1.7976931348623157e308]',
'[0,0,1,1e+21,1e-7,1.23e-7,5e-324,0,1.7976931348623157e+308]'),
)
_FIRST_FORM_VECTORS = (
("[1.0,1,-0,0.0,1e16,1e15,0.00001,0.000001,1.5e300,18446744073709551615,"
"18446744073709551616,-9223372036854775808,-9223372036854775809,2.5,-1.5e-7]",
"[1.0,1,-0.0,0.0,1e+16,1000000000000000.0,0.00001,1e-6,1.5e+300,18446744073709551615,"
"1.8446744073709552e+19,-9223372036854775808,-9.223372036854776e+18,2.5,-1.5e-7]"),
# §8.2: a positive exponent with its sign, a negative one as before.
("[1e16,1.5e300,1e-7,1e15]", "[1e+16,1.5e+300,1e-7,1000000000000000.0]"),
)
_UNREADABLE_VECTORS = (
(b'{"a":1,"a":2}', "duplicate"),
(b'{"a":1,"\\u0061":2}', "duplicate"),
(b'["\\ud800"]', "surrogate"),
(b'["\\ud800x"]', "surrogate"),
(b'["\\udc00\\ud800"]', "surrogate"),
(b'["a\x01"]', "control"),
(b'[1e400]', "number_overflow"),
(b'[-1e400]', "number_overflow"),
(str(2 ** 1024 - 2 ** 970).encode(), "number_overflow"),
(b'\xef\xbb\xbf{}', "bom"),
(b'["\xed\xa0\x80"]', "utf8"),
(b'["\xc0\xaf"]', "utf8"),
(b'{"a":1,}', "syntax"),
(b'[01]', "syntax"),
(b'[NaN]', "syntax"),
(b'{} {}', "syntax"),
(b'', "syntax"),
(b'[' * 128 + b']' * 128, "depth"),
)
_READABLE_VECTORS = (
b'[' * 127 + b']' * 127,
str(2 ** 1024 - 2 ** 970 - 1).encode(),
b'[1e-400, "\\ufffe", "\\ufdd0", "\xef\xbf\xbf"]',
)
def _seal(seed, request_text, result_text, form="rfc8785", receipt_extra=None, envelope=""):
"""A job body sealed here, for the self-test only."""
request, result = read_json(request_text.encode()), read_json(result_text.encode())
canonical = form == "rfc8785"
digest = seal_digest(2 if canonical else 1, text_of(request, canonical).encode(),
text_of(result, canonical).encode())
public, sig = _ed25519_sign(seed, digest)
receipt = {"alg": "ed25519", "key": public.hex(), "digest": digest.hex(), "signature": sig.hex()}
if canonical:
receipt["canon"] = "rfc8785"
receipt.update(receipt_extra or {})
body = '{%s"request":%s,"result":%s,"receipt":%s}}' % (
envelope, request_text, result_text[:-1], json.dumps(receipt, separators=(",", ":")))
return body.encode()
_PROVIDER_REQUEST = '{"qasm":"OPENQASM 3.0;\\nqubit[1] q;\\nbit[1] c;\\nx q[0];\\nc = measure q;\\n","provider":"lab","shots":4}'
_PROVIDER_QASM3 = "OPENQASM 3.0;\nbit[1] c;\nx $0;\nc[0] = measure $0;\n"
def _provider_result(**changes):
r = {
"method": "provider", "qubits": 1, "gates": 1,
"accuracy": {"class": "simulated", "note": "counts a simulator returned"},
"provider": {"name": "lab", "kind": "process", "protocol": "wai.quantum.provider/1",
"device": "reference", "provenance": "simulator:the reference simulator",
"qubits": 2, "basis": "rzsxxcz", "describe": "ab" * 32},
"calibration": "snap-1",
"compiled": {"basis": "rzsxxcz", "qasm3": _PROVIDER_QASM3,
"program": blake3(_PROVIDER_QASM3.encode()).hex(), "hash": "BLAKE3 of qasm3",
"native_gates": 1, "two_qubit_gates": 0, "swaps": 0, "layout": [0],
"final_layout": [0], "checked": "checked here", "placement": {}},
"job": {"id": "j-1", "polls": 0},
"counts": {"1": 4}, "distinct_outcomes": 1, "omitted_shots": 0, "shots": 4,
"counts_source": "shots",
"execution": {"stated_by": "provider", "mitigation": "off", "twirling": "none",
"decoupling": "none", "remapping": "off", "optimisation": "off",
"verbatim": True},
"ideal": {"computed": True, "total_variation_distance": 0, "hellinger_fidelity": 1},
"cost": {"free": True, "estimate": {"free": True}, "charged": None, "confirmed": False},
"energy": {"unmetered": "the work ran at the provider"},
"engine": {"name": "wai-quantum", "version": "0.9.0"}, "schema": "wai.quantum.job-result/1",
}
for path, value in changes.items():
node = r
parts = path.split("__")
for part in parts[:-1]:
node = node[part]
if value is _DELETE:
node.pop(parts[-1], None)
else:
node[parts[-1]] = value
return json.dumps(r, separators=(",", ":"))
_DELETE = object()
def _contract_job(seed=None, extra_routes=(), **changes):
"""§8.7: the provider job above, named under a contract that allows it and wants a
simulator's counts, with its reasoning and its shadow, for the self-test only:
(request text, result text). Every outcome is written here, not computed."""
request = json.loads(_PROVIDER_REQUEST)
request["contract"] = {"exactness": "simulated", "providers": "allowed"}
if seed is not None:
request["seed"] = seed
job_bytes = 1 << 30
facts = {"job_bytes": job_bytes, "routes": [
{"route": "method:exact", "class": "bit-exact", "seconds": None, "memory_bytes": None, "work": None}]}
digest = blake3(text_of(read_json(json.dumps(facts).encode()), True).encode("utf-8")).hex()
shadow_request = {"qasm": request["qasm"], "shots": 4, "seed": ((1 if seed is None else seed) + 2 ** 32) % 2 ** 53, "method": "exact"}
free_now = {"money": {"free": True}, "time": {"seconds": 1.5, "basis": "provider"}, "memory_bytes": None,
"work": None, "energy": {"joules": None, "why": "no provider states it"}, "leaves_out": ["energy"]}
planner = {
"format": "wai.quantum.planner/1", "wanted": "simulated", "wanted_from": "contract",
"named": "provider:lab", "question": "counts", "auto": None,
"host": {"job_bytes": job_bytes, "providers": ["lab"] + [r["provider"] for r in extra_routes]},
"routes": [
{"route": "method:exact", "kind": "local", "method": "exact", "class": "bit-exact", "host_dependent": False,
"auto_rank": 20, "price": None, "outcome": "rejected", "rejected": {"code": "not_named", "why": "the job names another route"}},
{"route": "provider:lab", "kind": "provider", "provider": "lab", "class": "simulated", "host_dependent": True,
"price": free_now, "outcome": "chosen"},
] + list(extra_routes),
"choice": "provider:lab", "why": "the route the job names",
"stable": {"scope": "the host-independent routes", "routes": ["method:exact"], "digest": digest, "choice": False},
"kept": {},
"shadow": {"route": "method:exact", "class": "bit-exact", "budget_seconds": 300,
"price": {"money": {"free": True}, "time": {"seconds": 0.001, "basis": "nominal"}, "memory_bytes": 1024,
"work": 8, "energy": {"joules": None, "why": "none"}, "leaves_out": []},
"request": shadow_request},
}
# By hand: 8 shots of "1" pooled, E|2B - 8| = (3/2)(5/4)(7/6) = 2.1875; half of it over 4.
n, d, tv, hf, bound = 0, 8, 0.0, 1.0, 0.2734375
shadow = {"ran": True, "route": "method:exact", "request": shadow_request, "shots": 4,
"accuracy": {"class": "bit-exact"}, "counts": {"1": 4}, "distinct_outcomes": 1, "omitted_shots": 0,
"distance": {"computed": True, "numerator": n, "denominator": d, "total_variation": tv,
"hellinger_fidelity": hf, "sampling_tvd_bound": bound}}
result = json.loads(_provider_result())
result["planner"], result["shadow"] = planner, shadow
both = {"request": request, "result": result}
for path, value in changes.items():
node = both
parts = path.split("__")
for part in parts[:-1]:
node = node[int(part)] if isinstance(node, list) else node[part]
last = int(parts[-1]) if isinstance(node, list) else parts[-1]
if value is _DELETE:
node.pop(last)
else:
node[last] = value
return json.dumps(both["request"], separators=(",", ":")), json.dumps(both["result"], separators=(",", ":"))
def _lr(name, cls, rank, outcome, code=None, seconds=0.001, memory=1024, joules=None, host_dependent=False, priced=True, watch="a test's reading"):
"""A local route, every member written out, for the self-test only."""
r = {"route": "method:" + name, "kind": "local", "method": name, "class": cls, "host_dependent": host_dependent,
"auto_rank": rank, "outcome": outcome,
"price": {"money": {"free": True}, "time": {"seconds": seconds, "basis": "nominal"}, "memory_bytes": memory,
"work": 8, "energy": {"joules": joules, "basis": "a test"} if joules is not None else {"joules": None, "why": "none"},
"leaves_out": []} if priced else None}
if priced and watch is not None:
r["price"]["energy"]["watch"] = watch
if code:
r["rejected"] = {"code": code, "why": "said so"}
return r
def _local_contract_job(contract, routes, choice, auto, stable_choice, kept, request_extra=None, energy=None, providers=(), result_class="bit-exact"):
"""§8.7: a job under a contract run on one of the engine's methods, for the self-test
only: (request text, result text). Every outcome, the choice, auto and stable.choice
are written by the caller, never computed here."""
request = {"qasm": "OPENQASM 3.0;\nqubit[1] q;\nbit[1] c;\nx q[0];\nc = measure q;\n", "shots": 4, "contract": contract}
request.update(request_extra or {})
job_bytes = 1 << 30
covered = [r for r in routes if r["kind"] == "local" and r["host_dependent"] is False]
facts = {"job_bytes": job_bytes, "routes": [{"route": r["route"], "class": r["class"],
"seconds": (r["price"] or {}).get("time", {}).get("seconds"), "memory_bytes": (r["price"] or {}).get("memory_bytes"),
"work": (r["price"] or {}).get("work")} for r in covered]}
digest = blake3(text_of(read_json(json.dumps(facts).encode()), True).encode("utf-8")).hex()
wanted = contract.get("exactness")
planner = {
"format": "wai.quantum.planner/1", "wanted": wanted, "wanted_from": "contract" if wanted else None,
"named": None, "question": "counts", "auto": auto,
"host": {"job_bytes": job_bytes, "providers": list(providers)}, "routes": routes, "choice": choice,
"why": "the cheapest", "kept": kept,
"stable": {"scope": "the host-independent routes", "routes": [r["route"] for r in covered], "digest": digest, "choice": stable_choice},
}
result = {"method": choice[len("method:"):], "qubits": 1, "gates": 1, "accuracy": {"class": result_class},
"counts": {"1": 4}, "elapsed_ms": 3, "planner": planner,
"energy": energy if energy is not None else {"unmetered": "a test"},
"engine": {"name": "wai-quantum", "version": "0.9.0"}, "schema": "wai.quantum.job-result/1"}
return json.dumps(request, separators=(",", ":")), json.dumps(result, separators=(",", ":"))
def _has_num(o):
if isinstance(o, Num):
return True
if isinstance(o, dict):
return any(_has_num(v) for v in o.values())
if isinstance(o, list):
return any(_has_num(v) for v in o)
return False
def _dump(o):
"""JSON text of a self-test value, a Num written by its own text."""
if not _has_num(o):
return json.dumps(o)
return _first_text(o)
def _first_text(o):
if isinstance(o, Num):
return o.text
if isinstance(o, dict):
return "{" + ",".join(json.dumps(k) + ":" + _first_text(v) for k, v in o.items()) + "}"
if isinstance(o, list):
return "[" + ",".join(_first_text(v) for v in o) + "]"
return json.dumps(o)
def _seal_set(seed, request, head, items, receipt_extra=None, form="rfc8785"):
"""A set sealed here over its request and head, for the self-test only."""
canonical = form == "rfc8785"
drop_key, upper_key = head.pop("_drop_key", False), head.pop("_upper_key", False)
q = text_of(read_json(_dump(request).encode()), canonical).encode()
t = text_of(read_json(_dump(head).encode()), canonical).encode()
digest = seal_digest(2 if canonical else 1, q, t)
public, sig = _ed25519_sign(seed, digest)
result = dict(head, items=items)
receipt = {"alg": "ed25519", "key": public.hex(), "digest": digest.hex(), "signature": sig.hex()}
if canonical:
receipt["canon"] = "rfc8785"
result["receipt"] = dict(receipt, **(receipt_extra or {}))
if drop_key:
del result["receipt"]["key"]
if upper_key:
result["receipt"]["key"] = result["receipt"]["key"].upper()
return ("{\"request\":%s,\"result\":%s}" % (_dump(request), _dump(result))).encode()
_ITEM_RESULT = ('{"method":"statevector","qubits":1,"gates":1,"accuracy":{"class":"exact"},'
'"counts":{"1":10}}')
def _set_body(seed, request, item_requests, errors=(), before_root=None, after_root=None,
head_extra=None, item_result=_ITEM_RESULT, item_seed=None, form="rfc8785"):
"""A set of items made and sealed here, each item a job sealed with the same seed.
before_root changes the items before the leaves are taken; after_root changes the
head and items after the root and paths are made, before the set is sealed."""
items = []
for i, asked in enumerate(item_requests):
if i in errors:
items.append({"index": i, "request": asked, "error": "it failed"})
else:
job = json.loads(_seal(item_seed or seed, _dump(asked), item_result).decode())
items.append({"index": i, "request": asked, "result": job["result"]})
if before_root:
before_root(items)
hashes = [_leaf_hash(item_leaf(read_json(_dump(item).encode()))) for item in items]
levels = merkle_levels(hashes) if hashes else [[]]
for i, item in enumerate(items):
item["path"] = [h.hex() for h in merkle_path(levels, i)]
head = {"format": SET_FORMAT, "count": len(items),
"root": levels[-1][0].hex() if hashes else "00" * 32}
head.update(head_extra or {})
if after_root:
after_root(head, items)
return _seal_set(seed, request, head, items, form=form)
# ---------------------------------------------- the wasmQ cases (quantum-wasmq §6.5)
#
# The self-test's wasmQ jobs, each made and sealed here, with the reasons §8.4 gives it and
# the rules of quantum-wasmq §6.5 it breaks, both written by hand from the text, never from
# this file's verdict. `--wasmq-cases` writes the same bytes and reasons, so that another
# verifier is held to what the text says, not to what this one does.
_WASMQ_SEED = bytes(range(32)) # the self-test's key (its `seed`), every case's
_WASMQ_FORM = ["wasmq_form"]
_WASMQ_DONE = '"status":"done","method":"stabilizer",'
_WASMQ_FAULTED = '"status":"fault","method":"stabilizer",'
_WASMQ_SEALED_LINE = '; the sealed result says '
_WASMQ_UNCHECKED_NAME = "plant wasmq-unchecked: strict verdict"
def _wasmq_parts(fault):
"""The request and result of a wasmQ job that keeps every rule of §6.5: a run of 32
shots, state shot; or, with `fault`, one of 8 shots, state job, stopped in shot 2's call
of decode64 by a fault of the call's fuel. The numbers the ties of rules 20 to 35 ask:
the run's instances, 3000, are at least W × P = 32 × (3 + 7) = 320 (rule 21); each
member of its callouts has fuel from calls to calls × max, and at least max and 1 for
each other call (rule 20); its prior's 3 + 7 fits per_instance (rule 33). The fault's
run has W = 1 (state job), P = 10, at most its instances 400; the stopped call used
per_call, 400 (rule 28), and decode64's two calls that returned used 600, from 2 to
2 × 400 (rule 20, its max not more than the stopped call's 400); decode64 is the extern
of callout 0, whose module 0 is the decoder (rule 22). In both a call returned, so rule
35 leaves the transcript free. Either's work (rule 30) is some 2^37, and its envelope
(rule 31) some 2^15 bytes."""
budget = {"per_call": 400 if fault else 10000000, "per_job": 17179869184, "per_instance": 100000000}
asked = {"wasmq": {
"profile": WASMQ_PROFILE,
"program": {"blake3": "a1" * 32, "bytes": 1104, "inputs": {"rounds": 3, "offset": -2}},
"modules": [{"name": "decoder", "blake3": "b2" * 32, "bytes": 39442,
"priors": [{"name": "checks", "blake3": "c3" * 32, "bytes": 7}]},
{"name": "planner", "blake3": "d4" * 32, "bytes": 2048, "priors": []}],
"callouts": [{"extern": "decode64", "module": 0, "export": "decode64"},
{"extern": "plan", "module": 1, "export": "plan"}],
"run": {"shots": 8 if fault else 32, "seed": 1234, "method": "stabilizer",
"state": "job" if fault else "shot", "fuel": dict(budget)}},
"envelope_blake3": "e5" * 32}
made = {
"format": WASMQ_FORMAT, "profile": WASMQ_PROFILE, "status": "ok", "method": "stabilizer",
"qubits": 17, "shots": 32, "shots_run": 32, "seed": 1234,
"counts": {"0101": 30, "1100": 2}, "callouts": 34,
"fuel": {"used": 9500, "instances": 3000, "budget": dict(budget),
"callouts": {"decode64": {"calls": 32, "fuel": 6400, "max": 200},
"plan": {"calls": 2, "fuel": 100, "max": 60}}},
"modules": [{"name": "decoder", "blake3": "b2" * 32}, {"name": "planner", "blake3": "d4" * 32}],
"transcript_blake3": "f6" * 32, "accuracy": {"class": "exact"},
"energy": {"unmetered": WASMQ_ENERGY}}
if fault: # state job: stopped in shot 2's call of decode64
made.update(status="fault", shots=8, shots_run=2, counts={"0101": 1, "1100": 1}, callouts=3,
fault={"reason": "fuel_exhausted", "shot": 2, "phase": "call", "module": "decoder",
"fuel": 400, "callout": "decode64", "budget": "call"})
made["fuel"].update(used=1400, instances=400,
callouts={"decode64": {"calls": 3, "fuel": 1000, "max": 400}})
return asked, made
def _wasmq_clone(v):
"""A change's value copied, so that a case never changes another's."""
if isinstance(v, dict):
return dict((k, _wasmq_clone(x)) for k, x in v.items())
if isinstance(v, list):
return [_wasmq_clone(x) for x in v]
return v
_WASMQ_TRANSCRIPT = object() # a result's transcript_blake3: the one rule 35 gives
def _wasmq_u64(v):
"""A count's 8 bytes, little-endian; 0 for what is no count (rule 35)."""
x = v.value if isinstance(v, Num) else v
if isinstance(x, bool) or not isinstance(x, (int, float)) or x != int(x) or not 0 <= x <= 2 ** 53 - 1:
x = 0
return int(x).to_bytes(8, "little")
def _wasmq_transcript(made):
"""§6.4, rule 35: the transcript of a run in which no call returned, written here from
§6.4's words: BLAKE3 over "wai:wasmq-transcript" and the byte 1, then, after a fault,
"fault", its shot (u64), its reason's UTF-8 bytes and its fuel (u64), little-endian."""
data = "wai:wasmq-transcript".encode("ascii") + bytes([1])
fault = made.get("fault")
if made.get("status") == "fault" and isinstance(fault, dict):
reason = fault.get("reason")
data += ("fault".encode("ascii") + _wasmq_u64(fault.get("shot"))
+ (reason.encode("utf-8") if isinstance(reason, str) else b"")
+ _wasmq_u64(fault.get("fuel")))
return blake3(data).hex()
def _wasmq_job(fault=False, request=None, result=None, envelope=_WASMQ_DONE, **seal_options):
"""A wasmQ job sealed here, each change a path (members joined by "__") and its value,
applied in order. A result's transcript_blake3 of _WASMQ_TRANSCRIPT is replaced, once
every change is made, by the transcript §6.4 gives the run (rule 35)."""
asked, made = _wasmq_parts(fault)
for target, changes in ((asked, request), (made, result)):
for path, value in (changes or {}).items():
node, parts = target, path.split("__")
for part in parts[:-1]:
node = node[int(part)] if isinstance(node, list) else node[part]
last = int(parts[-1]) if isinstance(node, list) else parts[-1]
if value is _DELETE:
del node[last]
elif isinstance(node, list) and last == len(node):
node.append(_wasmq_clone(value))
else:
node[last] = _wasmq_clone(value)
if made.get("transcript_blake3") is _WASMQ_TRANSCRIPT:
made["transcript_blake3"] = _wasmq_transcript(made)
return _seal(_WASMQ_SEED, _dump(asked), _dump(made), envelope=envelope, **seal_options)
def _wasmq_changed_after(raw, change):
"""A job changed after its seal."""
job = json.loads(raw.decode())
change(job)
return json.dumps(job).encode()
def _wasmq_statement(outcome, problems=(), notes=()):
return {"outcome": outcome, "problems": list(problems), "notes": list(notes)}
def _landscape_job(request=None, **changes):
"""An energy-landscape run sealed here, for the self-test only: built from
quantum-landscape §3 and §5.4 (not by any engine), every rule holding, then each member
of `changes` set on its result (None removes it)."""
request = request or {"program": "vars 2\nagree 0 1\nminimize\n"}
prog = request["program"].encode("utf-8")
cells, energy, sweeps = [0, 0], 0, 60
data = LANDSCAPE.encode() + b"\0" + struct.pack("<Q", len(prog)) + prog + struct.pack("<Q", 1) + b"settle\0"
data += struct.pack("<Q", 1) + struct.pack("<I", sweeps) + bytes(c + 1 for c in cells) + struct.pack("<q", energy)
result = {
"protocol": LANDSCAPE, "schema": LANDSCAPE, "engine": {"name": "wai-quantum", "version": "0"},
"label": "a test's answer", "member": {"id": "cpu:reference", "class": "cpu", "kernel": L_SETTLE, "parity": "reference"},
"program_digest": blake3(prog).hex(), "variables": 2, "seed": "1", "mode": "settle", "temperature": 0,
"restarts": 1, "sweeps": sweeps, "state": "00", "energy": energy, "truth": {"lowest": -1}, "reached": False,
"verdict": "missed", "joules": {"kind": "priced", "metered": None}, "state_hash": _l_fnv(cells), "replay": blake3(data).hex(),
}
for k, v in changes.items():
if v is None:
result.pop(k, None)
else:
result[k] = v
dump = lambda v: json.dumps(v, separators=(",", ":"), ensure_ascii=False)
return _seal(bytes(range(32)), dump(request), dump(result))
def _wasmq_unchecked_job():
"""The job of the plant wasmq-unchecked: one rule (11) broken."""
return _wasmq_job(result={"profile": "wai.quantum.wasmq/2"})
def _wasmq_tables():
"""The wasmQ cases: (cases, statements, verdicts).
cases: (name, job, the reasons, the rules of §6.5 it breaks, None for no wasmQ job);
statements: (name, job, the reasons, the statement beside its verdict);
verdicts: (name, job, the reasons, whether the whole verdict is those reasons alone).
Every reason and rule here is the text's, worked out by hand for the job's numbers."""
form = _WASMQ_FORM
shot_state = {"wasmq__run__state": "shot"}
job_state = {"wasmq__run__state": "job"}
# A fault outside a call that is no fault of fuel: a trap of 100 fuel, with no callout and
# no budget. On the fault's job (instances 400) it keeps rule 25: in state shot,
# 100 + W × P + E = 100 + 2 × (10 + 1) + 0 in seed, + 10 more in init (the decoder's own
# prior); in state job, 100 + 1 × 11.
seed_trap = {"fault__reason": "unreachable", "fault__phase": "seed", "fault__callout": _DELETE,
"fault__budget": _DELETE, "fault__fuel": 100}
init_trap = dict(seed_trap, fault__phase="init")
# A call's trap (no budget) of 150 fuel: below decode64's max of 400.
call_trap = {"fault__reason": "unreachable", "fault__budget": _DELETE, "fault__fuel": 150}
# State job, stopped at the first shot by a trap in the decoder's seed: no shot ran,
# no call was made, and no instance was made whole (W = 0, rule 21; E = 0, the decoder
# first). No call returned, so its transcript is the one rule 35 gives.
first_shot = {"shots_run": 0, "counts": {}, "callouts": 0, "fuel__used": 50, "fuel__instances": 50,
"fuel__callouts": {}, "transcript_blake3": _WASMQ_TRANSCRIPT,
"fault": {"reason": "unreachable", "shot": 0, "phase": "seed", "module": "decoder", "fuel": 50}}
a_call_at_first = {"callouts": 1, "fuel__used": 60,
"fuel__callouts": {"decode64": {"calls": 1, "fuel": 10, "max": 10}}}
# The run's budget the limit of decode64's third call: per_job 1150, of which the
# instances used 400 and two calls 400 and 200, leaving 150 < per_call (400).
run_budget = {"fuel__budget__per_job": 1150, "fuel__used": 1150, "fuel__callouts__decode64__fuel": 750,
"fault__fuel": 150, "fault__budget": "run"}
# A fault in init of the instance's budget, state shot: per_instance 100, all used.
init_exhausted = {"fuel__budget__per_instance": 100, "fault__phase": "init", "fault__budget": "instance",
"fault__callout": _DELETE, "fault__fuel": 100}
# A fault in the decoder's prior, state shot.
prior_fault = {"fault__reason": "bad_result", "fault__phase": "prior", "fault__callout": _DELETE,
"fault__budget": _DELETE, "fault__fuel": 100}
# A fault in plan's call (the module of index 1), plan's one call the one that stopped.
plan_fault = {"callouts": 3, "fault__callout": "plan", "fault__module": "planner",
"fuel__callouts": {"decode64": {"calls": 2, "fuel": 600, "max": 400},
"plan": {"calls": 1, "fuel": 400, "max": 400}}}
plan_fuel = {"calls": 2, "fuel": 100, "max": 60}
# The ok run with no call made: its instances all its fuel; its transcript is f6... but
# for a case that asks the one rule 35 gives.
no_call = {"callouts": 0, "fuel__callouts": {}, "fuel__used": 3000}
# The fault's run whose one call made is the call that stopped (shot 2's of decode64).
one_call = {"callouts": 1, "fuel__used": 800,
"fuel__callouts": {"decode64": {"calls": 1, "fuel": 400, "max": 400}}}
many_shots = {"wasmq__run__state": "job", "wasmq__run__shots": 2 ** 20}
many_made = {"shots": 2 ** 20, "shots_run": 2 ** 20}
# Rule 30: with the ok run's numbers (34 callouts, 4097 each), all but 8 × per_job comes
# to 5 440 169 634 (state shot, 17 qubits), 5 440 172 770 (33 qubits, w = 2) and
# 5 438 375 540 (state job, I = 1); none is a multiple of 8, so the most per_job leaves
# the work just under 2^42, and one more puts it just past.
work_at = 549075792683 # ⌊(2^42 − 5 440 169 634) / 8⌋: the work 2^42 − 6
work_at_33 = 549075792291 # ⌊(2^42 − 5 440 172 770) / 8⌋: the work 2^42 − 6
work_job = 549076016945 # ⌊(2^42 − 5 438 375 540) / 8⌋: the work 2^42 − 4
# Rule 31: the envelope is 20 bytes, the manifest (192 + "17", "32" and "1234": 200
# bytes), the contract in RFC 8785 form (786 bytes, its prior's bytes of 9 digits, state
# job, per_instance 2^28) and the frames, 1104 + 39442 + 2048 and the prior's bytes. At
# a prior of 134 174 128 bytes it is 2^27 exactly. State job, so that W = 1 and the
# instances hold one passing of the prior, 3 + its bytes (rule 21); per_instance 2^28,
# so that the prior fits one lifecycle call (rule 33).
envelope_prior = 2 ** 27 - (20 + 200 + 786 + 1104 + 39442 + 2048)
big_prior_asked = dict(job_state, wasmq__run__fuel__per_instance=2 ** 28)
big_prior = {"fuel__budget__per_instance": 2 ** 28, "fuel__instances": 3 + envelope_prior + 1,
"fuel__used": 3 + envelope_prior + 1 + 6500}
cases = (
("wasmq: a run", _wasmq_job(), [], []),
("wasmq: a run stopped by a fault", _wasmq_job(fault=True, envelope=_WASMQ_FAULTED), [], []),
("wasmq: shots written 32.0", _wasmq_job(request={"wasmq__run__shots": 32.0},
result={"shots": 32.0, "shots_run": 32.0}), [], []),
("wasmq: shots written 3.2e1, a count 30e0", _wasmq_job(request={"wasmq__run__shots": Num("3.2e1", 32.0)},
result={"counts__0101": Num("30e0", 30.0)}), [], []),
("wasmq: a module index written -0 and 1e0", _wasmq_job(request={
"wasmq__callouts__0__module": Num("-0", -0.0), "wasmq__callouts__1__module": Num("1e0", 1.0)}), [], []),
("wasmq: the unsealed status and method changed", _wasmq_job(envelope='"status":"failed","method":7,'),
[], []),
("wasmq: the unsealed status and method removed", _wasmq_job(envelope=""), [], []),
("wasmq: a fault's unsealed status says done", _wasmq_job(fault=True), [], []),
("wasmq: a member added to the receipt", _wasmq_job(receipt_extra={"note": "added", "x": [1]}), [], []),
("wasmq: an input negative, at its size", _wasmq_job(request={
"wasmq__program__inputs__offset": -(2 ** 53 - 1)}), [], []),
("wasmq: an empty prior", _wasmq_job(request={"wasmq__modules__0__priors__0__bytes": 0}), [], []),
# Rule 12: a program declares a qubit at least.
("wasmq rule 12: qubits 0", _wasmq_job(result={"qubits": 0}), form, [12]),
("wasmq: qubits 1", _wasmq_job(result={"qubits": 1}), [], []),
("wasmq: qubits 2^15", _wasmq_job(result={"qubits": 2 ** 15}), [], []),
("wasmq: instances and used moved together", _wasmq_job(result={
"fuel__instances": 3001, "fuel__used": 9501}), [], []),
("wasmq: an outcome of no bits", _wasmq_job(result={"counts": {"": 32}}), [], []),
("wasmq: a fault in init, of its instance's budget", _wasmq_job(fault=True, request=dict(
shot_state, wasmq__run__fuel__per_instance=100), result=init_exhausted), [], []),
("wasmq: a fault of the run's budget in a call", _wasmq_job(fault=True, request={
"wasmq__run__fuel__per_job": 1150}, result=run_budget), [], []),
("wasmq: a trap in seed", _wasmq_job(fault=True, request=shot_state, result=seed_trap), [], []),
("wasmq: state shot, a fault's instance counted (M = 2 + 1)", _wasmq_job(fault=True, request={
"wasmq__run__state": "shot", "wasmq__run__fuel__per_instance": 27},
result={"fuel__budget__per_instance": 27}), [], []),
("wasmq: state job, one instance (M = 1)", _wasmq_job(fault=True, request={
"wasmq__run__fuel__per_instance": 80}, result={"fuel__budget__per_instance": 80}), [], []),
("wasmq: a call's fuel below its callout's max", _wasmq_job(fault=True, result=dict(
call_trap, fault__reason="integer_divide_by_zero", fuel__callouts__decode64__fuel=750,
fuel__used=1150)), [], []),
("wasmq: a call's callout's max written 4e2, its fuel's", _wasmq_job(fault=True, result={
"fuel__callouts__decode64__max": Num("4e2", 400.0)}), [], []),
("wasmq: another format is not a wasmQ job's", _wasmq_job(result={"format": "other", "profile": "x"}),
[], None),
# Rule 1, beside the rule of the number it breaks: every number a job of the form
# holds is a count or an input, each held to 2^53 − 1 by a rule of its own.
("wasmq rule 1: an input of 2^53", _wasmq_job(request={"wasmq__program__inputs__rounds": 2 ** 53}),
form, [1, 5]),
("wasmq rule 1: an input of -2^53", _wasmq_job(request={"wasmq__program__inputs__offset": -2 ** 53}),
form, [1, 5]),
("wasmq rule 1: a seed of 2^53", _wasmq_job(request={"wasmq__run__seed": 2 ** 53},
result={"seed": 2 ** 53}), form, [1, 8]),
# Rules 2 to 19.
("wasmq rule 2: envelope_blake3 in upper case", _wasmq_job(request={"envelope_blake3": "E5" * 32}),
form, [2]),
("wasmq rule 2: a member more", _wasmq_job(request={"note": "x"}), form, [2]),
("wasmq rule 2: envelope_blake3 missing", _wasmq_job(request={"envelope_blake3": _DELETE}), form, [2]),
("wasmq rule 3: the program a member more", _wasmq_job(request={"wasmq__program__note": "x"}), form, [3]),
("wasmq rule 3: the contract a member more", _wasmq_job(request={"wasmq__note": "x"}), form, [3]),
("wasmq rule 3: run a member more", _wasmq_job(request={"wasmq__run__note": "x"}), form, [3]),
("wasmq rule 3: run's fuel a member more, the budget alike", _wasmq_job(
request={"wasmq__run__fuel__extra": 1}, result={"fuel__budget__extra": 1}), form, [3]),
("wasmq rule 4: another profile", _wasmq_job(request={"wasmq__profile": "wai.quantum.wasmq/2"}),
form, [4]),
("wasmq rule 5: no bytes", _wasmq_job(request={"wasmq__program__bytes": 0}), form, [5]),
("wasmq rule 5: past 2^20 bytes", _wasmq_job(request={"wasmq__program__bytes": 2 ** 20 + 1}), form, [5]),
("wasmq rule 5: an input not whole", _wasmq_job(request={"wasmq__program__inputs__rounds": 1.5}),
form, [5]),
("wasmq rule 5: inputs an array", _wasmq_job(request={"wasmq__program__inputs": []}), form, [5]),
("wasmq rule 5: the program's digest in upper case", _wasmq_job(request={
"wasmq__program__blake3": "A1" * 32}), form, [5]),
("wasmq rule 6: a module of no bytes", _wasmq_job(request={"wasmq__modules__0__bytes": 0}), form, [6]),
("wasmq: a module of one byte", _wasmq_job(request={"wasmq__modules__1__bytes": 1}), [], []),
("wasmq rule 6: the modules past 2^19 bytes together", _wasmq_job(request={
"wasmq__modules__0__bytes": 2 ** 19}), form, [6]),
# Rule 6 bounds the modules' bytes only by their sum: one module may hold most of it.
("wasmq: the modules at 2^19 bytes together, one of them 2^19 - 2048", _wasmq_job(request={
"wasmq__modules__0__bytes": 2 ** 19 - 2048}), [], []),
("wasmq rule 6: the modules one byte past 2^19 together", _wasmq_job(request={
"wasmq__modules__0__bytes": 2 ** 19 - 2047}), form, [6]),
# Rule 6 no longer bounds a prior's bytes: rule 31 does (the envelope past 2^27), rule
# 21 counts them in the instances' fuel (W × P = 32 × (3 + 2^27 + 1), past the
# instances' 3000), and rule 33 holds a prior passed whole to per_instance (10^8).
("wasmq rules 21, 31 and 33: a prior past 2^27 bytes, no longer rule 6's", _wasmq_job(request={
"wasmq__modules__0__priors__0__bytes": 2 ** 27 + 1}), form, [21, 31, 33]),
# A prior's bytes null is no count: rule 6 fails, and rule 21 reads it as 0
# (W × P = 32 × 2, within the instances' 100).
("wasmq rule 6: a prior's bytes null, read as 0 by rule 21", _wasmq_job(
request={"wasmq__modules__0__priors__0__bytes": None},
result={"fuel__instances": 100, "fuel__used": 6600}), form, [6]),
("wasmq rule 6: a prior a member more", _wasmq_job(request={"wasmq__modules__0__priors__0__note": "x"}),
form, [6]),
("wasmq rule 6: priors an object", _wasmq_job(request={"wasmq__modules__0__priors": {}}), form, [6]),
("wasmq rule 6: a module's name a number, alike in the result", _wasmq_job(
request={"wasmq__modules__1__name": 7}, result={"modules__1__name": 7}), form, [6]),
("wasmq rule 7: a module no callout names", _wasmq_job(request={"wasmq__callouts__1__module": 0}),
form, [7]),
("wasmq rule 7: a module index past the modules", _wasmq_job(request={"wasmq__callouts__1__module": 2}),
form, [7]),
("wasmq rule 7: an extern twice", _wasmq_job(request={"wasmq__callouts__2": {
"extern": "decode64", "module": 1, "export": "decode"}}), form, [7]),
("wasmq rule 7: a module index not whole", _wasmq_job(request={"wasmq__callouts__1__module": 1.5}),
form, [7]),
("wasmq rule 7: an export not a string", _wasmq_job(request={"wasmq__callouts__0__export": 7}),
form, [7]),
("wasmq rule 8: another state", _wasmq_job(request={"wasmq__run__state": "batch"}), form, [8]),
("wasmq rule 8: another method, alike in the result", _wasmq_job(
request={"wasmq__run__method": "statevector"}, result={"method": "statevector"}), form, [8]),
("wasmq rule 8: a seed below 0, alike in the result", _wasmq_job(
request={"wasmq__run__seed": -1}, result={"seed": -1}), form, [8]),
("wasmq rule 8: a budget past 2^39", _wasmq_job(request={"wasmq__run__fuel__per_call": 2 ** 39 + 1},
result={"fuel__budget__per_call": 2 ** 39 + 1}),
form, [8]),
("wasmq: per_call and per_instance at 2^39", _wasmq_job(
request={"wasmq__run__fuel__per_call": 2 ** 39, "wasmq__run__fuel__per_instance": 2 ** 39},
result={"fuel__budget__per_call": 2 ** 39, "fuel__budget__per_instance": 2 ** 39}), [], []),
("wasmq rule 8: per_instance past 2^39", _wasmq_job(
request={"wasmq__run__fuel__per_instance": 2 ** 39 + 1},
result={"fuel__budget__per_instance": 2 ** 39 + 1}), form, [8]),
# Rule 8 holds per_job to be a count only (rule 30 bounds it); null is no count, and
# rule 13 then reads it as 0, below the used 9500.
("wasmq rule 8: per_job null, no count", _wasmq_job(
request={"wasmq__run__fuel__per_job": None}, result={"fuel__budget__per_job": None}),
form, [8, 13]),
("wasmq rule 9: a member more", _wasmq_job(result={"note": "x"}), form, [9]),
("wasmq rule 10: sealed in the first form", _wasmq_job(form="first"), form, [10]),
("wasmq rule 11: another profile", _wasmq_job(result={"profile": "wai.quantum.wasmq/2"}), form, [11]),
("wasmq rule 11: accuracy a member more", _wasmq_job(result={"accuracy__note": "x"}), form, [11]),
("wasmq rule 11: another energy", _wasmq_job(result={"energy__unmetered": "x"}), form, [11]),
("wasmq rule 11: another seed", _wasmq_job(result={"seed": 1235}), form, [11]),
("wasmq rule 11: another method", _wasmq_job(result={"method": "statevector"}), form, [11]),
("wasmq rule 12: past 2^15 qubits", _wasmq_job(result={"qubits": 2 ** 15 + 1}), form, [12]),
("wasmq rule 12: the transcript's digest in upper case", _wasmq_job(result={
"transcript_blake3": "F6" * 32}), form, [12]),
("wasmq rule 13: fuel a member more", _wasmq_job(result={"fuel__note": "x"}), form, [13]),
("wasmq rule 13: a budget not run's", _wasmq_job(result={"fuel__budget__per_call": 400}), form, [13]),
("wasmq rule 13: used past per_job", _wasmq_job(request={"wasmq__run__fuel__per_job": 9499},
result={"fuel__budget__per_job": 9499}), form, [13]),
("wasmq rule 14: a member no extern names", _wasmq_job(result={"fuel__callouts__plan": _DELETE,
"fuel__callouts__plan2": plan_fuel}),
form, [14]),
# A max past its member's fuel is past what rule 20 lets the calls that returned hold:
# max 120 is more than e = 0, so T = 100 must be at least 120 + 2 - 1.
("wasmq rule 14: max past its fuel", _wasmq_job(result={"fuel__callouts__plan__max": 120}),
form, [14, 20]),
# Rule 14 holds a member's fuel to be a count only: rule 20 bounds it by calls × max.
("wasmq rule 20: fuel past calls × max, no longer rule 14's", _wasmq_job(result={
"fuel__callouts__decode64__max": 199}), form, [20]),
("wasmq rule 14: max past per_call", _wasmq_job(request={"wasmq__run__fuel__per_call": 150},
result={"fuel__budget__per_call": 150}), form, [14]),
("wasmq rule 14: no calls", _wasmq_job(result={"fuel__callouts__plan": {"calls": 0, "fuel": 0, "max": 0},
"fuel__used": 9400, "callouts": 32}), form, [14]),
("wasmq rule 15: used not the sum", _wasmq_job(result={"fuel__used": 9501}), form, [15]),
("wasmq rule 15: callouts not the calls", _wasmq_job(result={"callouts": 35}), form, [15]),
("wasmq rule 16: a module named otherwise", _wasmq_job(result={"modules__1__name": "other"}), form, [16]),
("wasmq rule 16: a module missing", _wasmq_job(result={"modules__1": _DELETE}), form, [16]),
("wasmq rule 16: a module a member more", _wasmq_job(result={"modules__0__bytes": 39442}), form, [16]),
("wasmq rule 16: another digest", _wasmq_job(result={"modules__0__blake3": "d4" * 32}), form, [16]),
("wasmq: instances at most M × S × per_instance (32 × 5 × 19)", _wasmq_job(
request={"wasmq__run__fuel__per_instance": 19}, result={"fuel__budget__per_instance": 19}), [], []),
("wasmq rule 17: instances past M × S × per_instance (32 × 5 × 18)", _wasmq_job(
request={"wasmq__run__fuel__per_instance": 18}, result={"fuel__budget__per_instance": 18}),
form, [17]),
("wasmq rule 17: state shot, past (2 + 1) × S × per_instance", _wasmq_job(fault=True, request={
"wasmq__run__state": "shot", "wasmq__run__fuel__per_instance": 26},
result={"fuel__budget__per_instance": 26}), form, [17]),
("wasmq rule 17: state job, past 1 × S × per_instance", _wasmq_job(fault=True, request={
"wasmq__run__fuel__per_instance": 79}, result={"fuel__budget__per_instance": 79}), form, [17]),
("wasmq rule 18: ok, a shot not run", _wasmq_job(result={"shots_run": 31, "counts__0101": 29}), form, [18]),
("wasmq rule 18: ok, with a fault", _wasmq_job(result={"fault": {
"reason": "unreachable", "shot": 32, "phase": "seed", "module": "decoder", "fuel": 1}}), form, [18]),
# With status ok there is no fault for rules 20 to 31: had this one been taken, rule
# 27 would fail (a lifecycle fault at shot 0 beside 34 callouts).
("wasmq rule 18: ok, with a lifecycle fault at shot 0, no fault of rules 20 to 31", _wasmq_job(result={
"fault": {"reason": "unreachable", "shot": 0, "phase": "seed", "module": "decoder", "fuel": 1}}),
form, [18]),
("wasmq rule 18: ok, with a fault of null", _wasmq_job(result={"fault": None}), form, [18]),
("wasmq rule 18: another status", _wasmq_job(result={"status": "done"}), form, [18]),
# Status done, beside a fault: no fault for rules 20 to 35. Taken, rule 28 (budget run,
# used 802 not per_job) would fail. Rule 20 holds either way: with s = 0, T = 402 is
# max 400 and 1 for each other call; with s = 1, T = 2 = k.
("wasmq rule 18: status done beside a fault, no fault of rules 20 to 35", _wasmq_job(fault=True, result={
"status": "done", "fault__budget": "run", "fuel__callouts__decode64__fuel": 402, "fuel__used": 802}),
form, [18]),
("wasmq rule 18: fault, and no fault", _wasmq_job(fault=True, result={"fault": _DELETE}), form, [18]),
("wasmq rule 18: fault, with a fault of null", _wasmq_job(fault=True, result={"fault": None}), form, [18]),
("wasmq rule 18: a reason §6.2 does not name", _wasmq_job(fault=True, result={"fault__reason": "timeout"}),
form, [18]),
("wasmq rule 18: every shot run", _wasmq_job(fault=True, result={
"shots_run": 8, "counts__0101": 7, "fault__shot": 8}), form, [18]),
("wasmq rule 18: the fault's shot not shots_run", _wasmq_job(fault=True, result={"fault__shot": 1}),
form, [18]),
# A phase of another value is a lifecycle fault's (rules 20 to 35): in state job at
# shot 2, rule 26 fails too. Its instances hold its fuel and W × P (400 + 1 × 10, rule
# 25; no 1 more, its phase is not seed or init).
("wasmq rule 18: another phase", _wasmq_job(fault=True, result={
"fault__phase": "run", "fuel__instances": 410, "fuel__used": 1410}), form, [18, 26]),
# A call's fault's module is its callout's (rule 22): one no module has is not it.
("wasmq rule 18: a module not the contract's", _wasmq_job(fault=True, result={"fault__module": "other"}),
form, [18, 22]),
# A call's fuel past per_call (400) is past its callout's max (400, rule 14), which
# rule 18 holds it to; of the call's budget, it is not per_call itself (rule 28).
("wasmq rule 18: fuel past per_call in a call", _wasmq_job(fault=True, result={"fault__fuel": 401}),
form, [18, 28]),
# Rule 18 holds a call's fuel to per_call only through its callout's max, and the max
# to per_call is rule 14's: a trap of 400 under per_call 399, beside a max of 400.
("wasmq rule 14: a call's trap past per_call, held by its max", _wasmq_job(
fault=True, request={"wasmq__run__fuel__per_call": 399}, result={
"fuel__budget__per_call": 399, "fault__reason": "unreachable", "fault__budget": _DELETE}),
form, [14]),
# Rule 18 no longer holds a fault's fuel within F's used: rule 25 holds a lifecycle
# fault's within the instances' (and rule 20 a call's within its member's).
("wasmq rule 25: a lifecycle fault's fuel past F's used, no longer rule 18's", _wasmq_job(
fault=True, request=shot_state, result=dict(init_trap, fault__fuel=1401)), form, [25]),
# Outside a call, rule 18 holds a fault's fuel to per_instance.
("wasmq: a trap in seed at per_instance", _wasmq_job(fault=True, request=dict(
shot_state, wasmq__run__fuel__per_instance=100), result=dict(
seed_trap, fault__fuel=100, fuel__budget__per_instance=100)), [], []),
("wasmq rule 18: a trap in seed past per_instance", _wasmq_job(fault=True, request=dict(
shot_state, wasmq__run__fuel__per_instance=100), result=dict(
seed_trap, fault__fuel=101, fuel__budget__per_instance=100)), form, [18]),
# With no callout, or one no callout of C has, there is no callout for rule 22.
("wasmq rule 18: a call without its callout", _wasmq_job(fault=True, result={"fault__callout": _DELETE}),
form, [18, 22]),
("wasmq rule 18: a callout no extern names", _wasmq_job(fault=True, result={"fault__callout": "plan2"}),
form, [18, 22]),
("wasmq rule 18: a callout outside a call", _wasmq_job(fault=True, request=shot_state, result=dict(
init_trap, fault__callout="decode64")), form, [18]),
("wasmq rule 18: fuel_exhausted without its budget", _wasmq_job(fault=True, result={
"fault__budget": _DELETE}), form, [18]),
# Rule 28 says what a whole limit is for the budgets call, instance and run alone.
("wasmq rule 18: fuel_exhausted, its budget null", _wasmq_job(fault=True, result={"fault__budget": None}),
form, [18]),
("wasmq rule 18: a budget on a trap", _wasmq_job(fault=True, result={"fault__reason": "unreachable"}),
form, [18]),
# Budget instance: the fault's fuel is not per_instance (rule 28).
("wasmq rule 18: an instance's budget in a call", _wasmq_job(fault=True, result={
"fault__budget": "instance"}), form, [18, 28]),
("wasmq rule 18: the fault a member more", _wasmq_job(fault=True, result={"fault__note": "x"}), form, [18]),
# The call that stopped is one of the calls made: its extern names a member of F's
# callouts whose max is at least the fault's fuel.
("wasmq rule 18: a call's callout an extern with no member in F's callouts", _wasmq_job(
fault=True, result={"fault__callout": "plan", "fault__module": "planner"}), form, [18]),
("wasmq rule 18: a call's fuel past its callout's max", _wasmq_job(fault=True, result={
"fuel__callouts__decode64__max": 399}), form, [18]),
# A member that is null is present (§6.5).
("wasmq rule 18: a call's callout null, present and no extern", _wasmq_job(fault=True, result={
"fault__callout": None}), form, [18, 22]),
("wasmq rule 18: a callout of null outside a call, present", _wasmq_job(
fault=True, request=shot_state, result=dict(init_trap, fault__callout=None)), form, [18]),
("wasmq rule 18: a budget of null on a trap, present", _wasmq_job(fault=True, result={
"fault__reason": "unreachable", "fault__budget": None}), form, [18]),
("wasmq rule 19: outcomes of two lengths", _wasmq_job(result={"counts": {"0101": 30, "110": 2}}),
form, [19]),
("wasmq rule 19: an outcome not of 0 and 1", _wasmq_job(result={"counts": {"0101": 30, "1102": 2}}),
form, [19]),
("wasmq rule 19: a count of 0", _wasmq_job(result={"counts": {"0101": 32, "1100": 0}}), form, [19]),
("wasmq rule 19: counts not shots_run", _wasmq_job(result={"counts__0101": 29}), form, [19]),
("wasmq rule 19: counts an array", _wasmq_job(result={"counts": []}), form, [19]),
# Rule 20: the fuel of the calls that returned, each at least 1 and at most max.
("wasmq: plan's calls at 1 fuel each", _wasmq_job(result={
"fuel__callouts__plan": {"calls": 2, "fuel": 2, "max": 1}, "fuel__used": 9402}), [], []),
("wasmq rule 20: plan's two calls of 1 fuel together", _wasmq_job(result={
"fuel__callouts__plan": {"calls": 2, "fuel": 1, "max": 1}, "fuel__used": 9401}), form, [20]),
("wasmq: beside the stopped call, the calls that returned at 1 fuel each", _wasmq_job(fault=True, result={
"fuel__callouts__decode64__fuel": 402, "fuel__used": 802}), [], []),
("wasmq rule 20: beside the stopped call, two calls that returned of 1 fuel together", _wasmq_job(
fault=True, result={"fuel__callouts__decode64__fuel": 401, "fuel__used": 801}), form, [20]),
("wasmq: beside a trap, the calls that returned at max each", _wasmq_job(fault=True, result=dict(
call_trap, fuel__callouts__decode64__fuel=950, fuel__used=1350)), [], []),
("wasmq rule 20: beside a trap, the calls that returned past max each", _wasmq_job(fault=True, result=dict(
call_trap, fuel__callouts__decode64__fuel=951, fuel__used=1351)), form, [20]),
# The fault's fuel that is no count is read as 0: then 1000 is the returned calls'
# fuel, past 2 × 400; with 800, within it.
("wasmq rule 20: the fault's fuel null, read as 0", _wasmq_job(fault=True, result=dict(
call_trap, fault__fuel=None)), form, [18, 20]),
("wasmq rule 18: the fault's fuel null, rule 20 reading it as 0", _wasmq_job(fault=True, result=dict(
call_trap, fault__fuel=None, fuel__callouts__decode64__fuel=800, fuel__used=1200)), form, [18]),
# Rule 21: the instances' fuel at least W × P + E (P = 3 + 7 = 10 but for a fault in
# seed or init; E = 0 but for a lifecycle fault).
("wasmq: instances at W × P, state shot (W = 32)", _wasmq_job(result={
"fuel__instances": 320, "fuel__used": 6820}), [], []),
("wasmq rule 21: instances below W × P, state shot (W = 32)", _wasmq_job(result={
"fuel__instances": 319, "fuel__used": 6819}), form, [21]),
("wasmq: instances at W × P, a call's fault in state shot (W = 2 + 1)", _wasmq_job(
fault=True, request=shot_state, result={"fuel__instances": 30, "fuel__used": 1030}), [], []),
("wasmq rule 21: instances below W × P, a call's fault in state shot (W = 2 + 1)", _wasmq_job(
fault=True, request=shot_state, result={"fuel__instances": 29, "fuel__used": 1029}), form, [21]),
("wasmq: instances at W × P, state job (W = 1)", _wasmq_job(fault=True, result={
"fuel__instances": 10, "fuel__used": 1010}), [], []),
("wasmq rule 21: instances below W × P, state job (W = 1)", _wasmq_job(fault=True, result={
"fuel__instances": 9, "fuel__used": 1009}), form, [21]),
# A lifecycle fault, state shot (W = 2): rule 25 holds its fuel beside W × P + E, so
# its least is rule 25's, and rule 21 fails only below W × P + E itself.
# A trap of 1 in the decoder's seed: P = 10 + 1 (its module exports wasmq-seed), E = 0.
("wasmq: a trap in seed, the instances at its fuel and W × P (1 + 2 × 11)", _wasmq_job(
fault=True, request=shot_state, result=dict(
seed_trap, fault__fuel=1, fuel__instances=23, fuel__used=1023)), [], []),
("wasmq rule 25: a trap in seed, the instances one below its fuel and W × P", _wasmq_job(
fault=True, request=shot_state, result=dict(
seed_trap, fault__fuel=1, fuel__instances=22, fuel__used=1022)), form, [25]),
# In the planner's init: E holds the decoder's prior, passed before it (3 + 7).
("wasmq: a trap in the planner's init, the instances at its fuel, W × P and E (1 + 22 + 10)",
_wasmq_job(fault=True, request=shot_state, result=dict(
init_trap, fault__module="planner", fault__fuel=1, fuel__instances=33, fuel__used=1033)), [], []),
("wasmq rule 25: a trap in the planner's init, the instances one below", _wasmq_job(
fault=True, request=shot_state, result=dict(
init_trap, fault__module="planner", fault__fuel=1, fuel__instances=32, fuel__used=1032)),
form, [25]),
("wasmq rules 21 and 25: a trap in the planner's init, the instances below W × P + E", _wasmq_job(
fault=True, request=shot_state, result=dict(
init_trap, fault__module="planner", fault__fuel=1, fuel__instances=31, fuel__used=1031)),
form, [21, 25]),
# In the decoder's init: E holds its own prior, passed before its init.
("wasmq: a trap in the decoder's init, its own prior in E (1 + 22 + 10)", _wasmq_job(
fault=True, request=shot_state, result=dict(
init_trap, fault__fuel=1, fuel__instances=33, fuel__used=1033)), [], []),
("wasmq rule 25: a trap in the decoder's init, its own prior in E, one below", _wasmq_job(
fault=True, request=shot_state, result=dict(
init_trap, fault__fuel=1, fuel__instances=32, fuel__used=1032)), form, [25]),
# In the decoder's prior: no 1 more (P = 10), and E = 0: a bad_result of 2.
("wasmq: a fault in the decoder's prior, the instances at its fuel and W × P (2 + 2 × 10)", _wasmq_job(
fault=True, request=shot_state, result=dict(
prior_fault, fault__fuel=2, fuel__instances=22, fuel__used=1022)), [], []),
("wasmq rule 25: a fault in the decoder's prior, the instances one below", _wasmq_job(
fault=True, request=shot_state, result=dict(
prior_fault, fault__fuel=2, fuel__instances=21, fuel__used=1021)), form, [25]),
# Rule 22: a call runs in its callout's module.
("wasmq rule 22: a call's fault in another module than its callout's", _wasmq_job(fault=True, result={
"fault__module": "planner"}), form, [22]),
("wasmq: a call's fault in plan, of the module of index 1", _wasmq_job(fault=True, result=plan_fault),
[], []),
("wasmq rule 22: a call's fault in plan, named in the module of index 0", _wasmq_job(fault=True, result=dict(
plan_fault, fault__module="decoder")), form, [22]),
("wasmq rule 22: its callout's module past the modules", _wasmq_job(fault=True, request={
"wasmq__callouts__0__module": 2}), form, [7, 22]),
("wasmq rule 22: its extern on two callouts, of two modules", _wasmq_job(fault=True, request={
"wasmq__callouts__2": {"extern": "decode64", "module": 1, "export": "decode"}}), form, [7, 22]),
# Rule 23: a prior is passed only to a module that has one.
("wasmq: a fault in the decoder's prior", _wasmq_job(fault=True, request=shot_state, result=prior_fault),
[], []),
("wasmq rule 23: a fault in a prior of the planner, which has none", _wasmq_job(
fault=True, request=shot_state, result=dict(prior_fault, fault__module="planner")), form, [23]),
("wasmq rule 23: a fault in a prior, priors an object read as none", _wasmq_job(
fault=True, request=dict(shot_state, wasmq__modules__0__priors={}), result=prior_fault),
form, [6, 23]),
# Rule 24: only a call or a prior passes bytes or takes a result.
("wasmq: bad_result in a call", _wasmq_job(fault=True, result={
"fault__reason": "bad_result", "fault__budget": _DELETE}), [], []),
("wasmq rule 24: bad_result in init", _wasmq_job(fault=True, request=shot_state, result=dict(
init_trap, fault__reason="bad_result")), form, [24]),
("wasmq rule 24: bad_result in seed", _wasmq_job(fault=True, request=shot_state, result=dict(
seed_trap, fault__reason="bad_result")), form, [24]),
# Rule 25: a lifecycle fault's fuel, beside W × P + E (2 × 11 for a trap in seed, state
# shot), within the instances' 400.
("wasmq: a trap in seed of 378, at the instances' 400 with W × P", _wasmq_job(
fault=True, request=shot_state, result=dict(seed_trap, fault__fuel=378)), [], []),
("wasmq rule 25: a trap in seed of 379, past the instances' 400 with W × P", _wasmq_job(
fault=True, request=shot_state, result=dict(seed_trap, fault__fuel=379)), form, [25]),
# Rules 26 and 27: the first shot's instances, made before its first step.
("wasmq: a trap in seed at the first shot, state job (W = 0)", _wasmq_job(fault=True, result=first_shot),
[], []),
("wasmq: a trap in seed at a first shot written -0", _wasmq_job(fault=True, result=dict(
first_shot, fault__shot=Num("-0", -0.0))), [], []),
("wasmq: a trap in seed at the first shot, state shot", _wasmq_job(
fault=True, request=shot_state, result=first_shot), [], []),
("wasmq rule 26: a trap in seed at shot 1, state job", _wasmq_job(fault=True, result=dict(
seed_trap, shots_run=1, counts={"0101": 1}, fault__shot=1)), form, [26]),
("wasmq: a trap in seed at shot 1, state shot", _wasmq_job(fault=True, request=shot_state, result=dict(
seed_trap, shots_run=1, counts={"0101": 1}, fault__shot=1)), [], []),
("wasmq rule 26: a trap in seed at shot 2, state job", _wasmq_job(fault=True, result=seed_trap),
form, [26]),
("wasmq rule 26: a trap in seed, its shot null", _wasmq_job(fault=True, result=dict(
first_shot, fault__shot=None)), form, [18, 26]),
# A phase of null is present, a value other than call: a lifecycle fault's (rule 26
# fails at shot 2 of state job; its instances hold 400 + 1 × 10, rule 25). One that is
# absent is no lifecycle fault's.
("wasmq rule 26: a fault's phase null, a lifecycle fault's", _wasmq_job(fault=True, result={
"fault__phase": None, "fuel__instances": 410, "fuel__used": 1410}), form, [18, 26]),
("wasmq rule 18: a fault's phase absent, no lifecycle fault's", _wasmq_job(fault=True, result={
"fault__phase": _DELETE}), form, [18]),
# Rule 27 is no longer broken alone: at a lifecycle fault of shot 0, rule 18 makes
# shots_run 0, so no shot ran steps (H = 0) and rule 32 holds the callouts to 0 too.
("wasmq rule 27: a trap in seed at the first shot, beside a call", _wasmq_job(fault=True, result=dict(
first_shot, **a_call_at_first)), form, [27, 32]),
("wasmq rule 27: a trap in seed at the first shot, beside a call, state shot", _wasmq_job(
fault=True, request=shot_state, result=dict(first_shot, **a_call_at_first)), form, [27, 32]),
# Rule 28: a fault of fuel used its whole limit.
("wasmq rule 28: the call's budget, one short of per_call", _wasmq_job(fault=True, result={
"fault__fuel": 399}), form, [28]),
("wasmq rule 28: the instance's budget, one short of per_instance", _wasmq_job(fault=True, request=dict(
shot_state, wasmq__run__fuel__per_instance=101), result=dict(
init_exhausted, fuel__budget__per_instance=101)), form, [28]),
("wasmq rule 28: the run's budget, per_job not used up", _wasmq_job(fault=True, request={
"wasmq__run__fuel__per_job": 1151}, result=dict(run_budget, fuel__budget__per_job=1151)),
form, [28]),
("wasmq: the run's budget in a call, one below per_call", _wasmq_job(fault=True, request={
"wasmq__run__fuel__per_job": 1399}, result=dict(
run_budget, fuel__budget__per_job=1399, fuel__used=1399, fuel__callouts__decode64__fuel=999,
fault__fuel=399)), [], []),
("wasmq rule 28: the run's budget in a call, at per_call", _wasmq_job(fault=True, request={
"wasmq__run__fuel__per_job": 1400}, result=dict(
run_budget, fuel__budget__per_job=1400, fuel__used=1400, fuel__callouts__decode64__fuel=1000,
fault__fuel=400)), form, [28]),
("wasmq: the run's budget in init", _wasmq_job(fault=True, request=dict(
shot_state, wasmq__run__fuel__per_job=1400), result={
"fuel__budget__per_job": 1400, "fault__phase": "init", "fault__callout": _DELETE,
"fault__budget": "run", "fault__fuel": 50}), [], []),
("wasmq rule 28: the run's budget in init, at per_instance", _wasmq_job(fault=True, request=dict(
shot_state, wasmq__run__fuel__per_job=1400, wasmq__run__fuel__per_instance=50), result={
"fuel__budget__per_job": 1400, "fuel__budget__per_instance": 50, "fault__phase": "init",
"fault__callout": _DELETE, "fault__budget": "run", "fault__fuel": 50}), form, [28]),
# The run's budget: "F's used is a count equal to the budget per_job (a count)": a
# per_job of null is no count, so rule 28 fails though used is 0 (rule 13 reads the
# null as 0, and holds).
("wasmq rule 28: the run's budget, per_job null, nothing used", _wasmq_job(
fault=True, request={"wasmq__run__fuel__per_job": None}, result=dict(
first_shot, fuel__budget__per_job=None, fuel__used=0, fuel__instances=0,
fault__reason="fuel_exhausted", fault__fuel=0, fault__budget="run")), form, [8, 28]),
# The run's budget, its own limit no count: per_call (or per_instance) read as 0, so
# the fault's fuel is not less than it (rule 28), beside rule 8 and the rules that
# read that budget (14: max at most per_call; 17 and 18: at most per_instance).
("wasmq rule 28: the run's budget in a call, per_call null", _wasmq_job(fault=True, request={
"wasmq__run__fuel__per_job": 1150, "wasmq__run__fuel__per_call": None}, result=dict(
run_budget, fuel__budget__per_call=None)), form, [8, 14, 28]),
("wasmq rule 28: the run's budget in a call, per_call null in the contract alone", _wasmq_job(
fault=True, request={"wasmq__run__fuel__per_job": 1150, "wasmq__run__fuel__per_call": None},
result=run_budget), form, [8, 13, 14, 28]),
("wasmq rule 28: the run's budget in a call, per_call 400.5", _wasmq_job(fault=True, request={
"wasmq__run__fuel__per_job": 1150, "wasmq__run__fuel__per_call": 400.5}, result=dict(
run_budget, fuel__budget__per_call=400.5)), form, [8, 14, 28]),
("wasmq rule 28: the run's budget in init, per_instance null", _wasmq_job(fault=True, request=dict(
shot_state, wasmq__run__fuel__per_job=1400, wasmq__run__fuel__per_instance=None), result={
"fuel__budget__per_job": 1400, "fuel__budget__per_instance": None, "fault__phase": "init",
"fault__callout": _DELETE, "fault__budget": "run", "fault__fuel": 50}),
form, [8, 17, 18, 28, 33]),
# "A fault with no phase has no limit here, and breaks rule 18": its fuel 150 at
# per_instance 150 is not held by rule 28.
("wasmq rule 18: the run's budget, its phase absent, no limit of rule 28's", _wasmq_job(
fault=True, request={"wasmq__run__fuel__per_job": 1150, "wasmq__run__fuel__per_instance": 150},
result=dict(run_budget, fuel__budget__per_instance=150, fault__phase=_DELETE)), form, [18]),
# Rule 29: a program's bits, and shots times them.
("wasmq: an outcome of 2^20 bits", _wasmq_job(result={"counts": {"0" * 2 ** 20: 32}}), [], []),
("wasmq rule 29: an outcome of 2^20 + 1 bits", _wasmq_job(result={"counts": {"0" * (2 ** 20 + 1): 32}}),
form, [29]),
("wasmq: 2^20 shots of 2^8 bits, 2^28", _wasmq_job(request=many_shots, result=dict(
many_made, counts={"0" * 2 ** 8: 2 ** 20})), [], []),
("wasmq rule 29: 2^20 shots of 2^8 + 1 bits, past 2^28", _wasmq_job(request=many_shots, result=dict(
many_made, counts={"0" * (2 ** 8 + 1): 2 ** 20})), form, [29]),
# Rule 30: the work a receipt shows.
# At 2^42 + 2 only with the calls' 4097 × 34: without them it would be 2^42 - 139 296.
("wasmq: the work at 2^42 - 6", _wasmq_job(request={"wasmq__run__fuel__per_job": work_at},
result={"fuel__budget__per_job": work_at}), [], []),
("wasmq rule 30: the work at 2^42 + 2", _wasmq_job(request={"wasmq__run__fuel__per_job": work_at + 1},
result={"fuel__budget__per_job": work_at + 1}),
form, [30]),
("wasmq rule 30: per_job at 2^39", _wasmq_job(
request={"wasmq__run__fuel__per_job": 2 ** 39}, result={"fuel__budget__per_job": 2 ** 39}),
form, [30]),
# Rule 8 no longer bounds per_job: past 2^39 it breaks rule 30 alone.
("wasmq rule 30: per_job past 2^39, no longer rule 8's", _wasmq_job(
request={"wasmq__run__fuel__per_job": 2 ** 39 + 1}, result={"fuel__budget__per_job": 2 ** 39 + 1}),
form, [30]),
("wasmq: the work at 2^42 - 6, 33 qubits (w = 2)", _wasmq_job(
request={"wasmq__run__fuel__per_job": work_at_33},
result={"qubits": 33, "fuel__budget__per_job": work_at_33}), [], []),
("wasmq rule 30: the work at 2^42 + 2, 33 qubits (w = 2)", _wasmq_job(
request={"wasmq__run__fuel__per_job": work_at_33 + 1},
result={"qubits": 33, "fuel__budget__per_job": work_at_33 + 1}), form, [30]),
("wasmq: the work at 2^42 - 4, state job (I = 1)", _wasmq_job(
request=dict(job_state, wasmq__run__fuel__per_job=work_job),
result={"fuel__budget__per_job": work_job}), [], []),
("wasmq rule 30: the work at 2^42 + 4, state job (I = 1)", _wasmq_job(
request=dict(job_state, wasmq__run__fuel__per_job=work_job + 1),
result={"fuel__budget__per_job": work_job + 1}), form, [30]),
# Rule 31: the envelope the contract names, at most 2^27 bytes. One more byte past it:
# a prior's, a digit of the manifest's qubits (17 to 170), or one of the contract's
# own (a module's name, the same in the result).
("wasmq: the envelope at 2^27 bytes", _wasmq_job(request=dict(
big_prior_asked, wasmq__modules__0__priors__0__bytes=envelope_prior), result=big_prior), [], []),
("wasmq rule 31: the envelope at 2^27 + 1 bytes, a prior's", _wasmq_job(request=dict(
big_prior_asked, wasmq__modules__0__priors__0__bytes=envelope_prior + 1), result=big_prior),
form, [31]),
("wasmq rule 31: the envelope at 2^27 + 1 bytes, a digit of qubits", _wasmq_job(request=dict(
big_prior_asked, wasmq__modules__0__priors__0__bytes=envelope_prior), result=dict(
big_prior, qubits=170)), form, [31]),
("wasmq rule 31: the envelope at 2^27 + 1 bytes, a byte of the contract", _wasmq_job(request=dict(
big_prior_asked, wasmq__modules__0__priors__0__bytes=envelope_prior,
wasmq__modules__1__name="planners"), result=dict(big_prior, modules__1__name="planners")),
form, [31]),
# Rule 20: when max is more than e, the most was a returned call's, and each other
# returned call used 1 at least: T at least max + k - 1.
("wasmq: plan's fuel at its max and 1 for its other call (60 + 1)", _wasmq_job(result={
"fuel__callouts__plan__fuel": 61, "fuel__used": 9461}), [], []),
("wasmq rule 20: plan's fuel below its max and 1 for its other call", _wasmq_job(result={
"fuel__callouts__plan__fuel": 60, "fuel__used": 9460}), form, [20]),
("wasmq: beside a trap of 150, the calls that returned at max and 1 (400 + 1)", _wasmq_job(
fault=True, result=dict(call_trap, fuel__callouts__decode64__fuel=551, fuel__used=951)), [], []),
# e is the stopped call's fuel for its own member alone: plan's two calls beside
# decode64's call fault are held as their own (s = 0, e = 0: T = 100, at least 60 + 1).
("wasmq: a call's fault in decode64 beside plan's calls, held as their own", _wasmq_job(
fault=True, result={"callouts": 5, "fuel__used": 1500,
"fuel__callouts__plan": {"calls": 2, "fuel": 100, "max": 60}}), [], []),
("wasmq rule 20: beside a trap of 150, the calls that returned below max and 1", _wasmq_job(
fault=True, result=dict(call_trap, fuel__callouts__decode64__fuel=550, fuel__used=950)),
form, [20]),
# Rule 32: the callouts at most 2^21 for each shot that ran steps: H = 2 shots run and
# the one a call's fault stopped. decode64's calls that returned used 1 each beside the
# stopped call's 400 (its max, so rule 20's last bound does not apply).
("wasmq: callouts at 2^21 × 3", _wasmq_job(fault=True, result={
"callouts": 3 * 2 ** 21, "fuel__used": 800 + 3 * 2 ** 21 - 1, "fuel__callouts__decode64": {
"calls": 3 * 2 ** 21, "fuel": 400 + 3 * 2 ** 21 - 1, "max": 400}}), [], []),
("wasmq rule 32: callouts at 2^21 × 3 + 1", _wasmq_job(fault=True, result={
"callouts": 3 * 2 ** 21 + 1, "fuel__used": 800 + 3 * 2 ** 21, "fuel__callouts__decode64": {
"calls": 3 * 2 ** 21 + 1, "fuel": 400 + 3 * 2 ** 21, "max": 400}}), form, [32]),
# Rule 33: a prior passed whole fits one lifecycle call's limit, 3 and its 7 bytes. The
# ok run's instances 1000 keep rule 17 (32 × 5 × 9 = 1440).
("wasmq: a prior at per_instance (3 + 7 = 10)", _wasmq_job(
request={"wasmq__run__fuel__per_instance": 10},
result={"fuel__budget__per_instance": 10, "fuel__instances": 1000, "fuel__used": 7500}), [], []),
("wasmq rule 33: a prior past per_instance (3 + 7, per_instance 9)", _wasmq_job(
request={"wasmq__run__fuel__per_instance": 9},
result={"fuel__budget__per_instance": 9, "fuel__instances": 1000, "fuel__used": 7500}), form, [33]),
# With no set of instances made whole (W = 0), only the priors E counts: a trap in the
# planner's init at the first shot passed the decoder's prior whole (E = 10).
("wasmq: a trap in the planner's init at the first shot, the decoder's prior at per_instance", _wasmq_job(
fault=True, request={"wasmq__run__fuel__per_instance": 10}, result=dict(
first_shot, fault__phase="init", fault__module="planner", fault__fuel=1, fuel__instances=11,
fuel__used=11, fuel__budget__per_instance=10)), [], []),
("wasmq rule 33: a trap in the planner's init at the first shot, the decoder's prior past per_instance",
_wasmq_job(fault=True, request={"wasmq__run__fuel__per_instance": 9}, result=dict(
first_shot, fault__phase="init", fault__module="planner", fault__fuel=1, fuel__instances=11,
fuel__used=11, fuel__budget__per_instance=9)), form, [33]),
# A trap in the decoder's seed at the first shot passed no prior: E counts none.
("wasmq: a trap in the decoder's seed at the first shot, per_instance below a prior none passed",
_wasmq_job(fault=True, request={"wasmq__run__fuel__per_instance": 9}, result=dict(
first_shot, fault__fuel=5, fuel__instances=5, fuel__used=5, fuel__budget__per_instance=9)), [], []),
# Rule 34: a fault's fuel at least what its reason shows was charged. A call's trap,
# its calls that returned at 600 (rule 20: from 401 to 800 beside a max of 400).
("wasmq: a call's trap of 1", _wasmq_job(fault=True, result=dict(
call_trap, fault__fuel=1, fuel__callouts__decode64__fuel=601, fuel__used=1001)), [], []),
("wasmq rule 34: a call's trap of 0", _wasmq_job(fault=True, result=dict(
call_trap, fault__fuel=0, fuel__callouts__decode64__fuel=600, fuel__used=1000)), form, [34]),
("wasmq: a call's bad_result of 2", _wasmq_job(fault=True, result=dict(
call_trap, fault__reason="bad_result", fault__fuel=2, fuel__callouts__decode64__fuel=602,
fuel__used=1002)), [], []),
("wasmq rule 34: a call's bad_result of 1", _wasmq_job(fault=True, result=dict(
call_trap, fault__reason="bad_result", fault__fuel=1, fuel__callouts__decode64__fuel=601,
fuel__used=1001)), form, [34]),
# stack_exhausted in seed, state shot: its fuel and W × P (2 × 11) within the instances.
("wasmq: stack_exhausted of 788 in seed", _wasmq_job(fault=True, request=shot_state, result=dict(
seed_trap, fault__reason="stack_exhausted", fault__fuel=788, fuel__instances=810,
fuel__used=1810)), [], []),
("wasmq rule 34: stack_exhausted of 787 in seed", _wasmq_job(fault=True, request=shot_state, result=dict(
seed_trap, fault__reason="stack_exhausted", fault__fuel=787, fuel__instances=810,
fuel__used=1810)), form, [34]),
# A reason §6.2 does not name, or null (present), shows 1; a fault with no reason shows
# nothing (rule 18 fails for each).
("wasmq rule 34: a call's trap of 0, its reason timeout", _wasmq_job(fault=True, result=dict(
call_trap, fault__reason="timeout", fault__fuel=0, fuel__callouts__decode64__fuel=600,
fuel__used=1000)), form, [18, 34]),
("wasmq rule 34: a call's trap of 0, its reason null", _wasmq_job(fault=True, result=dict(
call_trap, fault__reason=None, fault__fuel=0, fuel__callouts__decode64__fuel=600,
fuel__used=1000)), form, [18, 34]),
("wasmq rule 18: a call's trap of 0, no reason, held to no least", _wasmq_job(fault=True, result=dict(
call_trap, fault__reason=_DELETE, fault__fuel=0, fuel__callouts__decode64__fuel=600,
fuel__used=1000)), form, [18]),
# Rule 35: when no call returned, the transcript is the one §6.4 gives the run.
("wasmq: a run of no call, its transcript the one of no call", _wasmq_job(result=dict(
no_call, transcript_blake3=_WASMQ_TRANSCRIPT)), [], []),
("wasmq rule 35: a run of no call, another transcript", _wasmq_job(result=no_call), form, [35]),
("wasmq: a run of no call written 0e0, its transcript the one of no call", _wasmq_job(result=dict(
no_call, callouts=Num("0e0", 0.0), transcript_blake3=_WASMQ_TRANSCRIPT)), [], []),
("wasmq rules 12 and 35: a run of no call, its transcript in upper case", _wasmq_job(result=dict(
no_call, transcript_blake3=_wasmq_transcript({"status": "ok"}).upper())), form, [12, 35]),
("wasmq: a call's fault the one call made, its transcript the fault's", _wasmq_job(fault=True, result=dict(
one_call, transcript_blake3=_WASMQ_TRANSCRIPT)), [], []),
("wasmq rule 35: a call's fault the one call made, another transcript", _wasmq_job(
fault=True, result=one_call), form, [35]),
# One call made, and a lifecycle fault: that call returned, so the transcript is free.
("wasmq: a trap in seed at shot 1 beside one call that returned, its transcript free", _wasmq_job(
fault=True, request=shot_state, result=dict(
seed_trap, shots_run=1, counts={"0101": 1}, fault__shot=1, callouts=1, fuel__used=600,
fuel__callouts={"decode64": {"calls": 1, "fuel": 200, "max": 200}})), [], []),
# The fault's members in the transcript: a reason null or absent no bytes, a fuel null 0.
("wasmq rule 18: a trap at the first shot, its reason null, no bytes in the transcript", _wasmq_job(
fault=True, result=dict(first_shot, fault__reason=None)), form, [18]),
("wasmq rule 18: a trap at the first shot, no reason, no bytes in the transcript", _wasmq_job(
fault=True, result=dict(first_shot, fault__reason=_DELETE)), form, [18]),
("wasmq rules 18 and 25: a trap at the first shot, its fuel null, 0 in the transcript", _wasmq_job(
fault=True, result=dict(first_shot, fault__fuel=None)), form, [18, 25]),
# wasmq_form beside §8.4's other reasons, never instead of them.
("wasmq: inexact, beside", _wasmq_job(request={"wasmq__run__seed": Num("9007199254740993", 2.0 ** 53)},
result={"seed": Num("9007199254740993", 2.0 ** 53)}),
["inexact_number", "wasmq_form"], [1, 8]),
("wasmq: a class other methods may not have, beside", _wasmq_job(result={"accuracy__class": "simulated"}),
["provider_class", "wasmq_form"], [11]),
("wasmq: method provider, held to the provider rules too", _wasmq_job(result={"method": "provider"}),
["counts", "provider_class", "request_provider", "request_shots", "wasmq_form"], [11]),
("wasmq: receipt_form, the canon kept", _wasmq_job(receipt_extra={"alg": "ed448"}), ["receipt_form"], []),
("wasmq: receipt_form, the canon null, beside", _wasmq_job(receipt_extra={"canon": None}),
["receipt_form", "wasmq_form"], [10]),
)
# quantum-wasmq §6.5: beside a judged wasmQ job's verdict, its outcome, its problems
# (one a rule) and the notes on its unsealed body; none of it changes the verdict.
statement, said = _wasmq_statement, _WASMQ_SEALED_LINE
statements = (
("a run", _wasmq_job(), [], statement("ok")),
("a run stopped by a fault", _wasmq_job(fault=True, envelope=_WASMQ_FAULTED), [], statement("fault")),
("a job breaking one rule", _wasmq_job(result={"fuel__callouts__plan": _DELETE,
"fuel__callouts__plan2": plan_fuel}), form,
statement("ok", ["rule 14: " + WASMQ_RULE_WORDS[14]])),
("a call fault past its callout's max", _wasmq_job(
fault=True, envelope=_WASMQ_FAULTED, result={"fuel__callouts__decode64__max": 399}), form,
statement("fault", [_rule_words(18, {"status": "fault"})])),
("a job breaking two of the ties", _wasmq_job(fault=True, envelope=_WASMQ_FAULTED, result={
"fault__module": "planner", "fault__fuel": 399}), form,
statement("fault", ["rule 22: " + WASMQ_RULE_WORDS[22], "rule 28: " + WASMQ_RULE_WORDS[28]])),
("a fault's unsealed status says done: valid, one note", _wasmq_job(fault=True), [],
statement("fault", notes=['the host\'s unsealed status says "done"' + said + '"fault"'])),
("the unsealed status and method changed", _wasmq_job(envelope='"status":"failed","method":7,'), [],
statement("ok", notes=[
'the host\'s unsealed status says "failed"' + said + '"ok", and the body carries "done" for that',
'the host\'s unsealed method says 7' + said + '"stabilizer"'])),
("the unsealed status and method missing", _wasmq_job(envelope=""), [],
statement("ok", notes=["the host's unsealed status is missing", "the host's unsealed method is missing"])),
("the unsealed status null: present, so differing", _wasmq_job(envelope='"status":null,"method":"stabilizer",'),
[], statement("ok", notes=[
'the host\'s unsealed status says null' + said + '"ok", and the body carries "done" for that'])),
("members beyond the four, one null", _wasmq_job(
envelope='"why":null,"status":"done","method":"stabilizer","id":"j-7",'), [],
statement("ok", notes=['the body\'s member "id" is the host\'s word; nothing seals it',
'the body\'s member "why" is the host\'s word; nothing seals it'])),
("a sealed status no string: outcome null", _wasmq_job(result={"status": 7}), form,
statement(None, ["rule 18: the status is neither ok nor fault"],
['the host\'s unsealed status says "done"' + said + '7, and the body carries "fault" for that'])),
("a sealed status missing: outcome null", _wasmq_job(
result={"status": _DELETE}, envelope=_WASMQ_FAULTED), form,
statement(None, ["rule 9: " + WASMQ_RULE_WORDS[9], "rule 18: the status is neither ok nor fault"])),
("receipt_form: judged, so stated", _wasmq_job(receipt_extra={"alg": "ed448"}), ["receipt_form"],
statement("ok")),
("method provider: held to the provider rules, and stated", _wasmq_job(result={"method": "provider"}),
["counts", "provider_class", "request_provider", "request_shots", "wasmq_form"],
statement("ok", ["rule 11: " + WASMQ_RULE_WORDS[11]],
['the host\'s unsealed method says "stabilizer"' + said + '"provider"'])),
)
run = _wasmq_job()
asked, made = _wasmq_parts(False)
verdicts = (
("wasmq: changed after its seal, the form kept: digest_mismatch alone", _wasmq_changed_after(
run, lambda job: job["result"].update(qubits=18)), ["digest_mismatch"], False),
("wasmq: changed after its seal, the form broken: beside", _wasmq_changed_after(
run, lambda job: job["result"].update(profile="x")), ["digest_mismatch", "wasmq_form"], False),
("wasmq: no receipt, alone", _wasmq_changed_after(
run, lambda job: (job["result"].pop("receipt"), job["result"].update(profile="x"))),
["no_receipt"], False),
("wasmq: not a job, alone", _wasmq_changed_after(run, lambda job: job.update(request=[])),
["not_a_job"], False),
("wasmq: a set's item, valid", _set_body(
_WASMQ_SEED, {"programs": [asked]}, [asked], item_result=_dump(made)), [], False),
("wasmq: a set's item breaking a rule", _set_body(
_WASMQ_SEED, {"programs": [asked]}, [asked], item_result=_dump(dict(made, profile="x"))),
["set_item"], False),
# Reported alone, a job's form is not read, and it states nothing: the whole verdict
# is the reason alone.
("wasmq statement: unreadable states none", run.replace(b'{"status"', b'{"status":"x","status"'),
["unreadable"], True),
("wasmq statement: no_receipt states none", _wasmq_changed_after(
run, lambda job: job["result"].pop("receipt")), ["no_receipt"], True),
("wasmq statement: not_a_job states none", _wasmq_changed_after(
run, lambda job: job.update(request=[])), ["not_a_job"], True),
)
return cases, statements, verdicts
def wasmq_case_lines():
"""Every wasmQ case of the self-test whose whole-job verdict it writes: (name, the
exact bytes of the job's text, the reasons the self-test writes for it). It judges
nothing: the reasons are the self-test author's, from the text."""
cases, statements, verdicts = _wasmq_tables()
out = [(name, raw, sorted(want)) for name, raw, want, _ in cases]
out += [("wasmq statement: " + name, raw, sorted(want)) for name, raw, want, _ in statements]
out += [(name, raw, sorted(want)) for name, raw, want, _ in verdicts]
out.append((_WASMQ_UNCHECKED_NAME, _wasmq_unchecked_job(), list(_WASMQ_FORM)))
return out
def write_wasmq_cases(args):
"""--wasmq-cases OUT.jsonl [ES_NUMBER_FILE]: write wasmq_case_lines(), one JSON object a
line, {"name", "raw" (base64 of the job's bytes), "reasons"}. The ES_NUMBER_FILE the
self-test takes is accepted and not read: no wasmQ case uses it."""
import base64
if not 1 <= len(args) <= 2:
return _usage()
lines = wasmq_case_lines()
try:
with open(args[0], "w", encoding="ascii", newline="\n") as out:
for name, raw, want in lines:
out.write(json.dumps({"name": name, "raw": base64.b64encode(raw).decode("ascii"),
"reasons": want}) + "\n")
except (OSError, ValueError) as e:
sys.stderr.write("receipt_verify: cannot write %s (%s)\n" % (args[0], type(e).__name__))
return 1
sys.stdout.write("receipt_verify: wrote %d wasmQ cases to %s\n" % (len(lines), args[0]))
return 0
def self_test(args):
results = []
def check(name, ok):
results.append((name, bool(ok)))
def reasons_of(raw):
return judge(raw)["reasons"]
seed = bytes(range(32))
# BLAKE3
for n, want in _BLAKE3_VECTORS:
check("blake3 length %d" % n, blake3(bytes(i % 251 for i in range(n))).hex() == want)
check("blake3 abc", blake3(b"abc").hex() == _BLAKE3_ABC)
# Ed25519, RFC 8032 §7.1, then §8.2's strict rules.
for sk, pk, msg, sig in _RFC8032_VECTORS:
pub, made = _ed25519_sign(bytes.fromhex(sk), bytes.fromhex(msg))
a = key_point(bytes.fromhex(pk))
check("rfc8032 %s public" % pk[:8], pub.hex() == pk)
check("rfc8032 %s sign" % pk[:8], made.hex() == sig)
check("rfc8032 %s verify" % pk[:8], a is not None and signature_holds(
a, bytes.fromhex(pk), bytes.fromhex(msg), bytes.fromhex(sig)))
key, msg, sig = (bytes.fromhex(x) for x in _RFC8032_VECTORS[1][1:])
a = key_point(key)
s = int.from_bytes(sig[32:], "little")
check("S + l refused", not signature_holds(a, key, msg, sig[:32] + (s + _L).to_bytes(32, "little")))
check("another message refused", not signature_holds(a, key, b"\x73", sig))
for p in _SMALL_ORDER:
check("small-order key %s refused" % p[:6], key_point(bytes.fromhex(p)) is None)
check("non-canonical key refused", key_point((_P + 1).to_bytes(32, "little")) is None)
mixed = _encode_point(_add(a, _decode_point(bytes.fromhex(_SMALL_ORDER[1]))))
check("mixed-order key refused", key_point(mixed) is None)
# §8.2 reading
for raw, detail in _UNREADABLE_VECTORS:
try:
read_json(raw)
got = None
except Unreadable as e:
got = e.detail
check("unreadable %r" % raw[:16], got == detail)
for raw in _READABLE_VECTORS:
try:
read_json(raw)
check("readable %r" % raw[:16], True)
except Unreadable:
check("readable %r" % raw[:16], False)
# §8.2 texts
for text, want in _CANONICAL_VECTORS:
check("canonical %s" % text[:20], text_of(read_json(text.encode()), True) == want)
for text, want in _FIRST_FORM_VECTORS:
check("first-form numbers", text_of(read_json(text.encode()), False) == want)
if args:
lines = 0
with open(args[0], "rb") as f:
for line in f.read().decode("ascii").splitlines():
if line.strip():
hexbits, want = line.split(" ", 1)
lines += 1
if es_number(struct.unpack(">d", bytes.fromhex(hexbits))[0]) != want:
check("es number %s" % hexbits, False)
check("es number table, %d lines" % lines, lines > 0)
# Seals of both forms, made here, and what breaks them (§8.4).
req = '{"qasm":"OPENQASM 3.0;\\nqubit[1] q;\\nbit[1] c;\\nx q[0];\\nc = measure q;\\n","shots":10}'
res = ('{"method":"statevector","qubits":1,"gates":1,"accuracy":{"class":"exact"},'
'"counts":{"1":10},"expectations":[{"observable":"Z0","coeff":1.0,"value":-1.0}]}')
for form in ("rfc8785", "first"):
body = _seal(seed, req, res, form)
v = judge(body)
check("%s seals" % form, v["reasons"] == [] and v["form"] == form and v["key"] is not None)
check("%s tampered: digest_mismatch alone" % form,
reasons_of(body.replace(b'"1":10', b'"1":11')) == ["digest_mismatch"])
relabelled = (body.replace(b'"canon":"rfc8785",', b"").replace(b',"canon":"rfc8785"', b"")
if form == "rfc8785" else body.replace(b'"alg":"ed25519"', b'"alg":"ed25519","canon":"rfc8785"'))
check("%s relabelled" % form, reasons_of(relabelled) == ["digest_mismatch"])
check("%s upper-case key" % form, reasons_of(body.replace(
v["key"].encode(), v["key"].upper().encode())) == ["receipt_form"])
check("%s envelope not read" % form, reasons_of(body.replace(
b'{"request"', b'{"status":"failed","method":"other","id":7,"request"')) == [])
body = _seal(seed, req, res)
check("canon null names no form", reasons_of(body.replace(b'"canon":"rfc8785"', b'"canon":null')) == ["receipt_form"])
check("alg other", reasons_of(body.replace(b'"alg":"ed25519"', b'"alg":"ed448"')) == ["receipt_form"])
check("unknown receipt member ignored", reasons_of(body.replace(b'"alg":', b'"x":"y","alg":')) == [])
check("canonical survives re-spelling and order", reasons_of(body.replace(
b'"coeff":1.0', b'"coeff":1e0').replace(b'"qubits":1,"gates":1', b'"gates":1, "qubits":1')) == [])
first = _seal(seed, req, res, "first")
check("first form refuses member order", reasons_of(first.replace(
b'"qubits":1,"gates":1', b'"gates":1,"qubits":1')) == ["digest_mismatch"])
check("first form refuses re-spelling", reasons_of(first.replace(b'"coeff":1.0', b'"coeff":1')) == ["digest_mismatch"])
big = _seal(seed, req.replace('"shots":10', '"shots":10,"seed":9007199254740993'), res)
check("inexact_number", reasons_of(big) == ["inexact_number"])
check("first form seals a u64 by its digits", reasons_of(
_seal(seed, req.replace('"shots":10', '"shots":10,"seed":9007199254740993'), res, "first")) == [])
check("first form past u64 is sealed as a double", reasons_of(
_seal(seed, req.replace('"shots":10', '"shots":10,"seed":18446744073709551617'), res, "first"))
== ["inexact_number"])
check("first form 2^64 is a double, exactly", reasons_of(
_seal(seed, req.replace('"shots":10', '"shots":10,"seed":18446744073709551616'), res, "first")) == [])
check("first form below -2^63", reasons_of(
_seal(seed, req.replace('"shots":10', '"shots":10,"seed":-9223372036854775809'), res, "first"))
== ["inexact_number"])
def seeded(seed_text, form="rfc8785"):
return _seal(seed, req.replace('"shots":10', '"shots":10,"seed":%s' % seed_text), res, form)
check("2^60 in its canonical spelling", reasons_of(seeded("1152921504606847000")) == [])
check("-2^60 in its canonical spelling", reasons_of(seeded("-1152921504606847000")) == [])
check("2^60's double, in another spelling", reasons_of(seeded("1152921504606847001")) == ["inexact_number"])
check("2^60 + 1, inexact", reasons_of(seeded("1152921504606846977")) == ["inexact_number"])
check("2^53 + 1 is no double's canonical text", reasons_of(seeded("9007199254740993")) == ["inexact_number"])
check("under 10^21, read as 10^21: no canonical whole spelling", reasons_of(
seeded("999999999999999999999")) == ["inexact_number"])
check("first form: 2^65 canonical, past its integers", reasons_of(
seeded("36893488147419103000", "first")) == [])
check("first form: past its integers, not canonical", reasons_of(
seeded("36893488147419103001", "first")) == ["inexact_number"])
check("receipt_form reads numbers as canonical", reasons_of(
_seal(seed, req.replace('"shots":10', '"shots":10,"seed":9007199254740993'), res, "first")
.replace(b'"alg":"ed25519"', b'"alg":"ed448"')) == ["inexact_number", "receipt_form"])
check("inexact_number not in the receipt", reasons_of(
_seal(seed, req, res, receipt_extra={"x": 0}).replace(b'"x":0', b'"x":9007199254740993')) == [])
check("other method may not be simulated", reasons_of(_seal(seed, req, res.replace(
'"exact"', '"simulated"'))) == ["provider_class"])
check("unknown class is not a reason", reasons_of(_seal(seed, req, res.replace('"exact"', '"novel"'))) == [])
check("no_receipt alone", reasons_of(b'{"request":{},"result":{"method":"provider"}}') == ["no_receipt"])
check("not_a_job", reasons_of(b'{"request":[],"result":{}}') == ["not_a_job"])
# The identity key with R = [S]B holds for every digest unless the key rules refuse it.
anything = _seal(seed, req, res)
forged = json.loads(anything.decode())
forged["result"]["receipt"]["key"] = _SMALL_ORDER[0]
forged["result"]["receipt"]["signature"] = (_encode_point(_mul(5, _B)) + (5).to_bytes(32, "little")).hex()
forged = json.dumps(forged).encode()
check("identity key: bad_key", reasons_of(forged) == ["bad_key"])
# §8.2: R of small order, in a signature whose equation holds, so that only the
# rules on R can refuse it: R the identity, k = SHA-512(R ‖ A ‖ digest) mod l,
# S = k·a mod l, a the clamped scalar of the demo seed.
demo = bytes([42] * 32)
demo_scalar = (int.from_bytes(hashlib.sha512(demo).digest()[:32], "little") & ((1 << 254) - 8)) | (1 << 254)
demo_key = _encode_point(_mul(demo_scalar, _B))
demo_digest = seal_digest(2, text_of(read_json(req.encode()), True).encode(),
text_of(read_json(res.encode()), True).encode())
def small_r_body(r_bytes):
k = int.from_bytes(hashlib.sha512(r_bytes + demo_key + demo_digest).digest(), "little") % _L
s_value = k * demo_scalar % _L
holds = _same_point(_mul(s_value, _B), _add(_IDENTITY, _mul(k, _decode_point(demo_key))))
signature = r_bytes + s_value.to_bytes(32, "little")
return holds, _seal(demo, req, res, receipt_extra={"signature": signature.hex()})
identity_holds, identity_r_body = small_r_body(bytes.fromhex(_SMALL_ORDER[0]))
alias_r = (_P + 1).to_bytes(32, "little") # the identity again, spelt y = p + 1
alias_holds, alias_r_body = small_r_body(alias_r)
check("identity R: the equation holds", identity_holds)
check("identity R: bad_signature", reasons_of(identity_r_body) == ["bad_signature"])
check("identity R spelt y = p + 1: refused by its decoding", _decode_point(alias_r) is None)
check("identity R spelt y = p + 1: the equation holds", alias_holds)
check("identity R spelt y = p + 1: bad_signature", reasons_of(alias_r_body) == ["bad_signature"])
# A provider's stated result (§8.1, §8.3, §8.4).
def provider_body(request=_PROVIDER_REQUEST, **changes):
return _seal(seed, request, _provider_result(**changes))
names = {"0": "Q0"}
nobody = {"stated_by": "nobody", "mitigation": "unknown", "twirling": "unknown", "decoupling": "unknown",
"remapping": "unknown", "optimisation": "unknown", "verbatim": None}
two_to_53, two_to_54 = 2 ** 53, 2 ** 54
prx_row = ROWS["prx-circuits"][0][2]
processor_row, simulator_row = ROWS["cloud-tasks"][0][2], ROWS["cloud-tasks"][1][2]
noise_row = dict(ROWS["native-turns"][1][2], sent={
"fields": ROWS["native-turns"][1][2]["sent"]["fields"],
"settings": {"/input/gateset": "native", "/settings/error_mitigation/debiasing": False,
"/noise/model": "a device's model"}})
cases = (
("stated provider result", provider_body(), []),
("class measured on a simulator", provider_body(accuracy__class="measured"), ["provider_class"]),
("approximate false", provider_body(accuracy__approximate=False), ["provider_class"]),
("approximate true", provider_body(accuracy__approximate=True), []),
("silicon is measured", provider_body(provider__provenance="silicon", accuracy__class="measured"), []),
("request names another", provider_body(provider__name="other"), ["request_provider"]),
("request shots", provider_body(request=_PROVIDER_REQUEST.replace('"shots":4', '"shots":5')), ["request_shots"]),
("default 1024 shots", provider_body(request=_PROVIDER_REQUEST.replace(',"shots":4', '')), ["request_shots"]),
("counts sum", provider_body(counts={"1": 3}), ["counts"]),
("zero count", provider_body(counts={"1": 4, "0": 0}, distinct_outcomes=2), ["counts"]),
("describe missing", provider_body(provider__describe=_DELETE), ["provider_members"]),
("estimate null", provider_body(cost__estimate=None), ["provider_members"]),
("counts_source of another row", provider_body(provider__kind="prx-circuits"), ["counts_source", "execution"]),
("http: client-stated", provider_body(provider__kind="http", execution=dict(
prx_row)), ["execution"]),
("verbatim with remapping on", provider_body(execution__remapping="on"), ["execution"]),
("execution extra member", provider_body(execution__extra="x"), ["execution"]),
("provider may say unknown", provider_body(execution__twirling="unknown"), []),
("provider may not say default", provider_body(execution__twirling="default"), ["execution"]),
("nobody", provider_body(execution=nobody), []),
("nobody on a kind with rows", provider_body(provider__kind="cloud-tasks", execution=nobody), []),
("nobody on sampler-v2", provider_body(provider__kind="sampler-v2", execution=nobody), []),
("nobody on a kind with rows, its source still the rows'", provider_body(
provider__kind="prx-circuits", execution=nobody), ["counts_source"]),
("provider on a kind with rows", provider_body(provider__kind="cloud-tasks"), ["execution"]),
("cloud-tasks processor row on silicon", provider_body(
provider__kind="cloud-tasks", provider__provenance="silicon", accuracy__class="measured",
compiled__qubit_names=names, execution=dict(processor_row, note="sent verbatim")), []),
("cloud-tasks processor row on a simulator", provider_body(
provider__kind="cloud-tasks", compiled__qubit_names=names, execution=dict(processor_row)), ["execution"]),
("cloud-tasks simulator row on an emulator", provider_body(
provider__kind="cloud-tasks", provider__provenance="emulator", compiled__qubit_names=names,
execution=dict(simulator_row)), []),
("cloud-tasks simulator row on silicon", provider_body(
provider__kind="cloud-tasks", provider__provenance="silicon", accuracy__class="measured",
compiled__qubit_names=names, execution=dict(simulator_row)), ["execution"]),
("row with its fields reordered", provider_body(
provider__kind="cloud-tasks", compiled__qubit_names=names, execution=dict(
simulator_row, sent={"fields": list(reversed(_CLOUD_TASKS_FIELDS)), "settings": {}})), ["execution"]),
# §8.4 compiled.qubit_names
("qubit_names required: cloud-tasks by client", provider_body(
provider__kind="cloud-tasks", execution=dict(simulator_row)), ["provider_members"]),
("qubit_names required: prx-circuits by client", provider_body(
provider__kind="prx-circuits", counts_source="vendor_counts", execution=dict(prx_row)), ["provider_members"]),
("qubit_names given: prx-circuits by client", provider_body(
provider__kind="prx-circuits", counts_source="vendor_counts", compiled__qubit_names=names,
execution=dict(prx_row)), []),
("qubit_names optional elsewhere, and held when given", provider_body(compiled__qubit_names=names), []),
("qubit_names null is given", provider_body(compiled__qubit_names=None), ["provider_members"]),
("qubit_names an array", provider_body(compiled__qubit_names=["Q0"]), ["provider_members"]),
("qubit_names leading zero", provider_body(compiled__qubit_names={"0": "Q0", "01": "Q1"}), ["provider_members"]),
("qubit_names key not an index", provider_body(compiled__qubit_names={"0": "Q0", "x": "Q1"}), ["provider_members"]),
("qubit_names empty name", provider_body(compiled__qubit_names={"0": ""}), ["provider_members"]),
("qubit_names name not a string", provider_body(compiled__qubit_names={"0": 7}), ["provider_members"]),
("qubit_names without a layout entry", provider_body(compiled__qubit_names={"1": "Q1"}), ["provider_members"]),
("qubit_names without a final_layout entry", provider_body(
compiled__final_layout=[1], compiled__qubit_names=names), ["provider_members"]),
("qubit_names holds more than the layouts", provider_body(compiled__qubit_names={"0": "Q0", "5": "Q5"}), []),
("qubit_names: an entry however written", provider_body(
compiled__layout=[1.0], compiled__final_layout=[1e0], compiled__qubit_names={"0": "Q0", "1": "Q1"}), []),
("qubit_names: an entry in full", provider_body(
compiled__layout=[1e21], compiled__final_layout=[1e21],
compiled__qubit_names={"0": "Q0", "1000000000000000000000": "Q"}), []),
("qubit_names: not as a number's text", provider_body(
compiled__layout=[1e21], compiled__final_layout=[1e21],
compiled__qubit_names={"0": "Q0", "1e+21": "Q"}), ["provider_members"]),
("qubit_names not read in the earlier form", provider_body(
counts_source=_DELETE, execution=_DELETE, accuracy__class="measured",
compiled__qubit_names=None), []),
# §8.4: a whole number however large; only a count's value has a ceiling; a sum exact.
("a whole number however large", provider_body(job__polls=1e300, compiled__swaps=two_to_53), []),
("a count past its ceiling", provider_body(
request=_PROVIDER_REQUEST.replace('"shots":4', '"shots":%d' % two_to_53),
counts={"1": two_to_53}, shots=two_to_53), ["counts"]),
("shots past a count's ceiling", provider_body(
request=_PROVIDER_REQUEST.replace('"shots":4', '"shots":%d' % two_to_54),
counts={"00": two_to_53 - 1, "01": two_to_53 - 1, "10": 2}, distinct_outcomes=3, shots=two_to_54), []),
("a sum exact, not a double's", provider_body(
request=_PROVIDER_REQUEST.replace('"shots":4', '"shots":%d' % two_to_54),
counts={"00": two_to_53 - 1, "01": two_to_53 - 1, "10": 3}, distinct_outcomes=3, shots=two_to_54), ["counts"]),
# §8.4: "the request's" is by value.
("the request's shots by value", provider_body(
request=_PROVIDER_REQUEST.replace('"shots":4', '"shots":4.0')), []),
("two equal strings are the same", provider_body(
request=_PROVIDER_REQUEST.replace('"shots":4', '"shots":"4"'), shots="4"), ["counts"]),
("a string is not a number", provider_body(
request=_PROVIDER_REQUEST.replace('"shots":4', '"shots":"4"')), ["request_shots"]),
("native-turns with noise", provider_body(provider__kind="native-turns", counts_source="probabilities",
execution=noise_row), []),
("native-turns with noise on silicon", provider_body(
provider__kind="native-turns", counts_source="probabilities", provider__provenance="silicon",
accuracy__class="measured", execution=noise_row), ["execution"]),
("native-turns without noise on silicon", provider_body(
provider__kind="native-turns", counts_source="probabilities", provider__provenance="silicon",
accuracy__class="measured", execution=dict(ROWS["native-turns"][0][2])), []),
("a later kind's settings names", provider_body(provider__kind="later", execution=dict(
prx_row, twirling="off", sent={"fields": ["a", "b~c"], "settings": {
"/b~0c/x": 1, "any_name": True}})), []),
("a settings key ''", provider_body(provider__kind="later", execution=dict(
prx_row, twirling="off", sent={"fields": ["a"], "settings": {"": 1}})), ["execution"]),
("a pointer outside the fields", provider_body(provider__kind="later", execution=dict(
prx_row, twirling="off", sent={"fields": ["a"], "settings": {"/z": 1}})), ["execution"]),
("a pointer's rest not read", provider_body(provider__kind="later", execution=dict(
prx_row, twirling="off", sent={"fields": ["a"], "settings": {"/a/~2": 1}})), []),
("negative omitted_shots", provider_body(omitted_shots=-1, counts={"1": 5}), ["counts"]),
("negative swaps", provider_body(compiled__swaps=-1), ["provider_members"]),
("compiled program hash", provider_body(compiled__program="00" * 32), ["compiled_program"]),
("upper-case program hash", provider_body(compiled__program=blake3(
_PROVIDER_QASM3.encode()).hex().upper()), ["provider_members"]),
("confirmed on a free run", provider_body(cost__confirmed=True), ["cost_confirmation"]),
# §8.1, §8.4: a provider's own record takes a submit as the confirmation of a
# run that is not free, and of no other.
("a provider's own record, confirmed by the submit", provider_body(
cost__free=False, cost__confirmed=True, cost__confirmed_by="submit"), []),
("a free run confirmed by the submit", provider_body(cost__confirmed_by="submit"), ["cost_confirmation"]),
("confirmed_by of no value", provider_body(
cost__free=False, cost__confirmed=True, cost__confirmed_by="person"), ["cost_confirmation"]),
("confirmed_by null", provider_body(
cost__free=False, cost__confirmed=True, cost__confirmed_by=None), ["cost_confirmation"]),
("confirmed_by beside confirmed null", provider_body(
cost__free=False, cost__confirmed=None, cost__confirmed_by="submit"), ["cost_confirmation", "provider_members"]),
("earlier form must be measured", provider_body(counts_source=_DELETE, execution=_DELETE), ["provider_class"]),
("earlier form, measured", provider_body(counts_source=_DELETE, execution=_DELETE,
accuracy__class="measured", provider__describe=_DELETE), []),
)
for name, raw_case, want in cases:
check(name, reasons_of(raw_case) == want)
# §8.4: qubit_names holds every index qasm3 acts on.
def with_qasm3(text, names_given):
return provider_body(compiled__qasm3=text, compiled__program=blake3(text.encode()).hex(),
compiled__qubit_names=names_given)
names_short = with_qasm3("x $0;\ncz $0, $1;\n", {"0": "Q0"})
for name, raw_case, want in (
("qasm3 acts on an index not named", names_short, ["provider_members"]),
("qasm3's indices named", with_qasm3("x $0;\ncz $0, $1;\n", {"0": "Q0", "1": "Q1"}), []),
("qasm3 $01 names 1", with_qasm3("x $0;\nx $01;\n", {"0": "Q0", "1": "Q1"}), []),
("qasm3 $12 names 12", with_qasm3("x $0;\nx $12;\n", {"0": "Q0", "1": "Q1"}), ["provider_members"]),
("qasm3: a $ with no digit names none", with_qasm3("x $0;\n// $ and $x\n", {"0": "Q0"}), []),
("qasm3 with names absent", with_qasm3("x $0;\ncz $0, $1;\n", _DELETE), []),
("qasm3: a long run of zeros", with_qasm3("x $" + "0" * 5000 + ";\n", {"0": "Q0"}), [])):
check(name, reasons_of(raw_case) == want)
# §8.6: a set's receipt.
program_a = "OPENQASM 3.0;\nqubit[1] q;\nbit[1] c;\nx q[0];\nc = measure q;\n"
program_b = "OPENQASM 3.0;\nqubit[1] q;\nbit[1] c;\nc = measure q;\n"
programs_request = {"programs": [program_a, {"qasm": program_b, "shots": 5}], "shots": 10, "dry_run": False}
programs_items = [{"shots": 10, "qasm": program_a}, {"shots": 5, "qasm": program_b}]
def programs_of(n):
return ({"programs": [program_a] * n, "shots": 10}, [{"shots": 10, "qasm": program_a}] * n)
sweep_request = {"qasm": "OPENQASM 3.0;\ninput angle t;\nqubit[1] q;\nrx(t) q[0];\n", "shots": 10,
"sweep": {"t": [0.5, 1], "u": [1, 2, 3]}}
sweep_items = [{"shots": 10, "qasm": "OPENQASM 3.0;\nqubit[1] q;\nrx(%d) q[0];\n" % i} for i in range(6)]
def set_of(n, **kw):
asked, items = programs_of(n)
return _set_body(seed, asked, items, **kw)
def drop(member):
return lambda head, items: head.pop(member)
def wrong_root(head, items):
head["root"] = "ab" * 32
def tamper_count(items):
items[0]["result"]["counts"] = {"1": 11}
def tamper_after(head, items):
items[0]["result"]["counts"] = {"1": 11}
def swap_path(head, items):
items[0]["path"][0] = "cd" * 32
def longer_path(head, items):
items[0]["path"].append(head["root"])
def index_off(head, items):
items[1]["index"] = 7
def both(head, items):
items[0]["error"] = "and an error"
def upper_path(head, items):
items[0]["path"][0] = items[0]["path"][0].upper()
def unsealed_members(head, items):
for i, item in enumerate(items):
item.update(status="done", method="statevector", why="a fixture", point={"t": i})
def drop_key(head, items):
head["_drop_key"] = True # _seal_set removes it, and the receipt's key
def upper_key(head, items):
head["_upper_key"] = True
def head_provider(head, items):
head.update({"method": "provider", "accuracy": {"class": "measured"}})
set_cases = (
("set of programs", _set_body(seed, programs_request, programs_items), []),
("set of one", set_of(1), []),
("set of three, one an error", _set_body(seed, programs_of(3)[0], programs_of(3)[1], errors=(1,)), []),
("set of five", set_of(5), []),
("set of a sweep", _set_body(seed, sweep_request, sweep_items), []),
("set: sweep null is none", _set_body(seed, dict(programs_request, sweep=None), programs_items), []),
("set: count wrong", set_of(2, head_extra={"count": 3}), ["set_items"]),
("set: count missing", set_of(2, after_root=drop("count")), ["set_items"]),
("set: count 2.0 is 2", set_of(2, head_extra={"count": 2.0}), []),
("set: items emptied", set_of(2, after_root=lambda head, items: items.clear()), ["set_items"]),
("set: an index off stops the next two", set_of(2, after_root=lambda h, it: (index_off(h, it), tamper_after(h, it))),
["set_items"]),
("set: result and error both", set_of(2, after_root=both), ["set_items"]),
("set: a path digit upper-case", set_of(2, after_root=upper_path), ["set_items"]),
("set: an item not the program's", _set_body(
seed, programs_request, [programs_items[0], dict(programs_items[1], shots=6)]), ["set_items"]),
("set: an item more than the programs", _set_body(seed, programs_request, programs_items + programs_items[:1]),
["set_items"]),
("set: programs and sweep both", _set_body(seed, dict(programs_request, sweep={"t": [1]}), programs_items),
["set_items"]),
("set: neither, and no items", _set_body(seed, {"shots": 10}, []), ["set_items"]),
("set: a sweep value empty", _set_body(seed, dict(sweep_request, sweep={"t": [], "u": [1]}), sweep_items[:0]),
["set_items"]),
("set: a sweep item's request otherwise", _set_body(
seed, sweep_request, sweep_items[:5] + [dict(sweep_items[5], shots=11)]), ["set_items"]),
("set: a sweep of the wrong count", _set_body(seed, sweep_request, sweep_items[:5]), ["set_items"]),
("set: an item tampered before its leaf", set_of(2, before_root=tamper_count), ["set_item"]),
("set: an item tampered after the root", set_of(2, after_root=tamper_after), ["set_item", "set_root"]),
("set: the root another", set_of(2, after_root=wrong_root), ["set_root"]),
("set: a path's sibling another", set_of(3, after_root=swap_path), ["set_root"]),
("set: a path too long", set_of(2, after_root=longer_path), ["set_root"]),
("set: an item inexact", set_of(1, item_result=_ITEM_RESULT.replace('"gates":1', '"gates":9007199254740993')),
["set_item"]),
("set: its request inexact", _set_body(
seed, dict(programs_of(1)[0], dry_run=Num("9007199254740993", 2.0 ** 53)), programs_of(1)[1]),
["inexact_number"]),
("set: no provider rules on a head", set_of(1, after_root=head_provider), []),
("set: an error item writes 2^53 + 1", _set_body(
seed, dict(programs_of(1)[0], seed=2 ** 53),
[dict(programs_of(1)[1][0], seed=Num("9007199254740993", 2.0 ** 53))], errors=(0,)), ["set_item"]),
("set: an error item writes 2^60 canonically", _set_body(
seed, dict(programs_of(1)[0], seed=2 ** 60),
[dict(programs_of(1)[1][0], seed=Num("1152921504606847000", 2.0 ** 60))], errors=(0,)), []),
("set: first form, an error item's u64 read as canonical", _set_body(
seed, dict(programs_of(1)[0], seed=2 ** 53),
[dict(programs_of(1)[1][0], seed=Num("9007199254740993", 2.0 ** 53))], errors=(0,), form="first"),
["set_item"]),
("set: first form, an error item's exact u64", _set_body(
seed, dict(programs_of(1)[0], seed=2 ** 53),
[dict(programs_of(1)[1][0], seed=2 ** 53)], errors=(0,), form="first"), []),
("set: first form, an error item past u64", _set_body(
seed, dict(programs_of(1)[0], seed=2 ** 64),
[dict(programs_of(1)[1][0], seed=Num("18446744073709551617", 2.0 ** 64))], errors=(0,), form="first"),
["set_item"]),
("set: first form sealed", set_of(2, form="first"), []),
("set: an item signed by another key", set_of(2, item_seed=bytes([7] * 32)), ["set_item"]),
("set: an item's result a set's", set_of(1, item_result=_ITEM_RESULT.replace(
'"method"', '"format":"wai.quantum.set/1","method"')), ["set_item"]),
("set: an item's unsealed members", set_of(2, after_root=unsealed_members), []),
("set: an item's unsealed members changed", set_of(2, after_root=lambda h, it: (
unsealed_members(h, it), it[0].update(status="failed", method=7, why=None, point=[]))), []),
("set: an item receipt's own extra member", set_of(2, after_root=lambda h, it: (
it[0]["result"]["receipt"].update(note="ignored", x=[1, 2]))), []),
("set: its receipt with no key", set_of(1, after_root=drop_key), ["receipt_form", "set_item"]),
("set: its key in upper case", set_of(1, after_root=upper_key), ["receipt_form", "set_item"]),
)
for name, raw_case, want in set_cases:
check(name, reasons_of(raw_case) == want)
sealed_set = set_of(2)
check("set: the head tampered", reasons_of(sealed_set.replace(b'"count": 2', b'"count": 3'))
== ["digest_mismatch", "set_items"])
unlisted = json.loads(sealed_set.decode())
del unlisted["result"]["items"]
check("set: items missing", reasons_of(json.dumps(unlisted).encode()) == ["set_items"])
check("set: no receipt, alone", reasons_of(json.dumps(
{"request": {}, "result": {"format": SET_FORMAT, "items": 5}}).encode()) == ["no_receipt"])
# quantum-wasmq §6.5: the wasmQ jobs of _wasmq_tables, each judged once: its reasons, the
# rules it breaks, and its statement's problems, one entry a rule, in order, there
# exactly when wasmq_form is reported (another job states nothing). Each rule from 2 to
# the last is broken alone by one case at least; rule 1 cannot be (see the table).
def rules_of(raw):
job = read_json(raw)
return wasmq_broken(job["request"], job["result"])
def problem_rules(v):
return [int(p.split(":", 1)[0][len("rule "):]) for p in v["wasmq"]["problems"]]
wasmq_cases, statement_cases, verdict_cases = _wasmq_tables()
unstated = []
for name, raw_case, want, rules in wasmq_cases:
v = judge(raw_case)
check(name, v["reasons"] == want)
if rules is None:
held = "wasmq" not in v
else:
check(name + ": its rules", rules_of(raw_case) == rules)
held = ("wasmq" in v and problem_rules(v) == rules
and all(p.startswith("rule ") for p in v["wasmq"]["problems"])
and ("wasmq_form" in v["reasons"]) == bool(rules))
if not held:
unstated.append(name)
alone = set(rules[0] for _, _, want, rules in wasmq_cases if want == ["wasmq_form"] and len(rules) == 1)
# Rule 27 is never broken alone: a lifecycle fault at shot 0 has shots_run 0 (rule 18), so
# rule 32 holds the callouts to 0 (and rule 15 to a count) as rule 27 does.
check("wasmq: each of rules 2 to %d but 27 broken alone" % WASMQ_RULES,
alone == set(range(2, WASMQ_RULES + 1)) - {27})
check("wasmq statement: its problems are the rules broken, in all %d cases%s" % (
len(wasmq_cases), (": " + ", ".join(unstated)) if unstated else ""), not unstated)
exported = [name for name, _, _ in wasmq_case_lines()]
check("wasmq: the %d cases --wasmq-cases writes have distinct names" % len(exported),
len(set(exported)) == len(exported))
for name, raw_case, want, alone_verdict in verdict_cases:
v = judge(raw_case)
check(name, v == _verdict(want) if alone_verdict else v["reasons"] == want)
for name, raw_case, want, want_statement in statement_cases:
v = judge(raw_case)
check("wasmq statement: " + name, v["reasons"] == want and v.get("wasmq") == want_statement)
check("wasmq statement: method provider states its provider too",
"provider" in judge(_wasmq_job(result={"method": "provider"})))
check("wasmq statement: the first 64 problems, then how many more",
_first_and_more(["p%d" % i for i in range(70)]) == ["p%d" % i for i in range(64)] + ["and 6 more"]
and _first_and_more(["p"] * 64) == ["p"] * 64 and _first_and_more([]) == [])
wasmq_asked, wasmq_made = _wasmq_parts(False)
check("wasmq statement: a set holding a wasmQ job states none", "wasmq" not in judge(_set_body(
_WASMQ_SEED, {"programs": [wasmq_asked]}, [wasmq_asked], item_result=_dump(wasmq_made))))
check("wasmq statement: another job states none", "wasmq" not in judge(body))
# The scan of sent.settings against sent.fields is linear. Every key names the last
# field, so a scan of the list walks all of it each time (tens of seconds).
many_fields = ["f%06d" % i for i in range(50000)]
many_settings = dict(("/%s/k%d" % (many_fields[-1], i), i) for i in range(50000))
many = dict(prx_row, twirling="off", sent={"fields": many_fields, "settings": many_settings})
started = time.perf_counter()
many_hold = execution_rules_hold(many)
check("50,000 fields and 50,000 settings, within 3 s",
many_hold and time.perf_counter() - started < 3.0)
# Each plant changes a verdict a differential would compare.
def planted(plant, raw):
PLANTS.add(plant)
try:
return judge(raw)["reasons"]
finally:
PLANTS.discard(plant)
# §8.7: a job under a contract, as it is and broken one way at a time.
def contract_body(job_seed=None, extra_routes=(), **changes):
return _seal(seed, *_contract_job(seed=job_seed, extra_routes=extra_routes, **changes))
def local_body(contract, routes, choice, auto, stable_choice, kept, **kw):
return _seal(seed, *_local_contract_job(contract, routes, choice, auto, stable_choice, kept, **kw))
def stopped_body(**changes):
request, result = _local_contract_job({"exactness": "exact", "max_joules": 2}, [
_lr("exact", "bit-exact", 20, "chosen", joules=1.0), _lr("statevector", "exact", 30, "met", memory=2048, joules=1.0),
_lr("statevector_single", "single", 40, "rejected", "class", host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "rejected", "class", memory=4096, joules=1.0)], "method:exact", "method:exact", False,
{"energy": {"max_joules": 2, "joules": 2.5, "kept": False}}, result_class="none")
both = {"request": json.loads(request), "result": json.loads(result)}
del both["result"]["counts"]
both["result"]["stopped"] = {"at": "max_joules", "joules": 2.5, "max_joules": 2, "elapsed_ms": 3, "read": "a test's reading"}
for path, value in changes.items():
node = both
parts = path.split("__")
for part in parts[:-1]:
node = node[part]
if value is _DELETE:
del node[parts[-1]]
else:
node[parts[-1]] = value
return _seal(seed, json.dumps(both["request"], separators=(",", ":")), json.dumps(both["result"], separators=(",", ":")))
def energy_routes(statevector):
return local_body({"exactness": "exact", "max_joules": 2}, [
_lr("exact", "bit-exact", 20, "chosen", joules=1.0), statevector,
_lr("statevector_single", "single", 40, "rejected", "class", host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "rejected", "class", memory=4096, joules=1.0)], "method:exact", "method:exact", False,
{"energy": {"max_joules": 2, "joules": 2.0, "kept": True}}, energy={"joules_micro": 2000000})
def read_and_not():
r = _lr("statevector", "exact", 30, "met", memory=2048, joules=1.0)
r["price"]["energy"]["unwatched"] = "and yet"
return r
check("a stop on a provider's run, which nothing here reads", "stopped" in reasons_of(stopped_body(result__method="provider")))
def contract_edited(edit):
request, text = _contract_job(seed=None, extra_routes=())
body = {"request": json.loads(request), "result": json.loads(text)}
edit(body)
return _seal(seed, json.dumps(body["request"], separators=(",", ":")), json.dumps(body["result"], separators=(",", ":")))
def chosen(b):
return next(r for r in b["result"]["planner"]["routes"] if r["route"] == b["result"]["planner"]["choice"])
check("a run sealed at a cost its route does not state", reasons_of(contract_edited(
lambda b: b["result"]["cost"].update(free=False, confirmed=True, estimate={"free": False, "amount": "50", "currency": "USD"}))) == ["planner_choice"])
check("the route chosen names another device than ran", reasons_of(contract_edited(lambda b: chosen(b).update(device="elsewhere"))) == ["planner_choice"])
check("members alike by value: 7 and 7.0, -0 and 0", _alike(Num("7", 7.0), Num("7.0", 7.0)) and _alike(Num("-0", -0.0), Num("0", 0.0)))
check("a boolean is no number, and null is absent", not _alike(True, Num("1", 1.0)) and _alike(None, None) and not _alike("a", None))
check("lists and objects alike member by member", _alike([Num("7", 7.0)], [Num("7.0", 7.0)]) and _alike({"a": Num("-0", -0.0), "b": None}, {"a": Num("0", 0.0)})
and not _alike([True], [Num("1", 1.0)]) and not _alike({"a": "x"}, {"a": "y"}))
check("an earlier-form provider result under a contract", "contract_form" in reasons_of(contract_edited(
lambda b: [b["result"].pop(k) for k in ("counts_source", "execution")])))
check("the route chosen names the device that ran", reasons_of(contract_edited(lambda b: chosen(b).update(device=b["result"]["provider"]["device"]))) == [])
def timed_by_host(kept):
request, text = _local_contract_job({"exactness": "exact", "deadline_seconds": 60}, base(), "method:exact", "method:exact", True, kept)
result = json.loads(text)
del result["elapsed_ms"]
return _seal(seed, request, json.dumps(result, separators=(",", ":")))
contract_ok = contract_body()
check("a contract job's reasoning and shadow", reasons_of(contract_ok) == [])
for name, raw_case, want in (
("a contract that does not read", contract_body(request__contract={"exactness": "nearly"}), ["contract_form"]),
("a reasoning dropped", contract_body(result__planner=_DELETE), ["planner_form"]),
("a digest not the routes'", contract_body(result__planner__stable__digest="00" * 32), ["planner_stable"]),
("a choice said to be the host's own", contract_body(result__planner__stable__choice=True), ["planner_stable"]),
("a kept the contract does not ask", contract_body(result__planner__kept={"deadline": {}}), ["planner_kept"]),
("a class short of what is wanted", contract_body(result__accuracy__approximate=True), ["contract_class"]),
("a shadow on another seed", contract_body(result__shadow__request__seed=4), ["shadow"]),
("a shadow's omitted_shots of 0.0", contract_body(result__shadow__omitted_shots=0.0), []),
("a distance not computed, every shot listed", contract_body(
result__shadow__distance={"computed": False, "why": "said so"}), ["shadow"]),
("the least it can come to, on a free route", contract_body(
result__planner__routes__1__price__money={"free": True, "at_least": False}), ["planner_form"]),
("a named provider under never", contract_body(request__contract__providers="never"),
["contract_provider", "planner_choice", "planner_route"]),
("a shadow request with a noise model", contract_body(
result__planner__shadow__request__noise={"depolarizing_2q": 0.2},
result__shadow__request__noise={"depolarizing_2q": 0.2}), ["shadow"]),
("a route with no watch, said to meet a ceiling", energy_routes(_lr("statevector", "exact", 30, "met", memory=2048, joules=1.0, watch=None)), ["planner_route"]),
("a watched route said to have no reading", energy_routes(_lr("statevector", "exact", 30, "rejected", "energy_unwatched", memory=2048, joules=1.0)), ["planner_route"]),
("a watch that is no sentence", local_body({"exactness": "exact", "max_joules": 2}, [
_lr("exact", "bit-exact", 20, "chosen", joules=1.0), _lr("statevector", "exact", 30, "met", memory=2048, joules=1.0, watch=True),
_lr("statevector_single", "single", 40, "rejected", "class", host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "rejected", "class", memory=4096, joules=1.0)], "method:exact", "method:exact", False,
{"energy": {"max_joules": 2, "joules": 2.0, "kept": True}}, energy={"joules_micro": 2000000}), ["planner_form"]),
("a run stopped past no ceiling it has", stopped_body(result__stopped__max_joules=9), ["stopped"]),
("a run stopped under its ceiling", stopped_body(result__stopped__joules=1.5, result__planner__kept__energy__joules=1.5), ["stopped"]),
("a stopped run that gives an answer", stopped_body(result__counts={"1": 4}), ["stopped"]),
("a stopped run said to have kept its ceiling", stopped_body(result__planner__kept__energy__kept=True), ["planner_kept"]),
("a run stopped with no ceiling", stopped_body(request__contract={"exactness": "exact"}), ["planner_kept", "planner_stable", "stopped"]),
("a run stopped with no contract", stopped_body(request__contract=_DELETE), ["planner_form", "stopped"]),
("a reading exactly at the ceiling stops a run", stopped_body(result__stopped__joules=2, result__planner__kept__energy__joules=2), []),
("a stopped run that claims a class", stopped_body(result__accuracy__class="exact"), ["stopped"]),
("a stop that does not say what read it", stopped_body(result__stopped__read=7), ["stopped"]),
("a stop at a time that is no whole number", stopped_body(result__stopped__elapsed_ms=1.5), ["stopped"]),
("a stop with a member its form does not have", stopped_body(result__stopped__note="more"), ["stopped"]),
("a stop at something other than the energy ceiling", stopped_body(result__stopped__at="deadline"), ["stopped"]),
("an estimate exactly at the ceiling refuses nothing", energy_routes(_lr("statevector", "exact", 30, "met", memory=2048, joules=2.0)), []),
("a route said both to be read and to have no reading", energy_routes(read_and_not()), ["planner_form"]),
# By hand: "1" 4 and 1 times, 5 pooled, E|2B - 5| = 1.875; half of it over 4.
("a shadow's counts short of its shots, the distance what they give", contract_body(
result__shadow__counts={"1": 1},
result__shadow__distance={"computed": True, "numerator": 3, "denominator": 8, "total_variation": 0.375,
"hellinger_fidelity": 0.25, "sampling_tvd_bound": 0.234375}), ["shadow"]),
# By hand: "1" 4 and "x" 4 times, each pooled 4, E|2B - 4| = 1.5 twice; half of it over 4.
("a shadow's outcomes that are not bits, the distance what they give", contract_body(
result__shadow__counts={"x": 4},
result__shadow__distance={"computed": True, "numerator": 8, "denominator": 8, "total_variation": 1.0,
"hellinger_fidelity": 0.0, "sampling_tvd_bound": 0.375}), ["shadow"]),
("a shadow that says more outcomes than it lists", contract_body(result__shadow__distinct_outcomes=7), ["shadow"]),
("a shadow's class its method does not have", contract_body(
result__planner__routes__0__route="method:mps", result__planner__routes__0__method="mps",
result__planner__routes__0__class="heuristic", result__planner__routes__0__auto_rank=60, result__planner__stable__routes=["method:mps"],
result__planner__shadow__route="method:mps", result__planner__shadow__class="heuristic",
result__planner__shadow__request__method="mps", result__shadow__route="method:mps",
result__shadow__request__method="mps"), ["planner_stable", "shadow"]),
("host.providers that are not its provider routes", contract_body(result__planner__host__providers=["someone-else"]), ["planner_form"]),
("a provider that states its memory", contract_body(result__planner__routes__1__price__memory_bytes=1024), ["planner_form"]),
("a provider's route said not to depend on the host", contract_body(result__planner__routes__1__host_dependent=False), ["planner_route"]),
("a method on no GPU said to depend on the host", contract_body(result__planner__routes__0__host_dependent=True), ["planner_route", "planner_stable"]),
("a built-in route stated a class it does not have", contract_body(result__planner__routes__0__class="exact"), ["planner_route", "planner_stable", "shadow"]),
("a method's result of a class it does not have", local_body({"exactness": "exact"}, [
_lr("exact", "bit-exact", 20, "chosen"), _lr("statevector", "exact", 30, "met", memory=2048),
_lr("statevector_single", "single", 40, "rejected", "class", host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "rejected", "class", memory=4096)], "method:exact", "method:exact", True, {}, result_class="exact"), ["contract_class"]),
("a method's memory that is not stated", local_body({"exactness": "exact"}, [
_lr("exact", "bit-exact", 20, "chosen"), dict(_lr("statevector", "exact", 30, "met"), price={"money": {"free": True}, "time": {"seconds": 0.001, "basis": "nominal"}, "memory_bytes": None, "work": 8, "energy": {"joules": None, "why": "none"}, "leaves_out": []}),
_lr("statevector_single", "single", 40, "rejected", "class", host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "rejected", "class", memory=4096)], "method:exact", "method:exact", True, {}), ["planner_form"]),
("a shadow planned at a class its route is not listed with",
contract_body(result__planner__shadow__class="heuristic"), ["shadow"]),
("a time past what a price states", contract_body(result__planner__routes__1__price__time__seconds=1e306), ["planner_form"]),
):
check(name, reasons_of(raw_case) == want)
# §8.7, rule by rule: each case is valid, and a verifier that bends the rule it
# holds to gives it a reason. Every outcome is written here by hand.
approx = {"route": "provider:approx", "kind": "provider", "provider": "approx", "class": "simulated",
"host_dependent": True, "approximate": True, "outcome": "rejected",
"rejected": {"code": "class", "why": "approximate"},
"price": {"money": {"free": True}, "time": {"seconds": 1.0, "basis": "provider"}, "memory_bytes": None,
"work": None, "energy": {"joules": None, "why": "none"}, "leaves_out": ["energy"]}}
sim = dict(approx, provider="sim", route="provider:sim", outcome="met")
del sim["approximate"], sim["rejected"]
sim["price"] = dict(approx["price"], time={"seconds": 0.0, "basis": "provider"})
def base(cls_of_sv_single="class", **kw):
return [_lr("exact", "bit-exact", 20, "chosen"), _lr("statevector", "exact", 30, "met", memory=2048, **kw),
_lr("statevector_single", "single", 40, "rejected", cls_of_sv_single, host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "rejected", "class", memory=4096)]
routed = dict(request__provider=_DELETE, result__planner__named=None, result__planner__routes__0__rejected__code="class")
ceiling = {"exactness": "simulated", "providers": "allowed", "max_cost": {"amount": "1", "currency": "USD"}}
kept_free = {"cost": {"max_cost": {"amount": "1", "currency": "USD"}, "charged": None, "kept": True}}
def provider_route(name, money, code, seconds=1.0):
return {"route": "provider:" + name, "kind": "provider", "provider": name, "class": "simulated", "host_dependent": True,
"outcome": "rejected", "rejected": {"code": code, "why": "said so"},
"price": {"money": money, "time": {"seconds": seconds, "basis": "provider"}, "memory_bytes": None,
"work": None, "energy": {"joules": None, "why": "none"}, "leaves_out": ["energy"]}}
sim_never = provider_route("sim", {"free": True}, "providers", seconds=0.0)
for name, raw_case, want in (
("the least it can come to is not within a ceiling", contract_body(
extra_routes=(provider_route("least", {"free": False, "amount": "0.1", "currency": "USD", "at_least": True}, "cost_at_least"),),
request__contract=ceiling, result__planner__kept=kept_free, **routed), []),
("a ceiling in another currency is not met", contract_body(
extra_routes=(provider_route("euro", {"free": False, "amount": "0.1", "currency": "EUR"}, "cost_currency"),),
request__contract=ceiling, result__planner__kept=kept_free, **routed), []),
("a cost with no ceiling is not met", contract_body(
extra_routes=(provider_route("paid", {"free": False, "amount": "0.1", "currency": "USD"}, "cost_no_ceiling"),), **routed), []),
("a charge the result does not state", contract_body(
request__contract=ceiling, result__planner__kept={"cost": dict(kept_free["cost"], charged={"amount": "0", "currency": "USD"})}, **routed),
["planner_kept"]),
("a planned shadow said not to have run", contract_body(result__shadow={"ran": False, "code": "none", "why": "said so"}), ["shadow"]),
("a plan's code that no plan has", contract_body(
result__planner__shadow={"route": None, "code": "failed", "why": "said so"},
result__shadow={"ran": False, "code": "failed", "why": "said so"}), ["shadow"]),
("a provider under never, beside a local route", local_body({"exactness": "any"}, [
_lr("exact", "bit-exact", 20, "chosen", seconds=0.0001), _lr("statevector", "exact", 30, "met", seconds=0.0001, memory=2048),
_lr("statevector_single", "single", 40, "rejected", "cannot", host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "met", seconds=0.0001, memory=4096), sim_never], "method:exact", "method:exact", False, {},
providers=("sim",)), []),
("a time not known does not meet a deadline", local_body({"exactness": "exact", "deadline_seconds": 60}, [
_lr("exact", "bit-exact", 20, "chosen"), dict(_lr("statevector", "exact", 30, "rejected", "deadline_unknown"),
price=dict(_lr("statevector", "exact", 30, "met")["price"], time={"seconds": None, "why": "not known"})),
_lr("statevector_single", "single", 40, "rejected", "class", host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "rejected", "class", memory=4096)], "method:exact", "method:exact", True,
{"deadline": {"seconds": 60, "elapsed_ms": 3, "kept": True}}), []),
("a deadline a host's timer kept, the result stating no time of its own", timed_by_host({"deadline": {"seconds": 60, "elapsed_ms": 3, "kept": True}}), []),
("the matrix product state's route stated exact", local_body({"exactness": "exact", "deadline_seconds": 60}, base()[:3] + [_lr("mps", "exact", 60, "met", memory=4096)],
"method:exact", "method:exact", True, {"deadline": {"seconds": 60, "elapsed_ms": 3, "kept": True}}), ["planner_route"]),
("a method the host registered, said not to depend on the host", local_body({"exactness": "exact", "deadline_seconds": 60}, base() + [_lr("turbo", "bit-exact", None, "met")],
"method:exact", "method:exact", True, {"deadline": {"seconds": 60, "elapsed_ms": 3, "kept": True}}), ["planner_route"]),
("the same, said to depend on it", local_body({"exactness": "exact", "deadline_seconds": 60}, base() + [_lr("turbo", "bit-exact", None, "met", host_dependent=True)],
"method:exact", "method:exact", False, {"deadline": {"seconds": 60, "elapsed_ms": 3, "kept": True}}), []),
("a deadline's time that is not the result's", local_body({"exactness": "exact", "deadline_seconds": 60}, base(), "method:exact",
"method:exact", True, {"deadline": {"seconds": 60, "elapsed_ms": 4, "kept": True}}),
["planner_kept"]),
("auto said to be another route", local_body({"exactness": "exact"}, base(), "method:exact", "method:statevector", True, {}), ["planner_form"]),
("a built-in method's rank not its own", local_body({"exactness": "exact"}, [
_lr("exact", "bit-exact", 20, "chosen"), _lr("statevector", "exact", 30, "met", memory=2048),
_lr("statevector_single", "single", 0, "rejected", "class", host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "rejected", "class", memory=4096)], "method:exact", "method:exact", True, {}), ["planner_form"]),
("a local route that costs money", local_body({"exactness": "exact"}, [
_lr("exact", "bit-exact", 20, "chosen"), _lr("statevector", "exact", 30, "met", memory=2048),
_lr("statevector_single", "single", 40, "rejected", "class", host_dependent=True, priced=False),
dict(_lr("mps", "heuristic", 60, "rejected", "class", memory=4096),
price=dict(_lr("mps", "heuristic", 60, "met")["price"], money={"free": False, "unknown": "a host's word"}))],
"method:exact", "method:exact", True, {}), ["planner_form"]),
("a ceiling past 64 characters", local_body({"exactness": "exact", "max_cost": {"amount": "1" * 65, "currency": "USD"}}, base(),
"method:exact", "method:exact", True,
{"cost": {"max_cost": {"amount": "1" * 65, "currency": "USD"}, "charged": None, "kept": True}}),
["contract_form"]),
):
check("rule: " + name, reasons_of(raw_case) == want)
# The distance in its order, by hand: three shots of "1" against "0" twice and "1"
# once. R = sqrt(3), and R*R/(S*S) is 0.33333333333333326, where (R/S)^2 is not.
three = contract_body(
request__shots=3, result__shots=3, result__counts={"1": 3},
result__planner__shadow__request__shots=3, result__shadow__request__shots=3, result__shadow__shots=3,
result__shadow__counts={"0": 2, "1": 1}, result__shadow__distinct_outcomes=2,
result__shadow__distance={"computed": True, "numerator": 4, "denominator": 6, "total_variation": 4 / 6,
"hellinger_fidelity": 0.33333333333333326, "sampling_tvd_bound": 0.4166666666666667})
check("rule: the Hellinger fidelity in its order", reasons_of(three) == [])
for name, raw_case in (
# Routed, no provider named: the approximate one is quicker, and not met.
("an approximate simulator does not meet simulated", contract_body(
extra_routes=(approx,), request__provider=_DELETE, result__planner__named=None,
result__planner__routes__0__rejected__code="class")),
("the shadow's seed wraps at 2^53", contract_body(job_seed=2 ** 53 - 2)),
("single does not meet bounded", local_body({"exactness": "bounded"}, base(), "method:exact", "method:exact", True, {})),
("a job's memory at its cap", local_body({"exactness": "exact"}, [
_lr("exact", "bit-exact", 20, "chosen"), _lr("statevector", "exact", 30, "met", memory=1 << 30),
_lr("statevector_single", "single", 40, "rejected", "class", host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "rejected", "class", memory=4096)], "method:exact", "method:exact", True, {})),
("a GPU's method off the CPU", local_body({"exactness": "single"}, base("fabric"), "method:exact", "method:exact", True, {},
request_extra={"fabric": "cpu"})),
("energy at its ceiling, and a host's estimate", local_body({"exactness": "exact", "max_joules": 2}, [
_lr("exact", "bit-exact", 20, "chosen", joules=1.0), _lr("statevector", "exact", 30, "met", memory=2048, joules=1.0),
_lr("statevector_single", "single", 40, "rejected", "class", host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "rejected", "class", memory=4096, joules=1.0)], "method:exact", "method:exact", False,
{"energy": {"max_joules": 2, "joules": 2.0, "kept": True}}, energy={"joules_micro": 2000000})),
("a route no reading can stop, refused under a ceiling", energy_routes(_lr("statevector", "exact", 30, "rejected", "energy_unwatched", memory=2048, joules=1.0, watch=None))),
("an estimate past the ceiling refuses a watched route", energy_routes(_lr("statevector", "exact", 30, "rejected", "energy", memory=2048, joules=3.0))),
("a run stopped at its ceiling, and said so", stopped_body()),
("an approximate simulator named, under a contract that names no class", contract_body(
request__contract={"providers": "allowed"}, result__planner__wanted_from="named",
result__planner__routes__1__approximate=True)),
("a local route before a provider's at one time", local_body({"exactness": "any", "providers": "allowed"}, [
_lr("exact", "bit-exact", 20, "chosen", seconds=0.0001), _lr("statevector", "exact", 30, "met", seconds=0.0001, memory=2048),
_lr("statevector_single", "single", 40, "rejected", "cannot", host_dependent=True, priced=False),
_lr("mps", "heuristic", 60, "met", seconds=0.0001, memory=4096), sim], "method:exact", "method:exact", False, {},
providers=("sim",))),
):
check("rule: " + name, reasons_of(raw_case) == [])
unnamed_route = contract_body(result__planner__routes__0__outcome="met", result__planner__routes__0__rejected=_DELETE)
another_answered = contract_body(result__provider__name="other")
distance_said = contract_body(result__shadow__distance__numerator=1)
simulator_measured = provider_body(accuracy__class="measured")
duplicated = body.replace(b'{"request"', b'{"why":"a","why":"b","request"')
plant_cases = (
("lenient-key", forged, ["bad_key"], []),
("no-alg", body.replace(b'"alg":"ed25519"', b'"alg":"ed448"'), ["receipt_form"], []),
("last-duplicate", duplicated, ["unreadable"], []),
("no-inexact", big, ["inexact_number"], []),
("measured-simulator", simulator_measured, ["provider_class"], []),
("whole-cap", provider_body(job__polls=two_to_53), [], ["provider_members"]),
("lax-small-order-r", identity_r_body, ["bad_signature"], []),
("no-canonical-spelling", seeded("1152921504606847000"), [], ["inexact_number"]),
("set-seal-only", set_of(2, head_extra={"count": 3}), ["set_items"], []),
("names-layout-only", names_short, ["provider_members"], []),
("route-unchecked", unnamed_route, ["planner_route"], []),
("choice-unchecked", another_answered, ["planner_choice", "request_provider"], ["request_provider"]),
("distance-unchecked", distance_said, ["shadow"], []),
("wasmq-unchecked", _wasmq_unchecked_job(), ["wasmq_form"], []),
("landscape-unchecked", _landscape_job(state_hash="0000000000000000"), ["landscape_form"], []),
)
for plant, raw, strict, lenient in plant_cases:
check("plant %s: strict verdict" % plant, reasons_of(raw) == strict)
check("plant %s: planted verdict" % plant, planted(plant, raw) == lenient)
check("every plant is tested", set(c[0] for c in plant_cases) == set(PLANTS_KNOWN))
# An energy-landscape job (quantum-landscape §5.4): one that holds every rule, and one
# change at each rule that can be made alone, each that rule's landscape_form.
check("landscape: a run that holds every rule", reasons_of(_landscape_job()) == [])
for name, job in (
("rule 2, its schema", _landscape_job(schema="wai.quantum.job-result/1")),
("rule 3, a seed of no form", _landscape_job(request={"program": "vars 2\nagree 0 1\nminimize\n", "seed": "1x"})),
("rule 4, no operation", _landscape_job(state=None)),
("rule 5, an empty label", _landscape_job(label="")),
("rule 6, a reference that is not cpu:reference", _landscape_job(member={"id": "gpu:x", "class": "gpu", "kernel": L_SETTLE, "parity": "reference"})),
("rule 7, demoted at a grade", _landscape_job(member={"id": "fpga:x", "class": "fpga", "kernel": L_SETTLE, "parity": "uncertified", "demoted": 1})),
("rule 8, under the floor", _landscape_job(member={"id": "fpga:x", "class": "fpga", "kernel": L_SETTLE, "parity": "bit-exact", "capacity": {"cells": 31}}, audit={"checked": [{}]})),
("rule 9, bit-exact with no audit", _landscape_job(member={"id": "fpga:x", "class": "fpga", "kernel": L_SETTLE, "parity": "bit-exact"})),
("rule 10, another replay digest", _landscape_job(replay="0" * 64)),
("rule 10, reached where the energy is not the lowest", _landscape_job(reached=True)),
("rule 13, a provider's members on a job that names none", _landscape_job(job={"id": "x", "polls": 0})),
):
check("landscape: %s" % name, reasons_of(job) == ["landscape_form"])
check("landscape: an audit with a grade that earns it", reasons_of(_landscape_job(member={"id": "fpga:x", "class": "fpga", "kernel": L_SETTLE, "parity": "bit-exact", "capacity": {"cells": 64}}, audit={"checked": [{}]})) == [])
# wasmq-unchecked runs no rule, so it states no problem; outcome and notes are no
# rules, and it still states them.
unchecked = _wasmq_unchecked_job()
PLANTS.add("wasmq-unchecked")
try:
unchecked_statement = judge(unchecked).get("wasmq")
finally:
PLANTS.discard("wasmq-unchecked")
check("plant wasmq-unchecked: strict statement",
judge(unchecked).get("wasmq") == _wasmq_statement("ok", ["rule 11: " + WASMQ_RULE_WORDS[11]]))
check("plant wasmq-unchecked: planted statement, no problem, its notes kept",
unchecked_statement == _wasmq_statement("ok"))
PLANTS.add("wasmq-unchecked")
try:
unchecked_notes = judge(_wasmq_job(fault=True)).get("wasmq")
finally:
PLANTS.discard("wasmq-unchecked")
check("plant wasmq-unchecked: notes still given", unchecked_notes == _wasmq_statement(
"fault", notes=['the host\'s unsealed status says "done"' + _WASMQ_SEALED_LINE + '"fault"']))
# Its decoding still refuses the alias, with the small-order rule off.
check("plant lax-small-order-r: y = p + 1 still refused",
planted("lax-small-order-r", alias_r_body) == ["bad_signature"])
failed = [name for name, ok in results if not ok]
for name in failed:
sys.stdout.write("FAIL %s\n" % name)
sys.stdout.write("self-test: %d checks, %d failed\n" % (len(results), len(failed)))
return 1 if failed else 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))