<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://invarians.org/index.php?action=history&amp;feed=atom&amp;title=The_Principia_Machina%2FTPC-PY%2Ftpc_strike.py</id>
	<title>The Principia Machina/TPC-PY/tpc strike.py - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://invarians.org/index.php?action=history&amp;feed=atom&amp;title=The_Principia_Machina%2FTPC-PY%2Ftpc_strike.py"/>
	<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_strike.py&amp;action=history"/>
	<updated>2026-10-21T07:32:23Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_strike.py&amp;diff=4889&amp;oldid=prev</id>
		<title>BFP Rauch: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_strike.py&amp;diff=4889&amp;oldid=prev"/>
		<updated>2026-09-30T02:11:04Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw-interface=&quot;&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:11, 30 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>BFP Rauch</name></author>
	</entry>
	<entry>
		<id>https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_strike.py&amp;diff=4888&amp;oldid=prev</id>
		<title>BFP Rauch: TPC-PY source tpc_strike.py (0.3.0), SHA-256 c2d6586e704d98b1; conformed TPS 0.4.0; PROPOSED, not declared (TPC-PY 0.2.0)</title>
		<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_strike.py&amp;diff=4888&amp;oldid=prev"/>
		<updated>2026-09-30T02:10:58Z</updated>

		<summary type="html">&lt;p&gt;TPC-PY source tpc_strike.py (0.3.0), SHA-256 c2d6586e704d98b1; conformed TPS 0.4.0; PROPOSED, not declared (TPC-PY 0.2.0)&lt;/p&gt;
&lt;a href=&quot;https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_strike.py&amp;amp;diff=4888&amp;amp;oldid=4235&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>BFP Rauch</name></author>
	</entry>
	<entry>
		<id>https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_strike.py&amp;diff=4235&amp;oldid=prev</id>
		<title>BFP Rauch: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_strike.py&amp;diff=4235&amp;oldid=prev"/>
		<updated>2026-09-28T04:37:36Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw-interface=&quot;&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 04:37, 28 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>BFP Rauch</name></author>
	</entry>
	<entry>
		<id>https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_strike.py&amp;diff=4234&amp;oldid=prev</id>
		<title>BFP Rauch: TPC-PY source tpc_strike.py (0.2.0), SHA-256 ada528509f224997; conformed TPS 0.3.0; PROPOSED, not declared (CO-8)</title>
		<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/tpc_strike.py&amp;diff=4234&amp;oldid=prev"/>
		<updated>2026-09-27T15:43:18Z</updated>

		<summary type="html">&lt;p&gt;TPC-PY source tpc_strike.py (0.2.0), SHA-256 ada528509f224997; conformed TPS 0.3.0; PROPOSED, not declared (CO-8)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;# -*- coding: utf-8 -*-&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
