# WAI Extension: Energy-Landscape Jobs (`wai.quantum.landscape/1`)

Status: **Draft.** Reference: the `quantum_landscape` feature of `wai-quantum`
(`wai_quantum::quantum_landscape`), the command `wai-quantum landscape`, and
`QuantumEngine.landscape` in the browser build. Answer schema:
`wai-quantum/schemas/landscape.v1.json`. Conformance set:
`quantum-conformance/landscape/vectors.json`. Results:
`quantum-conformance/landscape/`.

Keywords **MUST**, **MUST NOT**, **SHOULD** and **MAY** are RFC 2119/8174.

## 0. What this extension adds

A job of this kind gives no circuit. It states an energy over variables of
three states and asks for a state of low energy. A machine that takes such a
job settles: each cell adds up the pull of the cells it is coupled to and moves
to the state that pull favours, with or without randomness, until the whole
comes to rest.

This text is the job, the answer and the seam between them and the device that
runs them. The same job can be run by the reference in software, by a GPU or by
an FPGA board, and its answer names what ran it, says how far that device is
held to the reference, and states its joules so that a priced figure can never
be read as a measured one.

The reference is a classical emulation. Its cells are three-state values
sampled with classical random draws. Nothing here is a quantum effect, and no
run of the reference involves any device but the machine it runs on.

## 1. The energy

```text
E(s) = − Σ_{i<j} W_ij s_i s_j − Σ_i b_i s_i + c · Σ_i |s_i|,    s_i ∈ {−1, 0, +1}
```

The couplings `W_ij` are −1, 0 or +1 and symmetric, with none on the diagonal.
The fields `b_i` are whole numbers and the cost `c ≥ 0` is a whole number, each
at most 2⁴⁰ in size on the landscape a program finally gives, after pins (§2.1)
and quantisation (§2.2). The state 0 is "left out", with its own price, and is not a
third colour: this is the spin-1 model with a single-ion term.

A state is written as text, one character a variable, in order: `+`, `-` or `0`.

Every energy on this landscape is a whole number and exact. An energy on declared
weights (§2.2) is a double.

## 2. The job

A job is one JSON request and one operation. The request:

| field | | |
|---|---|---|
| `program` | required | the program's text (§2.1) |
| `seed` | optional, default 1 | a whole number, or a string of 1 to 20 ASCII digits, so that all 64 bits survive a language whose numbers are doubles |
| `temperature` | optional | the starting temperature, over the program's own; 0 is the deterministic mode. A JSON number, which a reader MUST read to the nearest double, or a string `[0-9]+(.[0-9]+)?` of at most 40 characters, read to the nearest double: no sign, no exponent, no other form |
| `seeds` | `sweep`, `compare`, `replay` | how many seeds, from `seed` up, 1 to 100,000; default 20 |
| `temperatures` | `sweep` | 1 to 64 of the same; by default 0, 0.25, 0.5, 1, 2, 4 and 8, with the default start (§4.3) and the largest row of couplings added where they are not already there, in increasing order |
| `protocol` | optional | if given, it MUST be this protocol's name |

The operations are `run`, `sweep` (the program at each temperature, with the
same budget at each), `compare` (§6), `replay` (many seeds, one line each) and
`examples`.

A host MUST refuse a request or a program it cannot run with one plain sentence,
and name the line where a line means anything: `Line 6: ...`. Nothing in a
program is silently dropped. A refusal is not an answer and carries no receipt.

### 2.0. Limits

Every quantity a job can ask for is bounded before any of it runs, and every host
applies the same bounds, so that a job answered on one host is answered on every
host, in a page as natively. A host MUST refuse, with one plain sentence:

