Jump to content

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

From The Invariance Itself
m 1 revision imported
TPC-PY source gen_cluster_corpus.py (0.3.0), SHA-256 f9c06c6035e7a1fa; conformed TPS 0.4.0; PROPOSED, not declared (TPC-PY 0.2.0)
Line 141: Line 141:
here = os.path.dirname(os.path.abspath(__file__))
here = os.path.dirname(os.path.abspath(__file__))
json.dump({"corpus": "cluster", "version": "0.3.0", "cases": out},
json.dump({"corpus": "cluster", "version": "0.3.0", "cases": out},
           open(os.path.join(here, "cluster_corpus.json"), "w"), indent=1,
           open(os.path.join(here, "cluster_corpus.json"), "w", encoding="utf-8", newline="\n"), indent=1,
           sort_keys=True)
           sort_keys=True)
print("cases", len(out))
print("cases", len(out))
Line 148: Line 148:
old_path = os.path.join(here, "cluster_corpus_0_2_0.json")
old_path = os.path.join(here, "cluster_corpus_0_2_0.json")
if os.path.exists(old_path):
if os.path.exists(old_path):
     old = json.load(open(old_path))["cases"]
     old = json.load(open(old_path, encoding="utf-8"))["cases"]
     same = 0
     same = 0
     for a, b in zip(old, out[:26]):
     for a, b in zip(old, out[:26]):

Revision as of 02:10, 30 September 2026

"""gen_cluster_corpus 0.3.0: builds cluster_corpus.json for tpc_cluster 0.3.0.
The 26 cases of 0.2.0 (C01-C26) are carried verbatim, computed by the
amended function without a paired input, and proved byte-identical to
cluster_corpus_0_2_0.json (names, rows, params, expected) when that file
sits beside this script; the FIXED-SET cases (P01-P20) and the
resolving_step cases (R01-R20) are new. Expectations are computed by
tpc_cluster.py and pinned; hand_checked cases were also worked by hand
(the cluster speculation's appendix A, the docs' specimen, F30's table)."""
import json
import os
import sys

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from tpc_cluster import run_case  # noqa: E402

P = {"in_max": 2.5, "cusp_max": 3.5, "z": 1.645, "spacing_floor": 0.0}
PF = {"in_max": 2.5, "cusp_max": 3.5, "z": 1.645, "spacing_floor": 0.5}
P1 = {"in_max": 2.5, "cusp_max": 3.5, "z": 1.0, "spacing_floor": 0.0}


def one(*triples):  # single-configuration rows
    return [[t[0], "default", t[1], t[2]] for t in triples]


def rows(*quads):
    return [list(q) for q in quads]