TPC-PY --- strike-rule arithmetic (TPC, step 2 first increment)&lt;br /&gt;
===============================================================&lt;br /&gt;
The Principia Calculator, published advisory residence (TPC-PY).&lt;br /&gt;
Pure functions, Python standard library only, Python 3.7+.&lt;br /&gt;
Runs unmodified on Windows and Linux (no OS calls, no third-party imports).&lt;br /&gt;
&lt;br /&gt;
Scope of this module: the fully-specified strike-rule arithmetic named in&lt;br /&gt;
PMP-TPM STRIKE RULE / TPS 4.4 --- SR4 distance d(r), SR8 uncertainty&lt;br /&gt;
scaling, the SR3 mechanical contradiction tests (M-M, L-M), SR5 ordering,&lt;br /&gt;
and the SR6 independence count. Digests (need the TPS 2.5 canonicalization),&lt;br /&gt;
the SR9 C-test harness, the isomorphism bodies and the kernel tests T1-T6&lt;br /&gt;
are later increments and are NOT in this file.&lt;br /&gt;
&lt;br /&gt;
0.2.0 (PROPOSED, unreleased working label; D180.3, taken 2026-09-26): one&lt;br /&gt;
function added, sr3_scope(tfk, quantity), the interim scope of the SR3 M-M&lt;br /&gt;
and L-M tests and of SR8&amp;#039;s scale factor (TPS 4.4.13 and 4.2.13 as staged&lt;br /&gt;
for revision 6, provisional numbers). Vectors: tpc/vectors/&lt;br /&gt;
sr3_scope_corpus.json (gen_sr3_scope_corpus.py). No earlier function&lt;br /&gt;
changed. sr3_scope reads with tpc_zone&amp;#039;s helpers, imported on first use&lt;br /&gt;
(so sr3_scope needs Python 3.8+, as tpc_zone does; the rest stays 3.7+).&lt;br /&gt;
&lt;br /&gt;
Residence model (D96.1): this file is the published, runnable residence.&lt;br /&gt;
The residence of record is TPC-PHP inside TPX, whose PUBLISHED form is&lt;br /&gt;
pseudocode (tpc_php/tpc_strike.pseudo.php). Both residences MUST reproduce&lt;br /&gt;
the published vector corpus (tpc/vectors/strike_corpus.json) byte for byte;&lt;br /&gt;
the corpus, compared through canon(), is the shared oracle. &amp;quot;Byte-identical&amp;quot;&lt;br /&gt;
is defined by canon(): booleans as &amp;quot;true&amp;quot;/&amp;quot;false&amp;quot;, integers as base-10,&lt;br /&gt;
floats via the C printf format &amp;quot;%.12g&amp;quot; (identical in Python and PHP), and&lt;br /&gt;
lists as &amp;quot;[a,b,...]&amp;quot;. Nothing here exposes an enforcement path or the&lt;br /&gt;
canary/probe suite.&lt;br /&gt;
&lt;br /&gt;
L-L contradiction (SR3) is not here: it needs a derivation/logic oracle and&lt;br /&gt;
is an INSPECTION check, not a mechanical TPC function.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
TPC_STRIKE_VERSION = &amp;quot;0.2.0&amp;quot;     # PROPOSED, unreleased working label (D180.3: sr3_scope)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
# Canonical serialization --- the byte-identity contract across residences.&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
def _canon_float(x):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;C &amp;quot;%.12g&amp;quot; of a double, derived from the digits of &amp;quot;%.11e&amp;quot;: one&lt;br /&gt;
    rounding to 12 significant digits, then fixed notation for exponents&lt;br /&gt;
    -4..11 and exponent notation (sign, at least two digits) otherwise,&lt;br /&gt;
    trailing zeros removed. Written out so that TPC-PHP can mirror it.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if x != x:                        # NaN guard: never a valid TPC output&lt;br /&gt;
        raise ValueError(&amp;quot;canon: NaN is not a permitted result&amp;quot;)&lt;br /&gt;
    if x in (float(&amp;quot;inf&amp;quot;), float(&amp;quot;-inf&amp;quot;)):&lt;br /&gt;
        return &amp;quot;inf&amp;quot; if x &amp;gt; 0 else &amp;quot;-inf&amp;quot;&lt;br /&gt;
    if x == 0:&lt;br /&gt;
        return &amp;quot;0&amp;quot;                    # 0.0 and -0.0 alike&lt;br /&gt;
    mant, exp = (&amp;quot;%.11e&amp;quot; % abs(x)).split(&amp;quot;e&amp;quot;)&lt;br /&gt;
    digits = mant.replace(&amp;quot;.&amp;quot;, &amp;quot;&amp;quot;)    # twelve significant digits&lt;br /&gt;
    e = int(exp)&lt;br /&gt;
    if -4 &amp;lt;= e &amp;lt; 12:&lt;br /&gt;
        if e &amp;gt;= 0:&lt;br /&gt;
            ip, fp = digits[:e + 1], digits[e + 1:]&lt;br /&gt;
        else:&lt;br /&gt;
            ip, fp = &amp;quot;0&amp;quot;, &amp;quot;0&amp;quot; * (-e - 1) + digits&lt;br /&gt;
        fp = fp.rstrip(&amp;quot;0&amp;quot;)&lt;br /&gt;
        out = ip + (&amp;quot;.&amp;quot; + fp if fp else &amp;quot;&amp;quot;)&lt;br /&gt;
    else:&lt;br /&gt;
        rest = digits[1:].rstrip(&amp;quot;0&amp;quot;)&lt;br /&gt;
        out = digits[0] + (&amp;quot;.&amp;quot; + rest if rest else &amp;quot;&amp;quot;) + &amp;quot;e&amp;quot; + (&amp;quot;-&amp;quot; if e &amp;lt; 0 else &amp;quot;+&amp;quot;) + &amp;quot;%02d&amp;quot; % abs(e)&lt;br /&gt;
    return (&amp;quot;-&amp;quot; if x &amp;lt; 0 else &amp;quot;&amp;quot;) + out&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def canon(value):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Canonical string form of a result, identical across residences.&lt;br /&gt;
