Reconstruct each item’s subtotal while preserving variable-length prediction geometry.
Each subtotal must use the quantity and price at its own item coordinate. The proof combines learning this local relationship with checking that empty, short, and full collections keep the correct prediction coordinates.
Seed 31 on gpu: 5 of 5 behavioral checks met. See the measurements below.
Insights
The model learns each item’s subtotal and keeps its prediction attached to the correct coordinate. Repeated decoder queries can use aligned quantity and price inputs as well as ancestor context; they are not limited to one identical root representation for every item.
Permuting only target subtotals leaves requests and predictions unchanged but raises error against the altered labels. That isolates coordinate alignment. Separate checks verify that real items are inferred and padded coordinates are not, including empty orders. The arithmetic score is still aggregated over lengths, so a weak individual length could be hidden. This establishes local learned arithmetic and output geometry, not general cross-item reasoning or exact billing calculations.
Setup
Code
"""Reconstruct quantity times unit price at each original item coordinate.Rows range from empty to five items. Permuting only target subtotals tests localalignment; fixed output lengths and inferred flags distinguish real coordinatesfrom padding.Run this file with --help for seed, training-budget, and reporting options."""from __future__ import annotationsfrom collections.abc import Iteratorfrom functools import partialimport lightning.pytorch as litimport numpy as npimport torchfrom reporting import reportimport relflow as rfPROOF_ID ="P030"LENGTH =5
Subtotals are supervision hidden by mask=True and removed before prediction. The generator uses the exact product of quantity and unit price, with no additional target noise.
An empty order has no inferred subtotal
items:[]
This is a valid length-zero record in the proof. The fixed output schema still has five subtotal coordinates, all marked inferred=False; there is no real item for which a value should be inferred.
The control permutes only the first example’s subtotals. These are deliberately incorrect targets for the visible quantity/price pairs. The requests and model predictions stay unchanged, so worse error against these labels demonstrates that the intact result was tied to each item’s coordinate.
Synthetic data and controls
Code
def records(*, rows: int, seed: int, permute_targets: bool=False) -> Iterator[dict]: rng = np.random.default_rng(seed) target_rng = np.random.default_rng(seed +10000)for row inrange(rows): length = row % (LENGTH +1) quantity = rng.uniform(0.25, 2.0, size=length) unit_price = rng.uniform(-1.5, 1.5, size=length) subtotal = quantity * unit_priceif permute_targets and length >1: subtotal = subtotal[target_rng.permutation(length)]yield {"items": [ {"quantity": float(item_quantity), "unit_price": float(item_price), "subtotal": float(item_subtotal)}for item_quantity, item_price, item_subtotal inzip(quantity, unit_price, subtotal, strict=True) ] }def inputs(rows: list[dict]) ->list[dict]:return [ {"items": [{key: value for key, value in item.items() if key !="subtotal"} for item in row["items"]]}for row in rows ]def targets(rows: list[dict]) -> np.ndarray:return np.asarray([item["subtotal"] for row in rows for item in row["items"]])def rmse(actual: np.ndarray, predicted: np.ndarray |float) ->float:returnfloat(np.sqrt(np.mean(np.square(actual - predicted))))
Model tree
Figure 1: The branch supports up to five items with masked subtotals. Default attention summaries coexist with each target’s aligned quantity and price context.
The branch uses default attention reduction. Related inputs and their target stay together instead of being flattened into unrelated rows.
How it works
Shared coordinates expose each target’s own visible siblings to the decoder. A paired control keeps every visible order unchanged but permutes target subtotals between items. Predictions are therefore identical, while comparison against the corrupted targets should become substantially worse.
Lengths cycle from zero through five. The output uses five coordinates per row; real items must be marked inferred=True, with every padded coordinate marked inferred=False.
Training and evaluation
Code
def run(seed: int, steps: int|None, accelerator: str) ->tuple[dict, dict]: lit.seed_everything(seed, workers=True) model = rf.Model( name="order", d_model=48, n_layers=1, n_heads=4, batch_size=128, optimizer=lambda module: torch.optim.Adam(module.parameters(), lr=1e-3), items=rf.Branch( length=LENGTH, overflow="error", n_layers=2, quantity=rf.Number, unit_price=rf.Number, subtotal=rf.Number(mask=True, objective="mse"), ), ) data = rf.SyntheticDataModule( model=model, train=partial(records, rows=4096, seed=seed +1), validate=partial(records, rows=1024, seed=seed +2), seed=seed, ) trainer = lit.Trainer( accelerator=accelerator, max_steps=-1if steps isNoneelse steps, max_epochs=25, logger=False, enable_progress_bar=False, enable_model_summary=False, enable_checkpointing=False, deterministic=True, ) trainer.fit(model, datamodule=data) train =list(records(rows=4096, seed=seed +1)) test =list(records(rows=2048, seed=seed +3)) broken =list(records(rows=2048, seed=seed +3, permute_targets=True)) output = model.predict(inputs(test)).to_pylist() coordinates = [row["predictions"]["order/items/subtotal"] for row in output] lengths = [len(row["items"]) for row in test] predicted = np.asarray( [value["content"] for row, length inzip(coordinates, lengths, strict=True) for value in row[:length]] ) actual = targets(test) baseline = rmse(actual, float(targets(train).mean())) aligned = rmse(actual, predicted) / baseline broken_error = rmse(targets(broken), predicted) / baseline inferred = [[bool(value["inferred"]) for value in row] for row in coordinates] expected = [[True] * length + [False] * (LENGTH - length) for length in lengths] metrics = {"aligned_nrmse": aligned, "permuted_target_nrmse": broken_error, "baseline_rmse": baseline} checks = {"Target permutation preserves visible inputs": inputs(test) == inputs(broken),"Output retains the fixed branch length": all(len(row) == LENGTH for row in coordinates),"Inferred flags match real and padded coordinates": inferred == expected,"Aligned subtotal nRMSE <= 0.25": aligned <=0.25,"Permuting targets increases nRMSE by >= 0.50": broken_error >= aligned +0.50, }return metrics, checks
Evidence
Latest full run
Seed 31, gpu, recorded 2026-09-15T02:28:14.376443+00:00. Outcome: met.
Report accuracy separately by nonempty length and repeat three paired core seeds plus ten calibration seeds. The proof guide also flags a mismatch between its exact-product generator and the noisy-product proposal; that broader noisy task has not been established by this case.
Reproduce
Run by stable ID from the repository root:
uv run python proofs/run.py P030
Or run the self-contained script directly:
PYTHONPATH=proofs uv run python proofs/relational/repeated_subtotal_reconstruction.py
Add --accelerator gpu for CUDA or --seed 42 for another seeded experiment. --steps 2 checks execution with a short training budget; it is recorded as a smoke run.