Jump to content

The Principia Machina/TPC-PY/gen probe corpus.py: Difference between revisions

From The Invariance Itself
TPC-PY source gen_probe_corpus.py (0.1.0), SHA-256 5dad4c53e217e269; conformed TPS 0.3.0; PROPOSED, not declared (CO-8)
 
m 1 revision imported
 
(2 intermediate revisions by the same user not shown)
Line 163: Line 163:
add("K35 M unit with a bar escaped", "compare",
add("K35 M unit with a bar escaped", "compare",
     cmpM(mrec(1.0, 0.1, "m|s"), mrec(1.0, 0.1, "m|s"), []), True)
     cmpM(mrec(1.0, 0.1, "m|s"), mrec(1.0, 0.1, "m|s"), []), True)
# 0.2.0 (increment 12; tpm_record_functions 0.1.0 8.2, D195.3, RD-RS-13): CP1's EQUATION type, canonical
# when tpc_form parse_form(value, "equation") returns ["OK", value]; TEXT and DECIMAL unchanged
add("K36 L EQUATION equal: MATCH", "compare",
    {"kind": "L", "original": lrec("EQUATION", "x*2=y"), "reproduction": lrec("EQUATION", "x*2=y")},
    True, "L|MATCH|x*2=y|x*2=y")
add("K37 L EQUATION x*2 against 2*x: NON-CORROBORATION (TPS 2.2.14's limit)", "compare",
    {"kind": "L", "original": lrec("EQUATION", "x*2=y"), "reproduction": lrec("EQUATION", "2*x=y")},
    True, "L|NON-CORROBORATION|x*2=y|2*x=y")
add("K38 L EQUATION not in parse_form's spelling refused", "compare",
    {"kind": "L", "original": lrec("EQUATION", "x * 2 = y"), "reproduction": lrec("EQUATION", "x*2=y")},
    True, "ERROR:CANON")
add("K39 L EQUATION that does not parse refused", "compare",
    {"kind": "L", "original": lrec("EQUATION", "x==y"), "reproduction": lrec("EQUATION", "x=y")},
    True, "ERROR:CANON")
add("K40 L EQUATION against DECIMAL refused", "compare",
    {"kind": "L", "original": lrec("EQUATION", "x=5"), "reproduction": lrec("DECIMAL", "5")},
    True, "ERROR:form")
add("K41 L EQUATION value not a string refused", "compare",
    {"kind": "L", "original": lrec("EQUATION", 5), "reproduction": lrec("EQUATION", "x=5")},
    True, "ERROR:record")
add("K42 L EQUATION with a derivative: MATCH", "compare",
    {"kind": "L", "original": lrec("EQUATION", "m*D(v,t)=-k_s*x"),
    "reproduction": lrec("EQUATION", "m*D(v,t)=-k_s*x")},
    True, "L|MATCH|m*D(v,t)=-k_s*x|m*D(v,t)=-k_s*x")


# independent SR3/SR8 check of the pinned M cases
# independent SR3/SR8 check of the pinned M cases
Line 603: Line 627:
for fn, m in sorted(counts.items()):
for fn, m in sorted(counts.items()):
     assert m >= 20, (fn, m)
     assert m >= 20, (fn, m)
out = {"corpus": "probe_corpus", "version": "0.1.0", "module": "tpc_probe 0.1.0",
out = {"corpus": "probe_corpus", "version": "0.2.0", "module": "tpc_probe 0.2.0",
       "params_fixture": "PMP-TPM 0.12.0 fleet defaults (params_fixture.FLEET)",
       "params_fixture": "PMP-TPM 0.12.0 fleet defaults (params_fixture.FLEET)",
       "counts": counts, "cases": cases}
       "counts": counts, "cases": cases}
with open(os.path.join(here, "probe_corpus.json"), "w", encoding="utf-8") as f:
with open(os.path.join(here, "probe_corpus.json"), "w", encoding="utf-8", newline="\n") as f:
     json.dump(out, f, indent=1, ensure_ascii=False)
     json.dump(out, f, indent=1, ensure_ascii=False)
     f.write("\n")
     f.write("\n")
print("probe_corpus.json", len(cases), "cases", counts)
print("probe_corpus.json", len(cases), "cases", counts)



Latest revision as of 02:11, 30 September 2026

"""gen_probe_corpus 0.1.0: builds probe_corpus.json for tpc_probe 0.1.0.
Deterministic (no random draw; every r is a fixed 32-hex string).
Expectations are computed by tpc_probe.py and pinned; hand_checked cases
are checked here first: every uniform against hashlib over the D97
netstring written out independently; the M comparisons against
tpc_strike.mm_contradicts and sr8_scale_factor called directly with the
handoff's k; LOAD on drawn graphs; the schedule's tiers at the declared
boundaries (100/101, 1000/1001); the ratio's k against the cumulative
weights computed here."""
import hashlib
import json
import math
import os
import sys

here = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, here)
from params_fixture import FLEET, fleet  # noqa: E402
from tpc_probe import run_case, uniform  # noqa: E402
from tpc_beta import canon_float  # noqa: E402

cases = []
P = FLEET
R1 = "0123456789abcdef0123456789abcdef"
R2 = "ffffffffffffffffffffffffffffffff"
R3 = "00000000000000000000000000000000"
R4 = "deadbeefdeadbeefdeadbeefdeadbeef"
R5 = "0f1e2d3c4b5a69788796a5b4c3d2e1f0"
RS = [R1, R2, R3, R4, R5]


def add(name, fn, args, hand=False, check=None):
    got = run_case(fn, args)
    if check is not None:
        assert got == check, (name, got, check)
    cases.append({"name": name, "fn": fn, "args": args, "hand_checked": hand,
                  "expected": got})


def ind_uniform(tag, r, counter):
    fields = [tag, "1", r, str(counter)]
    ns = b"".join(str(len(f.encode("utf-8"))).encode() + b":" + f.encode("utf-8") for f in fields)
    return int(hashlib.sha256(ns).hexdigest()[:13], 16) / 4503599627370496.0