&lt;br /&gt;
    bool  -&amp;gt; &amp;quot;true&amp;quot; / &amp;quot;false&amp;quot;      (checked before int: bool subclasses int)&lt;br /&gt;
    int   -&amp;gt; base-10&lt;br /&gt;
    float -&amp;gt; C printf &amp;quot;%.12g&amp;quot;, built by _canon_float from the twelve&lt;br /&gt;
             significant digits of &amp;quot;%.11e&amp;quot; so that both residences produce&lt;br /&gt;
             it byte for byte (PHP&amp;#039;s own sprintf(&amp;#039;%.12g&amp;#039;) writes exponents&lt;br /&gt;
             differently: &amp;quot;2.0e-9&amp;quot; where C writes &amp;quot;2e-09&amp;quot;); -0.0 -&amp;gt; &amp;quot;0&amp;quot;;&lt;br /&gt;
             infinities -&amp;gt; &amp;quot;inf&amp;quot; / &amp;quot;-inf&amp;quot;&lt;br /&gt;
    str   -&amp;gt; itself&lt;br /&gt;
    list/tuple -&amp;gt; &amp;quot;[e1,e2,...]&amp;quot; of canon(e)&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if isinstance(value, bool):&lt;br /&gt;
        return &amp;quot;true&amp;quot; if value else &amp;quot;false&amp;quot;&lt;br /&gt;
    if isinstance(value, int):&lt;br /&gt;
        return str(value)&lt;br /&gt;
    if isinstance(value, float):&lt;br /&gt;
        return _canon_float(value)&lt;br /&gt;
    if isinstance(value, str):&lt;br /&gt;
        return value&lt;br /&gt;
    if isinstance(value, (list, tuple)):&lt;br /&gt;
        return &amp;quot;[&amp;quot; + &amp;quot;,&amp;quot;.join(canon(v) for v in value) + &amp;quot;]&amp;quot;&lt;br /&gt;
    raise TypeError(&amp;quot;canon: unsupported type %r&amp;quot; % type(value))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
# SR4 --- distance d(r) = (a(r), s(r)), lexicographic, lower is closer.&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
def assumption_closure(rid, records):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;The set of assumption identifiers in the transitive closure of r:&lt;br /&gt;
    r&amp;#039;s own ASSUMPTIONS plus those of every record it cites, transitively.&lt;br /&gt;
    Cited-record cycles are tolerated (a visited set guards them).&lt;br /&gt;
    &amp;#039;records&amp;#039; maps record id -&amp;gt; {&amp;quot;assumptions&amp;quot;:[aid...], &amp;quot;cites&amp;quot;:[rid...]}.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    seen_records = set()&lt;br /&gt;
    acc = set()&lt;br /&gt;
    stack = [rid]&lt;br /&gt;
    while stack:&lt;br /&gt;
        cur = stack.pop()&lt;br /&gt;
        if cur in seen_records:&lt;br /&gt;
            continue&lt;br /&gt;
        seen_records.add(cur)&lt;br /&gt;
        rec = records[cur]&lt;br /&gt;
        acc.update(rec.get(&amp;quot;assumptions&amp;quot;, []))&lt;br /&gt;
        stack.extend(rec.get(&amp;quot;cites&amp;quot;, []))&lt;br /&gt;
    return acc&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def a_of_r(rid, records, tfk_assumptions=()):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;SR4 a(r): count of DISTINCT assumption identifiers in r&amp;#039;s closure,&lt;br /&gt;
    EXCLUDING the TFK&amp;#039;s own assumptions. Counted over identifiers (D41).&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    tfk = set(tfk_assumptions)&lt;br /&gt;
    return len(assumption_closure(rid, records) - tfk)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def d_of_r(rid, records, tfk_assumptions=()):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;SR4 d(r) = (a(r), s(r)). s(r) is r&amp;#039;s own derivation-step count under&lt;br /&gt;
    the UWC&amp;#039;s STEP CONVENTION, carried on the record as &amp;#039;steps&amp;#039;.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    a = a_of_r(rid, records, tfk_assumptions)&lt;br /&gt;
    s = int(records[rid][&amp;quot;steps&amp;quot;])&lt;br /&gt;
    return (a, s)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def d_compare(d1, d2):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Lexicographic compare of two d() tuples. -1 if d1 closer, 1 if d2&lt;br /&gt;
    closer, 0 if equal (SR4; used by SR5).&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if d1 &amp;lt; d2:&lt;br /&gt;
        return -1&lt;br /&gt;
    if d1 &amp;gt; d2:&lt;br /&gt;
        return 1&lt;br /&gt;
    return 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
