Jump to content

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

From The Invariance Itself
TPC-PY source diff_probe.py (0.1.0), SHA-256 21d1ac46f0e4e908; conformed TPS 0.3.0; PROPOSED, not declared (CO-8)
 
m 1 revision imported
 
(2 intermediate revisions by the same user not shown)
Line 3: Line 3:
boundary and malformed records, the params fixture varied), both
boundary and malformed records, the params fixture varied), both
residences on the same inputs, every render compared byte for byte; 0
residences on the same inputs, every render compared byte for byte; 0
differences is the pass. Usage: python3 diff_probe.py [seed] [cases]."""
differences is the pass. Usage: python3 diff_probe.py [seed] [cases].
Increment 12 (tpc_probe 0.2.0): compare's L findings also of type
EQUATION (EQS below)."""
import json
import json
import os
import os
Line 21: Line 23:
TEXTS = ["x = 1", "x=1", "café", "café", "a|b", "a\\b", "line\nline", "a\r\nb", "",
TEXTS = ["x = 1", "x=1", "café", "café", "a|b", "a\\b", "line\nline", "a\r\nb", "",
         "Å", "Å", "가", "가", "tab\there", "́x"]
         "Å", "Å", "가", "가", "tab\there", "́x"]
EQS = ["x=1", "x*2=y", "2*x=y", "x = 1", "x==y", "m*D(v,t)=-k_s*x", "sin(x)=cos(x)", "", "x=1\n", "x"]
DECS = ["0", "5", "15e2", "1500", "-5e-2", "5e0", "05", "-0", "123", "12e1", "1e-1", "-1", "10",
DECS = ["0", "5", "15e2", "1500", "-5e-2", "5e0", "05", "-0", "123", "12e1", "1e-1", "-1", "10",
         "1e+1", "7e7", "-", "e5", "1.5"]
         "1e+1", "7e7", "-", "e5", "1.5"]
Line 106: Line 109:
     if fn == "compare":
     if fn == "compare":
         if rnd.random() < 0.5:
         if rnd.random() < 0.5:
             t = kind(["TEXT", "DECIMAL"], ["PROSE"])
             t = kind(["TEXT", "DECIMAL", "EQUATION"], ["PROSE"])
             vals = TEXTS if t == "TEXT" else DECS
             vals = TEXTS if t == "TEXT" else EQS if t == "EQUATION" else DECS
             v1 = pick(vals)
             v1 = pick(vals)
             v2 = v1 if rnd.random() < 0.5 else pick(vals)
             v2 = v1 if rnd.random() < 0.5 else pick(vals)

Latest revision as of 02:11, 30 September 2026

"""diff_probe 0.1.0: the cross-residence differential for tpc_probe 0.1.0.
Random inputs from a seed over every function (random r values, valid,
boundary and malformed records, the params fixture varied), both
residences on the same inputs, every render compared byte for byte; 0
differences is the pass. Usage: python3 diff_probe.py [seed] [cases].
Increment 12 (tpc_probe 0.2.0): compare's L findings also of type
EQUATION (EQS below)."""
import json
import os
import random
import subprocess
import sys
import tempfile

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, FNS  # noqa: E402

seed = int(sys.argv[1]) if len(sys.argv) > 1 else 1
count = int(sys.argv[2]) if len(sys.argv) > 2 else 20000
rnd = random.Random(seed)
TEXTS = ["x = 1", "x=1", "café", "café", "a|b", "a\\b", "line\nline", "a\r\nb", "",
         "Å", "Å", "가", "가", "tab\there", "́x"]
EQS = ["x=1", "x*2=y", "2*x=y", "x = 1", "x==y", "m*D(v,t)=-k_s*x", "sin(x)=cos(x)", "", "x=1\n", "x"]
DECS = ["0", "5", "15e2", "1500", "-5e-2", "5e0", "05", "-0", "123", "12e1", "1e-1", "-1", "10",
        "1e+1", "7e7", "-", "e5", "1.5"]


def pick(xs):
    return xs[rnd.randrange(len(xs))]


def bad():
    return rnd.random() < 0.03


def kind(good, more):
    return pick(more) if bad() else pick(good)


def rhex():
    if bad():
        return pick(["", "zz", "0" * 31, "0" * 33, "A" * 32, 5, None])
    return "%032x" % rnd.getrandbits(128)


def cnt(lo, hi):
    if bad():
        return pick([True, None, "5", 1.5, -1])
    return rnd.randint(lo, hi)


def num(lo, hi):
    if bad():
        return pick([True, None, "1", -1])
    return round(rnd.uniform(lo, hi), rnd.randint(0, 6))


def flag():
    return (rnd.random() < 0.5) if not bad() else pick([1, "x", None])