# ---- uniform ---------------------------------------------------------------
i = 0
for tag in ("TPC-PROBE", "TPC-RATIO-EPOCH", "TPC-SCHEDULE-GAP", "T"):
    for r in RS[:3]:
        for counter in (0, 1):
            i += 1
            v = ind_uniform(tag, r, counter)
            add("U%02d %s %s %d" % (i, tag, r[:4], counter), "uniform",
                {"tag": tag, "r": r, "counter": counter}, True, canon_float(v))
add("U25 uppercase r refused", "uniform", {"tag": "T", "r": R1.upper(), "counter": 0}, True,
    "ERROR:r")
add("U26 r 31 chars refused", "uniform", {"tag": "T", "r": R1[:31], "counter": 0}, True, "ERROR:r")
add("U27 counter negative refused", "uniform", {"tag": "T", "r": R1, "counter": -1}, True,
    "ERROR:counter")
add("U28 empty tag refused", "uniform", {"tag": "", "r": R1, "counter": 0}, True, "ERROR:tag")
add("U29 counter boolean refused", "uniform", {"tag": "T", "r": R1, "counter": True}, True,
    "ERROR:counter")
add("U30 large counter", "uniform", {"tag": "T", "r": R4, "counter": 999999999}, True,
    canon_float(ind_uniform("T", R4, 999999999)))

# ---- compare ---------------------------------------------------------------
def lrec(t, v):
    return {"finding": {"type": t, "value": v}}


def mrec(x, u, unit="m"):
    return {"x": x, "u": u, "unit": unit}


def cmpM(o, rp, standing, k=2, mr=2):
    st = [{"x": m["x"], "u": m["u"]} if "unit" in m else m for m in standing]
    return {"kind": "M", "original": o, "reproduction": rp, "standing": st, "k": k,
            "material_ratio": mr}


add("K01 L DECIMAL equal: MATCH", "compare",
    {"kind": "L", "original": lrec("DECIMAL", "15e2"), "reproduction": lrec("DECIMAL", "15e2")},
    True, "L|MATCH|15e2|15e2")
add("K02 L DECIMAL different: NON-CORROBORATION", "compare",
    {"kind": "L", "original": lrec("DECIMAL", "15e2"), "reproduction": lrec("DECIMAL", "16e2")},
    True, "L|NON-CORROBORATION|15e2|16e2")
add("K03 L non-canonical decimal refused (1500 is 15e2)", "compare",
    {"kind": "L", "original": lrec("DECIMAL", "1500"), "reproduction": lrec("DECIMAL", "15e2")},
    True, "ERROR:CANON")
add("K04 L leading zero refused", "compare",
    {"kind": "L", "original": lrec("DECIMAL", "05"), "reproduction": lrec("DECIMAL", "5")}, True,
    "ERROR:CANON")
add("K05 L zero", "compare",
    {"kind": "L", "original": lrec("DECIMAL", "0"), "reproduction": lrec("DECIMAL", "0")}, True,
    "L|MATCH|0|0")
add("K06 L -0 refused", "compare",
    {"kind": "L", "original": lrec("DECIMAL", "-0"), "reproduction": lrec("DECIMAL", "0")}, True,
    "ERROR:CANON")
add("K07 L negative exponent", "compare",
    {"kind": "L", "original": lrec("DECIMAL", "-5e-2"), "reproduction": lrec("DECIMAL", "-5e-2")},
    True, "L|MATCH|-5e-2|-5e-2")
add("K08 L e0 refused", "compare",
    {"kind": "L", "original": lrec("DECIMAL", "5e0"), "reproduction": lrec("DECIMAL", "5")}, True,
    "ERROR:CANON")
add("K09 L TEXT equal NFC: MATCH", "compare",
    {"kind": "L", "original": lrec("TEXT", "café"), "reproduction": lrec("TEXT", "café")},
    True, "L|MATCH|café|café")
add("K10 L TEXT not NFC refused", "compare",
    {"kind": "L", "original": lrec("TEXT", "café"), "reproduction": lrec("TEXT", "café")},
    True, "ERROR:CANON")
add("K11 L TEXT with CR refused", "compare",
    {"kind": "L", "original": lrec("TEXT", "a\r\nb"), "reproduction": lrec("TEXT", "a\nb")}, True,
    "ERROR:CANON")
add("K12 L TEXT differing by a space: NON-CORROBORATION (zero tolerance)", "compare",
    {"kind": "L", "original": lrec("TEXT", "x = 1"), "reproduction": lrec("TEXT", "x=1")}, True,
    "L|NON-CORROBORATION|x = 1|x=1")
add("K13 L forms differ refused", "compare",
    {"kind": "L", "original": lrec("TEXT", "5"), "reproduction": lrec("DECIMAL", "5")}, True,
    "ERROR:form")
add("K14 L type unknown refused", "compare",
    {"kind": "L", "original": lrec("PROSE", "5"), "reproduction": lrec("PROSE", "5")}, True,
    "ERROR:record")
add("K15 kind unknown refused", "compare",
    {"kind": "X", "original": lrec("TEXT", "5"), "reproduction": lrec("TEXT", "5")}, True,
    "ERROR:kind")
add("K16 L TEXT with a bar and LF escaped in the render", "compare",
    {"kind": "L", "original": lrec("TEXT", "a|b\nc"), "reproduction": lrec("TEXT", "a|b\nc")}, True,
    "L|MATCH|a\\|b\\x0ac|a\\|b\\x0ac")
add("K17 M inside the tolerance, same u: MATCH", "compare",
    cmpM(mrec(1.0, 0.1), mrec(1.15, 0.1), [mrec(1.0, 0.1)]), True)
add("K18 M inside the tolerance, u doubled: MATCH WITH DIFFERENCE NOTED", "compare",
    cmpM(mrec(1.0, 0.1), mrec(1.15, 0.2), [mrec(1.0, 0.1)]), True)