# SR8 --- uncertainty discipline / Birge scale factor.&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
def sr8_scale_factor(measurements):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;SR8 scale factor S for N&amp;gt;=2 standing M records of ONE quantity,&lt;br /&gt;
    each {&amp;quot;x&amp;quot;: value, &amp;quot;u&amp;quot;: u_c &amp;gt; 0}, already normalized to one UNIT.&lt;br /&gt;
&lt;br /&gt;
    Weighted mean over the included set, reduced chi-square, and, per the&lt;br /&gt;
    PDG Birge rule the spec cites, S computed over records with&lt;br /&gt;
    u_i &amp;lt; 3*sqrt(N)*mean(u). S = sqrt(reduced) when reduced &amp;gt; 1, else 1.0.&lt;br /&gt;
    Returns 1.0 for N &amp;lt; 2. Raises on a non-positive uncertainty.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    n = len(measurements)&lt;br /&gt;
    if n &amp;lt; 2:&lt;br /&gt;
        return 1.0&lt;br /&gt;
    us = [float(m[&amp;quot;u&amp;quot;]) for m in measurements]&lt;br /&gt;
    xs = [float(m[&amp;quot;x&amp;quot;]) for m in measurements]&lt;br /&gt;
    if any(u &amp;lt;= 0.0 for u in us):&lt;br /&gt;
        raise ValueError(&amp;quot;sr8: every M record needs u_c &amp;gt; 0&amp;quot;)&lt;br /&gt;
    # The operations below follow TPC-PHP, the residence of record, one for&lt;br /&gt;
    # one and left to right: explicit accumulation (Python 3.12&amp;#039;s sum() adds&lt;br /&gt;
    # floats with compensation, PHP does not), x * w with w = 1/(u*u), and&lt;br /&gt;
    # d * d rather than d ** 2 (pow need not round as a product does).&lt;br /&gt;
    u_mean = 0.0&lt;br /&gt;
    for u in us:&lt;br /&gt;
        u_mean = u_mean + u&lt;br /&gt;
    u_mean = u_mean / n&lt;br /&gt;
    cutoff = 3.0 * math.sqrt(n) * u_mean&lt;br /&gt;
    incl = [i for i in range(n) if us[i] &amp;lt; cutoff]&lt;br /&gt;
    if len(incl) &amp;lt; 2:&lt;br /&gt;
        return 1.0&lt;br /&gt;
    wsum, xw = 0.0, 0.0&lt;br /&gt;
    for i in incl:&lt;br /&gt;
        w = 1.0 / (us[i] * us[i])&lt;br /&gt;
        wsum = wsum + w&lt;br /&gt;
        xw = xw + xs[i] * w&lt;br /&gt;
    xbar = xw / wsum&lt;br /&gt;
    chi2 = 0.0&lt;br /&gt;
    for i in incl:&lt;br /&gt;
        d = xs[i] - xbar&lt;br /&gt;
        chi2 = chi2 + (d * d) / (us[i] * us[i])&lt;br /&gt;
    reduced = chi2 / (len(incl) - 1)&lt;br /&gt;
    return math.sqrt(reduced) if reduced &amp;gt; 1.0 else 1.0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
