Jump to content

The Principia Machina/TPC-PY/gen conditions corpus.py

From The Invariance Itself
Revision as of 02:11, 30 September 2026 by BFP Rauch (talk | contribs) (1 revision imported)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
# -*- coding: utf-8 -*-
"""gen_conditions_corpus 0.1.0 (agent TQ, increment 12): writes
vectors/conditions_corpus.json, the vectors of tpc_strike 0.3.0's
conditions_of, comparison_set and sr8_groups (tpm_record_functions 0.2.0
section 9; D196.1; RD-RS-29, RD-RS-33, RD-RS-36), answered through
tpc_record's run_case (tpc_strike imports nothing of tpc_record).

VECTORS FIRST: every expectation below is a literal of this generator,
written from the specification before the functions existed, in TPM's
canonical JSON (the writer cj below). The TFK is the tree's example
spring_draft.json (E_x's DOF x free; E_z's DOF z the TARGET of the FIX
CONSTRAINT C_NOZ). Standard library only; run from tpc/.
"""
import copy
import json
import os

HERE = os.path.dirname(os.path.abspath(__file__))
CORPUS_VERSION = "0.1.0"
CASES = []


def cj(v):
    if v is True:
        return "true"
    if v is False:
        return "false"
    if v is None:
        return "null"
    if type(v) is int:
        return str(v)
    if type(v) is str:
        out = ['"']
        for ch in v:
            if ch == '"':
                out.append('\\"')
            elif ch == "\\":
                out.append("\\\\")
            elif ord(ch) < 0x20:
                out.append("\\u%04x" % ord(ch))
            else:
                out.append(ch)
        out.append('"')
        return "".join(out)
    if type(v) is list:
        return "[" + ",".join(cj(x) for x in v) + "]"
    if type(v) is dict:
        return "{" + ",".join(cj(k) + ":" + cj(v[k]) for k in sorted(v)) + "}"
    raise TypeError(type(v))


def add(name, fn, args, expected):
    CASES.append({"name": name, "fn": fn, "args": args, "expected": expected})


def refused(*p):
    return cj(["REFUSED", [list(x) for x in sorted(set(tuple(x) for x in p))]])


with open(os.path.join(HERE, "examples", "spring_draft.json"), encoding="utf-8") as _f:
    TFK = json.load(_f)


def res(rid, regime="M", quantity="E_x", value="0.01", unit="m", at=None, assumptions=(), cites=(), **kv):
    r = {"ID": rid, "CLASS": "RESULT", "GRADE": "PROVISIONAL", "STATUS": "UNMARKED", "REGIME": regime,
         "QUANTITY": quantity, "VALUE": value, "UNIT": unit, "ASSUMPTIONS": list(assumptions),
         "CITES": list(cites)}
    if regime == "M":
        r["U_C"] = "0.001"
    if at is not None:
        r["AT"] = at
    r.update(kv)
    return r


def pt(dof, v, u):
    return {"DOF": dof, "VALUE": v, "UNIT": u}


SIT2 = {"ID": "RR-2", "CLASS": "ASSUMPTION", "GRADE": "PROVISIONAL", "SITUATION": "INITIAL", "DOF": "x",
        "VALUE": "0.01", "UNIT": "m", "ASSUMPTIONS": [], "CITES": []}
SIT3 = dict(SIT2, ID="RR-3", SITUATION="BOUNDARY")
PLAIN4 = {"ID": "RR-4", "CLASS": "ASSUMPTION", "GRADE": "PROVISIONAL", "PROPOSITION": "p",
          "ASSUMPTIONS": [], "CITES": []}
M10 = res("RR-10", at=[pt("t", "0", "s")], assumptions=["RR-2"])
M11 = res("RR-11", at=[pt("t", "0", "ms")], assumptions=["RR-2"])
M12 = res("RR-12", at=[pt("t", "1", "s")], assumptions=["RR-2"])
M13 = res("RR-13", assumptions=["RR-2"])
M14 = res("RR-14", assumptions=["RR-2"])
L15 = res("RR-15", regime="L", at=[pt("t", "0", "s")], assumptions=["RR-2"])
L16 = res("RR-16", regime="L", at=[pt("t", "0", "s")], assumptions=["RR-2"])
L17 = res("RR-17", regime="L", assumptions=["RR-2"])
del L17["VALUE"], L17["UNIT"], L17["QUANTITY"]
REG = [SIT2, SIT3, PLAIN4, M10, M11, M12, M13, M14, L15, L16, L17]
WORDS = dict((r["ID"], "PROVISIONAL") for r in REG)


def co(name, records, rid, expected):
    add(name, "conditions_of", {"records": records, "id": rid}, expected)