def params():
    p = fleet()
    r = rnd.random()
    if r < 0.6:
        return p
    invalid = r > 0.93
    if rnd.random() < 0.5:
        sets = [[0.5, 1 / 3, 0.2, 1 / 7], [0.5, 1 / 3], [0.25], [1, 2, 3]]
        st = pick(sets)
        ws = [1.0 / len(st)] * len(st) if rnd.random() < 0.5 else [round(x, 4) for x in [0.3, 0.5, 0.15, 0.05][:len(st)]]
        tot = sum(ws)
        ws = [w / tot for w in ws]
        if invalid:
            ws = pick([ws[:-1] + [ws[-1] + 0.1], [0] * len(st), ws])
        p["PARROT RATIO"] = {"set": st, "weights": ws, "epoch": pick([[50, 100], [1, 1], [3, 9], [10, 10]] + ([[100, 50], [0, 5]] if invalid else []))}
    if rnd.random() < 0.5:
        p["CANARY SCHEDULE"] = {"tiers": pick([[[1, 100, 5], [101, 1000, 10], [1001, None, 20]], [[1, 100, 5], [101, None, 20]],
                                               [[1, None, 3]], [[1, 10, 2], [11, 20, 4], [21, None, 8]]]
                                              + ([[[1, 100, 5], [102, None, 20]], [[1, 100, 5], [101, 1000, 20]], []] if invalid else [])),
                                "burst_rates": pick([[5, 10], [5], [2, 3, 4]] + ([[], [0]] if invalid else [])),
                                "burst_duration": pick([[50, 200], [1, 1], [2, 5]] + ([[5, 2]] if invalid else [])),
                                "burst_gap": pick([[200, 500], [1, 3], [2, 2]] + ([[0, 1]] if invalid else []))}
    if rnd.random() < 0.3:
        p["RESET RULE"] = pick([5, 2, 1, 3] + ([0, "5"] if invalid else []))
    if rnd.random() < 0.3:
        p["CONSISTENCY SHARE"] = pick([0.1, 0.5, 1, 0] + ([1.5, -0.1] if invalid else []))
    if rnd.random() < 0.3:
        p["ORANGE PASSES"] = pick([3, 1, 5] + ([0] if invalid else []))
    if invalid and rnd.random() < 0.3:
        del p[pick(["PARROT RATIO", "CANARY SCHEDULE", "RESET RULE", "ORANGE PASSES"])]
    return p


def mrec():
    r = {"x": num(-10, 10), "u": kind([0.1, 0.2, 0.05, 1, 0.5, round(rnd.uniform(0.01, 3), 4)], [0, -1, "0.1"]),
         "unit": kind(["m", "m s-1", "kg"], [5, "m|s"])}
    if bad():
        del r["unit"]
    return r