# SR3 --- mechanical contradiction tests (M-M, L-M). k is a TMS parameter.&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
def mm_contradicts(x1, u1, x2, u2, k, S=1.0):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;SR3 M-M: |x1 - x2| &amp;gt; k * sqrt((S u1)^2 + (S u2)^2), after SR8 scaling.&lt;br /&gt;
    Caller guarantees same QUANTITY and one UNIT (TPX refuses cross-entry).&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    su1 = S * float(u1)&lt;br /&gt;
    su2 = S * float(u2)&lt;br /&gt;
    return abs(float(x1) - float(x2)) &amp;gt; float(k) * math.sqrt(su1 * su1 + su2 * su2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def lm_contradicts(x_l, x_m, u_m, k, S=1.0):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;SR3 L-M: the M value fails the M-M test against the L record&amp;#039;s derived&lt;br /&gt;
    value. The L result carries no uncertainty, so the bound is k*S*u_m.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return abs(float(x_m) - float(x_l)) &amp;gt; float(k) * S * float(u_m)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
# SR3 and SR8 for trajectories, INTERIM (D180.3): which QUANTITY is tested.&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
SR3_MECHANICAL = &amp;quot;MECHANICAL&amp;quot;&lt;br /&gt;
SR3_INSPECTION = &amp;quot;INSPECTION&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def _zone():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;tpc_zone, imported on first use (its helpers read the TFK&amp;#039;s shape).&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    import tpc_zone&lt;br /&gt;
    return tpc_zone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def _sr3_field(tag, e, f):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;None when e[f] is a string; else the problem, in trm_well_formed&amp;#039;s&lt;br /&gt;
    and t1_well_formed&amp;#039;s words.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if f not in e:&lt;br /&gt;
        return tag + &amp;quot;: missing field &amp;quot; + f&lt;br /&gt;
    if not isinstance(e[f], str):&lt;br /&gt;
        return tag + &amp;quot;: field &amp;quot; + f + &amp;quot; has the wrong type&amp;quot;&lt;br /&gt;
    return None&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def sr3_scope(tfk, quantity):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;The interim scope of an M record&amp;#039;s QUANTITY under SR3 and SR8, under&lt;br /&gt;
    D180.3 until the record field schema (C-16) is written: TPX runs the SR3&lt;br /&gt;
    M-M and L-M tests and SR8&amp;#039;s scale factor only over quantities scoped&lt;br /&gt;
    MECHANICAL, and lists the rest for row-21 inspection (TPS 4.4.13 and&lt;br /&gt;
    4.2.13 as staged, provisional numbers). When C-16 lands, a CONDITIONS&lt;br /&gt;
    field on the records replaces this interim (T-C3).&lt;br /&gt;
&lt;br /&gt;
    tfk: a TFK {&amp;quot;TPK&amp;quot;, &amp;quot;TrM&amp;quot;, &amp;quot;TMS&amp;quot;} in the parsed shape tpc_zone validates&lt;br /&gt;
    (the caller has validated it). quantity: the QUANTITY an M record names,&lt;br /&gt;
    a TrM entry NAME. Returns&lt;br /&gt;
      &amp;quot;MECHANICAL&amp;quot;  the TrM entry of that NAME exists and its DOF is the&lt;br /&gt;
                    TARGET of a TPK CONSTRAINT whose ACTION is FIX;&lt;br /&gt;
      &amp;quot;INSPECTION&amp;quot;  the entry exists and no FIX CONSTRAINT targets its DOF&lt;br /&gt;
                    (a REMOVE constraint does not count; the independent&lt;br /&gt;
                    variable is an ordinary DOF here);&lt;br /&gt;
      [&amp;quot;REFUSED&amp;quot;, reason]  no TrM entry has that NAME, or the input is not of&lt;br /&gt;
                    the shape read. Never raised; a reason that quotes input&lt;br /&gt;
                    escapes disallowed code points (zone schemas 6.3).&lt;br /&gt;
    Matching is exact: NAMEs are ASCII identifiers, and a QUANTITY that is&lt;br /&gt;
    not one is refused without being echoed.&lt;br /&gt;
&lt;br /&gt;
    WHAT IS READ, in this order, the first problem refusing: the QUANTITY;&lt;br /&gt;
    the TFK; the TrM and its ENTRIES, each entry&amp;#039;s NAME and DOF (every&lt;br /&gt;
    entry, before the answer); the QUANTITY resolved (none: refused; two&lt;br /&gt;
    entries of that NAME: refused as ambiguous); the TPK and its CONSTRAINT&lt;br /&gt;
    kind (absent: none), each constraint&amp;#039;s TARGET and ACTION (every&lt;br /&gt;
    constraint). Nothing else is read or checked: not the TMS, not the other&lt;br /&gt;
    fields or kinds, not the values T1, the TrM schema check, the IC checks&lt;br /&gt;
    and T3 own (a TARGET that is no DOF, an ACTION other than FIX or REMOVE,&lt;br /&gt;
    an entry on a REMOVEd DOF, a DOF both FIXed and REMOVEd). A FIX counts&lt;br /&gt;
    only as ACTION &amp;quot;FIX&amp;quot; exactly with TARGET equal to the entry&amp;#039;s DOF.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Z = _zone()&lt;br /&gt;