co("CO01 an M record's situation and point", REG, "RR-10", cj(["OK", [["RR-2"], [["t", "0", "none"]]]]))
co("CO02 the point in ms normalized to SI", REG, "RR-11", cj(["OK", [["RR-2"], [["t", "0", "none"]]]]))
co("CO03 AT absent: no point", REG, "RR-13", cj(["OK", [["RR-2"], []]]))
co("CO04 the closure through CITES", REG + [res("RR-18", assumptions=["RR-3", "RR-4"], cites=["RR-10"],
                                                at=[pt("t", "1000", "ms")])], "RR-18",
   cj(["OK", [["RR-2", "RR-3"], [["t", "1", "none"]]]]))
co("CO05 a plain ASSUMPTION is no situation", REG + [res("RR-19", assumptions=["RR-4"])], "RR-19",
   cj(["OK", [[], []]]))
co("CO06 identifiers outside the records ignored", REG + [res("RR-19", assumptions=["RR-2", "RR-99"],
                                                              cites=["RR-98"])], "RR-19",
   cj(["OK", [["RR-2"], []]]))
co("CO07 points sorted by DOF", REG + [res("RR-19", at=[pt("x", "2", "cm"), pt("t", "1.5", "s")])], "RR-19",
   cj(["OK", [[], [["t", "15e-1", "none"], ["x", "2e-2", "none"]]]]))
VER = {"ID": "RR-30", "CLASS": "VERIFICATION", "GRADE": "PROVISIONAL", "REGIME": "M", "TARGET": "RR-18",
       "ASSUMPTIONS": ["RR-3"], "CITES": [], "AT": [pt("t", "1", "s")]}
co("CO08 a VERIFICATION: its TARGET's premises with its own AT (RD-RS-36)",
   REG + [res("RR-18", assumptions=["RR-3"], cites=["RR-10"]), VER], "RR-30",
   cj(["OK", [["RR-2", "RR-3"], [["t", "1", "none"]]]]))
co("CO09 a kind recorded: a point in Hz", REG + [res("RR-19", at=[pt("t", "2", "Hz")])], "RR-19",
   cj(["OK", [[], [["t", "2", "Hz1"]]]]))
co("CO10 REC-73 an ASSUMPTION", REG, "RR-2",
   refused(["REC-73", "-", "conditions_of reads a RESULT or a VERIFICATION"]))
co("CO11 REC-52 not in the records", REG, "RR-77", refused(["REC-52", "-", "record RR-77 is not in the register"]))
co("CO12 list-form members ignored", REG + [["RR-90", "HOLD", "x"]], "RR-10",
   cj(["OK", [["RR-2"], [["t", "0", "none"]]]]))
co("CO13 REC-50 records not a register", {"RR-1": {}}, "RR-1",
   refused(["REC-50", "-", 'records {"RR-1":{}} is not a register']))
co("CO14 REC-50 an AT point that does not normalize",
   REG + [res("RR-19", at=[{"DOF": "t", "VALUE": "x", "UNIT": "s"}])], "RR-19",
   refused(["REC-50", "-", 'AT [{"DOF":"t","UNIT":"s","VALUE":"x"}] is not a list of points that normalize']))
co("CO15 a VERIFICATION whose TARGET is not in the records: no situation",
   [SIT2, dict(VER, TARGET="RR-88")], "RR-30", cj(["OK", [[], [["t", "1", "none"]]]]))
co("CO16 REC-52 an identifier that is not a string", REG, 7, refused(["REC-52", "-", "record 7 is not in the register"]))


def cs(name, records, words, quantity, expected):
    add(name, "comparison_set", {"records": records, "words": words, "tfk": TFK, "quantity": quantity}, expected)


cs("CS01 E_x: equal conditions, both with AT (TEST); AT empty (INSPECT); L against M listed; never L-L",
   REG, WORDS, "E_x",
   cj(["OK", [["RR-10", "RR-11", "TEST"], ["RR-10", "RR-15", "TEST"], ["RR-10", "RR-16", "TEST"],
              ["RR-11", "RR-15", "TEST"], ["RR-11", "RR-16", "TEST"], ["RR-13", "RR-14", "INSPECT"]]]))
cs("CS02 a HELD record is not standing, not listed", REG, dict(WORDS, **{"RR-11": "HELD"}), "E_x",
   cj(["OK", [["RR-10", "RR-15", "TEST"], ["RR-10", "RR-16", "TEST"], ["RR-13", "RR-14", "INSPECT"]]]))