add("K19 M inside the tolerance, u halved: MATCH WITH DIFFERENCE NOTED", "compare",
    cmpM(mrec(1.0, 0.1), mrec(1.05, 0.05), [mrec(1.0, 0.1)]), True)
add("K20 M u ratio 1.9 under the material ratio: MATCH", "compare",
    cmpM(mrec(1.0, 0.1), mrec(1.05, 0.19), [mrec(1.0, 0.1)]), True)
add("K21 M outside the tolerance: NON-CORROBORATION", "compare",
    cmpM(mrec(1.0, 0.1), mrec(1.5, 0.1), [mrec(1.0, 0.1)]), True)
add("K22 M at the bound exactly: not a contradiction (strict >)", "compare",
    cmpM(mrec(0.0, 3.0), mrec(10.0, 4.0), [mrec(0.0, 3.0)]), True)
add("K23 M SR8 scaling widens the bound (two standing records disagree)", "compare",
    cmpM(mrec(1.0, 0.1), mrec(1.5, 0.1), [mrec(1.0, 0.1), mrec(1.4, 0.1)]), True)
add("K24 M no standing records: S 1", "compare",
    cmpM(mrec(1.0, 0.1), mrec(1.5, 0.1), []), True)
add("K25 M UNIT difference refused", "compare",
    cmpM(mrec(1.0, 0.1, "m"), mrec(100.0, 10.0, "cm"), [mrec(1.0, 0.1)]), True, "ERROR:UNIT")
add("K26 M u 0 refused", "compare", cmpM(mrec(1.0, 0.0), mrec(1.0, 0.1), []), True,
    "ERROR:record")
add("K27 M k 0 refused", "compare", cmpM(mrec(1.0, 0.1), mrec(1.0, 0.1), [], 0), True, "ERROR:k")
add("K28 M material ratio below 1 refused", "compare",
    cmpM(mrec(1.0, 0.1), mrec(1.0, 0.1), [], 2, 0.5), True, "ERROR:material_ratio")
add("K29 M standing record malformed refused", "compare",
    cmpM(mrec(1.0, 0.1), mrec(1.0, 0.1), [{"x": 1}]), True, "ERROR:standing")
add("K30 M material ratio 1: every difference noted", "compare",
    cmpM(mrec(1.0, 0.1), mrec(1.0, 0.1000001), [], 2, 1), True)
add("K31 M k 3", "compare", cmpM(mrec(1.0, 0.1), mrec(1.4, 0.1), [], 3), True)
add("K32 M negative values", "compare", cmpM(mrec(-2.5, 0.5), mrec(-2.0, 0.5), []), True)
add("K33 M an L record given as M refused", "compare",
    cmpM(lrec("TEXT", "x"), mrec(1.0, 0.1), []), True, "ERROR:record")
add("K34 M large standing set with an outlier excluded by SR8's cutoff", "compare",
    cmpM(mrec(1.0, 0.1), mrec(1.3, 0.1),
         [mrec(1.0, 0.1), mrec(1.2, 0.1), mrec(0.9, 0.1), mrec(1.1, 50.0)]), True)
add("K35 M unit with a bar escaped", "compare",
    cmpM(mrec(1.0, 0.1, "m|s"), mrec(1.0, 0.1, "m|s"), []), True)
# 0.2.0 (increment 12; tpm_record_functions 0.1.0 8.2, D195.3, RD-RS-13): CP1's EQUATION type, canonical
# when tpc_form parse_form(value, "equation") returns ["OK", value]; TEXT and DECIMAL unchanged
add("K36 L EQUATION equal: MATCH", "compare",
    {"kind": "L", "original": lrec("EQUATION", "x*2=y"), "reproduction": lrec("EQUATION", "x*2=y")},
    True, "L|MATCH|x*2=y|x*2=y")
add("K37 L EQUATION x*2 against 2*x: NON-CORROBORATION (TPS 2.2.14's limit)", "compare",
    {"kind": "L", "original": lrec("EQUATION", "x*2=y"), "reproduction": lrec("EQUATION", "2*x=y")},
    True, "L|NON-CORROBORATION|x*2=y|2*x=y")
add("K38 L EQUATION not in parse_form's spelling refused", "compare",
    {"kind": "L", "original": lrec("EQUATION", "x * 2 = y"), "reproduction": lrec("EQUATION", "x*2=y")},
    True, "ERROR:CANON")
add("K39 L EQUATION that does not parse refused", "compare",
    {"kind": "L", "original": lrec("EQUATION", "x==y"), "reproduction": lrec("EQUATION", "x=y")},
    True, "ERROR:CANON")
add("K40 L EQUATION against DECIMAL refused", "compare",
    {"kind": "L", "original": lrec("EQUATION", "x=5"), "reproduction": lrec("DECIMAL", "5")},
    True, "ERROR:form")
add("K41 L EQUATION value not a string refused", "compare",
    {"kind": "L", "original": lrec("EQUATION", 5), "reproduction": lrec("EQUATION", "x=5")},
    True, "ERROR:record")
add("K42 L EQUATION with a derivative: MATCH", "compare",
    {"kind": "L", "original": lrec("EQUATION", "m*D(v,t)=-k_s*x"),
     "reproduction": lrec("EQUATION", "m*D(v,t)=-k_s*x")},
    True, "L|MATCH|m*D(v,t)=-k_s*x|m*D(v,t)=-k_s*x")

# independent SR3/SR8 check of the pinned M cases
from tpc_strike import mm_contradicts, sr8_scale_factor  # noqa: E402
checked_m = 0
for c in cases:
    if c["fn"] == "compare" and c["args"]["kind"] == "M" and not c["expected"].startswith("ERROR"):
        a = c["args"]
        S = sr8_scale_factor([{"x": m["x"], "u": m["u"]} for m in a["standing"]])
        contra = mm_contradicts(a["original"]["x"], a["original"]["u"], a["reproduction"]["x"],
                                a["reproduction"]["u"], a["k"], S)
        out = c["expected"].split("|")[1]
        assert (out == "NON-CORROBORATION") == contra, c["name"]
        assert c["expected"].split("|")[6] == canon_float(S), c["name"]
        checked_m += 1