&lt;br /&gt;
    def refuse(msg):&lt;br /&gt;
        return [&amp;quot;REFUSED&amp;quot;, Z._show(msg)]&lt;br /&gt;
&lt;br /&gt;
    if not Z._is_ident(quantity):&lt;br /&gt;
        return refuse(&amp;quot;QUANTITY is not an identifier&amp;quot;)&lt;br /&gt;
    if not Z._obj(tfk):&lt;br /&gt;
        return refuse(&amp;quot;TFK is not an object&amp;quot;)&lt;br /&gt;
    trm = tfk.get(&amp;quot;TrM&amp;quot;)&lt;br /&gt;
    if not Z._obj(trm):&lt;br /&gt;
        return refuse(&amp;quot;TrM: zone is not an object&amp;quot;)&lt;br /&gt;
    if &amp;quot;ENTRIES&amp;quot; not in trm:&lt;br /&gt;
        return refuse(&amp;quot;TrM: missing part ENTRIES&amp;quot;)&lt;br /&gt;
    ents = trm[&amp;quot;ENTRIES&amp;quot;]&lt;br /&gt;
    if not Z._list(ents):&lt;br /&gt;
        return refuse(&amp;quot;TrM ENTRIES is not a list&amp;quot;)&lt;br /&gt;
    found = []&lt;br /&gt;
    for e in ents:&lt;br /&gt;
        if not Z._obj(e):&lt;br /&gt;
            return refuse(&amp;quot;TrM ENTRIES: entry is not an object&amp;quot;)&lt;br /&gt;
        tag = &amp;quot;ENTRY:&amp;quot; + Z._name(e)&lt;br /&gt;
        for f in (&amp;quot;NAME&amp;quot;, &amp;quot;DOF&amp;quot;):&lt;br /&gt;
            p = _sr3_field(tag, e, f)&lt;br /&gt;
            if p is not None:&lt;br /&gt;
                return refuse(p)&lt;br /&gt;
        if e[&amp;quot;NAME&amp;quot;] == quantity:&lt;br /&gt;
            found.append(e[&amp;quot;DOF&amp;quot;])&lt;br /&gt;
    if not found:&lt;br /&gt;
        return refuse(&amp;quot;QUANTITY &amp;quot; + quantity + &amp;quot; names no TrM entry&amp;quot;)&lt;br /&gt;
    if len(found) &amp;gt; 1:&lt;br /&gt;
        return refuse(&amp;quot;TrM: duplicate entry name &amp;quot; + quantity)&lt;br /&gt;
    dof = found[0]&lt;br /&gt;
    tpk = tfk.get(&amp;quot;TPK&amp;quot;)&lt;br /&gt;
    if not Z._obj(tpk):&lt;br /&gt;
        return refuse(&amp;quot;TPK: zone is not an object&amp;quot;)&lt;br /&gt;
    cons = tpk.get(&amp;quot;CONSTRAINT&amp;quot;, [])&lt;br /&gt;
    if not Z._list(cons):&lt;br /&gt;
        return refuse(&amp;quot;TPK kind CONSTRAINT is not a list&amp;quot;)&lt;br /&gt;
    fixed = False&lt;br /&gt;
    for cn in cons:&lt;br /&gt;
        if not Z._obj(cn):&lt;br /&gt;
            return refuse(&amp;quot;TPK kind CONSTRAINT: entry is not an object&amp;quot;)&lt;br /&gt;
        tag = &amp;quot;CONSTRAINT:&amp;quot; + Z._name(cn)&lt;br /&gt;
        for f in (&amp;quot;TARGET&amp;quot;, &amp;quot;ACTION&amp;quot;):&lt;br /&gt;
            p = _sr3_field(tag, cn, f)&lt;br /&gt;
            if p is not None:&lt;br /&gt;
                return refuse(p)&lt;br /&gt;
        if cn[&amp;quot;ACTION&amp;quot;] == &amp;quot;FIX&amp;quot; and cn[&amp;quot;TARGET&amp;quot;] == dof:&lt;br /&gt;
            fixed = True&lt;br /&gt;
    return SR3_MECHANICAL if fixed else SR3_INSPECTION&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
