Jump to content

The Principia Machina/TPC-PY/gen canon corpus.py

From The Invariance Itself
# -*- coding: utf-8 -*-
"""Generator for tpc/vectors/canon_corpus.json: the float form of canon(),
the shared oracle every other corpus is compared through. Expectations are
C printf "%.12g" written literally (0 for -0.0); the generator refuses to
write the corpus if tpc_strike.canon disagrees.
Run: cd tpc && python3 gen_canon_corpus.py
Recovered 2026-09-27 (BASE-GEN; record 0.18.0 section 7) from the TIDY 3
archive, tidy3_2026-09-25/gen_canon_corpus.py, SHA-256
8b59a14a09695c4a790c45fc4c5c7619eb8fb6f256687c9dfcbeb4d5a3d64abf, where it
regenerates the archived corpus byte for byte. Changed in the tree: the
writer only (write_layout, one line per case; RD-C8-2). No case changed."""
import json, os, sys
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
import tpc_strike as S


def write_layout(path, corpus, groups):
    """Write the corpus in the layout the published file carries (the
    corpus is never re-laid; the writer follows it): the meta as
    json.dumps(indent=1); each case on the lines groups(case) names, the
    keys of a line joined by ", ", the lines by ",\n   "; values as
    json.dumps writes them, a non-ASCII character as itself; UTF-8, LF."""
    def item(k, v):
        return json.dumps(k) + ": " + json.dumps(v, ensure_ascii=False)
    rows = []
    for c in corpus["cases"]:
        gs = groups(c)
        assert [k for g in gs for k in g] == list(c), c.get("id")
        rows.append("  {" + ",\n   ".join(", ".join(item(k, c[k]) for k in g)
                                           for g in gs) + "}")
    text = ('{\n "meta": '
            + json.dumps(corpus["meta"], indent=1, ensure_ascii=False).replace("\n", "\n ")
            + ',\n "cases": [\n' + ",\n".join(rows) + "\n ]\n}\n")
    with open(path, "w", encoding="utf-8", newline="\n") as f:
        f.write(text)

CASES = [
    (2.5, "2.5"), (3.0, "3"), (0.1, "0.1"), (1.0 / 3.0, "0.333333333333"),
    (0.0001, "0.0001"), (1e-05, "1e-05"), (2e-09, "2e-09"), (-2.5e-07, "-2.5e-07"),
    (123456789012.5, "123456789012"), (1e12, "1e+12"), (1.5e300, "1.5e+300"),
    (5e-324, "4.94065645841e-324"), (-0.0, "0"), (0.0, "0"), (-1e-300, "-1e-300"),
    (9.999999999995, "9.99999999999"), (1.7976931348623157e308, "1.79769313486e+308"),
]
cases = []
bad = 0
for i, (x, e) in enumerate(CASES):
    got = S.canon(x)
    if got != e:
        bad += 1
        print("MISMATCH", x, e, got)
    cases.append({"id": "float/%02d" % i, "fn": "canon", "input": {"x": x}, "expect": e})
if bad:
    sys.exit("refusing to write: %d mismatches" % bad)
corpus = {"meta": {
    "name": "tpc_canon_corpus", "version": "0.1.0", "status": "VERIFIED (both residences)",
    "module": "tpc_strike canon (float form rebuilt 2026-09-22)",
    "note": ("canon() writes a double as C printf %.12g. PHP's sprintf('%.12g') writes exponents "
             "differently ('2.0e-9' for '2e-09'), so both residences build the string from the "
             "digits of %.11e. -0.0 is written 0. Both residences MUST reproduce every expect.")},
    "cases": cases}
write_layout(os.path.join(HERE, "vectors", "canon_corpus.json"), corpus,
             lambda c: [list(c)])
print("wrote", len(cases), "canon cases; all match")