assert checked_m >= 12, checked_m

# ---- load / el -------------------------------------------------------------
def rec(cites=(), assumptions=(), standing=True):
    return {"cites": list(cites), "assumptions": list(assumptions), "standing": standing}


G1 = {"a": rec(["b"]), "b": rec(["c"], standing=False), "c": rec(), "d": rec([], ["c"]),
      "e": rec(["a"]), "f": rec()}
add("D01 LOAD through a non-standing intermediate", "load", {"records": G1, "r": "c"}, True,
    "3|a,d,e")
add("D02 LOAD of a leaf that nothing cites", "load", {"records": G1, "r": "f"}, True, "0|")
add("D03 LOAD of a: e only", "load", {"records": G1, "r": "a"}, True, "1|e")
add("D04 the record itself is not counted", "load", {"records": {"a": rec(["a"])}, "r": "a"},
    True, "0|")
add("D05 a cycle does not loop", "load",
    {"records": {"a": rec(["b"]), "b": rec(["a"]), "c": rec(["a"])}, "r": "b"}, True, "2|a,c")
add("D06 a TFK identifier is ignored", "load",
    {"records": {"a": rec([], ["TFK-1", "b"]), "b": rec()}, "r": "b"}, True, "1|a")
add("D07 non-standing reachers are not counted", "load",
    {"records": {"a": rec(["b"], standing=False), "b": rec()}, "r": "b"}, True, "0|")
add("D08 order by code point", "load",
    {"records": {"RR-10": rec(["x"]), "RR-2": rec(["x"]), "RR-1": rec(["x"]), "x": rec()},
     "r": "x"}, True, "3|RR-1,RR-10,RR-2")
add("D09 chain of five", "load",
    {"records": dict({"r%d" % i: rec(["r%d" % (i + 1)]) for i in range(5)}, r5=rec()),
     "r": "r5"}, True, "5|r0,r1,r2,r3,r4")
add("D10 diamond", "load",
    {"records": {"a": rec(["b", "c"]), "b": rec(["d"]), "c": rec(["d"]), "d": rec()}, "r": "d"},
    True, "3|a,b,c")
add("D11 unknown r refused", "load", {"records": G1, "r": "zz"}, True, "ERROR:r")
add("D12 records not an object refused", "load", {"records": [], "r": "a"}, True,
    "ERROR:records")
add("D13 standing not boolean refused", "load",
    {"records": {"a": {"cites": [], "assumptions": [], "standing": 1}}, "r": "a"}, True,
    "ERROR:records")
add("D14 cites not a list refused", "load",
    {"records": {"a": {"cites": "b", "assumptions": [], "standing": True}}, "r": "a"}, True,
    "ERROR:records")
add("D15 empty id in cites refused", "load",
    {"records": {"a": rec([""])}, "r": "a"}, True, "ERROR:records")
add("D16 missing field refused", "load", {"records": {"a": {"cites": []}}, "r": "a"}, True,
    "ERROR:records")
for i in range(6):
    g = {"n%d" % j: rec(["n%d" % ((j * 3 + i) % 8)], ["n%d" % ((j + 1) % 8)], j % 3 != 1)
         for j in range(8)}
    add("D%02d sweep graph %d" % (17 + i, i), "load", {"records": g, "r": "n%d" % i}, False)
add("D23 r with a bar", "load", {"records": {"a|b": rec(), "c": rec(["a|b"])}, "r": "a|b"}, True,
    "1|c")

add("X01 EL = (1 - 0.84) x 5", "el", {"e_lo": 0.84, "load": 5}, True,
    canon_float((1 - 0.84) * 5))
add("X02 thin file's e_lo 0.025 with LOAD 10", "el", {"e_lo": 0.025, "load": 10}, True,
    canon_float(0.975 * 10))
add("X03 LOAD 0: EL 0", "el", {"e_lo": 0.5, "load": 0}, True, "0")
add("X04 e_lo 1: EL 0", "el", {"e_lo": 1, "load": 7}, True, "0")
add("X05 e_lo 0: EL LOAD", "el", {"e_lo": 0, "load": 7}, True, "7")
for i in range(14):
    add("X%02d sweep" % (6 + i), "el", {"e_lo": 0.07 * i, "load": 3 * i + 1}, False)
add("X20 e_lo above 1 refused", "el", {"e_lo": 1.5, "load": 1}, True, "ERROR:e_lo")
add("X21 load negative refused", "el", {"e_lo": 0.5, "load": -1}, True, "ERROR:load")
add("X22 load a float refused", "el", {"e_lo": 0.5, "load": 2.0}, True, "ERROR:load")

# ---- ratio_step ------------------------------------------------------------
def rstate(k, remaining):
    return {"k": k, "remaining": remaining}


def check_ratio(name, r):
    u0 = ind_uniform("TPC-RATIO-EPOCH", r, 0)
    u1 = ind_uniform("TPC-RATIO-K", r, 0)
    length = min(100, 50 + int(math.floor(u0 * 51)))
    cum = 0.0
    kset = P["PARROT RATIO"]["set"]
    k = kset[-1]
    for kv, w in zip(kset, P["PARROT RATIO"]["weights"]):
        cum += w
        if u1 < cum:
            k = kv
            break
    return "%s|%d|true|%d" % (canon_float(k), length - 1, length)


for i, r in enumerate(RS):
    add("R%02d first epoch with r %s" % (i + 1, r[:4]), "ratio",
        {"state": rstate(None, 0), "r": r, "params": P}, True, check_ratio("", r))
add("R06 inside an epoch: remaining - 1", "ratio", {"state": rstate(0.5, 10), "r": R1,
                                                    "params": P}, True, "0.5|9|false|-")
add("R07 the last block of an epoch", "ratio", {"state": rstate(0.5, 1), "r": R1, "params": P},
    True, "0.5|0|false|-")