- a program longer than 4,194,304 bytes; more than 4096 variables; `steps` outside 1
  to 1,000,000; `restarts` outside 1 to 100,000; more than 16 `#! check` lines, or
  more than 65,536 items between them (pairs; a grid's `M²` cells; numbers; cells);
  a number in `#! check balance` above 2⁴⁰ in size; a field or cost, after pins and
  quantisation, above 2⁴⁰ in size;
- a job whose operations, counted as below before anything runs, exceed 2×10¹⁰;
- a job whose memory, counted as below before anything runs, exceeds 268,435,456
  bytes, or the host's own limit where it has a lower one (a page states its own).

With `n` variables, `P` coupled pairs, `C` items in the checks and a plan of `R`
starts of `S` sweeps, the operations of a job are `n²` (reading the couplings into
rows), plus, where `n ≤ 16`, `3ⁿ·(n + 1 + C)` (the exhaustive truth) and, for a
program with `weight`s, `3ⁿ·n²` more; plus, for each run, `(2P + n)·R·S` (the
sweeps) `+ (2P + n)·R` (each start's energy) `+ n²`, or `2n²` with weights (the
answer's energy) `+ C` (its checks). A `run` is one run; a `replay` and each row of
a `sweep` are one run a seed, a settle row one run; a `compare` is five runs a seed
of its sampling plan. The memory is the program's bytes `+ n²`, `+ 8n²` with
weights, `+ 32P + 64n`, `+ 2,359,296` (a batch of chains, §5), `+ 256` a line of a
`replay`, `+ 1,048,576`.

A host does not hold more than one batch of chains at once: at most 1,048,576 cells
and at most 4096 chains a call to a member.

### 2.1. The program: epuML

The grammar is ASCII and strict. Lines end at a line feed (U+000A), and a carriage
return just before one is dropped. `#` starts a comment, to the end of the line.
Tokens are separated by spaces (U+0020) and tabs (U+0009) and by nothing else, so
any other character, a no-break space or a byte-order mark among them, is part of
a token, and a token no statement takes is refused. Numbers:

| | grammar | |
|---|---|---|
| a variable, a count | `[0-9]+` | leading zeros allowed |
| a whole number | `-?[0-9]+` | within 64 bits; no `+` |
| a temperature | `[0-9]+(.[0-9]+)?` | at most 40 characters; no sign, no exponent |
| a weight | `-?[0-9]+(.[0-9]+)?(e-?[0-9]{1,3})?` | `E` for `e` too; at most 40 characters |

A decimal is read to the nearest double. One statement a line; the first statement
is `vars`, and the last is the run line.

```text
vars N             N variables, at most 4096
agree I J          coupling +1
oppose I J         coupling −1
couple I J W       a coupling given directly, W is −1, 0 or +1
weight I J W       a real-valued coupling, quantised to its sign (§2.2)
pin I +|-          hold I at + or −, with a field larger than anything else can outvote
lean I +|-         a field of +1 or −1 on I
field I B          a whole-number field on I
cost C             the cost c
minimize [steps=S]                   temperature 0, from every variable at 0; S defaults to 60
solve [t0=T] [restarts=R] [steps=S]  from R random starts, cooling from T to 0; R defaults to 8, S to 40
```

A reader MUST refuse an unknown statement or key, a statement after the run
line, `weight` together with `agree`, `oppose`, `couple` or `pin`, a variable
pinned both ways, and a `pin` on a variable that has a field. Setting a pair
twice is a warning, and the last one holds.

**A pin's size.** Once every line is read, each pinned variable gets the field
`±(D + B + c + 1)`, where `D` is the largest number of couplings any one variable
has (at least 1), `B` the largest `|b_i|` of every field set by `field` and `lean`,
and `c` the cost. If that is above 2⁴⁰ the program is refused, at the first `pin`'s line.

Lines beginning `#!` are comments to the language, so a program with them is
still a plain program. To a reader that knows them they say what the program
means and how to check an answer against the problem it was written for:

```text
#! title T    #! about T    #! expect works|fails
#! item NOUN  #! plus NAME  #! minus NAME  #! zero NAME
#! check different 0-1 1-2     each pair ends up in different states
#! check permutation M         an M×M grid holds one + in each row and column, and no −
#! check balance A B C …       the numbers split into two equal piles, none left out
#! check matches +-0+          the state is this one, or its mirror image
```

### 2.2. Weights

A coupling is one sign. A program that gives real-valued `weight`s is quantised,
exactly so:

1. The scale `m` is the mean of `|w|` over the pairs given a weight other than 0,
   summed in order of `i`, then `j > i`, as doubles; 1 if there are none.
2. A weight with `|w| > m/2` becomes the coupling of its sign; any other weight
   becomes 0, and is dropped.
3. Each field `b_i` becomes `round(b_i / m)` and the cost `round(c / m)` (at least
   0), dividing as doubles and rounding half away from zero. A result above 2⁴⁰ in
   size is refused: the weights are too small beside the fields and the cost.

The answer MUST say what was lost (`declared.quantised`: the scale, how many were
declared, kept and dropped, and the relative error `√(Σ(w − m·t)² / Σw²)` with `t`
each weight's coupling), give the energy of its state on the weights as declared,
and where every arrangement can be checked say whether that state is the lowest on
them (`declared`, §3). Two energies on declared weights are equal within 10⁻⁹. A program whose sizes matter does
not run on this model, and its answer says so rather than reaching a low energy
on signs that mean something else.

## 3. The answer

A `run` answers with these fields (the schema has them all):

| field | |
|---|---|
| `protocol` | `wai.quantum.landscape/1` |
| `label` | what kind of run this is, in the member's own words (§5.3) |
| `member` | what ran it: `id`, `class`, `kernel` and `parity` (§5) |
| `program_digest` | BLAKE3 of the program's bytes |
| `seed`, `mode`, `temperature`, `temperature_from`, `restarts`, `sweeps` | how it ran; `seed` is a decimal string; `mode` is `settle`, `quench` or `sample` |
| `state`, `energy` | the state of lowest energy found, and its energy from the program |
| `truth` | every arrangement checked (up to 16 variables), else null: `arrangements`, `lowest`, `at_lowest`, `at_lowest_passing` and `example` |
| `reached` | whether `energy` is `truth.lowest`; null where there is no truth |
| `declared` | for a program with `weight`s: §2.2; else null |
| `warnings` | what the reader found in the program: `code`, `line`, `text` |
| `checks` | each `#! check`, graded on `state` |
| `verdict`, `summary` | `solved`, `missed`, `failed` or `unchecked`, and the sentence that says why |
| `work` | `sweeps`, `accumulates`, `cell_updates`, `draws`, `ended`, `rests` |
| `joules` | §4.4 |
| `state_hash`, `replay` | §3.2 |

An accumulate is one read of one coupling into one cell's field, and is the unit
of work. The accumulates of a sweep are the non-zero entries of `W`, counting each
pair twice, whatever device does it.

### 3.1. The verdict

`failed` means the answer does not solve what the program states. A host MUST
report it when: the deterministic mode never came to rest; it ran out of sweeps;
the answer fails a `#! check`; the lowest states of the landscape fail the
program's check, in which case the landscape itself does not express the problem,
whatever a run returns; or the answer misses the lowest energy on declared weights.
A host MUST grade every lowest state, not just the one it found: an answer can
pass by luck where the landscape is wrong. `at_lowest_passing` holds that count.

`missed` means the truth is known and the run did not reach it. `solved` means it
did, or that a check passed where the truth is out of reach, in which case the
summary says nothing shows the energy is the lowest. `unchecked` means neither a
truth nor a check exists. A job that ran exits as success on a command line,
whatever its verdict.

### 3.2. Replay

The digest's restarts are 1 for a settle, and its sweeps are the plan's sweeps,
the `steps` asked, not the sweeps a settle ran.

`state_hash` is FNV-1a over the state's cells, each the byte `s + 1`, printed as 16
hex digits. `replay` is BLAKE3 over, in order: the protocol's name and a zero byte;
the program's length (u64, little-endian) and its bytes; the seed (u64, little-endian);
the mode's name and a zero byte; above temperature 0, the bits of the starting
temperature (IEEE 754 binary64, as a u64, little-endian); the restarts (u64,
little-endian); the sweeps (u32, little-endian); the state's cells, each the byte
`s + 1`; the energy (i64, little-endian).

The digest leaves out the member and the work. Two members that give the same
bits give the same digest, and anyone can re-run a job on any member held to bits
and compare. For a member with draws of its own (§5.1) the digest identifies the
answer and cannot be reproduced from the seed. The energy can always be recomputed
from the program.

## 4. The kernels

A host's plan is one of three, from the run line and the request's temperature `T`:

| run line | `T` | plan | starts | sweeps |
|---|---|---|---|---|
| `minimize steps=S` | none, or 0 | `settle`: from every cell at 0, stopping when it comes to rest | 1 | at most `S` |
| `minimize steps=S` | above 0 | `sample`, cooling from `T` | 8 | `S` each |
| `solve restarts=R steps=S` | 0 | `quench`: chains at temperature 0, every sweep run | `R` | `S` each |
| `solve restarts=R steps=S` | above 0 | `sample`, cooling from `T` | `R` | `S` each |
| `solve t0=T₀ …` | none | `quench` if `T₀` is 0, else `sample`, cooling from `T₀` | `R` | `S` each |
| `solve …` without `t0` | none | `sample`, cooling from the default start (§4.3) | `R` | `S` each |

A `settle` runs the settle kernel; a `quench` and a `sample` run chains through the
sampling kernel, a quench's every sweep at 0. Of many starts the host keeps the first
state of lowest energy, in order of start.

### 4.1. `wai.quantum.landscape/settle`

Each cell adds up its field, `h_i = b_i + Σ_j W_ij s_j`, and moves to +1 when
`h_i > c`, to −1 when `h_i < −c`, and to 0 otherwise. A sweep reads all the fields
from the same state, then moves all the cells. A settle ends at a fixed point (the
state did not change), a two-cycle (the state returned to the one two sweeps back;
the state reported is the one the last sweep computed) or the bound. Everything here is whole-number arithmetic: the result cannot depend
on the order a field is added in, on how many lanes a device has or on how it
splits the cells. A settle kernel MUST give the reference's bits.

A `quench` runs chains through the kernel of §4.2 at temperature 0, whose every
sweep is this one.

### 4.2. `wai.quantum.landscape/sample`

Cell by cell, in order, each reading the states the cells before it have just
taken, a cell draws its next state with the Boltzmann weights of its field:

```text
P(s) ∝ exp((h·s − c·|s|) / T),    s ∈ {−1, 0, +1}
```

Updating every cell at once from one common old state does not sample this model's
joint distribution: two coupled cells would each follow the other's old value. A
kernel that does so fails the battery of §7.2 and is not granted `statistical`. A
kernel that colours its cells properly, so that no two coupled cells move at once,
can pass it.

**The schedule.** The host gives a member every sweep's temperature. A chain of `K`
sweeps cooling from `T₀` has, at sweep `k` (from 0), `q = k / (K − 1)` and
`T_k = T₀ − T₀·q`, each operation rounded to the nearest double in that order; a
chain of one sweep is at 0. So the last sweep is at 0, where a sweep is §4.1's. The
conformance set pins the schedule's bits (§7.1).

**One draw, two cut points.** For a field `h` at a temperature `T` above 0, with
`β = 1 / T`, `l₋ = −h − c`, `l₊ = h − c` (whole numbers, exact as doubles) and `m`
the largest of `l₋`, 0 and `l₊`:

```text
w₋ = exp(β · (l₋ − m)),   w₀ = exp(β · (0 − m)),   w₊ = exp(β · (l₊ − m))
z  = (w₋ + w₀) + w₊
a  = ⌊ (w₋ / z) · 2⁵³ ⌋,    b = ⌊ ((w₋ + w₀) / z) · 2⁵³ ⌋
```

every operation a double rounded to the nearest, in the order the parentheses give,
and `exp` the function of Appendix A.

A 53-bit number `u` gives −1 if `u < a`, 0 if `u < b`, else +1. A device needs a table
of cut points for the fields it can see at each sweep's temperature and two comparisons
a cell. It needs no exponential and no floating point. The host may give it the table.

**The reference's draws.** They come from a counter, not from a state carried along:

```text
mix(x):     x ^= x >> 30;  x *= 0xBF58476D1CE4E5B9;
            x ^= x >> 27;  x *= 0x94D049BB133111EB;  x ^= x >> 31
out(s, j) = mix(s + j · 0x9E3779B97F4A7C15)          (64-bit, wrapping; j ≥ 1)
```

For a run's seed `S`, start `r` (from 0) has the chain seed `C = out(S, r + 1)`; its
cell `i` starts at `out(!C, i + 1) mod 3 − 1`; and the draw of cell `i` in sweep `k`
is `out(C, k·n + i + 1) >> 11`. Any draw can be computed alone, so chains may run
side by side and still give the reference's bits. The exponential of Appendix A uses
`+ − × ÷` alone, so it gives the same bits on every IEEE 754 platform; the conformance
set pins its values and the cut points it gives (§7.1). A device takes the table from
the host, or computes its own and is held to it.

A member MAY use draws of its own, and then its parity is `statistical` at most.

### 4.3. The default start

A `solve` with no `t0` starts at `max(1, √(2·P/n))`, where `P` is how many pairs are
coupled: the square root of the mean couplings a variable has. The answer's
`temperature_from` is `landscape`, and its words say this is the default. A starting
temperature set from the largest row of couplings is hotter than most instances
need, and at the same budget does worse on the larger instances of the published
table; the table's `start_temperature` section has the numbers.

### 4.4. How the joules are stated

`joules` is an object with `kind: "priced"`, always. It is this run's accumulates
multiplied by a rate measured elsewhere, with that rate's source named. A host:

- MUST state the figure as priced, and MUST NOT call it measured, read, or metered,
  in `line` or anywhere an answer's reader sees it. `rate_source` may say the *rate*
  was measured, and on what.
- MUST state its class in the terms of [energy-measurement](energy-measurement.md):
  `ModelBased` for the figure, which describes the board the rate was calibrated on
  and says nothing of what the machine that ran the job spent (`describes`), and
  `Estimator` for the published add's figure (`published_add`).
- MUST price temperature 0 and sampling at separate rates. Sampling costs more.
- MUST say what the rate leaves out (`left_out`): a rate that is a difference
  cancels the board's own draw, so a small job prices low, by an amount the answer
  gives from the fewest clocks the work could take.
- MUST NOT print an uncertainty it does not have.

A member with a meter puts its reading in `joules.metered`: `{ "joules_micro": …,
"class": … }`, with the class and the evidence energy-measurement asks of that class.
The reading stands beside the priced figures and does not replace them, so the two can
be compared. Where there is no meter, `metered` is null. No figure is `0` for being
unmeasured.

The reference's rates:

| | pJ per accumulate | from |
|---|---|---|
| temperature 0 | about 0.16 | one FPGA board, a dense 64-cell test design at 100 MHz, the slope of power against clock speed |
| sampling | about 0.41 | the same board: about 0.25 more, from paired readings at one temperature, 0.25, on a design that updates all its cells at once |
| for scale | about 0.03 | a published 2014 figure for one 8-bit integer add in 45 nm logic: a reference point, not a model of any processor, with no term for sampling |
| left out | about 3.1 W at every clock | the same board's own draw, at 100 MHz |

These are the numbers of one board and one meter. They are not part of the protocol:
another host MAY price at rates of its own, with their sources named.

## 5. Members

A member runs the two kernels and nothing else. The reader, the truth, the energy of the
state it returns, the checks, the verdict, the replay digest and the seal stay on the
host, and do not trust the member.

What the host gives a member: the lowered workload (`n`, the couplings as compressed
rows, the fields, the cost); for a settle, a start and a bound; for chains, each chain's
start and chain seed, and every sweep's temperature (§4.2). A host gives at most one
batch of chains at a time (§2.0).

What a member gives back, for a settle or each chain: the state, the sweeps, how it
ended, the accumulates and the draws.

A host MUST check what comes back, and refuse the answer with one plain sentence if
any of these does not hold:

- the state has the right length and every cell is −1, 0 or +1;
- for a settle: 1 to `bound` sweeps; accumulates `2P` a sweep and no draws; a fixed
  point that rests (no cell would move); a two-cycle of period exactly 2 (one sweep
  moves the state, a second returns it), after at least 2 sweeps; a bound reached
  only after `bound` sweeps;
- for a chain: every sweep of the schedule run; accumulates `2P` a sweep and `n`
  draws a sweep above 0; and the ending a fixed point exactly when the state rests.

It MUST recompute the energy from the program. So a member can be wrong about a state
only by returning a worse one, and it cannot price itself low. How many sweeps a settle
took before it came to rest can be checked only by running it again: a `bit-exact`
certificate is what vouches for it.

A member names itself `class:name`, with `class` one of the fabric's (`cpu`, `gpu`,
`fpga`) and the class it gives, and `name` lower-case letters, digits, `.`, `_` and `-`,
at most 64 characters in all. `cpu:reference` is the reference's, and no other member's.

### 5.1. Parity

A member does not state its parity: the host finds it, by running the member's kernels
on the conformance set (§7), and an answer states what the host found for the kernel the
run used (`member.kernel`, `member.parity`).

| parity | granted when |
|---|---|
| `reference` | to the host's own reference kernels, and to nothing else |
| `bit-exact` | settle: the member gives every `settle` vector exactly. Sample: it gives every `chains` vector exactly, each case's chains in one call |
| `statistical` | sample: not `bit-exact`, and every workload of the `statistical` battery passes (§7.2) |
| `uncertified` | anything else, or a member the host was asked to run by name without certifying it |

A settle kernel can earn `bit-exact` on any device. A sampling kernel can, if it uses the
reference's draws and order and the cut points of §4.2.

The fabric's placement never places an uncertified kernel. A host MAY still run one when
it is asked for that member by name, which is how a board gets its first answers; the
answer says `uncertified`, and nothing should be concluded from its state but its energy.

### 5.2. The receipt

A host seals an answer in the form of every engine result: the request, and the result
with `receipt` (`wai-quantum/schemas/receipt.v2.json`), a digest over both and an Ed25519
signature. `member` is inside what is signed. The receipt says which key vouched for the
answer and the answer says what ran it, so a board's answer sealed by the host that drove
it names the board and names the host's key. `wai-quantum verify` checks it.

### 5.3. The label

Every answer carries `label`, a sentence that says what kind of run this is. The
reference's, word for word:

> A classical emulator of the settling model of a planned energy-based processor, running on your machine.
> Energies are computed exactly. The joule line is this run's operation count priced at
> rates measured on an FPGA, with a published figure for one integer add beside it for
> scale. No photonic hardware, custom chip or quantum effect is involved in this run.

A member states its own, and MUST say what device ran the job, whether its joules are
priced or read from a meter, and that no quantum effect is involved where none is.

## 6. The comparison

`compare` runs the program on the member and on three classical methods on the same
three-state energy: simulated annealing, tabu search and greedy descent. Each has the
same budget of operations a run: the sampling run's own count, where one operation is
one coupling read, one cell updated or one move considered, whoever does it. A host
gives each row's count of runs at the target, and its best energy. A table MUST be
published as it comes out, including where a classical method leads.

The operation count is not a machine's time. It says nothing of cells that settle side
by side, and the comparison is not a claim about any device.

## 7. Conformance

`quantum-conformance/landscape/vectors.json` is rebuilt by `wai-quantum landscape
vectors`, and a test holds the file to the code. Each part pins a rule of this text, so
that an implementation written from the text alone, which computes any of these another
way, is caught.

### 7.1. Bits

- `settle`: whole workloads, starts and bounds, and the state, sweeps, ending,
  accumulates and state hash the settle kernel gives: the four recall vectors, every
  ending, a two-cycle with fields, a bound of one sweep and fields at 2⁴⁰. A settle
  kernel is `bit-exact` when it gives every one exactly.
- `exp`: the bits of Appendix A's function at the arguments the cut points use and at its
  edges, as `[x, exp(x)]` pairs of 16 hexadecimal digits.
- `schedule`: the bits of every sweep's temperature for starting temperatures and chain
  lengths that tell `T₀ − T₀·q` from other ways of writing it.
- `cells`: the two cut points for fields from −40 to 40, costs from 0 to 8 and temperatures
  from 0.25 to 25, the temperature given by its bits too.
- `chains`: whole chains from their starts and chain seeds, with every start of some runs,
  cooling from starting temperatures that include one that is not a short decimal. A
  sampling kernel is `bit-exact` when it gives every case's chains exactly, from one call.
- `jobs`: whole requests and what their answers hold, refusals included: every worked
  example at seed 1, and requests that pin a rule each (a `minimize` above temperature 0,
  a temperature given as text, a pin's size, quantised weights, the state a two-cycle
  reports, a settle's digest, leading zeros, and refusals of a `+` sign, an exponent in a
  temperature, a byte-order mark, a no-break space, no steps, too many starts, the most
  negative whole number, a weight too small and a pin too large). A host that claims this
  protocol on the reference's kernels MUST give exactly these.

### 7.2. The battery

A sampling kernel with draws of its own is held to `statistical`: workloads of two to four
cells, each with a schedule. Workload `k` runs `statistical.chains` (20,000) chains, chain
`r` with the chain seed `out(statistical.seed + k, r + 1)` and its start from that seed
(§4.2), through the workload's temperatures. The final states are counted over the `3ⁿ`
states, in the order `Σ (s_i + 1)·3ⁱ`, and held to `exact`: the Boltzmann distribution at
the schedule's last temperature above 0, carried through one deterministic sweep where the
schedule ends at 0. The statistic is Pearson's, every state expected fewer than
`statistical.pool_below` (5) times pooled into one bin; with `df` the bins less one, a
workload passes when it is at most `df + 5·√(2·df)`.

The workloads hold pairs of coupled cells next to each other, two apart and three apart,
a triangle no two colours can split, fields to 40 and a cost of 8 at a high temperature, a
small field at a low one, a schedule that ends at 0, and one that cools from 6 to 0.7. A
kernel that moves two coupled cells at once in any order of cells, that ignores the
schedule, that samples the last sweep rather than running it at 0, or whose table is wrong
for large fields fails at least one of them; the reference's own kernel, and one that
colours its cells properly, pass every one. A test holds both statements, with kernels
that are wrong in each of those ways.

## 8. What does not run on this model

The worked examples include each of these, and they fail there, on purpose: problems of three
interchangeable options (colouring a map), where the state 0 is not a third colour; problems
whose sizes matter (two equal piles), where a coupling keeps only a sign; assignment beyond a
2×2 grid written as sums; and a constraint at temperature 0, which flips between two states
and never rests. A host MUST NOT hide these, and a program marked `#! expect fails` MUST fail.

## 9. Versioning

The protocol's name carries its version. Within `/1`: fields may be added to an answer, never
removed or given another meaning; the kernels' bits, the replay digest and the conformance
set's `settle`, `chains` and `jobs` do not change. A change to any of those is `/2`, with a
new kernel name. The words of a sentence, the rates of §4.4 and the published table are not part of
the protocol, and a host's `label` is its own.

## Appendix A. The exponential

The exponential of §4.2, as the reference computes it, with every operation a double
rounded to the nearest and no operation fused. With `ln2_hi = 6.93147180369123816490e-1`,
`ln2_lo = 1.90821492927058770002e-10`, `inv_ln2 = 1.44269504088896338700`, and
`P1 … P5 = 1.66666666666666019037e-1, −2.77777777770155933842e-3,
6.61375632143793436117e-5, −1.65339022054652515390e-6, 4.13813679705723846039e-8`:

1. A NaN is returned as it is; `x > 709.782712893383973096` gives +∞, and
   `x < −745.133219101941108420` gives 0.
2. If `|x| > ½·ln 2` (`ln 2` the double nearest it): `k = ±1` when `|x| < 1.5·ln 2`, with
   the sign of `x`, and otherwise `k = trunc(inv_ln2·x + (x < 0 ? −0.5 : 0.5))`; then
   `hi = x − k·ln2_hi`, `lo = k·ln2_lo`. If `|x| < 2⁻²⁸`, the result is `1 + x`.
   Otherwise `hi = x`, `lo = 0`, `k = 0`.
3. `r = hi − lo`, `t = r·r`, `c = r − t·(P1 + t·(P2 + t·(P3 + t·(P4 + t·P5))))`.
4. If `k = 0`, the result is `1 − ((r·c)/(c − 2) − r)`. Otherwise
   `y = 1 − ((lo − (r·c)/(2 − c)) − hi)`, and the result is `y·2ᵏ`: computed as
   `y·2¹⁰²³·2^(k−1023)` when `k > 1023`, as `y·2^(k+1000)·2⁻¹⁰⁰⁰` when `k < −1021`, and as
   `y·2ᵏ` otherwise, each power of two exact.

The conformance set's `exp` part holds its values.