Z20 = res("RR-20", quantity="E_z", value="0", unit="m")
Z21 = res("RR-21", quantity="E_z", value="0.001", unit="m")
cs("CS03 a FIXed DOF, AT empty: TEST", REG + [Z20, Z21], dict(WORDS, **{"RR-20": "PROVISIONAL",
                                                                      "RR-21": "ESTABLISHED"}), "E_z",
   cj(["OK", [["RR-20", "RR-21", "TEST"]]]))
H22 = res("RR-22", at=[pt("t", "2", "Hz")])
H23 = res("RR-23", at=[pt("t", "2", "s-1")])
cs("CS04 Hz against s-1 in AT: CONVENTION", [H22, H23], {"RR-22": "PROVISIONAL", "RR-23": "PROVISIONAL"},
   "E_x", cj(["OK", [["RR-22", "RR-23", "CONVENTION"]]]))
cs("CS05 same situation, different AT: not paired", [SIT2, M10, M12], WORDS, "E_x", cj(["OK", []]))
cs("CS06 different situations: not paired", [SIT2, SIT3, M10, res("RR-24", at=[pt("t", "0", "s")],
                                                                 assumptions=["RR-3"])],
   dict(WORDS, **{"RR-24": "PROVISIONAL"}), "E_x", cj(["OK", []]))
cs("CS07 a record absent from words does not stand", REG, {"RR-10": "PROVISIONAL"}, "E_x", cj(["OK", []]))
cs("CS08 REC-74 a quantity outside the TrM", REG, WORDS, "E_q",
   refused(["REC-74", "-", "quantity E_q is not an entry of the TrM"]))
cs("CS09 an L record without VALUE is not a comparison record", [SIT2, L17, M13], WORDS, "E_x", cj(["OK", []]))
cs("CS10 REC-50 words not a map", REG, ["RR-10"], "E_x",
   refused(["REC-50", "-", 'words ["RR-10"] is not a map of status words']))
add("CS11 REC-39 the TFK not readable", "comparison_set", {"records": REG, "words": WORDS, "tfk": {"TPK": {}},
                                                           "quantity": "E_x"},
    refused(["REC-39", "-", "the TFK is not readable"]))
cs("CS12 REC-74 a quantity that is not a string", REG, WORDS, 5,
   refused(["REC-74", "-", "quantity 5 is not an entry of the TrM"]))
cs("CS13 REC-50 records not a register", "x", WORDS, "E_x", refused(["REC-50", "-", 'records "x" is not a register']))


def s8(name, records, words, quantity, expected):
    add(name, "sr8_groups", {"records": records, "words": words, "tfk": TFK, "quantity": quantity}, expected)


s8("S801 groups split by CONDITIONS; L records not in SR8's groups", REG, WORDS, "E_x",
   cj(["OK", [["TEST", ["RR-10", "RR-11"]], ["TEST", ["RR-12"]], ["INSPECT", ["RR-13", "RR-14"]]]]))
s8("S802 a convention splits a group", [H22, H23], {"RR-22": "PROVISIONAL", "RR-23": "PROVISIONAL"}, "E_x",
   cj(["OK", [["TEST", ["RR-22"]], ["TEST", ["RR-23"]]]]))
s8("S803 a FIXed DOF: TEST without AT", [Z20, Z21], {"RR-20": "PROVISIONAL", "RR-21": "PROVISIONAL"}, "E_z",
   cj(["OK", [["TEST", ["RR-20", "RR-21"]]]]))
s8("S804 a HELD record left out", REG, dict(WORDS, **{"RR-10": "HELD"}), "E_x",
   cj(["OK", [["TEST", ["RR-11"]], ["TEST", ["RR-12"]], ["INSPECT", ["RR-13", "RR-14"]]]]))
s8("S805 REC-74", REG, WORDS, "E_q", refused(["REC-74", "-", "quantity E_q is not an entry of the TrM"]))


def main():
    names = [c["name"] for c in CASES]
    assert len(set(names)) == len(names)
    for c in CASES:
        json.loads(c["expected"])
    out = {"corpus": "conditions", "version": CORPUS_VERSION,
           "spec": "tpm_record_functions 0.2.0 section 9 (tpc_strike 0.3.0)",
           "note": "vectors first: every expectation a literal of the generator, in TPM's canonical JSON",
           "cases": CASES}
    with open(os.path.join(HERE, "vectors", "conditions_corpus.json"), "w", encoding="utf-8",
              newline="\n") as f:
        json.dump(out, f, indent=1, sort_keys=True, ensure_ascii=True)
        f.write("\n")
    print("wrote %d conditions cases" % len(CASES))


if __name__ == "__main__":
    main()
# END OF ARTIFACT --- gen_conditions_corpus.py 0.1.0
# If this line is absent, the payload arrived truncated.