def gen(fn):
    p = params()
    if fn == "uniform":
        return {"tag": kind(["TPC-PROBE", "T", "x"], ["", 5]), "r": rhex(), "counter": cnt(0, 1000)}
    if fn == "compare":
        if rnd.random() < 0.5:
            t = kind(["TEXT", "DECIMAL", "EQUATION"], ["PROSE"])
            vals = TEXTS if t == "TEXT" else EQS if t == "EQUATION" else DECS
            v1 = pick(vals)
            v2 = v1 if rnd.random() < 0.5 else pick(vals)
            o = {"finding": {"type": t, "value": v1}}
            rp = {"finding": {"type": t if not bad() else "TEXT", "value": v2}}
            if bad():
                o = {"finding": {"type": t}}
            return {"kind": kind(["L"], ["M", "X"]), "original": o, "reproduction": rp}
        o = mrec()
        rp = mrec()
        if rnd.random() < 0.7 and isinstance(o.get("unit"), str):
            rp["unit"] = o["unit"]
        if rnd.random() < 0.5 and isinstance(o["x"], float):
            rp["x"] = round(o["x"] + rnd.uniform(-0.5, 0.5), 4)
        standing = [{"x": num(-10, 10), "u": kind([0.1, 0.2, 0.5, 1, 50], [0])} for _ in range(rnd.randint(0, 5))]
        if rnd.random() < 0.5 and standing:
            standing[0] = {"x": o["x"], "u": o["u"]}
        return {"kind": kind(["M"], ["L"]), "original": o, "reproduction": rp, "standing": standing if not bad() else {},
                "k": kind([2, 3, 1, 2.5], [0, -1, "2"]), "material_ratio": kind([2, 1.5, 1, 3], [0.5, "2"])}
    if fn == "load":
        ids = ["r%d" % i for i in range(rnd.randint(1, 9))]
        recs = {}
        for i in ids:
            recs[i] = {"cites": [pick(ids + ["TFK-1"]) for _ in range(rnd.randint(0, 2))],
                       "assumptions": [pick(ids) for _ in range(rnd.randint(0, 2))], "standing": flag()}
            if bad():
                recs[i]["cites"] = "x"
        return {"records": recs if not bad() else [], "r": kind(ids, ["zz", ""])}
    if fn == "el":
        return {"e_lo": kind([0.025, 0.5, 0.84, 1, 0, round(rnd.random(), 5)], [1.5, "x"]), "load": cnt(0, 50)}
    if fn == "ratio":
        return {"state": {"k": kind([None, 0.5, 1 / 3, 0.2], [-1, "x"]), "remaining": cnt(0, 100)}, "r": rhex(),
                "params": p}
    if fn == "schedule":
        b = kind([0, 99, 100, 999, 1000, 1001, 1500, rnd.randint(0, 3000)], [-1, 1.5])
        burst = None
        gap = None
        r = rnd.random()
        if r < 0.3:
            burst = {"rate": kind([5, 10], [0]), "remaining": kind([1, 2, 40, 199], [0])}
        elif r < 0.6:
            gap = kind([1, 2, 100, 499], [0])
        elif r < 0.63:
            burst = {"rate": 5, "remaining": 3}
            gap = 4
        return {"state": {"blocks": b, "burst": burst, "gap": gap}, "r": rhex(), "params": p}
    if fn == "probe":
        return {"schedule": {"tier": kind([1, 2, 3], [0]), "rate": kind([5, 10, 20, 1, 2], [0]), "burst": flag()},
                "ratio": kind([1 / 3, 0.5, 0.2, 1 / 7, 1000, 0.000001], [0, "x"]),
                "reset": {"in_force": flag(), "passes": cnt(0, 5)}, "has_own_record": flag(), "r": rhex(), "params": p}
    if fn == "step":
        return {"state": {"schedule": {"blocks": cnt(0, 2500), "burst": None if rnd.random() < 0.7 else {"rate": 5, "remaining": cnt(1, 50)},
                                       "gap": None if rnd.random() < 0.7 else cnt(1, 300)},
                          "ratio": {"k": pick([None, 0.5, 1 / 3]), "remaining": cnt(0, 80)},
                          "reset": {"in_force": flag(), "passes": cnt(0, 3)}} if not bad() else {},
                "r": rhex(), "params": p, "has_own_record": flag()}
    if fn == "reset":
        return {"reset": {"in_force": flag(), "passes": cnt(0, 5)},
                "event": kind(["NON-CORROBORATION", "CANARY PASS", "CANARY FAIL", "PARROT PASS", "AUDIT FINDING"], ["X"]),
                "account_state": kind(["GREEN", "YELLOW", "ORANGE", "SUSPENDED"], ["RED"]), "params": p}
    revs = []
    rev = 0
    allids = []
    for _ in range(rnd.randint(0, 6)):
        rev += rnd.randint(0, 4) if not bad() else 0
        ids = ["v%d_%d" % (rev, m) for m in range(rnd.randint(0, 3))]
        if bad() and allids:
            ids.append(pick(allids))
        allids += ids
        revs.append({"rev": rev, "allocated": ids if not bad() else "x"})
    return {"revisions": revs, "target": kind(allids or ["none"], ["zz", ""])}


cases = []
for _ in range(count):
    fn = pick(FNS)
    cases.append({"fn": fn, "args": gen(fn)})
CASES_PATH = os.environ.get("TPC_DIFF_CASES")  # named: kept, for crosspy.py
if not CASES_PATH:
    fd, CASES_PATH = tempfile.mkstemp(prefix="tpc_diff_", suffix=".json")  # outside the tree
    os.close(fd)
with open(CASES_PATH, "w", encoding="utf-8") as f:
    json.dump(cases, f, ensure_ascii=False)
py = [run_case(c["fn"], c["args"]) for c in cases]
php = json.loads(subprocess.run(["php", os.path.join(here, "diff_probe.php"), CASES_PATH], capture_output=True,
                                text=True, check=True).stdout)
if not os.environ.get("TPC_DIFF_CASES"):
    os.remove(CASES_PATH)
diffs = sum(1 for a, b in zip(py, php) if a != b)
outcomes = {}
for c, a in zip(cases, py):
    k = c["fn"] + ("/ERROR" if a.startswith("ERROR") else "")
    outcomes[k] = outcomes.get(k, 0) + 1
print("seed", seed, "cases", len(cases), "differences", diffs, "php_len", len(php),
      json.dumps(outcomes, sort_keys=True))
for c, a, b in zip(cases, py, php):
    if a != b:
        print(json.dumps(c, ensure_ascii=False)); print(a); print("---"); print(b); break