# SR5 --- ordering of two contradicting standing records.&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
def sr5_order(d1, d2):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;SR5: of two contradicting standing records, the smaller d stands and&lt;br /&gt;
    the other is struck; equal d opens an audit block. d1, d2 are d() tuples.&lt;br /&gt;
    Returns &amp;quot;r1&amp;quot;, &amp;quot;r2&amp;quot;, or &amp;quot;AUDIT&amp;quot;.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    c = d_compare(tuple(d1), tuple(d2))&lt;br /&gt;
    if c &amp;lt; 0:&lt;br /&gt;
        return &amp;quot;r1&amp;quot;&lt;br /&gt;
    if c &amp;gt; 0:&lt;br /&gt;
        return &amp;quot;r2&amp;quot;&lt;br /&gt;
    return &amp;quot;AUDIT&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
# SR6 --- independence count of the contradictions of a standing record r.&lt;br /&gt;
# --------------------------------------------------------------------------&lt;br /&gt;
_SR6_MAX_INPUTS = 24  # exact set-packing guard; realistic contradiction sets are tiny&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def sr6_independence_count(extra_assumption_sets, same_model_flags=None):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;SR6 n_ind(r): the largest sub-family of the contradictions whose&lt;br /&gt;
    extra-assumption sets are PAIRWISE DISJOINT (as identifier sets).&lt;br /&gt;
    A corroboration marked SAME-MODEL is excluded from the input first (D42).&lt;br /&gt;
&lt;br /&gt;
    extra_assumption_sets: list of iterables of assumption identifiers.&lt;br /&gt;
    same_model_flags: optional list of bool, same length; True drops that one.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    sets = [frozenset(s) for s in extra_assumption_sets]&lt;br /&gt;
    if same_model_flags is not None:&lt;br /&gt;
        sets = [s for s, sm in zip(sets, same_model_flags) if not sm]&lt;br /&gt;
    if len(sets) &amp;gt; _SR6_MAX_INPUTS:&lt;br /&gt;
        raise ValueError(&amp;quot;sr6: input exceeds exact packing guard (%d)&amp;quot; % _SR6_MAX_INPUTS)&lt;br /&gt;
    best = [0]&lt;br /&gt;
&lt;br /&gt;
    def bt(i, used, count):&lt;br /&gt;
        if count + (len(sets) - i) &amp;lt;= best[0]:&lt;br /&gt;
            return&lt;br /&gt;
        if i == len(sets):&lt;br /&gt;
            if count &amp;gt; best[0]:&lt;br /&gt;
                best[0] = count&lt;br /&gt;
            return&lt;br /&gt;
        bt(i + 1, used, count)                       # skip set i&lt;br /&gt;
        if used.isdisjoint(sets[i]):                 # take set i&lt;br /&gt;
            bt(i + 1, used | sets[i], count + 1)&lt;br /&gt;
&lt;br /&gt;
    bt(0, frozenset(), 0)&lt;br /&gt;
    return best[0]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def sr6_audit_opens(n_ind, n_x):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;SR6: an audit block opens on r when n_ind(r) reaches N_x (&amp;gt;= 2).&lt;br /&gt;
    Reaching N_x never strikes r by itself; it opens the block.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if int(n_x) &amp;lt; 2:&lt;br /&gt;
        raise ValueError(&amp;quot;sr6: N_x is a TMS parameter, at least 2&amp;quot;)&lt;br /&gt;
    return int(n_ind) &amp;gt;= int(n_x)&lt;br /&gt;
&lt;/div&gt;</summary>
		<author><name>BFP Rauch</name></author>
	</entry>
</feed>