add("R08 remaining 0 redraws", "ratio", {"state": rstate(0.5, 0), "r": R1, "params": P}, True,
    check_ratio("", R1))
add("R09 epoch bounds 1..1: every block redraws", "ratio",
    {"state": rstate(None, 0), "r": R1,
     "params": fleet({"PARROT RATIO": {"set": [0.5, 1 / 3], "weights": [0.5, 0.5], "epoch": [1, 1]}})},
    True)
add("R10 a one-member set", "ratio",
    {"state": rstate(None, 0), "r": R2,
     "params": fleet({"PARROT RATIO": {"set": [0.25], "weights": [1], "epoch": [50, 100]}})}, True,
    "0.25|%d|true|%d" % (min(100, 50 + int(ind_uniform("TPC-RATIO-EPOCH", R2, 0) * 51)) - 1,
                         min(100, 50 + int(ind_uniform("TPC-RATIO-EPOCH", R2, 0) * 51))))
add("R11 weights not summing to 1 refused", "ratio",
    {"state": rstate(None, 0), "r": R1,
     "params": fleet({"PARROT RATIO": {"set": [0.5, 1 / 3], "weights": [0.5, 0.4], "epoch": [50, 100]}})},
    True, "ERROR:params:PARROT RATIO")
add("R12 set and weights of different length refused", "ratio",
    {"state": rstate(None, 0), "r": R1,
     "params": fleet({"PARROT RATIO": {"set": [0.5], "weights": [0.5, 0.5], "epoch": [50, 100]}})},
    True, "ERROR:params:PARROT RATIO")
add("R13 epoch lo above hi refused", "ratio",
    {"state": rstate(None, 0), "r": R1,
     "params": fleet({"PARROT RATIO": {"set": [0.5], "weights": [1], "epoch": [100, 50]}})}, True,
    "ERROR:params:PARROT RATIO")
add("R14 k 0 in the set refused", "ratio",
    {"state": rstate(None, 0), "r": R1,
     "params": fleet({"PARROT RATIO": {"set": [0], "weights": [1], "epoch": [50, 100]}})}, True,
    "ERROR:params:PARROT RATIO")
add("R15 state k negative refused", "ratio", {"state": rstate(-1, 5), "r": R1, "params": P}, True,
    "ERROR:state")
add("R16 remaining negative refused", "ratio", {"state": rstate(0.5, -1), "r": R1, "params": P},
    True, "ERROR:state")
add("R17 r malformed refused", "ratio", {"state": rstate(0.5, 5), "r": "zz", "params": P}, True,
    "ERROR:r")
add("R18 PARROT RATIO missing refused", "ratio",
    {"state": rstate(None, 0), "r": R1, "params": {k: v for k, v in P.items() if k != "PARROT RATIO"}},
    True, "ERROR:params:PARROT RATIO")
add("R19 weights with a zero", "ratio",
    {"state": rstate(None, 0), "r": R3,
     "params": fleet({"PARROT RATIO": {"set": [0.5, 1 / 3], "weights": [0, 1], "epoch": [50, 100]}})},
    True)
add("R20 state extra key refused", "ratio",
    {"state": {"k": 0.5, "remaining": 5, "x": 1}, "r": R1, "params": P}, True, "ERROR:state")
add("R21 a tiny second weight", "ratio",
    {"state": rstate(None, 0), "r": R2,
     "params": fleet({"PARROT RATIO": {"set": [0.5, 1 / 7], "weights": [0.999999999, 0.000000001],
                                       "epoch": [50, 100]}})}, True)

# ---- schedule_step ---------------------------------------------------------
def sstate(blocks, burst=None, gap=None):
    return {"blocks": blocks, "burst": burst, "gap": gap}


add("S01 block 1: tier 1, 1 in 5", "schedule", {"state": sstate(0), "r": R1, "params": P}, True,
    "1|1|5|false|-|-")
add("S02 block 100: tier 1", "schedule", {"state": sstate(99), "r": R1, "params": P}, True,
    "100|1|5|false|-|-")
add("S03 block 101: tier 2, 1 in 10", "schedule", {"state": sstate(100), "r": R1, "params": P},
    True, "101|2|10|false|-|-")
add("S04 block 1000: tier 2", "schedule", {"state": sstate(999), "r": R1, "params": P}, True,
    "1000|2|10|false|-|-")
G0 = min(500, 200 + int(math.floor(ind_uniform("TPC-SCHEDULE-GAP", R1, 0) * 301)))
add("S05 block 1001: tier 3, the first gap drawn", "schedule",
    {"state": sstate(1000), "r": R1, "params": P}, True, "1001|3|20|false|-|%d" % (G0 - 1))
add("S06 inside the gap", "schedule", {"state": sstate(1200, None, 100), "r": R1, "params": P},
    True, "1201|3|20|false|-|99")
BR = P["CANARY SCHEDULE"]["burst_rates"][min(1, int(math.floor(ind_uniform("TPC-SCHEDULE-RATE", R1, 0) * 2)))]
DU = min(200, 50 + int(math.floor(ind_uniform("TPC-SCHEDULE-DURATION", R1, 0) * 151)))
add("S07 the gap ends: a burst starts on this block", "schedule",
    {"state": sstate(1200, None, 1), "r": R1, "params": P}, True,
    "1201|3|%d|true|%d/%d|-" % (BR, BR, DU - 1))
add("S08 inside a burst at 1 in 5", "schedule",
    {"state": sstate(1300, {"rate": 5, "remaining": 40}), "r": R1, "params": P}, True,
    "1301|3|5|true|5/39|-")
add("S09 inside a burst at 1 in 10", "schedule",
    {"state": sstate(1300, {"rate": 10, "remaining": 2}), "r": R1, "params": P}, True,
    "1301|3|10|true|10/1|-")
add("S10 the burst's last block: the next gap drawn", "schedule",
    {"state": sstate(1300, {"rate": 5, "remaining": 1}), "r": R1, "params": P}, True,
    "1301|3|5|true|-|%d" % G0)