# ---- the 26 cases of 0.2.0, verbatim ------------------------------------
cases = [
 ("C01 user example A", one(("A1",10.0,0.0),("A2",9.0,0.0),("A3",7.0,0.0),("A4",3.0,0.0)), P, True),
 ("C02 user example B", one(("B1",10.0,0.0),("B2",9.0,0.0),("B3",6.0,0.0),("B4",3.0,0.0)), P, True),
 ("C03 one model", one(("solo",50.0,2.0)), P, True),
 ("C04 two models far apart", one(("x",80.0,1.0),("y",20.0,1.0)), P, True),
 ("C05 three tied, zero se, then lower", one(("t1",10.0,0.0),("t2",10.0,0.0),("t3",10.0,0.0),("t4",9.9,0.0)), P, True),
 ("C06 leader far ahead", one(("L",90.0,0.0),("p2",60.0,0.0),("p3",55.0,0.0),("p4",50.0,0.0),("p5",45.0,0.0),("p6",40.0,0.0),("p7",20.0,0.0)), P, True),
 ("C07 constant steps after the first", one(("a",10.0,0.0),("b",9.0,0.0),("c",7.0,0.0),("d",5.0,0.0),("e",3.0,0.0),("f",1.0,0.0)), P, True),
 ("C08 a tie with the cusp row shares it", one(("aa",6.0,0.0),("b1",10.0,0.0),("b2",9.0,0.0),("zz",6.0,0.0),("z3",2.0,0.0)), P, True),
 ("C09 one model's two configurations at the top", rows(("X","high",40.0,0.0),("X","med",38.0,0.0),("Y","default",30.0,0.0),("Z","default",29.5,0.0)), P, True),
 ("C10 verifier case: two configurations and one other model", rows(("X","high",40.0,1.0),("X","med",38.0,1.0),("Y","d",30.0,1.0)), PF, True),
 ("C11 noise sets the spacing (SE 1)", one(("a",40.0,1.0),("b",38.0,1.0),("c",37.9,1.0),("d",34.0,1.0),("e",32.0,1.0)), PF, True),
 ("C12 step exactly 2.5 spacings is IN", one(("b1",10.0,0.0),("b2",9.0,0.0),("b3",6.5,0.0)), P, True),
 ("C13 step exactly 3.5 spacings is CUSP", one(("b1",10.0,0.0),("b2",9.0,0.0),("b3",5.5,0.0)), P, True),
 ("C14 step 3.6 spacings is OUT", one(("b1",10.0,0.0),("b2",9.0,0.0),("b3",5.4,0.0)), P, True),
 ("C15 spacing zero, positive step", one(("u1",5.0,0.0),("u2",5.0,0.0),("u3",5.0,0.0),("u4",4.9,0.0)), P, True),
 ("C16 worked month (specimen)", rows(("Model A","high",38.0,0.6),("Model B","high",35.5,0.6),("Model C","default",33.9,0.6),("Model D","high",32.0,0.6),("Model E","default",25.8,0.6),("Model F","default",17.5,0.7),("Model A","low",33.5,0.6),("Model D","default",27.0,0.6)), PF, True),
 ("C17 a similar month with SE about 1.2: nothing resolves", rows(("Model A","high",38.0,1.2),("Model B","high",35.5,1.1),("Model C","default",33.9,1.2),("Model D","high",32.0,1.2),("Model E","default",27.6,1.2),("Model F","default",21.5,1.3)), PF, False),
 ("C18 empty", [], P, True),
 ("C19 stricter thresholds", one(("A1",10.0,0.0),("A2",9.0,0.0),("A3",7.0,0.0),("A4",3.0,0.0)), {"in_max": 1.5, "cusp_max": 2.0, "z": 1.645, "spacing_floor": 0.0}, False),
 ("C20 bad parameters", one(("A1",10.0,0.0),("A2",9.0,0.0)), {"in_max": 3.5, "cusp_max": 2.5, "z": 1.645, "spacing_floor": 0.0}, True),
 ("C21 negative se", one(("A1",10.0,-1.0),("A2",9.0,0.0)), P, True),
 ("C22 duplicate model and configuration", rows(("A","d",10.0,0.0),("A","d",9.0,0.0)), P, True),
 ("C23 empty configuration id", rows(("A","",10.0,0.0)), P, True),
 ("C24 lower configuration within noise of the cusp row", rows(("a","d",40.0,0.5),("b","d",38.0,0.5),("c","d",36.0,0.5),("e","d",29.0,0.5),("c","low",28.5,0.5),("f","d",10.0,0.5)), PF, True),
 ("C25 unsorted input; score ties by se then id", one(("zeta",7.0,0.5),("beta",9.0,0.2),("alpha",9.0,0.2),("gamma",9.0,0.1),("eta",8.0,0.0)), PF, False),
 ("C26 after an OUT below a cusp, a noisy row level with the cusp row is OUT", one(("a",40.0,0.1),("b",38.0,0.1),("c",36.0,0.1),("d",29.0,0.1),("e",28.0,0.1),("f",27.9,5.0)), PF, True),
]
out = []
for name, rs, p, hand in cases:
    case = {"name": name, "rows": rs, "params": p, "hand_checked": hand}
    case["expected"] = run_case(case)
    out.append(case)

# ---- FIXED-SET: the paired noise input (D143.1 (e), R7) -------------------
def all_pairs(rs, sd):
    """Every unordered pair of rows at one paired SE."""
    ps = []
    for i in range(len(rs)):
        for j in range(i + 1, len(rs)):
            ps.append([rs[i][0], rs[i][1], rs[j][0], rs[j][1], sd])
    return ps


