The Principia Machina/TPC-PY/gen tests corpus.py
Appearance
# -*- coding: utf-8 -*-
"""Generator for tpc/vectors/tests_corpus.json (TPC step 2, increments 7 and
8: kernel tests T2, T3, T4, T5, T6 and the isomorphism checks IC1-IC4). Every
expectation is HAND-DERIVED and written literally below; the generator
refuses to write the corpus if the module disagrees with any of them.
SELECTED D106.1, D107.1, D108.1 (2026-09-22): the T2 cases follow D106.1,
the IC cases D107.1; increment 8 (2026-09-24) adds the runner cases of the
formulation's V8: kernel_tests with T4 and T6, final_checks with T3 over
laws, ic_checks with IC4 (a), and the OPTIONAL rule as a vector. Schema 0.5.0 (D176.1,
D177.1, 2026-09-26): every fixture LAW carries a ROLE; the D-variable cases at the end.
S33 (2026-09-26): a LAW restating the motion of a FIXed (or REMOVEd) DOF carries ROLE
CONSTRAINT; s33_roles sets the spring's ROLEs wherever a fixture's constraints change.
0.3.2 (C-MS-5, increment 11): the decode/ cases tell a JSON {} from a JSON [];
the corpus is written with LF line ends on every platform (S65).
Run: cd tpc && python3 gen_tests_corpus.py (Windows: py gen_tests_corpus.py)."""
import copy, json, os, sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import tpc_tests as K
import tpc_strike as S
# ---- the toy TFK of the zone corpus: a mass on a linear spring, z fixed at 0 -----
TPK = {
"DOF": [
{"NAME": "x", "DIMENSION": "L1"},
{"NAME": "v", "DIMENSION": "L1 T-1"},
{"NAME": "z", "DIMENSION": "L1"}],
"CONSTANT": [
{"NAME": "m", "DIMENSION": "M1"},
{"NAME": "k_s", "DIMENSION": "M1 T-2"},
{"NAME": "x_max", "DIMENSION": "L1", "VALUE": "0.05", "UNIT": "m", "UNCERTAINTY": "0.001"}],
"LAW": [
{"NAME": "N2", "STATEMENT": "m dv/dt = -k_s x", "REFS": ["m", "v", "k_s", "x"], "ROLE": "EOM(v)"},
{"NAME": "KIN", "STATEMENT": "dx/dt = v", "REFS": ["x", "v"], "ROLE": "EOM(x)"},
{"NAME": "FREE_Z", "STATEMENT": "d2z/dt2 = 0", "REFS": ["z"], "ROLE": "CONSTRAINT"}],
"ASSUMPTION": [
{"NAME": "A_lin", "PROPOSITION": "the restoring force is linear in x (Hooke r\u00e9gime)", "REFS": ["x"]}],
"CONSTRAINT": [
{"NAME": "C_NOZ", "TARGET": "z", "ACTION": "FIX", "VALUE": "0", "UNIT": "m", "STATEMENT": "motion confined to z = 0"}],
"BOUNDARY": [
{"NAME": "B_small", "PREDICATE": "|x| < x_max", "REFS": ["x", "x_max"]}],
}
TRM = {
"HEADER": {
"ENVIRONMENT_INVENTORY": [
{"ENVIRONMENT_QUANTITY": "position", "DIMENSION": "L1"},
{"ENVIRONMENT_QUANTITY": "velocity", "DIMENSION": "L1 T-1"},
{"ENVIRONMENT_QUANTITY": "height", "DIMENSION": "L1"}],
"SIGNATURE": [
{"NAME": "time_derivative", "OVER": ["x", "v"], "IMAGE": "d/dt maps position to velocity"}],
"TRANSFORMATIONS": [
{"NAME": "time_translation", "STATEMENT": "t -> t + t0"}]},
"ENTRIES": [
{"NAME": "E_x", "DOF": "x", "DOMAIN": "|x| < x_max", "ENVIRONMENT_QUANTITY": "position",
"IDENTIFICATION": "x is the displacement from equilibrium along the spring axis",
"FALSIFIER": "a measured restoring force not proportional to x inside the domain",
"FALSIFIER_CLASS": "F3", "BEARS": ["N2", "KIN"], "DIMENSION": "L1"},
{"NAME": "E_v", "DOF": "v", "DOMAIN": "|x| < x_max", "ENVIRONMENT_QUANTITY": "velocity",
"IDENTIFICATION": "v is the time derivative of x",
"FALSIFIER": "a measured velocity differing from dx/dt beyond uncertainty",
"FALSIFIER_CLASS": "F2", "BEARS": ["KIN"], "DIMENSION": "L1 T-1"},
{"NAME": "E_z", "DOF": "z", "DOMAIN": "always", "ENVIRONMENT_QUANTITY": "height",
"IDENTIFICATION": "z is the height above the track",
"FALSIFIER": "any measured z different from 0",
"FALSIFIER_CLASS": "F3", "BEARS": ["FREE_Z", "C_NOZ"], "DIMENSION": "L1"}],
}
TMS = {
"PARAMETERS": {"STEP_CONVENTION": "one application of an inference rule or algebraic identity is one step",
"K": "2", "N_X": 2, "S_MAX": 10},
"CONSTANTS": [{"NAME": "w_a", "VALUE": "1"}, {"NAME": "w_s", "VALUE": "0.5"}],
"YARDSTICKS": [{"NAME": "combined_distance", "KEY": ["SR1", "WSUM:w_a*A;w_s*S", "S"], "LIMITING": []}],
}
TFK = {"TPK": TPK, "TrM": TRM, "TMS": TMS}
def c(o):
return copy.deepcopy(o)
def entry(name, dof, q, dim, bears=()):
return {"NAME": name, "DOF": dof, "DOMAIN": "always", "ENVIRONMENT_QUANTITY": q,
"IDENTIFICATION": dof + " is " + q, "FALSIFIER": "a measured " + q + " unlike " + dof,
"FALSIFIER_CLASS": "F2", "BEARS": list(bears), "DIMENSION": dim}
# S33 (2026-09-26): EOM(q) is the ROLE of a law for the DOF it moves; a law restating the
# motion of a DOF the kernel FIXes (or REMOVEs, the like case) takes ROLE CONSTRAINT. MOTION
# names the DOF each law of the spring family moves; s33_roles sets those ROLEs from the
# TPK's constraints wherever a fixture's constraints change. Only the spring family's
# fixtures pass through it; a vector whose subject is the ROLE sets its ROLE after it.
MOTION = {"N2": "v", "EOM_X": "v", "KIN": "x", "FREE_Z": "z", "EOM_Z": "z"}
def s33_roles(tpk):
cons = tpk.get("CONSTRAINT", [])
held = set(e["TARGET"] for e in (cons if isinstance(cons, list) else [])
if isinstance(e, dict) and e.get("ACTION") in ("FIX", "REMOVE") and isinstance(e.get("TARGET"), str))
for l in tpk["LAW"]:
q = MOTION.get(l.get("NAME"))
if q is not None:
l["ROLE"] = "CONSTRAINT" if q in held else "EOM(" + q + ")"
return tpk
def with_cons(tpk, *cons):
t = c(tpk)
t["CONSTRAINT"] = list(cons)
return s33_roles(t)
def fix(name, target, value, unit):
return {"NAME": name, "TARGET": target, "ACTION": "FIX", "VALUE": value, "UNIT": unit,
"STATEMENT": target + " = " + value + " " + unit}
def remove(name, target):
return {"NAME": name, "TARGET": target, "ACTION": "REMOVE", "STATEMENT": "no " + target}
cases = []
def add(cid, fn, inp, expect, **extra):
cs = {"id": cid, "fn": fn, "input": inp}
cs.update(extra)
cs["expect"] = expect
cases.append(cs)
AND = 'joins claims with "and"'
# ---- T2, syntactic part (D106.1) ------------------------------------------------
T2 = [
("t2/pass-toy", "the restoring force is linear in x (Hooke r\u00e9gime)", "[]"),
("t2/and", "friction is negligible and the table is level", "[" + AND + "]"),
("t2/and-enclosed", "(friction is negligible and the table is level)", "[" + AND + "]"),
("t2/AND-double-enclosed", "((A holds AND B holds))", "[" + AND + "]"),
("t2/and-in-brackets", "(a and b) holds", "[]"),
("t2/limit-between", "x lies between 0 and 1", "[" + AND + "]"),
("t2/word-boundary", "Andrew's law holds", "[]"),
("t2/word-boundary-inner", "sand and band", "[" + AND + "]"),
("t2/ampersand", "x & y hold", '[joins claims with "&"]'),
("t2/logical-and", "x \u2227 y", "[joins claims with U+2227]"),
("t2/as-well-as", "mass as well as charge is conserved", '[joins claims with "as well as"]'),
("t2/but", "it is linear, but it saturates", '[joins claims with "but"]'),
("t2/whereas", "x rises whereas y falls", '[joins claims with "whereas"]'),
("t2/semicolon", "A holds; B holds", "[has a semicolon]"),
("t2/two-sentences", "It holds. Then it fails", "[has more than one sentence]"),
("t2/two-sentences-bang", "Ohm's law holds! It is linear", "[has more than one sentence]"),
("t2/abbreviation", "linear e.g. in x", "[]"),
("t2/decimal", "x = 0.5 m exactly", "[]"),
("t2/list-hyphen", "linear in x.\n- quadratic in y", "[is a list]"),
("t2/list-number", "first claim\n2. second claim", "[is a list]"),
("t2/quoted", 'the word "and" is quoted', "[]"),
("t2/curly-quoted", "the claim \u201cA and B\u201d is quoted", "[]"),
("t2/semicolon-in-brackets", "x holds and (y holds; z holds)", "[" + AND + "]"),
("t2/two-findings", "one; two and three", "[has a semicolon," + AND + "]"),
("t2/unmatched-closer", "a) and b", "[" + AND + "]"),
("t2/unclosed-bracket", "(A and B", "[" + AND + "]"),
("t2/unclosed-quote", 'he said "A and B', "[" + AND + "]"),
("t2/mismatched-brackets", "(A and B]", "[" + AND + "]"),
("t2/enclosed-with-space", " [A and B] ", "[" + AND + "]"),
("t2/two-groups", "(A) and (B)", "[" + AND + "]"),
("t2/nested-in-unclosed", "(A (x) and B", "[" + AND + "]"),
("t2/crlf-list", "first\r\n- second", "[is a list]"),
]
for cid, p, e in T2:
add(cid, "t2_findings", {"prop": p}, e)
t = c(TPK); t["ASSUMPTION"][0]["PROPOSITION"] = "friction is negligible and the table is level"
add("t2a/toy", "t2_atomicity", {"tpk": TPK}, "[true,[]]")
add("t2a/and", "t2_atomicity", {"tpk": t}, "[false,[ASSUMPTION:A_lin: PROPOSITION " + AND + " (T2)]]")
t = c(TPK); t["ASSUMPTION"] = [{"NAME": "A_1", "PROPOSITION": "x; y", "REFS": ["x"]},
{"NAME": "A_2", "PROPOSITION": "It holds. It fails", "REFS": ["x"]}]
add("t2a/two", "t2_atomicity", {"tpk": t},
"[false,[ASSUMPTION:A_1: PROPOSITION has a semicolon (T2),ASSUMPTION:A_2: PROPOSITION has more than one sentence (T2)]]")
t = c(TPK); t["ASSUMPTION"][0]["PROPOSITION"] = 7
add("t2a/malformed-left-to-T1", "t2_atomicity", {"tpk": t}, "[true,[]]")
t = c(TPK); t["ASSUMPTION"][0]["PROPOSITION"] = "a \u202e and b"
add("t2a/hidden-left-to-T1", "t2_atomicity", {"tpk": t}, "[true,[]]")
add("t2a/not-an-object", "t2_atomicity", {"tpk": "x"}, "[true,[]]")
# ---- T3, the executable fragment ----------------------------------------------------
add("t3/toy", "t3_consistency", {"tpk": TPK, "tms": TMS}, "[true,[]]")
add("t3/same-value", "t3_consistency", {"tpk": with_cons(TPK, TPK["CONSTRAINT"][0], fix("C_Z2", "z", "0", "cm")), "tms": TMS},
"[true,[]]")
add("t3/same-value-other-unit", "t3_consistency",
{"tpk": with_cons(TPK, fix("C_NOZ", "z", "0.05", "m"), fix("C_Z2", "z", "5", "cm")), "tms": TMS}, "[true,[]]")
add("t3/two-values", "t3_consistency", {"tpk": with_cons(TPK, TPK["CONSTRAINT"][0], fix("C_Z2", "z", "1", "m")), "tms": TMS},
"[false,[CONSTRAINT:C_NOZ and CONSTRAINT:C_Z2: z fixed at 0 m and at 1 m (T3)]]")
add("t3/removed-and-fixed", "t3_consistency", {"tpk": with_cons(TPK, TPK["CONSTRAINT"][0], remove("C_ZR", "z")), "tms": TMS},
"[false,[CONSTRAINT:C_NOZ and CONSTRAINT:C_ZR: z is both removed and fixed (T3)]]")
add("t3/removed-twice", "t3_consistency", {"tpk": with_cons(TPK, remove("C_R1", "z"), remove("C_R2", "z")), "tms": TMS},
"[true,[]]")
ang = c(TPK); ang["DOF"].append({"NAME": "theta", "DIMENSION": "1"})
add("t3/angle-equal", "t3_consistency",
{"tpk": with_cons(ang, fix("C_A", "theta", "90", "deg"), fix("C_B", "theta", "1.5707963267949", "rad")), "tms": TMS},
"[true,[]]")
add("t3/angle-unequal", "t3_consistency",
{"tpk": with_cons(ang, fix("C_A", "theta", "90", "deg"), fix("C_B", "theta", "1.5708", "rad")), "tms": TMS},
"[false,[CONSTRAINT:C_A and CONSTRAINT:C_B: theta fixed at 90 deg and at 1.5708 rad (T3)]]")
frq = c(TPK); frq["DOF"].append({"NAME": "f", "DIMENSION": "T-1"})
add("t3/kind-differs", "t3_consistency",
{"tpk": with_cons(frq, fix("C_F1", "f", "1", "Hz"), fix("C_F2", "f", "6.283185307179586", "rad s-1")), "tms": TMS},
"[false,[CONSTRAINT:C_F1 and CONSTRAINT:C_F2: the two FIX values of f cannot be compared: units of different kind: Hz1 and rad1 (T3)]]")
add("t3/three", "t3_consistency",
{"tpk": with_cons(TPK, fix("C_A", "z", "0", "m"), fix("C_B", "z", "1", "m"), remove("C_C", "z")), "tms": TMS},
"[false,[CONSTRAINT:C_A and CONSTRAINT:C_B: z fixed at 0 m and at 1 m (T3),"
"CONSTRAINT:C_A and CONSTRAINT:C_C: z is both removed and fixed (T3),"
"CONSTRAINT:C_B and CONSTRAINT:C_C: z is both removed and fixed (T3)]]")
add("t3/overflow", "t3_consistency", {"tpk": with_cons(TPK, TPK["CONSTRAINT"][0], fix("C_ZH", "z", "1e9999", "m")), "tms": TMS},
"[false,[CONSTRAINT:C_NOZ and CONSTRAINT:C_ZH: the two FIX values of z cannot be compared (T3)]]")
add("t3/no-depth", "t3_consistency", {"tpk": TPK, "tms": {"PARAMETERS": {"S_MAX": 0}}},
"[false,[T3: S_MAX is not a declared depth of at least 1]]")
add("t3/depth-bool", "t3_consistency", {"tpk": TPK, "tms": {"PARAMETERS": {"S_MAX": True}}},
"[false,[T3: S_MAX is not a declared depth of at least 1]]")
# ---- T5 ---------------------------------------------------------------------------
add("t5/toy", "t5_dof_yield", {"tpk": TPK}, "[true,[]]")
t = c(TPK); t["DOF"].append({"NAME": "w", "DIMENSION": "L1"})
add("t5/idle-dof", "t5_dof_yield", {"tpk": t}, "[false,[DOF:w: named by no LAW (T5 c)]]")
t2_ = c(t); t2_["BOUNDARY"].append({"NAME": "B_w", "PREDICATE": "w > 0", "REFS": ["w"]})
add("t5/boundary-is-not-a-law", "t5_dof_yield", {"tpk": t2_}, "[false,[DOF:w: named by no LAW (T5 c)]]")
t = c(TPK); t["LAW"] = [l for l in t["LAW"] if l["NAME"] != "FREE_Z"]
add("t5/void-constraint", "t5_dof_yield", {"tpk": t},
"[false,[CONSTRAINT:C_NOZ: TARGET z is named by no LAW, so no law leaves it free (T5 b),DOF:z: named by no LAW (T5 c)]]")
# ---- kernel_tests ---------------------------------------------------------------------
NO_FORM_INSP = ('[BOUNDARY:B_small: no CONDITION; T6 totality by inspection,LAW:FREE_Z: no EQUATION; T4 and T3 over this law by inspection,'
'LAW:KIN: no EQUATION; T4 and T3 over this law by inspection,LAW:N2: no EQUATION; T4 and T3 over this law by inspection]')
add("kt/toy", "kernel_tests", {"tpk": TPK},
"[true,[[T1,true,[]],[T2,true,[]],[T5,true,[]],[T4,NO FORM,[]],[T6,NO FORM,[]]]," + NO_FORM_INSP + "]",
note="the OPTIONAL rule as a vector (V8): a TPK without any form passes as at increment 7; T4 and T6 read NO FORM and the inspections owed are listed")
t = c(TPK); t["LAW"][1]["REFS"] = ["x", "v", "q"]
add("kt/T1-stops", "kernel_tests", {"tpk": t},
"[false,[[T1,false,[LAW:KIN: REFS q does not resolve]],[T2,NOT_RUN,[]],[T5,NOT_RUN,[]],[T4,NOT_RUN,[]],[T6,NOT_RUN,[]]],[]]")
t = c(TPK); t["ASSUMPTION"][0]["PROPOSITION"] = "friction is negligible and the table is level"
t["DOF"].append({"NAME": "w", "DIMENSION": "L1"})
add("kt/T2-T5", "kernel_tests", {"tpk": t},
"[false,[[T1,true,[]],[T2,false,[ASSUMPTION:A_lin: PROPOSITION " + AND + " (T2)]],[T5,false,[DOF:w: named by no LAW (T5 c)]],"
"[T4,NO FORM,[]],[T6,NO FORM,[]]]," + NO_FORM_INSP + "]")
# ---- increment 8: the spring with its forms (V8) --------------------------------------------
TPK_F = c(TPK)
TPK_F["DOF"].append({"NAME": "t", "DIMENSION": "T1"})
TPK_F["LAW"] = [
{"NAME": "N2", "STATEMENT": "m dv/dt = -k_s x", "REFS": ["m", "v", "k_s", "x", "t"], "ROLE": "EOM(v)",
"EQUATION": "m * D(v, t) = -k_s * x"},
{"NAME": "KIN", "STATEMENT": "dx/dt = v", "REFS": ["x", "v", "t"], "ROLE": "EOM(x)", "EQUATION": "D(x, t) = v"},
{"NAME": "FREE_Z", "STATEMENT": "d2z/dt2 = 0", "REFS": ["z", "t"], "ROLE": "CONSTRAINT", "EQUATION": "D(z, t, 2) = 0"}]
TPK_F["BOUNDARY"] = [{"NAME": "B_small", "PREDICATE": "|x| < x_max", "REFS": ["x", "x_max"], "CONDITION": "abs(x) < x_max"}]
TRM_F = c(TRM)
TRM_F["HEADER"]["ENVIRONMENT_INVENTORY"].append({"ENVIRONMENT_QUANTITY": "time", "DIMENSION": "T1"})
TRM_F["HEADER"]["SIGNATURE"] = [{"NAME": "time_derivative", "OVER": ["x", "v", "t"], "IMAGE": "d/dt maps position to velocity",
"FORM": "D(x, t) = v", "IMAGE_FORM": "D(position, time) = velocity"}]
TRM_F["ENTRIES"].append({"NAME": "E_t", "DOF": "t", "DOMAIN": "always", "ENVIRONMENT_QUANTITY": "time",
"IDENTIFICATION": "t is the laboratory clock reading",
"FALSIFIER": "two laboratory clocks that disagree beyond their stated uncertainty",
"FALSIFIER_CLASS": "F3", "BEARS": [], "DIMENSION": "T1"})
TFK_F = {"TPK": TPK_F, "TrM": TRM_F, "TMS": TMS}
ALL_PASS_F = "[true,[[T1,true,[]],[T2,true,[]],[T5,true,[]],[T4,true,[]],[T6,true,[]]],[]]"
add("kt/forms-pass", "kernel_tests", {"tpk": TPK_F}, ALL_PASS_F)
t = c(TPK_F); t["LAW"][0]["EQUATION"] = "m * D(v, t) = -k_s * x * x"
add("kt/T4-fails", "kernel_tests", {"tpk": t},
"[false,[[T1,true,[]],[T2,true,[]],[T5,true,[]],[T4,false,[LAW:N2: EQUATION sides have dimensions L1 M1 T-2 and L2 M1 T-2 (T4)]],[T6,true,[]]],[]]")
t = c(TPK_F); t["BOUNDARY"][0]["CONDITION"] = "x / x_max < 1"
add("kt/T6-fails", "kernel_tests", {"tpk": t},
"[false,[[T1,true,[]],[T2,true,[]],[T5,true,[]],[T4,true,[]],[T6,false,[BOUNDARY:B_small: CONDITION uses / on x_max with no guard x_max != 0 (T6)]]],[]]")
t = c(TPK_F); del t["LAW"][1]["EQUATION"]
add("kt/partial-forms", "kernel_tests", {"tpk": t},
"[true,[[T1,true,[]],[T2,true,[]],[T5,true,[]],[T4,true,[]],[T6,true,[]]],[LAW:KIN: no EQUATION; T4 and T3 over this law by inspection]]",
note="a law without a form is listed, never silently passed (kernel tests 12.3)")
t = c(TPK_F); t["LAW"][1]["REFS"] = ["x", "v"]
add("kt/T1-names", "kernel_tests", {"tpk": t},
"[false,[[T1,false,[LAW:KIN: EQUATION names t, which is not in REFS]],[T2,NOT_RUN,[]],[T5,NOT_RUN,[]],[T4,NOT_RUN,[]],[T6,NOT_RUN,[]]],[]]")
TPK_B = c(TPK_F)
TPK_B["CONSTANT"][0]["VALUE"] = "2"; TPK_B["CONSTANT"][0]["UNIT"] = "kg"
TPK_B["CONSTANT"][1]["VALUE"] = "3"; TPK_B["CONSTANT"][1]["UNIT"] = "N m-1"
TPK_B["CONSTRAINT"] += [fix("C_X", "x", "0.1", "m"), fix("C_V", "v", "0", "m s-1")]
s33_roles(TPK_B) # x and v FIXed: N2 and KIN restate their motion (S33)
add("t3/laws-ground-fragment", "t3_consistency", {"tpk": TPK_B, "tms": TMS},
"[false,[LAW:N2 and CONSTRAINT:C_V and CONSTRAINT:C_X: N2 evaluates 0 = -0.3 under the fixed values (T3)]]",
note="every identifier of N2 is bound; D(v,t) of the FIXed v is 0; KIN and FREE_Z evaluate 0 = 0")
add("t3/laws-nothing-claimed", "t3_consistency", {"tpk": TPK_F, "tms": TMS}, "[true,[]]")
add("ic/forms-pass", "ic_checks", {"trm": TRM_F, "tpk": TPK_F}, "[PASS,[],[]]")
t = c(TRM_F); t["HEADER"]["SIGNATURE"][0]["IMAGE_FORM"] = "D(position, time) = position"
add("ic/IC4a-fails", "ic_checks", {"trm": t, "tpk": TPK_F},
"[REJECT,[IC4(a): SIGNATURE:time_derivative: FORM under the entries reads D(position,time)=velocity, not IMAGE_FORM D(position,time)=position],[]]")
t = c(TRM_F); t["ENTRIES"] = [e for e in t["ENTRIES"] if e["NAME"] != "E_t"]
t["HEADER"]["ENVIRONMENT_INVENTORY"] = [q for q in t["HEADER"]["ENVIRONMENT_INVENTORY"] if q["ENVIRONMENT_QUANTITY"] != "time"]
t["HEADER"]["SIGNATURE"][0]["IMAGE_FORM"] = "D(position, height) = velocity"
t["ENTRIES"][0]["BEARS"] = []; t["ENTRIES"][1]["BEARS"] = []; t["ENTRIES"][2]["BEARS"] = ["C_NOZ"]
add("ic/IC4a-undecided-is-IC2-gap", "ic_checks", {"trm": t, "tpk": TPK_F}, "[GAP,[],[IC2: DOF t is untied]]",
note="a DOF in OVER with no entry is IC2's gap, not IC4's failure (S8): the signature is undecided, not rejected")
add("fp/forms-pass", "final_checks", {"tfk": TFK_F}, "[PASS,[],[]]")
f = c(TFK_F); f["TPK"] = TPK_B
add("fp/T3-laws", "final_checks", {"tfk": f},
"[REJECT,[LAW:N2 and CONSTRAINT:C_V and CONSTRAINT:C_X: N2 evaluates 0 = -0.3 under the fixed values (T3)],[]]")
# ---- IC1-IC4 (D107.1) -------------------------------------------------------------------
add("ic/toy", "ic_checks", {"trm": TRM, "tpk": TPK}, "[PASS,[],[]]")
gap = c(TRM)
gap["HEADER"]["ENVIRONMENT_INVENTORY"] = [q for q in gap["HEADER"]["ENVIRONMENT_INVENTORY"] if q["ENVIRONMENT_QUANTITY"] != "velocity"]
gap["ENTRIES"] = [e for e in gap["ENTRIES"] if e["NAME"] != "E_v"]
gap_clean = c(gap); gap_clean["ENTRIES"][0]["BEARS"] = []
add("ic/gap", "ic_checks", {"trm": gap_clean, "tpk": TPK}, "[GAP,[],[IC2: DOF v is untied]]")
add("ic/gap-borne-law", "ic_checks", {"trm": gap, "tpk": TPK},
"[REJECT,[IC4(c): ENTRY:E_x: BEARS LAW:KIN, which names DOF v that no entry identifies,"
"IC4(c): ENTRY:E_x: BEARS LAW:N2, which names DOF v that no entry identifies],[IC2: DOF v is untied]]")
t = c(TRM); t["HEADER"]["ENVIRONMENT_INVENTORY"].append({"ENVIRONMENT_QUANTITY": "acceleration", "DIMENSION": "L1 T-2"})
add("ic/IC1", "ic_checks", {"trm": t, "tpk": TPK}, "[REJECT,[IC1: environment quantity acceleration is identified by no entry],[]]")
rem = with_cons(TPK, remove("C_NOZ", "z"))
add("ic/codomain", "ic_checks", {"trm": TRM, "tpk": rem},
"[REJECT,[CODOMAIN: ENTRY:E_z identifies DOF z, which CONSTRAINT:C_NOZ removes,"
"IC4(c): ENTRY:E_z: BEARS CONSTRAINT:C_NOZ, whose TARGET z no entry identifies,"
"IC4(c): ENTRY:E_z: BEARS LAW:FREE_Z, which names DOF z that no entry identifies],[]]")
t = c(TRM)
t["HEADER"]["ENVIRONMENT_INVENTORY"] = [q for q in t["HEADER"]["ENVIRONMENT_INVENTORY"] if q["ENVIRONMENT_QUANTITY"] != "height"]
t["ENTRIES"] = [e for e in t["ENTRIES"] if e["NAME"] != "E_z"]
add("ic/removed-needs-no-entry", "ic_checks", {"trm": t, "tpk": rem}, "[PASS,[],[]]")
t = c(TRM); t["HEADER"]["ENVIRONMENT_INVENTORY"].append({"ENVIRONMENT_QUANTITY": "extension", "DIMENSION": "L1"})
t["ENTRIES"].append(entry("E_x2", "x", "extension", "L1"))
add("ic/IC3-dof", "ic_checks", {"trm": t, "tpk": TPK},
"[REJECT,[IC3: DOF x is identified with inequivalent quantities extension, position (ENTRY:E_x, ENTRY:E_x2)],[]]")
t = c(TRM); t["ENTRIES"].append(entry("E_h2", "x", "height", "L1"))
add("ic/IC3-both", "ic_checks", {"trm": t, "tpk": TPK},
"[REJECT,[IC3: DOF x is identified with inequivalent quantities height, position (ENTRY:E_h2, ENTRY:E_x),"
"IC3: environment quantity height is identified with DOF x, z (ENTRY:E_h2, ENTRY:E_z)],[]]")
t = c(TRM); t["ENTRIES"][1]["DIMENSION"] = "L1"
add("ic/IC4b-both-sides", "ic_checks", {"trm": t, "tpk": TPK},
"[REJECT,[IC4(b): ENTRY:E_v: DIMENSION L1 differs from DOF v's L1 T-1,"
"IC4(b): ENTRY:E_v: DIMENSION L1 differs from environment quantity velocity's L1 T-1],[]]")
t = c(TRM); t["HEADER"]["ENVIRONMENT_INVENTORY"][1]["DIMENSION"] = "L1 T-2"
add("ic/IC4b-environment", "ic_checks", {"trm": t, "tpk": TPK},
"[REJECT,[IC4(b): ENTRY:E_v: DIMENSION L1 T-1 differs from environment quantity velocity's L1 T-2],[]]")
t = c(TRM); t["ENTRIES"][1]["DIMENSION"] = "T-1 L1"
add("ic/IC4b-respelled", "ic_checks", {"trm": t, "tpk": TPK}, "[PASS,[],[]]")
t = c(TRM); del t["ENTRIES"]
add("ic/not-run-trm", "ic_checks", {"trm": t, "tpk": TPK}, "[NOT_RUN,[IC: the TrM is not well-formed],[]]")
t = c(TPK); t["LAW"][1]["REFS"] = ["x", "v", "q"]
add("ic/not-run-tpk", "ic_checks", {"trm": TRM, "tpk": t}, "[NOT_RUN,[IC: the TPK does not pass T1],[]]")
# ---- final pass -------------------------------------------------------------------------
add("fp/toy", "final_checks", {"tfk": TFK}, "[PASS,[],[]]")
f = c(TFK); f["TrM"] = gap_clean
add("fp/gap", "final_checks", {"tfk": f}, "[GAP,[],[IC2: DOF v is untied]]")
f2 = c(f); f2["TMS"]["PARAMETERS"]["IC2_POLICY"] = "REJECT"
add("fp/gap-rejected", "final_checks", {"tfk": f2}, "[REJECT,[IC2: DOF v is untied and IC2_POLICY is REJECT],[IC2: DOF v is untied]]")
f = c(TFK); f["TPK"] = with_cons(TPK, TPK["CONSTRAINT"][0], fix("C_Z2", "z", "1", "m"))
add("fp/T3", "final_checks", {"tfk": f}, "[REJECT,[CONSTRAINT:C_NOZ and CONSTRAINT:C_Z2: z fixed at 0 m and at 1 m (T3)],[]]")
f = c(TFK); f["TPK"]["ASSUMPTION"][0]["PROPOSITION"] = "friction is negligible and the table is level"
add("fp/not-run-kernel", "final_checks", {"tfk": f}, "[NOT_RUN,[final pass: the TPK does not pass T1, T2, T5, T4 and T6],[]]")
f = c(TFK); f["TrM"]["HEADER"]["ENVIRONMENT_INVENTORY"].append({"ENVIRONMENT_QUANTITY": "acceleration", "DIMENSION": "L1 T-2"})
add("fp/not-run-trm", "final_checks", {"tfk": f}, "[NOT_RUN,[final pass: the TrM does not pass IC1-IC4],[]]")
f = c(TFK); f["TMS"]["PARAMETERS"]["S_MAX"] = 0
add("fp/not-run-tms", "final_checks", {"tfk": f}, "[NOT_RUN,[final pass: the TMS is not well-formed],[]]")
add("fp/not-an-object", "final_checks", {"tfk": "x"}, "[NOT_RUN,[final pass: the TFK is not an object],[]]")
# ---- schema 0.5.0 and the D variable (D176.1, D177.1) ---------------------------------------
# T1 reads ROLE and the TPK PARAMETERS; T4 reads D(x, s, n) as dim(x) less n times dim(s), s any
# DOF that no CONSTRAINT targets (the DIMENSION T1 requirement removed). The research drafts
# below are copied from out/A/suite (A21, A10a) and out/D/examples (corner_fix_t) with ROLEs
# added by their physics; their TrMs follow the suite's entry template. Hand-derived.
def suite_trm(dofs, bears):
"""The out/A/suite TrM template: one environment quantity env_<d> and one entry E_<d> per DOF."""
return {"HEADER": {"ENVIRONMENT_INVENTORY": [{"ENVIRONMENT_QUANTITY": "env_" + d, "DIMENSION": dim} for d, dim in dofs],
"SIGNATURE": [],
"TRANSFORMATIONS": [{"NAME": "unit_rescaling", "STATEMENT": "a change of units rescales each value"}]},
"ENTRIES": [{"NAME": "E_" + d, "DOF": d, "DOMAIN": "inside every declared boundary", "ENVIRONMENT_QUANTITY": "env_" + d,
"IDENTIFICATION": d + " is identified with the measured env_" + d,
"FALSIFIER": "a measured env_" + d + " outside the kernel's prediction beyond uncertainty",
"FALSIFIER_CLASS": "F2", "BEARS": list(bears), "DIMENSION": dim} for d, dim in dofs]}
# A21: dimensionless (scaled) time tau, a DOF of DIMENSION 1
A21 = {"TPK": {"DOF": [{"NAME": "X", "DIMENSION": "1"}, {"NAME": "V", "DIMENSION": "1"}, {"NAME": "tau", "DIMENSION": "1"}],
"LAW": [{"NAME": "KIN", "STATEMENT": "dX/dtau = V", "REFS": ["X", "V", "tau"], "ROLE": "EOM(X)",
"EQUATION": "D(X, tau) = V"},
{"NAME": "N2", "STATEMENT": "dV/dtau = -X", "REFS": ["X", "V", "tau"], "ROLE": "EOM(V)",
"EQUATION": "D(V, tau) = -X"}]},
"TrM": suite_trm([("X", "1"), ("V", "1"), ("tau", "1")], ["KIN", "N2"]), "TMS": c(TMS)}
T6_NO_FORM = "[T6,NO FORM,[]]"
add("kt/s050-scaled-time-A21", "kernel_tests", {"tpk": A21["TPK"]},
"[true,[[T1,true,[]],[T2,true,[]],[T5,true,[]],[T4,true,[]]," + T6_NO_FORM + "],[]]",
note="out/A/suite/A21 with ROLEs added: D(X,tau) of X and tau of DIMENSION 1 is 1 (D177.1); "
"the DIMENSION T1 requirement refused it before")
add("fp/s050-scaled-time-A21", "final_checks", {"tfk": A21}, "[PASS,[],[]]")
# corner_fix_t: the clock FIXed, so no D variable (T1)
CFT_TPK = {
"DOF": [{"NAME": "t", "DIMENSION": "T1"}, {"NAME": "x", "DIMENSION": "L1"}, {"NAME": "v", "DIMENSION": "L1 T-1"},
{"NAME": "z", "DIMENSION": "L1"}],
"CONSTANT": [{"NAME": "m", "DIMENSION": "M1"}, {"NAME": "k_s", "DIMENSION": "M1 T-2"},
{"NAME": "x_max", "DIMENSION": "L1", "VALUE": "0.05", "UNIT": "m", "UNCERTAINTY": "0.001"}],
"LAW": [{"NAME": "EOM_X", "STATEMENT": "m dv/dt = -k_s x", "REFS": ["m", "v", "k_s", "x", "t"], "ROLE": "EOM(v)",
"EQUATION": "m * D(v, t) = -k_s * x"},
{"NAME": "KIN", "STATEMENT": "dx/dt = v", "REFS": ["x", "v", "t"], "ROLE": "EOM(x)", "EQUATION": "D(x, t) = v"},
{"NAME": "EOM_Z", "STATEMENT": "m d2z/dt2 = 0", "REFS": ["m", "z", "t"], "ROLE": "CONSTRAINT",
"EQUATION": "m * D(z, t, 2) = 0"}],
"ASSUMPTION": [{"NAME": "A_kpos", "PROPOSITION": "k_s is positive", "REFS": ["k_s"]},
{"NAME": "A_mpos", "PROPOSITION": "m is positive", "REFS": ["m"]}],
"CONSTRAINT": [{"NAME": "C_NOZ", "TARGET": "z", "ACTION": "FIX", "VALUE": "0", "UNIT": "m",
"STATEMENT": "only motion on the spring axis is described: z = 0"},
{"NAME": "C_T", "TARGET": "t", "ACTION": "FIX", "VALUE": "0", "UNIT": "s", "STATEMENT": "t = 0"}],
"BOUNDARY": [{"NAME": "B_small", "PREDICATE": "|x| < x_max", "REFS": ["x", "x_max"], "CONDITION": "abs(x) < x_max"}]}
NR4 = "[T2,NOT_RUN,[]],[T5,NOT_RUN,[]],[T4,NOT_RUN,[]],[T6,NOT_RUN,[]]"
add("kt/s050-corner-fix-t", "kernel_tests", {"tpk": CFT_TPK},
"[false,[[T1,false,[LAW:EOM_X: EQUATION's D variable t is the TARGET of CONSTRAINT:C_T,"
"LAW:EOM_Z: EQUATION's D variable t is the TARGET of CONSTRAINT:C_T,"
"LAW:KIN: EQUATION's D variable t is the TARGET of CONSTRAINT:C_T]]," + NR4 + "],[]]",
note="out/D/examples/corner_fix_t.json with ROLEs added: a FIXed clock is no D variable (D177.1); "
"under schema 0.4.0 it passed every check (E-N7)")
cft = c(CFT_TPK); cft["CONSTRAINT"] = cft["CONSTRAINT"][:1]
add("kt/s050-corner-fix-t-unfixed", "kernel_tests", {"tpk": cft},
"[true,[[T1,true,[]],[T2,true,[]],[T5,true,[]],[T4,true,[]],[T6,true,[]]],[]]",
note="the same kernel without C_T: t is a D variable again")
# A10a: the heat equation, two D variables (t and X)
HEAT_TPK = {
"DOF": [{"NAME": "u", "DIMENSION": "TH1"}, {"NAME": "X", "DIMENSION": "L1"}, {"NAME": "t", "DIMENSION": "T1"}],
"CONSTANT": [{"NAME": "alpha_d", "DIMENSION": "L2 T-1"}, {"NAME": "L_rod", "DIMENSION": "L1"}],
"LAW": [{"NAME": "HEAT", "STATEMENT": "du/dt = alpha d2u/dX2", "REFS": ["u", "t", "alpha_d", "X"], "ROLE": "EOM(u)",
"EQUATION": "D(u, t) = alpha_d * D(u, X, 2)"}],
"BOUNDARY": [{"NAME": "B_rod", "PREDICATE": "0 <= X <= L_rod", "REFS": ["X", "L_rod"], "CONDITION": "0 <= X and X <= L_rod"}]}
HEAT_TRM = suite_trm([("u", "TH1"), ("X", "L1"), ("t", "T1")], ["HEAT"])
add("kt/s050-heat-under-one", "kernel_tests", {"tpk": HEAT_TPK},
"[false,[[T1,false,[TPK: D_VARIABLES is ONE (ONE when absent), but the forms use D variables X (LAW:HEAT), t (LAW:HEAT)]],"
+ NR4 + "],[]]",
note="out/A/suite/A10a with ROLE EOM(u): two D variables under ONE, the default, are T1's refusal")
HEAT_SEV = c(HEAT_TPK); HEAT_SEV = dict([("PARAMETERS", {"D_VARIABLES": "SEVERAL"})] + list(HEAT_SEV.items()))
add("kt/s050-heat-under-several", "kernel_tests", {"tpk": HEAT_SEV},
"[true,[[T1,true,[]],[T2,true,[]],[T5,true,[]],[T4,true,[]],[T6,true,[]]],[]]",
note="SEVERAL admits the partial derivatives; T4: D(u,X,2) is TH1 L-2 and alpha_d times it TH1 T-1, as D(u,t)")
add("fp/s050-heat-under-several", "final_checks", {"tfk": {"TPK": HEAT_SEV, "TrM": HEAT_TRM, "TMS": c(TMS)}}, "[PASS,[],[]]")
add("fp/s050-heat-under-one", "final_checks", {"tfk": {"TPK": HEAT_TPK, "TrM": HEAT_TRM, "TMS": c(TMS)}},
"[NOT_RUN,[final pass: the TPK does not pass T1, T2, T5, T4 and T6],[]]")
# a static beam: the D variable is the arc length s (DIMENSION L1), not time
BEAM = {"DOF": [{"NAME": "w", "DIMENSION": "L1"}, {"NAME": "s", "DIMENSION": "L1"}],
"CONSTANT": [{"NAME": "M_b", "DIMENSION": "L2 M1 T-2"}, {"NAME": "E_y", "DIMENSION": "L-1 M1 T-2"},
{"NAME": "I_a", "DIMENSION": "L4"}],
"LAW": [{"NAME": "BEAM", "STATEMENT": "d2w/ds2 = M_b / (E_y I_a)", "REFS": ["w", "s", "M_b", "E_y", "I_a"],
"ROLE": "EOM(w)", "EQUATION": "D(w, s, 2) = M_b / (E_y * I_a)"}]}
add("kt/s050-beam-arc-length", "kernel_tests", {"tpk": BEAM},
"[true,[[T1,true,[]],[T2,true,[]],[T5,true,[]],[T4,true,[]]," + T6_NO_FORM + "],[]]",
note="T4 on a non-time D variable: D(w,s,2) is L1 less 2 x L1 = L-1, as M_b/(E_y*I_a)")
beam = c(BEAM); beam["CONSTANT"] = beam["CONSTANT"][:2]
beam["LAW"][0].update({"STATEMENT": "d2w/ds2 = M_b / E_y", "REFS": ["w", "s", "M_b", "E_y"], "EQUATION": "D(w, s, 2) = M_b / E_y"})
add("kt/s050-beam-T4-fails", "kernel_tests", {"tpk": beam},
"[false,[[T1,true,[]],[T2,true,[]],[T5,true,[]],[T4,false,[LAW:BEAM: EQUATION sides have dimensions L-1 and L3 (T4)]],"
+ T6_NO_FORM + "],[]]",
note="dim(w) less 2 dim(s) is L-1; M_b/E_y is L3")
# the TMS switch changes nothing at the final pass (the class is tpc_eom's, D176.1)
f = c(TFK_F); f["TMS"]["PARAMETERS"]["STRUCTURE_CHECK"] = "OFF"
add("fp/s050-structure-check-off", "final_checks", {"tfk": f}, "[PASS,[],[]]",
note="STRUCTURE_CHECK OFF is a well-formed TMS; T3 and IC2's disposition read nothing of it")
f = c(TFK_F); f["TMS"]["PARAMETERS"]["STRUCTURE_CHECK"] = "YES"
add("fp/s050-structure-check-refused", "final_checks", {"tfk": f},
"[NOT_RUN,[final pass: the TMS is not well-formed],[]]")
f = c(TFK_F); f["TPK"] = dict([("PARAMETERS", {"D_VARIABLES": "ONE"})] + list(f["TPK"].items()))
add("fp/s050-explicit-one", "final_checks", {"tfk": f}, "[PASS,[],[]]")
# ---- 0.3.2 (C-MS-5; increment 11): a JSON {} and a JSON [] are told apart -------------
# Expectations by hand from tpc_tests' readers: a kind that is not a list holds no entry
# for T2, T3 and T5; kernel_tests stops at T1; ic_checks and final_checks stop at the
# first zone that fails. Each case is one an assoc-array reading answered otherwise, or a
# valid empty object that must stay valid.
DX = {"NAME": "x", "DIMENSION": "L1"}
DZ = {"NAME": "z", "DIMENSION": "L1"}
NOT_RUN4 = "[T2,NOT_RUN,[]],[T5,NOT_RUN,[]],[T4,NOT_RUN,[]],[T6,NOT_RUN,[]]"
add("decode/kernel-tests-tpk-list", "kernel_tests", {"tpk": []},
"[false,[[T1,false,[TPK: zone is not an object]]," + NOT_RUN4 + "],[]]")
add("decode/kernel-tests-kind-object", "kernel_tests", {"tpk": {"LAW": {}}},
"[false,[[T1,false,[TPK kind LAW is not a list]]," + NOT_RUN4 + "],[]]")
add("decode/kernel-tests-parameters-empty-object", "kernel_tests", {"tpk": {"PARAMETERS": {}}},
"[true,[[T1,true,[]],[T2,true,[]],[T5,true,[]],[T4,NO FORM,[]],[T6,NO FORM,[]]],[]]",
note="the empty TPK with an empty PARAMETERS part passes; no law or boundary, so T4 and T6 read NO FORM")
add("decode/t5-kind-zero-keyed", "t5_dof_yield", {"tpk": {"DOF": {"0": DX}}}, "[true,[]]",
note="the DOF kind is not a list, so T5 reads no DOF (it read x and found it idle)")
add("decode/t5-kind-object", "t5_dof_yield", {"tpk": {"DOF": [DX], "LAW": {}}},
"[false,[DOF:x: named by no LAW (T5 c)]]", note="LAW {} holds no law, so x is idle")
add("decode/t2-kind-zero-keyed", "t2_atomicity",
{"tpk": {"ASSUMPTION": {"0": {"NAME": "A", "PROPOSITION": "a holds and b holds", "REFS": []}}}},
"[true,[]]", note="the ASSUMPTION kind is not a list: no proposition is read")
TMS1 = {"PARAMETERS": {"STEP_CONVENTION": "x", "K": "2", "N_X": 2, "S_MAX": 1}}
C_RM = {"NAME": "C1", "TARGET": "z", "ACTION": "REMOVE", "STATEMENT": "z removed"}
C_FX = {"NAME": "C2", "TARGET": "z", "ACTION": "FIX", "VALUE": "0", "UNIT": "m", "STATEMENT": "z fixed"}
add("decode/t3-constraints-list", "t3_consistency", {"tpk": {"DOF": [DZ], "CONSTRAINT": [C_RM, C_FX]}, "tms": TMS1},
"[false,[CONSTRAINT:C1 and CONSTRAINT:C2: z is both removed and fixed (T3)]]",
note="the pair below as a list: T3 finds it")
add("decode/t3-constraints-zero-keyed", "t3_consistency",
{"tpk": {"DOF": [DZ], "CONSTRAINT": {"0": C_RM, "1": C_FX}}, "tms": TMS1}, "[true,[]]",
note="the CONSTRAINT kind is not a list: T3 reads no constraint (T1 refuses the kind)")
add("decode/t3-tms-parameters-zero-keyed", "t3_consistency", {"tpk": {}, "tms": {"PARAMETERS": {"0": 1}}},
"[false,[T3: S_MAX is not a declared depth of at least 1]]")
add("decode/ic-checks-tpk-list", "ic_checks", {"trm": {"HEADER": {}, "ENTRIES": []}, "tpk": []},
"[NOT_RUN,[IC: the TPK does not pass T1],[]]")
HDR0 = {"ENVIRONMENT_INVENTORY": [], "SIGNATURE": [], "TRANSFORMATIONS": []}
add("decode/ic-checks-entries-object", "ic_checks", {"trm": {"HEADER": HDR0, "ENTRIES": {}}, "tpk": {"DOF": [DX]}},
"[NOT_RUN,[IC: the TrM is not well-formed],[]]",
note="ENTRIES {} is not a list (it read as no entry, and x as an untied DOF)")
add("decode/ic-checks-empty-trm-gap", "ic_checks", {"trm": {"HEADER": HDR0, "ENTRIES": []}, "tpk": {"DOF": [DX]}},
"[GAP,[],[IC2: DOF x is untied]]", note="the same with ENTRIES []: x is a named gap")
add("decode/final-tfk-list", "final_checks", {"tfk": []}, "[NOT_RUN,[final pass: the TFK is not an object],[]]")
TFK0 = {"TPK": {"PARAMETERS": {}}, "TrM": {"HEADER": HDR0, "ENTRIES": []}, "TMS": TMS1}
add("decode/final-empty-kernel-passes", "final_checks", {"tfk": TFK0}, "[PASS,[],[]]",
note="the empty TPK with an empty PARAMETERS object, an empty TrM and a minimal TMS")
add("decode/final-yardsticks-object", "final_checks", {"tfk": dict(TFK0, TMS=dict(TMS1, YARDSTICKS={}))},
"[NOT_RUN,[final pass: the TMS is not well-formed],[]]", note="YARDSTICKS {} is not a list")
add("decode/final-tpk-kind-object", "final_checks", {"tfk": dict(TFK0, TPK={"DOF": {}})},
"[NOT_RUN,[final pass: the TPK does not pass T1, T2, T5, T4 and T6],[]]")
def dispatch(fn, i):
if fn == "t2_findings": return K.t2_findings(i["prop"])
if fn == "t2_atomicity": return K.t2_atomicity(i["tpk"])
if fn == "t3_consistency": return K.t3_consistency(i["tpk"], i["tms"])
if fn == "t5_dof_yield": return K.t5_dof_yield(i["tpk"])
if fn == "kernel_tests": return K.kernel_tests(i["tpk"])
if fn == "ic_checks": return K.ic_checks(i["trm"], i["tpk"])
if fn == "final_checks": return K.final_checks(i["tfk"])
raise KeyError(fn)
bad = 0
for cs in cases:
got = S.canon(dispatch(cs["fn"], cs["input"]))
if got != cs["expect"]:
bad += 1
print("MISMATCH", cs["id"], "\n expect", cs["expect"], "\n got ", got)
if bad:
sys.exit("refusing to write: %d mismatches" % bad)
corpus = {
"meta": {
"name": "tpc_tests_corpus", "version": "0.3.2",
"status": "SELECTED D106.1, D107.1, D108.1 (2026-09-22); increment 8 at Option 1 of every slot (2026-09-24); schema 0.5.0 and the D variable, D176.1 and D177.1 (2026-09-26); VERIFIED (both residences)",
"conforms_tps": "0.1.0 revision 4 (kernel tests of TPS 2.2.3 and guide 3.6; isomorphism checks of TPS 2.3.7-2.3.14 and guide 4.6)",
"module": "tpc_tests 0.2.1 (tpc_zone 0.5.1, schema 0.5.0; tpc_form 0.2.1, with D177.1; tpc_units 0.1.1; tpc_strike 0.2.1), proposed with TPC-PY 0.2.0",
"note": ("Every expectation is hand-derived. The toy TFK is the zone corpus's: a mass on a linear "
"spring with z fixed at 0; the spring with its forms adds a DOF t, an entry E_t and the "
"declared forms (increment 8). Both are test fixtures, not physics under research. Both "
"residences MUST reproduce every expect. 0.3.0 (schema 0.5.0; D176.1, D177.1): every fixture LAW "
"carries a ROLE chosen by its physics, no earlier expectation changed; added, the research drafts "
"A21 (scaled time), A10a (the heat equation, under ONE and SEVERAL) and corner_fix_t (a FIXed "
"clock) with ROLEs added, a static beam whose D variable is its arc length, and the TMS switch at "
"the final pass. 0.3.1 (S33, 2026-09-26): a LAW restating the motion of a FIXed or REMOVEd DOF "
"carries ROLE CONSTRAINT (the toy's and the spring's FREE_Z, corner_fix_t's EOM_Z, N2 and KIN of "
"the FIX fixture); a variant whose constraints leave z free gives FREE_Z EOM(z). No expectation "
"moves. 0.3.2 (C-MS-5, increment 11, 2026-09-28): 16 decode/ cases, each a JSON {} where a list is "
"read, a JSON [] where an object is read, an object keyed 0 read as a list, or a valid empty "
"object; TPC-PHP now reads the JSON as written. No earlier expectation moves.")
},
"cases": cases
}
open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "vectors", "tests_corpus.json"), "w", encoding="utf-8", newline="\n").write(
json.dumps(corpus, indent=1, ensure_ascii=True) + "\n")
print("wrote", len(cases), "tests cases; all match hand-derived expectations")