for i, r in enumerate(RS[1:]):
    add("S%02d first gap with r %s" % (11 + i, r[:4]), "schedule",
        {"state": sstate(1000), "r": r, "params": P}, False)
for i, r in enumerate(RS[1:]):
    add("S%02d burst start with r %s" % (15 + i, r[:4]), "schedule",
        {"state": sstate(1500, None, 1), "r": r, "params": P}, False)
add("S19 a burst of duration 1 ends on its first block", "schedule",
    {"state": sstate(1500, None, 1), "r": R1,
     "params": fleet({"CANARY SCHEDULE": dict(P["CANARY SCHEDULE"], burst_duration=[1, 1])})}, True)
add("S20 a two-tier schedule: bursts from block 101", "schedule",
    {"state": sstate(100), "r": R1,
     "params": fleet({"CANARY SCHEDULE": {"tiers": [[1, 100, 5], [101, None, 20]], "burst_rates": [5],
                                          "burst_duration": [50, 200], "burst_gap": [200, 500]}})},
    True)
add("S21 tiers not contiguous refused", "schedule",
    {"state": sstate(0), "r": R1,
     "params": fleet({"CANARY SCHEDULE": {"tiers": [[1, 100, 5], [102, None, 20]], "burst_rates": [5],
                                          "burst_duration": [50, 200], "burst_gap": [200, 500]}})},
    True, "ERROR:params:CANARY SCHEDULE")
add("S22 last tier with an upper bound refused", "schedule",
    {"state": sstate(0), "r": R1,
     "params": fleet({"CANARY SCHEDULE": {"tiers": [[1, 100, 5], [101, 1000, 20]], "burst_rates": [5],
                                          "burst_duration": [50, 200], "burst_gap": [200, 500]}})},
    True, "ERROR:params:CANARY SCHEDULE")
add("S23 burst and gap both set refused", "schedule",
    {"state": sstate(1300, {"rate": 5, "remaining": 3}, 5), "r": R1, "params": P}, True,
    "ERROR:state")
add("S24 burst remaining 0 refused", "schedule",
    {"state": sstate(1300, {"rate": 5, "remaining": 0}), "r": R1, "params": P}, True,
    "ERROR:state")
add("S25 blocks negative refused", "schedule", {"state": sstate(-1), "r": R1, "params": P}, True,
    "ERROR:state")
add("S26 empty burst_rates refused", "schedule",
    {"state": sstate(0), "r": R1,
     "params": fleet({"CANARY SCHEDULE": dict(P["CANARY SCHEDULE"], burst_rates=[])})}, True,
    "ERROR:params:CANARY SCHEDULE")
add("S27 tier 1 in a varied schedule: 1 in 3", "schedule",
    {"state": sstate(5), "r": R1,
     "params": fleet({"CANARY SCHEDULE": dict(P["CANARY SCHEDULE"], tiers=[[1, 100, 3], [101, 1000, 10], [1001, None, 20]])})},
    True, "6|1|3|false|-|-")

# ---- probe_draw ------------------------------------------------------------
def sch(tier=1, rate=5, burst=False):
    return {"tier": tier, "rate": rate, "burst": burst}


def rset(f, p=0):
    return {"in_force": f, "passes": p}


def check_probe(sched, k, reset, own, r, params=P):
    rate = params["RESET RULE"] if reset["in_force"] else sched["rate"]
    u0 = ind_uniform("TPC-PROBE", r, 0)
    probe = u0 < 1.0 / rate
    kind = "-"
    if probe:
        if ind_uniform("TPC-PROBE", r, 1) < k / (1 + k):
            if ind_uniform("TPC-PROBE", r, 2) < params["CONSISTENCY SHARE"] and own:
                kind = "CONSISTENCY PARROT"
            else:
                kind = "CORROBORATION PARROT"
        else:
            kind = "CANARY"
    return "%s|%s|%d|%s|%d|%s|%s" % ("true" if probe else "false", kind, sched["tier"],
                                     "true" if sched["burst"] else "false", rate, canon_float(k),
                                     "true" if reset["in_force"] else "false")


n = 0
for r in RS:
    for own in (True, False):
        n += 1
        args = {"schedule": sch(), "ratio": 1 / 3, "reset": rset(False), "has_own_record": own,
                "r": r, "params": P}
        add("B%02d draw r %s own %s" % (n, r[:4], own), "probe", args, True,
            check_probe(sch(), 1 / 3, rset(False), own, r))
add("B11 reset in force: rate 5 whatever the tier", "probe",
    {"schedule": sch(3, 20, False), "ratio": 1 / 3, "reset": rset(True, 1), "has_own_record": True,
     "r": R1, "params": P}, True, check_probe(sch(3, 20, False), 1 / 3, rset(True, 1), True, R1))
add("B12 tier 3 no reset: rate 20", "probe",
    {"schedule": sch(3, 20, False), "ratio": 1 / 3, "reset": rset(False), "has_own_record": True,
     "r": R1, "params": P}, True, check_probe(sch(3, 20, False), 1 / 3, rset(False), True, R1))
add("B13 burst rate 10", "probe",
    {"schedule": sch(3, 10, True), "ratio": 0.5, "reset": rset(False), "has_own_record": True,
     "r": R2, "params": P}, True, check_probe(sch(3, 10, True), 0.5, rset(False), True, R2))
add("B14 rate 1: every block a probe", "probe",
    {"schedule": sch(1, 1, False), "ratio": 1 / 7, "reset": rset(False), "has_own_record": True,
     "r": R3, "params": P}, True, check_probe(sch(1, 1, False), 1 / 7, rset(False), True, R3))
add("B15 rate 1 with k 1000: nearly every probe a parrot", "probe",
    {"schedule": sch(1, 1, False), "ratio": 1000, "reset": rset(False), "has_own_record": False,
     "r": R4, "params": P}, True, check_probe(sch(1, 1, False), 1000, rset(False), False, R4))
