The Principia Machina/TPC-PY/diff identity.py: Difference between revisions
Appearance
TPC-PY source diff_identity.py (0.1.0), SHA-256 4e12aa6b64e9c321; conformed TPS 0.3.0; PROPOSED, not declared (CO-8) |
m 1 revision imported |
||
(No difference)
| |||
Latest revision as of 04:32, 28 September 2026
"""diff_identity 0.1.0: the cross-residence differential for tpc_identity
0.1.0. Random JSON texts (valid, with every value kind, escapes, NFC pairs,
numbers of every shape; and mutated to invalid), random digests, model
maps and lookups, both residences on the same inputs, 0 differences the
pass. Usage: python3 diff_identity.py [seed] [cases]."""
import json, os, random, subprocess, sys, tempfile
here = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, here)
from tpc_identity import run_case
seed = int(sys.argv[1]) if len(sys.argv) > 1 else 1
count = int(sys.argv[2]) if len(sys.argv) > 2 else 20000
random.seed(seed)
WORDS = ["a", "b", "Z", "key", "é", "é", "模型", "\U0001F600", "x y", "tab\tx", "q\"uote", "back\\slash", "", "10", "9", "Å", "Å"]
def jstr(s):
out = '"'
for ch in s:
o = ord(ch)
r = random.random()
if ch == '"': out += '\\"'
elif ch == "\\": out += "\\\\"
elif o < 0x20: out += random.choice(["\\u%04x" % o, "\\t" if ch == "\t" else "\\u%04x" % o])
elif o > 0x7f and r < 0.3:
if o > 0xffff:
o -= 0x10000
out += "\\u%04x\\u%04x" % (0xd800 + (o >> 10), 0xdc00 + (o & 0x3ff))
else:
out += "\\u%04x" % o
elif ch == "/" and r < 0.5: out += "\\/"
else: out += ch
return out + '"'
def jnum():
r = random.random()
if r < 0.3: return str(random.randint(-1000, 1000))
if r < 0.6: return "%s%d.%s" % (random.choice(["", "-"]), random.randint(0, 99), "".join(random.choice("0123456789") for _ in range(random.randint(1, 6))))
if r < 0.9: return "%d%s%s%d" % (random.randint(0, 9), random.choice(["e", "E"]), random.choice(["", "+", "-"]), random.randint(0, 20))
return random.choice(["0", "-0", "0.0", "1e0", "123456789012345678901234567890", "0.000000000000000000001"])
def jval(depth):
r = random.random()
if depth > 4 or r < 0.35: return random.choice([jstr(random.choice(WORDS)), jnum(), "true", "false", "null"])
ws = lambda: random.choice(["", " ", "\n", "\t ", "\r\n"])
if r < 0.7:
items = [jval(depth + 1) for _ in range(random.randint(0, 4))]
return "[" + ws() + (("," + ws()).join(items)) + ws() + "]"
keys = random.sample(WORDS, random.randint(0, 5))
members = [jstr(k) + ws() + ":" + ws() + jval(depth + 1) for k in keys]
return "{" + ws() + (("," + ws()).join(members)) + ws() + "}"
MAP = [
{"name": "claude-fable-5-1", "family": "Anthropic/Claude", "open": False, "server": None, "quantization": None},
{"name": "claude-opus-4", "family": "Anthropic/Claude", "open": False, "server": None, "quantization": None},
{"name": "gemini-3-pro", "family": "Google/Gemini", "open": False, "server": None, "quantization": None},
{"name": "together/llama-4-70b-fp8", "family": "Meta/Llama-4", "open": True, "server": "together", "quantization": "fp8"},
{"name": "modèle", "family": "Maison/Modèle", "open": False, "server": None, "quantization": None},
]
NAMES = [r["name"] for r in MAP] + ["gpt-9", "", "modèle", "Claude-Fable-5-1", "llama-4-70b"]
KEYS = ["6:CLOSED16:Anthropic/Claude", "6:CLOSED13:Google/Gemini", "4:OPEN12:Meta/Llama-48:together3:fp8", "UNMAPPED", "6:CLOSED14:Maison/Modèle"]
VEND = ["Anthropic", "Google", "anthropic", "Société", "Société", None, ""]
cases = []
for t in range(count):
fn = random.choice(["tools", "tools", "digest", "family", "class", "compare"])
if fn == "tools":
s = jval(0)
r = random.random()
if r < 0.15 and s:
i = random.randrange(len(s))
s = s[:i] + random.choice(["", ",", "]", "}", "\"", "NaN", "\\ud800", "\t", "01", "1.", "e5", "\\x"]) + s[i + 1:]
cases.append({"fn": "tools", "args": {"json": s}})
elif fn == "digest":
salt = "".join(random.choice("0123456789abcdef") for _ in range(32))
if random.random() < 0.1: salt = random.choice([salt.upper(), salt[:31], salt + "0", 12, "g" * 32])
cases.append({"fn": "digest", "args": {"family": random.choice(KEYS + [""]), "salt": salt, "template": random.choice(WORDS) * random.randint(0, 3), "tools": jval(0) if random.random() < 0.9 else "[1,"}})
elif fn == "family":
m = [dict(r) for r in MAP]
r = random.random()
if r < 0.05: m.append(dict(m[0]))
elif r < 0.10: m[3]["server"] = None
elif r < 0.15: m[0]["server"] = "s"
elif r < 0.18: m[1]["open"] = 1
cases.append({"fn": "family", "args": {"model": random.choice(NAMES), "map": m}})
elif fn == "class":
lk = {"family": random.choice(KEYS), "cluster": random.choice(["IN", "CUSP", "OUT", "FADING", "UNLISTED", "EXCLUDED", None, None, "X"])}
cases.append({"fn": "class", "args": {"certified": random.choice(KEYS[:3] + [""]), "last": random.choice(NAMES), "reported": random.choice(NAMES), "lookup": lk}})
else:
cases.append({"fn": "compare", "args": {"declared": random.choice(VEND), "stated": random.choice(VEND), "relayed": random.choice(VEND), "inferred": random.choice(VEND)}})
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_identity.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)
by = {}
for c, x in zip(cases, py):
k = c["fn"] + ("/ERROR" if x.startswith("ERROR") else "")
by[k] = by.get(k, 0) + 1
print("seed", seed, "cases", len(cases), "differences", diffs, json.dumps(by, sort_keys=True))
for c, a, b in zip(cases, py, php):
if a != b:
print(json.dumps(c, ensure_ascii=False)[:500]); print(a[:300]); print("---"); print(b[:300]); break