specimen = rows(("Model A","high",38.0,0.6),("Model B","high",35.5,0.6),("Model C","default",33.9,0.6),("Model D","high",32.0,0.6),("Model E","default",25.8,0.6),("Model F","default",17.5,0.7),("Model A","low",33.5,0.6),("Model D","default",27.0,0.6))
exA = one(("A1",10.0,0.0),("A2",9.0,0.0),("A3",7.0,0.0),("A4",3.0,0.0))
band = one(("a",40.0,1.0),("b",38.0,1.0),("c",37.9,1.0),("d",34.0,1.0),("e",32.0,1.0))
bnd = one(("b1",10.0,0.0),("b2",9.0,0.0),("b3",6.0,0.0))
uni = rows(("Modèle É","défaut",10.0,0.0),("模型乙","默认",9.0,0.0),("μ-3","α",7.0,0.0),("μ-4","α",3.0,0.0))
pcases = [
 ("P01 example A under FIXED-SET, paired SEs zero: as ITEM-SAMPLING", exA, P, all_pairs(exA, 0.0), True),
 ("P02 specimen under FIXED-SET, paired SE 0.4 everywhere: Model E's step 0.6 past CUSP MAX inside its paired noise 0.658, CUSP", specimen, PF, all_pairs(specimen, 0.4), True),
 ("P03 specimen under FIXED-SET, paired SE 0.3: Model E's step 0.6 past CUSP MAX outside its noise 0.494, OUT", specimen, PF, all_pairs(specimen, 0.3), True),
 ("P04 specimen under FIXED-SET, paired SE 1.2 (wider than unpaired 0.85): noise sets the spacing", specimen, PF, all_pairs(specimen, 1.2), False),
 ("P05 band month (C11) under FIXED-SET, paired SE 0.2: the spacing is the gap 0.1 raised to the floor 0.5; d and e resolve", band, PF, all_pairs(band, 0.2), False),
 ("P06 a missing pair the rule tests (ranks 4 and 5) is refused", specimen, PF, [x for x in all_pairs(specimen, 0.4) if not (x[0] == "Model D" and x[1] == "high" and x[2] == "Model E")], True),
 ("P06b a missing pair the rule never tests (two non-representatives) is not needed", specimen, PF, all_pairs(specimen, 0.4)[:-1], True),
 ("P07 a pair given twice, the second in reverse order, is refused", exA, P, all_pairs(exA, 0.0) + [["A2","default","A1","default",0.1]], True),
 ("P08 a self pair is refused", exA, P, all_pairs(exA, 0.0) + [["A1","default","A1","default",0.0]], True),
 ("P09 a pair naming an unknown row is refused", exA, P, all_pairs(exA, 0.0) + [["A9","default","A1","default",0.0]], True),
 ("P10 a negative paired SE is refused", exA, P, [["A1","default","A2","default",-0.1]] + all_pairs(exA, 0.0)[1:], True),
 ("P11 a paired entry of the wrong length is refused", exA, P, [["A1","default","A2","default"]] + all_pairs(exA, 0.0)[1:], True),
 ("P12 two models under FIXED-SET need no pair", one(("x",80.0,1.0),("y",20.0,1.0)), P, [], True),
 ("P13 one model under FIXED-SET: NONE", one(("solo",50.0,2.0)), P, [], True),
 ("P14 FIXED-SET boundary: step - CUSP MAX x u equal to the paired noise is not OUT (CUSP)", one(("b1",10.0,0.0),("b2",9.0,0.0),("b3",5.0,0.0)), P1, all_pairs(one(("b1",10.0,0.0),("b2",9.0,0.0),("b3",5.0,0.0)), 0.5), True),
 ("P15 FIXED-SET boundary: step - CUSP MAX x u past the paired noise by 0.01 is OUT", one(("b1",10.0,0.0),("b2",9.0,0.0),("b3",4.99,0.0)), P1, all_pairs(one(("b1",10.0,0.0),("b2",9.0,0.0),("b3",4.99,0.0)), 0.5), True),
 ("P16 FIXED-SET boundary: step - IN MAX x u equal to the paired noise is IN", bnd, P1, all_pairs(bnd, 0.5), True),
 ("P17 non-representative rows judged by their paired SE against the lowest IN and CUSP representatives", rows(("a","d",40.0,0.5),("b","d",38.0,0.5),("c","d",36.0,0.5),("e","d",29.0,0.5),("c","low",28.5,0.5),("f","d",10.0,0.5)), PF,
  all_pairs(rows(("a","d",40.0,0.5),("b","d",38.0,0.5),("c","d",36.0,0.5),("e","d",29.0,0.5),("c","low",28.5,0.5),("f","d",10.0,0.5)), 0.2)
  , True),
 ("P18 below a CUSP, a row level with it by its paired SE shares it; the next is OUT by its paired SE", one(("a",40.0,0.1),("b",38.0,0.1),("c",36.0,0.1),("d",29.0,0.1),("e",28.0,0.1),("f",27.9,5.0)), PF,
  [["a","default","b","default",0.1],["a","default","c","default",0.1],["a","default","d","default",0.1],["a","default","e","default",0.1],["a","default","f","default",0.1],["b","default","c","default",0.1],["b","default","d","default",0.1],["b","default","e","default",0.1],["b","default","f","default",0.1],["c","default","d","default",0.1],["c","default","e","default",0.1],["c","default","f","default",0.1],["d","default","e","default",0.8],["d","default","f","default",0.5],["e","default","f","default",0.1]], True),
 ("P19 unicode identifiers under FIXED-SET", uni, P, all_pairs(uni, 0.0), True),
 ("P20 an extra pair beyond those the rule tests is accepted", one(("x",10.0,0.0),("y",9.0,0.0),("z",7.0,0.0)), P, all_pairs(one(("x",10.0,0.0),("y",9.0,0.0),("z",7.0,0.0)), 0.0), True),
]
for name, rs, p, paired, hand in pcases:
    case = {"name": name, "rows": rs, "params": p, "paired": paired,
            "hand_checked": hand, "fn": "cluster"}
    case["expected"] = run_case(case)
    out.append(case)