add("B16 CONSISTENCY SHARE 1: every parrot a consistency parrot with an own record", "probe",
    {"schedule": sch(1, 1, False), "ratio": 1000, "reset": rset(False), "has_own_record": True,
     "r": R4, "params": fleet({"CONSISTENCY SHARE": 1})}, True,
    check_probe(sch(1, 1, False), 1000, rset(False), True, R4, fleet({"CONSISTENCY SHARE": 1})))
add("B17 CONSISTENCY SHARE 1 without an own record: corroboration", "probe",
    {"schedule": sch(1, 1, False), "ratio": 1000, "reset": rset(False), "has_own_record": False,
     "r": R4, "params": fleet({"CONSISTENCY SHARE": 1})}, True,
    check_probe(sch(1, 1, False), 1000, rset(False), False, R4, fleet({"CONSISTENCY SHARE": 1})))
add("B18 RESET RULE 2", "probe",
    {"schedule": sch(2, 10, False), "ratio": 1 / 3, "reset": rset(True), "has_own_record": True,
     "r": R5, "params": fleet({"RESET RULE": 2})}, True,
    check_probe(sch(2, 10, False), 1 / 3, rset(True), True, R5, fleet({"RESET RULE": 2})))
add("B19 ratio 0 refused", "probe",
    {"schedule": sch(), "ratio": 0, "reset": rset(False), "has_own_record": True, "r": R1,
     "params": P}, True, "ERROR:ratio")
add("B20 schedule rate 0 refused", "probe",
    {"schedule": sch(1, 0), "ratio": 0.5, "reset": rset(False), "has_own_record": True, "r": R1,
     "params": P}, True, "ERROR:schedule")
add("B21 has_own_record not boolean refused", "probe",
    {"schedule": sch(), "ratio": 0.5, "reset": rset(False), "has_own_record": 1, "r": R1,
     "params": P}, True, "ERROR:has_own_record")
add("B22 CONSISTENCY SHARE above 1 refused", "probe",
    {"schedule": sch(), "ratio": 0.5, "reset": rset(False), "has_own_record": True, "r": R1,
     "params": fleet({"CONSISTENCY SHARE": 1.5})}, True, "ERROR:params:CONSISTENCY SHARE")
add("B23 reset malformed refused", "probe",
    {"schedule": sch(), "ratio": 0.5, "reset": {"in_force": True}, "has_own_record": True, "r": R1,
     "params": P}, True, "ERROR:reset")

# ---- probe_step ------------------------------------------------------------
def pstate(blocks=0, burst=None, gap=None, k=None, rem=0, reset=False, passes=0):
    return {"schedule": sstate(blocks, burst, gap), "ratio": rstate(k, rem),
            "reset": rset(reset, passes)}


n = 0
for r in RS:
    n += 1
    add("T%02d first block, r %s" % (n, r[:4]), "step",
        {"state": pstate(), "r": r, "params": P, "has_own_record": True}, False)
for r in RS:
    n += 1
    add("T%02d block 1001 in a reset, r %s" % (n, r[:4]), "step",
        {"state": pstate(1000, None, None, 0.5, 7, True, 1), "r": r, "params": P,
         "has_own_record": False}, False)
for r in RS:
    n += 1
    add("T%02d inside a burst, r %s" % (n, r[:4]), "step",
        {"state": pstate(2000, {"rate": 5, "remaining": 3}, None, 1 / 7, 0), "r": r, "params": P,
         "has_own_record": True}, False)
add("T16 the gap's last block", "step",
    {"state": pstate(2000, None, 1, 0.2, 3), "r": R1, "params": P, "has_own_record": True}, False)
add("T17 tier 2", "step", {"state": pstate(500, None, None, 0.5, 20), "r": R2, "params": P,
                          "has_own_record": True}, False)
add("T18 state missing ratio refused", "step",
    {"state": {"schedule": sstate(0), "reset": rset(False)}, "r": R1, "params": P,
     "has_own_record": True}, True, "ERROR:state")
add("T19 ratio malformed refused", "step",
    {"state": {"schedule": sstate(0), "ratio": {"k": 0.5}, "reset": rset(False)}, "r": R1,
     "params": P, "has_own_record": True}, True, "ERROR:state")
add("T20 r malformed refused", "step", {"state": pstate(), "r": "x", "params": P,
                                        "has_own_record": True}, True, "ERROR:r")
add("T21 has_own_record malformed refused", "step",
    {"state": pstate(), "r": R1, "params": P, "has_own_record": "yes"}, True,
    "ERROR:has_own_record")

# ---- reset_update ----------------------------------------------------------
def ru(f, p, ev, st, params=P):
    return {"reset": rset(f, p), "event": ev, "account_state": st, "params": params}


add("V01 a non-corroboration starts the reset", "reset", ru(False, 0, "NON-CORROBORATION", "YELLOW"),
    True, "true|0|-")
add("V02 a second non-corroboration restarts the count", "reset",
    ru(True, 2, "NON-CORROBORATION", "ORANGE"), True, "true|0|-")
add("V03 YELLOW: the next canary pass ends it", "reset", ru(True, 0, "CANARY PASS", "YELLOW"),
    True, "false|0|PASS")
add("V04 GREEN ends as YELLOW (PD-SC-18)", "reset", ru(True, 0, "CANARY PASS", "GREEN"), True,
    "false|0|PASS")
add("V05 ORANGE: first pass", "reset", ru(True, 0, "CANARY PASS", "ORANGE"), True, "true|1|-")
add("V06 ORANGE: second pass", "reset", ru(True, 1, "CANARY PASS", "ORANGE"), True, "true|2|-")
add("V07 ORANGE: the third consecutive pass ends it", "reset", ru(True, 2, "CANARY PASS", "ORANGE"),
    True, "false|0|PASSES")
add("V08 SUSPENDED: passes never end it", "reset", ru(True, 9, "CANARY PASS", "SUSPENDED"), True,
    "true|10|-")
add("V09 SUSPENDED: the audit finding ends it", "reset", ru(True, 9, "AUDIT FINDING", "SUSPENDED"),
    True, "false|0|AUDIT")