# ---- resolving_step (D144.1 (i); RS1-RS3) ---------------------------------
R = {"in_max": 2.5, "cusp_max": 3.5, "z": 1.645}
rcases = [
 ("R01 the docs' specimen: u 1.6, SEs 0.6 with rank 6 at 0.7: 6.996 points, 4.37 spacings; the greatest 7.116", 1.6, [0.6,0.6,0.6,0.6,0.6,0.7], R, None, True),
 ("R02 F30 row: ECI, SE 2.00, spacing 4.65: CUSP at 16.3, OUT at 20.9", 4.65, [2.0,2.0,2.0], R, None, True),
 ("R03 F30 row: composite with CritPt, SE 1.66, spacing 3.86: 13.5 / 17.4", 3.86, [1.66,1.66,1.66], R, None, True),
 ("R04 F30 row: composite, item sampling, SE 0.96, spacing 2.23: 7.8 / 10.0", 2.23, [0.96,0.96,0.96], R, None, True),
 ("R05 F30 row: composite paired, SE 0.68, spacing 1.58: 5.5 / 7.1", 1.58, [0.68,0.68,0.68], R, None, True),
 ("R06 F30 row: fixed item set, SE 0.28, spacing 1.00: 3.2 / 4.2", 1.0, [0.28,0.28,0.28], R, None, True),
 ("R07 example A: u 1, SEs zero: 3.5 points, 3.5 spacings; CUSP at 2.5", 1.0, [0.0,0.0,0.0,0.0], R, None, True),
 ("R08 fewer than three ranks: NONE (two)", 1.0, [0.5,0.5], R, None, True),
 ("R09 fewer than three ranks: NONE (none)", 0.0, [], R, None, True),
 ("R10 spacing zero: points only, spacings undefined", 0.0, [0.5,0.5,0.5], R, None, True),
 ("R11 z zero: the thresholds are the spacing multiples alone", 2.0, [1.0,3.0,2.0], {"in_max": 2.5, "cusp_max": 3.5, "z": 0.0}, None, True),
 ("R12 varying SEs: the least pair sets the step, the greatest pair the greatest", 1.0, [0.1,0.2,0.9,0.05,0.3], R, None, True),
 ("R13 FIXED-SET: paired SEs of the adjacent differences replace the unpaired terms", 1.6, [0.6,0.6,0.6,0.6,0.6,0.7], R, [0.5,0.4,0.4,0.4,0.6], True),
 ("R14 FIXED-SET: paired list of the wrong length is refused", 1.6, [0.6,0.6,0.6], R, [0.4], True),
 ("R15 FIXED-SET: a negative paired SE is refused", 1.6, [0.6,0.6,0.6], R, [0.4,-0.1], True),
 ("R16 a negative SE is refused", 1.0, [0.5,-0.5,0.5], R, None, True),
 ("R17 a negative spacing is refused", -1.0, [0.5,0.5,0.5], R, None, True),
 ("R18 bad parameters (IN MAX above CUSP MAX) are refused", 1.0, [0.5,0.5,0.5], {"in_max": 3.5, "cusp_max": 2.5, "z": 1.645}, None, True),
 ("R19 a boolean SE is refused", 1.0, [0.5, True, 0.5], R, None, True),
 ("R20 ECI top twelve as F30 read them: u 6.01 by NOISE, SE 2.0 to 2.74", 6.01, [2.74,2.0,1.44,2.1,2.0,1.9,2.3,2.0,1.8,1.7,2.2,2.5], R, None, False),
]
for name, u, ses, p, paired, hand in rcases:
    case = {"name": name, "fn": "resolving", "spacing": u, "ses": ses,
            "params": p, "paired": paired, "hand_checked": hand}
    case["expected"] = run_case(case)
    out.append(case)

here = os.path.dirname(os.path.abspath(__file__))
json.dump({"corpus": "cluster", "version": "0.3.0", "cases": out},
          open(os.path.join(here, "cluster_corpus.json"), "w", encoding="utf-8", newline="\n"), indent=1,
          sort_keys=True)
print("cases", len(out))

# ---- the 0.2.0 proof -------------------------------------------------------
old_path = os.path.join(here, "cluster_corpus_0_2_0.json")
if os.path.exists(old_path):
    old = json.load(open(old_path, encoding="utf-8"))["cases"]
    same = 0
    for a, b in zip(old, out[:26]):
        if (a["name"] == b["name"] and a["rows"] == b["rows"]
                and a["params"] == b["params"] and a["expected"] == b["expected"]
                and a["hand_checked"] == b["hand_checked"]):
            same += 1
        else:
            print("CHANGED", a["name"])
    print("0.2.0 cases unchanged: %d/%d" % (same, len(old)))