add("V10 an audit finding under ORANGE changes nothing", "reset",
    ru(True, 1, "AUDIT FINDING", "ORANGE"), True, "true|1|-")
add("V11 a parrot pass changes nothing", "reset", ru(True, 1, "PARROT PASS", "YELLOW"), True,
    "true|1|-")
add("V12 a canary failure is CR6's case", "reset", ru(True, 1, "CANARY FAIL", "YELLOW"), True,
    "false|0|CR6")
add("V13 no reset: a pass changes nothing", "reset", ru(False, 0, "CANARY PASS", "GREEN"), True,
    "false|0|-")
add("V14 no reset: a canary failure", "reset", ru(False, 0, "CANARY FAIL", "GREEN"), True,
    "false|0|-")
add("V15 ORANGE PASSES 1", "reset", ru(True, 0, "CANARY PASS", "ORANGE", fleet({"ORANGE PASSES": 1})),
    True, "false|0|PASSES")
add("V16 ORANGE PASSES 5: the fourth pass", "reset",
    ru(True, 3, "CANARY PASS", "ORANGE", fleet({"ORANGE PASSES": 5})), True, "true|4|-")
add("V17 event unknown refused", "reset", ru(True, 0, "PARROT FAIL", "YELLOW"), True,
    "ERROR:event")
add("V18 state unknown refused", "reset", ru(True, 0, "CANARY PASS", "RED"), True,
    "ERROR:account_state")
add("V19 passes negative refused", "reset", ru(True, -1, "CANARY PASS", "YELLOW"), True,
    "ERROR:reset")
add("V20 ORANGE PASSES missing refused", "reset",
    ru(True, 0, "CANARY PASS", "ORANGE", {k: v for k, v in P.items() if k != "ORANGE PASSES"}), True,
    "ERROR:params:ORANGE PASSES")
add("V21 in_force not boolean refused", "reset",
    {"reset": {"in_force": 1, "passes": 0}, "event": "CANARY PASS", "account_state": "YELLOW",
     "params": P}, True, "ERROR:reset")

# ---- historical_view -------------------------------------------------------
REVS = [{"rev": 1, "allocated": ["a", "b"]}, {"rev": 3, "allocated": ["c"]},
        {"rev": 7, "allocated": ["d", "e"]}, {"rev": 9, "allocated": []},
        {"rev": 12, "allocated": ["f"]}]
add("H01 target in the third revision: the second is the view", "view",
    {"revisions": REVS, "target": "d"}, True, "3|a,b,c")
add("H02 a record allocated beside the target is absent too", "view",
    {"revisions": REVS, "target": "e"}, True, "3|a,b,c")
add("H03 target in the first revision: no view", "view", {"revisions": REVS, "target": "a"}, True,
    "-|")
add("H04 target after an empty revision: the empty revision is the view", "view",
    {"revisions": REVS, "target": "f"}, True, "9|a,b,c,d,e")
add("H05 target c", "view", {"revisions": REVS, "target": "c"}, True, "1|a,b")
add("H06 single revision", "view", {"revisions": [{"rev": 5, "allocated": ["x"]}], "target": "x"},
    True, "-|")
add("H07 unknown target refused", "view", {"revisions": REVS, "target": "zz"}, True,
    "ERROR:target")
add("H08 revisions not ascending refused", "view",
    {"revisions": [{"rev": 3, "allocated": ["a"]}, {"rev": 2, "allocated": ["b"]}], "target": "b"},
    True, "ERROR:revisions")
add("H09 duplicate revision refused", "view",
    {"revisions": [{"rev": 3, "allocated": ["a"]}, {"rev": 3, "allocated": ["b"]}], "target": "b"},
    True, "ERROR:revisions")
add("H10 a record allocated twice refused", "view",
    {"revisions": [{"rev": 3, "allocated": ["a"]}, {"rev": 4, "allocated": ["a"]}], "target": "a"},
    True, "ERROR:revisions")
add("H11 empty target refused", "view", {"revisions": REVS, "target": ""}, True,
    "ERROR:revisions")
add("H12 allocated not a list refused", "view",
    {"revisions": [{"rev": 3, "allocated": "a"}], "target": "a"}, True, "ERROR:revisions")
add("H13 rev negative refused", "view", {"revisions": [{"rev": -1, "allocated": ["a"]}],
                                         "target": "a"}, True, "ERROR:revisions")
add("H14 empty revisions refused", "view", {"revisions": [], "target": "a"}, True,
    "ERROR:target")
add("H15 rev 0 allowed", "view", {"revisions": [{"rev": 0, "allocated": ["a"]},
                                                {"rev": 1, "allocated": ["b"]}], "target": "b"},
    True, "0|a")
for i in range(6):
    revs = [{"rev": 10 * j + 1, "allocated": ["r%d_%d" % (j, m) for m in range(j % 3)]}
            for j in range(8)]
    add("H%02d sweep target r%d_0" % (16 + i, i + 1), "view",
        {"revisions": revs, "target": "r%d_0" % (i + 1)}, False)
add("H22 id with a bar escaped", "view",
    {"revisions": [{"rev": 1, "allocated": ["a|b"]}, {"rev": 2, "allocated": ["c"]}], "target": "c"},
    True, "1|a\\|b")

names = [c["name"] for c in cases]
assert len(names) == len(set(names)), "duplicate case names"
counts = {}
for c in cases:
    counts[c["fn"]] = counts.get(c["fn"], 0) + 1
for fn, m in sorted(counts.items()):
    assert m >= 20, (fn, m)
out = {"corpus": "probe_corpus", "version": "0.2.0", "module": "tpc_probe 0.2.0",
       "params_fixture": "PMP-TPM 0.12.0 fleet defaults (params_fixture.FLEET)",
       "counts": counts, "cases": cases}
with open(os.path.join(here, "probe_corpus.json"), "w", encoding="utf-8", newline="\n") as f:
    json.dump(out, f, indent=1, ensure_ascii=False)
    f.write("\n")
print("probe_corpus.json", len(cases), "cases", counts)