<?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%2Fgen_units_corpus.py</id>
	<title>The Principia Machina/TPC-PY/gen units corpus.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%2Fgen_units_corpus.py"/>
	<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/gen_units_corpus.py&amp;action=history"/>
	<updated>2026-10-21T12:10:47Z</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/gen_units_corpus.py&amp;diff=4181&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/gen_units_corpus.py&amp;diff=4181&amp;oldid=prev"/>
		<updated>2026-09-28T04:32:53Z</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;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 04:32, 28 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&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;!-- diff cache key pma_cutover_20261020t051351z-soft_:diff:1.41:old-4180:rev-4181 --&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/gen_units_corpus.py&amp;diff=4180&amp;oldid=prev</id>
		<title>BFP Rauch: TPC-PY source gen_units_corpus.py (-), SHA-256 d6b4132ba2b093c2; 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/gen_units_corpus.py&amp;diff=4180&amp;oldid=prev"/>
		<updated>2026-09-27T15:43:18Z</updated>

		<summary type="html">&lt;p&gt;TPC-PY source gen_units_corpus.py (-), SHA-256 d6b4132ba2b093c2; 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;Generator for tpc/vectors/units_corpus.json (increment 6, SELECTED&lt;br /&gt;
D103.1, D104.1, D105.1). Expectations are written literally below and derived by&lt;br /&gt;
hand: canonical spellings and DIMENSIONs from the catalogue, scales from&lt;br /&gt;
the SI Brochure&amp;#039;s exact values (degree = pi/180 rad), contradiction results&lt;br /&gt;
from the SR3 inequality worked on paper. The generator refuses to write the&lt;br /&gt;
corpus if the module disagrees with any of them.&lt;br /&gt;
Run: cd tpc &amp;amp;&amp;amp; python3 gen_units_corpus.py (Windows: py ...).&lt;br /&gt;
Recovered 2026-09-27 (BASE-GEN; record 0.18.0 section 7) from the TIDY 3&lt;br /&gt;
archive, tidy3_2026-09-25/gen_units_corpus.py, SHA-256&lt;br /&gt;
0472369761784d030f718bf00f1f96917bd797a20361826c7e3b2318c5192860, where it&lt;br /&gt;
regenerates the archived corpus byte for byte. Changed in the tree: S15&amp;#039;s&lt;br /&gt;
seven cases appended with corpus 0.1.1&amp;#039;s meta (RD-C8-3); the writer writes&lt;br /&gt;
a hidden character as itself, as the published corpus carries it&lt;br /&gt;
(RD-C8-2).&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
import json, os, sys&lt;br /&gt;
HERE = os.path.dirname(os.path.abspath(__file__))&lt;br /&gt;
sys.path.insert(0, HERE)&lt;br /&gt;
import tpc_strike as S&lt;br /&gt;
import tpc_units as U&lt;br /&gt;
&lt;br /&gt;
cases = []&lt;br /&gt;
def case(cid, fn, inp, expect, **extra):&lt;br /&gt;
    c = {&amp;quot;id&amp;quot;: cid, &amp;quot;fn&amp;quot;: fn, &amp;quot;input&amp;quot;: inp}&lt;br /&gt;
    c.update(extra)&lt;br /&gt;
    c[&amp;quot;expect&amp;quot;] = expect&lt;br /&gt;
    cases.append(c)&lt;br /&gt;
&lt;br /&gt;
P = &amp;quot;unit_parse&amp;quot;&lt;br /&gt;
# ---- grammar and canonical spelling -------------------------------------------------&lt;br /&gt;
case(&amp;quot;parse/newton-base&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;kg m s-2&amp;quot;}, &amp;quot;[OK,m kg s-2,L1 M1 T-2,none]&amp;quot;,&lt;br /&gt;
     note=&amp;quot;catalogue order: m before g; kg is k + g&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/any-order&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;s-2 m kg&amp;quot;}, &amp;quot;[OK,m kg s-2,L1 M1 T-2,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/named&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;N&amp;quot;}, &amp;quot;[OK,N,L1 M1 T-2,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/merge&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;m s-1 m&amp;quot;}, &amp;quot;[OK,m2 s-1,L2 T-1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/cancel&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;m m-1&amp;quot;}, &amp;quot;[OK,1,1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/exponent-one&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;m1&amp;quot;}, &amp;quot;[OK,m,L1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/zero-exponent&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;m0 s&amp;quot;}, &amp;quot;[OK,s,T1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/one&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;1&amp;quot;}, &amp;quot;[OK,1,1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/spelling-only&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;km m&amp;quot;}, &amp;quot;[OK,m km,L2,none]&amp;quot;,&lt;br /&gt;
     note=&amp;quot;only spelling is canonical: km m is not rewritten as m2&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/prefix-power-order&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;km mm&amp;quot;}, &amp;quot;[OK,mm km,L2,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/micro-ascii&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;uL&amp;quot;}, &amp;quot;[OK,uL,L3,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/deca&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;dam&amp;quot;}, &amp;quot;[OK,dam,L1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/hecto&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;hPa&amp;quot;}, &amp;quot;[OK,hPa,L-1 M1 T-2,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/megagram&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;Mg&amp;quot;}, &amp;quot;[OK,Mg,M1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/megatonne&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;Mt&amp;quot;}, &amp;quot;[OK,Mt,M1,none]&amp;quot;, note=&amp;quot;the Brochure is silent on prefixed t&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/milliarcsecond&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;marcsec&amp;quot;}, &amp;quot;[OK,marcsec,1,rad1]&amp;quot;, note=&amp;quot;mas in the Brochure&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/ohm&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;kOhm&amp;quot;}, &amp;quot;[OK,kOhm,L2 M1 T-3 I-2,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;parse/tesla-vs-tera&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;TT&amp;quot;}, &amp;quot;[OK,TT,M1 T-2 I-1,none]&amp;quot;,&lt;br /&gt;
     note=&amp;quot;tera-tesla; the tesla metre is written T m&amp;quot;)&lt;br /&gt;
# ---- refusals: shape --------------------------------------------------------------&lt;br /&gt;
case(&amp;quot;refused/empty&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;&amp;quot;}, &amp;quot;[REFUSED,UNIT  is not a unit]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/double-space&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;m  s&amp;quot;}, &amp;quot;[REFUSED,UNIT m  s is not a unit]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/caret&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;m^2&amp;quot;}, &amp;quot;[REFUSED,UNIT m^2 is not a unit]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/slash&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;m/s&amp;quot;}, &amp;quot;[REFUSED,UNIT m/s is not a unit]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/five-digit-exponent&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;m10000&amp;quot;}, &amp;quot;[REFUSED,UNIT m10000 is not a unit]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/bidi-control&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;m\u202e&amp;quot;}, &amp;quot;[REFUSED,UNIT m&amp;lt;U+202E&amp;gt; is not a unit]&amp;quot;,&lt;br /&gt;
     note=&amp;quot;the quoted input is escaped (zone schemas 6.3)&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/not-a-string&amp;quot;, P, {&amp;quot;u&amp;quot;: 5}, &amp;quot;[REFUSED,UNIT ? is not a unit]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/merged-range&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;m9999 m9999&amp;quot;},&lt;br /&gt;
     &amp;quot;[REFUSED,UNIT m9999 m9999: an exponent is out of range]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/dimension-range&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;L3334&amp;quot;},&lt;br /&gt;
     &amp;quot;[REFUSED,UNIT L3334: an exponent is out of range]&amp;quot;, note=&amp;quot;L3334 is L10002 as a DIMENSION&amp;quot;)&lt;br /&gt;
# ---- refusals: symbols ------------------------------------------------------------&lt;br /&gt;
case(&amp;quot;refused/unknown&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;furlong&amp;quot;}, &amp;quot;[REFUSED,UNIT furlong: furlong is not a unit symbol]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/double-prefix&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;kkg&amp;quot;}, &amp;quot;[REFUSED,UNIT kkg: kkg is not a unit symbol]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/day-prefix&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;kd&amp;quot;}, &amp;quot;[REFUSED,UNIT kd: d takes no prefix]&amp;quot;,&lt;br /&gt;
     note=&amp;quot;the SI Brochure forbids prefixes on the non-SI units of time&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/au-prefix&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;kau&amp;quot;}, &amp;quot;[REFUSED,UNIT kau: au takes no prefix]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/minute-prefix&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;mmin&amp;quot;}, &amp;quot;[REFUSED,UNIT mmin: min takes no prefix]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/hour-prefix&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;hh&amp;quot;}, &amp;quot;[REFUSED,UNIT hh: h takes no prefix]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/celsius&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;degC&amp;quot;},&lt;br /&gt;
     &amp;quot;[REFUSED,UNIT degC: degC is refused, an offset scale, not a ratio]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/dalton&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;mDa&amp;quot;},&lt;br /&gt;
     &amp;quot;[REFUSED,UNIT mDa: Da is refused, a measured value; the conversion would carry an uncertainty]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/decibel&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;dB&amp;quot;}, &amp;quot;[REFUSED,UNIT dB: dB is refused, a logarithmic scale]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/prefixed-decibel&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;kdB&amp;quot;}, &amp;quot;[REFUSED,UNIT kdB: dB is refused, a logarithmic scale]&amp;quot;)&lt;br /&gt;
case(&amp;quot;refused/neper&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;Np&amp;quot;}, &amp;quot;[REFUSED,UNIT Np: Np is refused, a logarithmic scale]&amp;quot;)&lt;br /&gt;
# ---- KIND ---------------------------------------------------------------------------&lt;br /&gt;
case(&amp;quot;kind/hertz&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;Hz&amp;quot;}, &amp;quot;[OK,Hz,T-1,Hz1]&amp;quot;)&lt;br /&gt;
case(&amp;quot;kind/rad-per-second&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;rad s-1&amp;quot;}, &amp;quot;[OK,s-1 rad,T-1,rad1]&amp;quot;)&lt;br /&gt;
case(&amp;quot;kind/per-second&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;s-1&amp;quot;}, &amp;quot;[OK,s-1,T-1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;kind/steradian&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;sr&amp;quot;}, &amp;quot;[OK,sr,1,rad2]&amp;quot;)&lt;br /&gt;
case(&amp;quot;kind/square-degree&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;deg2&amp;quot;}, &amp;quot;[OK,deg2,1,rad2]&amp;quot;)&lt;br /&gt;
case(&amp;quot;kind/lumen&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;lm&amp;quot;}, &amp;quot;[OK,lm,J1,rad2]&amp;quot;, note=&amp;quot;lm = cd sr&amp;quot;)&lt;br /&gt;
case(&amp;quot;kind/becquerel&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;Bq&amp;quot;}, &amp;quot;[OK,Bq,T-1,Bq1]&amp;quot;)&lt;br /&gt;
case(&amp;quot;kind/gray-sievert&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;Gy Sv-1&amp;quot;}, &amp;quot;[OK,Gy Sv-1,1,Gy1 Sv-1]&amp;quot;)&lt;br /&gt;
# ---- scale ----------------------------------------------------------------------------&lt;br /&gt;
SC = &amp;quot;unit_scale&amp;quot;&lt;br /&gt;
case(&amp;quot;scale/one&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;1&amp;quot;}, &amp;quot;[OK,1]&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/square-cm&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;cm2&amp;quot;}, &amp;quot;[OK,0.0001]&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/per-minute&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;min-1&amp;quot;}, &amp;quot;[OK,0.0166666666667]&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/hectare&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;ha&amp;quot;}, &amp;quot;[OK,10000]&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/au&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;au&amp;quot;}, &amp;quot;[OK,149597870700]&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/kiloelectronvolt&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;keV&amp;quot;}, &amp;quot;[OK,1.602176634e-16]&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/square-degree&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;deg2&amp;quot;}, &amp;quot;[OK,0.000304617419787]&amp;quot;, note=&amp;quot;(pi/180)^2&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/arcsecond&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;arcsec&amp;quot;}, &amp;quot;[OK,4.8481368111e-06]&amp;quot;, note=&amp;quot;pi/648000&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/megatonne&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;Mt&amp;quot;}, &amp;quot;[OK,1000000000]&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/km-per-hour&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;km h-1&amp;quot;}, &amp;quot;[OK,0.277777777778]&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/overflow&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;km9999&amp;quot;}, &amp;quot;[REFUSED,UNIT km9999 has no finite scale]&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/underflow-reciprocal&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;qm-20&amp;quot;}, &amp;quot;[REFUSED,UNIT qm-20 has no finite scale]&amp;quot;,&lt;br /&gt;
     note=&amp;quot;(1e-30)^20 underflows to zero; the reciprocal is refused, never divided&amp;quot;)&lt;br /&gt;
case(&amp;quot;scale/partial-overflow&amp;quot;, SC, {&amp;quot;u&amp;quot;: &amp;quot;Qm11 qm11&amp;quot;}, &amp;quot;[REFUSED,UNIT Qm11 qm11 has no finite scale]&amp;quot;,&lt;br /&gt;
     note=&amp;quot;a recorded limit: the whole is 1 m22, but a partial product leaves the double range&amp;quot;)&lt;br /&gt;
# ---- C-32 -----------------------------------------------------------------------------&lt;br /&gt;
MA = &amp;quot;unit_matches&amp;quot;&lt;br /&gt;
case(&amp;quot;c32/match&amp;quot;, MA, {&amp;quot;u&amp;quot;: &amp;quot;kg m s-2&amp;quot;, &amp;quot;dimension&amp;quot;: &amp;quot;L1 M1 T-2&amp;quot;}, &amp;quot;[OK,true]&amp;quot;)&lt;br /&gt;
case(&amp;quot;c32/match-any-order&amp;quot;, MA, {&amp;quot;u&amp;quot;: &amp;quot;N&amp;quot;, &amp;quot;dimension&amp;quot;: &amp;quot;T-2 M1 L1&amp;quot;}, &amp;quot;[OK,true]&amp;quot;)&lt;br /&gt;
case(&amp;quot;c32/mismatch&amp;quot;, MA, {&amp;quot;u&amp;quot;: &amp;quot;J&amp;quot;, &amp;quot;dimension&amp;quot;: &amp;quot;L1&amp;quot;}, &amp;quot;[OK,false]&amp;quot;)&lt;br /&gt;
case(&amp;quot;c32/angle-is-one&amp;quot;, MA, {&amp;quot;u&amp;quot;: &amp;quot;rad&amp;quot;, &amp;quot;dimension&amp;quot;: &amp;quot;1&amp;quot;}, &amp;quot;[OK,true]&amp;quot;)&lt;br /&gt;
case(&amp;quot;c32/bad-dimension&amp;quot;, MA, {&amp;quot;u&amp;quot;: &amp;quot;m&amp;quot;, &amp;quot;dimension&amp;quot;: &amp;quot;X1&amp;quot;}, &amp;quot;[REFUSED,DIMENSION X1 is not a dimension]&amp;quot;)&lt;br /&gt;
case(&amp;quot;c32/bad-unit&amp;quot;, MA, {&amp;quot;u&amp;quot;: &amp;quot;furlong&amp;quot;, &amp;quot;dimension&amp;quot;: &amp;quot;L1&amp;quot;},&lt;br /&gt;
     &amp;quot;[REFUSED,UNIT furlong: furlong is not a unit symbol]&amp;quot;)&lt;br /&gt;
# ---- D40 normalization -------------------------------------------------------------&lt;br /&gt;
NM = &amp;quot;normalize_measurement&amp;quot;&lt;br /&gt;
case(&amp;quot;norm/cm&amp;quot;, NM, {&amp;quot;value&amp;quot;: &amp;quot;5&amp;quot;, &amp;quot;uncertainty&amp;quot;: &amp;quot;0.1&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;cm&amp;quot;}, &amp;quot;[OK,0.05,0.001,L1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;norm/spring-x-max&amp;quot;, NM, {&amp;quot;value&amp;quot;: &amp;quot;0.05&amp;quot;, &amp;quot;uncertainty&amp;quot;: &amp;quot;0.001&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;m&amp;quot;}, &amp;quot;[OK,0.05,0.001,L1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;norm/hours&amp;quot;, NM, {&amp;quot;value&amp;quot;: &amp;quot;1.5&amp;quot;, &amp;quot;uncertainty&amp;quot;: &amp;quot;0.01&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;h&amp;quot;}, &amp;quot;[OK,5400,36,T1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;norm/negative-zero&amp;quot;, NM, {&amp;quot;value&amp;quot;: &amp;quot;-0&amp;quot;, &amp;quot;uncertainty&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;m&amp;quot;}, &amp;quot;[OK,0,0,L1,none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;norm/not-decimal&amp;quot;, NM, {&amp;quot;value&amp;quot;: &amp;quot;x&amp;quot;, &amp;quot;uncertainty&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;m&amp;quot;}, &amp;quot;[REFUSED,VALUE x is not a decimal]&amp;quot;)&lt;br /&gt;
case(&amp;quot;norm/negative-u&amp;quot;, NM, {&amp;quot;value&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;uncertainty&amp;quot;: &amp;quot;-1&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;m&amp;quot;},&lt;br /&gt;
     &amp;quot;[REFUSED,UNCERTAINTY -1 is negative]&amp;quot;)&lt;br /&gt;
case(&amp;quot;norm/value-overflow&amp;quot;, NM, {&amp;quot;value&amp;quot;: &amp;quot;1e308&amp;quot;, &amp;quot;uncertainty&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;km&amp;quot;},&lt;br /&gt;
     &amp;quot;[REFUSED,VALUE 1e308 in UNIT km is not a finite double]&amp;quot;)&lt;br /&gt;
# ---- SR3 after normalization ----------------------------------------------------------&lt;br /&gt;
MM = &amp;quot;mm_contradicts_units&amp;quot;&lt;br /&gt;
case(&amp;quot;mm/agree-across-prefix&amp;quot;, MM, {&amp;quot;x1&amp;quot;: &amp;quot;100&amp;quot;, &amp;quot;u1&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;unit1&amp;quot;: &amp;quot;cm&amp;quot;, &amp;quot;x2&amp;quot;: &amp;quot;1.02&amp;quot;, &amp;quot;u2&amp;quot;: &amp;quot;0.01&amp;quot;,&lt;br /&gt;
     &amp;quot;unit2&amp;quot;: &amp;quot;m&amp;quot;, &amp;quot;k&amp;quot;: 2.0}, &amp;quot;[OK,false]&amp;quot;, note=&amp;quot;|1.00-1.02| = 0.02 &amp;lt;= 2 x 0.01414&amp;quot;)&lt;br /&gt;
case(&amp;quot;mm/contradict-across-prefix&amp;quot;, MM, {&amp;quot;x1&amp;quot;: &amp;quot;100&amp;quot;, &amp;quot;u1&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;unit1&amp;quot;: &amp;quot;cm&amp;quot;, &amp;quot;x2&amp;quot;: &amp;quot;1.05&amp;quot;,&lt;br /&gt;
     &amp;quot;u2&amp;quot;: &amp;quot;0.01&amp;quot;, &amp;quot;unit2&amp;quot;: &amp;quot;m&amp;quot;, &amp;quot;k&amp;quot;: 2.0}, &amp;quot;[OK,true]&amp;quot;, note=&amp;quot;0.05 &amp;gt; 0.0283&amp;quot;)&lt;br /&gt;
case(&amp;quot;mm/hz-vs-rad&amp;quot;, MM, {&amp;quot;x1&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u1&amp;quot;: &amp;quot;0.01&amp;quot;, &amp;quot;unit1&amp;quot;: &amp;quot;Hz&amp;quot;, &amp;quot;x2&amp;quot;: &amp;quot;6.2832&amp;quot;, &amp;quot;u2&amp;quot;: &amp;quot;0.01&amp;quot;,&lt;br /&gt;
     &amp;quot;unit2&amp;quot;: &amp;quot;rad s-1&amp;quot;, &amp;quot;k&amp;quot;: 2.0}, &amp;quot;[CONVENTION,units of different kind: Hz1 and rad1]&amp;quot;,&lt;br /&gt;
     note=&amp;quot;the same oscillation; never compared, TPX opens an audit block&amp;quot;)&lt;br /&gt;
case(&amp;quot;mm/hz-vs-per-second&amp;quot;, MM, {&amp;quot;x1&amp;quot;: &amp;quot;50&amp;quot;, &amp;quot;u1&amp;quot;: &amp;quot;0.1&amp;quot;, &amp;quot;unit1&amp;quot;: &amp;quot;Hz&amp;quot;, &amp;quot;x2&amp;quot;: &amp;quot;50&amp;quot;, &amp;quot;u2&amp;quot;: &amp;quot;0.1&amp;quot;,&lt;br /&gt;
     &amp;quot;unit2&amp;quot;: &amp;quot;s-1&amp;quot;, &amp;quot;k&amp;quot;: 2.0}, &amp;quot;[CONVENTION,units of different kind: Hz1 and none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;mm/gray-vs-sievert&amp;quot;, MM, {&amp;quot;x1&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u1&amp;quot;: &amp;quot;0.1&amp;quot;, &amp;quot;unit1&amp;quot;: &amp;quot;Gy&amp;quot;, &amp;quot;x2&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u2&amp;quot;: &amp;quot;0.1&amp;quot;,&lt;br /&gt;
     &amp;quot;unit2&amp;quot;: &amp;quot;Sv&amp;quot;, &amp;quot;k&amp;quot;: 2.0}, &amp;quot;[CONVENTION,units of different kind: Gy1 and Sv1]&amp;quot;)&lt;br /&gt;
case(&amp;quot;mm/cross-dimension&amp;quot;, MM, {&amp;quot;x1&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u1&amp;quot;: &amp;quot;0.01&amp;quot;, &amp;quot;unit1&amp;quot;: &amp;quot;m&amp;quot;, &amp;quot;x2&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u2&amp;quot;: &amp;quot;0.01&amp;quot;,&lt;br /&gt;
     &amp;quot;unit2&amp;quot;: &amp;quot;s&amp;quot;, &amp;quot;k&amp;quot;: 2.0}, &amp;quot;[REFUSED,units of different dimension: L1 and T1]&amp;quot;)&lt;br /&gt;
LM = &amp;quot;lm_contradicts_units&amp;quot;&lt;br /&gt;
case(&amp;quot;lm/degree-agrees&amp;quot;, LM, {&amp;quot;x_l&amp;quot;: &amp;quot;180&amp;quot;, &amp;quot;unit_l&amp;quot;: &amp;quot;deg&amp;quot;, &amp;quot;x_m&amp;quot;: &amp;quot;3.14159&amp;quot;, &amp;quot;u_m&amp;quot;: &amp;quot;0.0001&amp;quot;,&lt;br /&gt;
     &amp;quot;unit_m&amp;quot;: &amp;quot;rad&amp;quot;, &amp;quot;k&amp;quot;: 2.0}, &amp;quot;[OK,false]&amp;quot;, note=&amp;quot;pi - 3.14159 = 2.65e-6 &amp;lt;= 2e-4&amp;quot;)&lt;br /&gt;
case(&amp;quot;lm/degree-contradicts&amp;quot;, LM, {&amp;quot;x_l&amp;quot;: &amp;quot;180&amp;quot;, &amp;quot;unit_l&amp;quot;: &amp;quot;deg&amp;quot;, &amp;quot;x_m&amp;quot;: &amp;quot;3.1&amp;quot;, &amp;quot;u_m&amp;quot;: &amp;quot;0.0001&amp;quot;,&lt;br /&gt;
     &amp;quot;unit_m&amp;quot;: &amp;quot;rad&amp;quot;, &amp;quot;k&amp;quot;: 2.0}, &amp;quot;[OK,true]&amp;quot;)&lt;br /&gt;
S8 = &amp;quot;sr8_scale_factor_units&amp;quot;&lt;br /&gt;
case(&amp;quot;sr8/mixed-prefix&amp;quot;, S8, {&amp;quot;measurements&amp;quot;: [{&amp;quot;x&amp;quot;: &amp;quot;1.00&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;0.01&amp;quot;, &amp;quot;unit&amp;quot;: &amp;quot;m&amp;quot;},&lt;br /&gt;
     {&amp;quot;x&amp;quot;: &amp;quot;103&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;unit&amp;quot;: &amp;quot;cm&amp;quot;}, {&amp;quot;x&amp;quot;: &amp;quot;0.99&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;0.01&amp;quot;, &amp;quot;unit&amp;quot;: &amp;quot;m&amp;quot;}]},&lt;br /&gt;
     &amp;quot;[OK,2.08166599947]&amp;quot;, note=&amp;quot;chi2/(N-1) = 4.3333 over 1.00, 1.03, 0.99 m&amp;quot;)&lt;br /&gt;
case(&amp;quot;sr8/convention&amp;quot;, S8, {&amp;quot;measurements&amp;quot;: [{&amp;quot;x&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;0.1&amp;quot;, &amp;quot;unit&amp;quot;: &amp;quot;Hz&amp;quot;},&lt;br /&gt;
     {&amp;quot;x&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;0.1&amp;quot;, &amp;quot;unit&amp;quot;: &amp;quot;s-1&amp;quot;}]}, &amp;quot;[CONVENTION,units of different kind: Hz1 and none]&amp;quot;)&lt;br /&gt;
case(&amp;quot;sr8/zero-u&amp;quot;, S8, {&amp;quot;measurements&amp;quot;: [{&amp;quot;x&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;unit&amp;quot;: &amp;quot;m&amp;quot;},&lt;br /&gt;
     {&amp;quot;x&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;0.1&amp;quot;, &amp;quot;unit&amp;quot;: &amp;quot;m&amp;quot;}]}, &amp;quot;[REFUSED,every M record needs an uncertainty above zero]&amp;quot;)&lt;br /&gt;
case(&amp;quot;sr8/refusal-first&amp;quot;, S8, {&amp;quot;measurements&amp;quot;: [{&amp;quot;x&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;unit&amp;quot;: &amp;quot;m&amp;quot;},&lt;br /&gt;
     {&amp;quot;x&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;0.1&amp;quot;, &amp;quot;unit&amp;quot;: &amp;quot;Hz&amp;quot;}, {&amp;quot;x&amp;quot;: &amp;quot;1&amp;quot;, &amp;quot;u&amp;quot;: &amp;quot;0.1&amp;quot;, &amp;quot;unit&amp;quot;: &amp;quot;s&amp;quot;}]},&lt;br /&gt;
     &amp;quot;[REFUSED,units of different dimension: L1 and T-1]&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# ---- S15 (tpc_units 0.1.1, proposed; corpus 0.1.1): appended, no earlier case&lt;br /&gt;
# changed. Hand-derived: the DIMENSION grammar bounds each base&amp;#039;s summed&lt;br /&gt;
# exponent to -9999..9999 (S15, D99, D103); tpc_units&amp;#039; own sums were audited&lt;br /&gt;
# and pinned. Reconstructed 2026-09-27 from the published corpus 0.1.1&lt;br /&gt;
# (BASE-GEN; append_units_s15.py, its seed, is not in the tree or the archive).&lt;br /&gt;
M = &amp;quot;unit_matches&amp;quot;&lt;br /&gt;
case(&amp;quot;s15/matches-dimension-out-of-range&amp;quot;, M, {&amp;quot;u&amp;quot;: &amp;quot;m&amp;quot;, &amp;quot;dimension&amp;quot;: &amp;quot;L9999 L1&amp;quot;},&lt;br /&gt;
     &amp;quot;[REFUSED,DIMENSION L9999 L1: an exponent is out of range]&amp;quot;,&lt;br /&gt;
     note=&amp;quot;S15: the DIMENSION&amp;#039;s bases sum to L10000, outside the grammar; tpc_units 0.1.0 answered [OK,false]&amp;quot;)&lt;br /&gt;
case(&amp;quot;s15/matches-dimension-bad-token&amp;quot;, M, {&amp;quot;u&amp;quot;: &amp;quot;m&amp;quot;, &amp;quot;dimension&amp;quot;: &amp;quot;L9999 L1 Q1&amp;quot;},&lt;br /&gt;
     &amp;quot;[REFUSED,DIMENSION L9999 L1 Q1 is not a dimension]&amp;quot;)&lt;br /&gt;
case(&amp;quot;s15/matches-sum-at-bound&amp;quot;, M, {&amp;quot;u&amp;quot;: &amp;quot;m9999&amp;quot;, &amp;quot;dimension&amp;quot;: &amp;quot;L5000 L4999&amp;quot;}, &amp;quot;[OK,true]&amp;quot;)&lt;br /&gt;
case(&amp;quot;s15/matches-sum-returns&amp;quot;, M, {&amp;quot;u&amp;quot;: &amp;quot;m&amp;quot;, &amp;quot;dimension&amp;quot;: &amp;quot;L5000 L-4999&amp;quot;}, &amp;quot;[OK,true]&amp;quot;)&lt;br /&gt;
case(&amp;quot;s15/audit-merged-symbol-sum&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;m5000 m5000&amp;quot;},&lt;br /&gt;
     &amp;quot;[REFUSED,UNIT m5000 m5000: an exponent is out of range]&amp;quot;,&lt;br /&gt;
     note=&amp;quot;S15 audit: one symbol&amp;#039;s exponents add and are bounded (tpc_units 0.1.0, unchanged)&amp;quot;)&lt;br /&gt;
case(&amp;quot;s15/audit-dimension-sum-across-symbols&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;km5000 m5000&amp;quot;},&lt;br /&gt;
     &amp;quot;[REFUSED,UNIT km5000 m5000: an exponent is out of range]&amp;quot;,&lt;br /&gt;
     note=&amp;quot;S15 audit: the resulting DIMENSION L10000 is bounded (tpc_units 0.1.0, unchanged)&amp;quot;)&lt;br /&gt;
case(&amp;quot;s15/audit-kind-not-a-grammar-form&amp;quot;, P, {&amp;quot;u&amp;quot;: &amp;quot;sr5000&amp;quot;}, &amp;quot;[OK,sr5000,1,rad10000]&amp;quot;,&lt;br /&gt;
     note=(&amp;quot;S15 audit: sr counts as rad2, so the KIND is rad10000; KIND is derived, written by no &amp;quot;&lt;br /&gt;
           &amp;quot;author and entering no preimage, so it is not bounded here; tpc_form refuses it where &amp;quot;&lt;br /&gt;
           &amp;quot;it is read (S14)&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def dispatch(fn, i):&lt;br /&gt;
    if fn == &amp;quot;unit_parse&amp;quot;:&lt;br /&gt;
        return U.unit_parse(i[&amp;quot;u&amp;quot;])&lt;br /&gt;
    if fn == &amp;quot;unit_scale&amp;quot;:&lt;br /&gt;
        return U.unit_scale(i[&amp;quot;u&amp;quot;])&lt;br /&gt;
    if fn == &amp;quot;unit_matches&amp;quot;:&lt;br /&gt;
        return U.unit_matches(i[&amp;quot;u&amp;quot;], i[&amp;quot;dimension&amp;quot;])&lt;br /&gt;
    if fn == &amp;quot;normalize_measurement&amp;quot;:&lt;br /&gt;
        return U.normalize_measurement(i[&amp;quot;value&amp;quot;], i[&amp;quot;uncertainty&amp;quot;], i[&amp;quot;u&amp;quot;])&lt;br /&gt;
    if fn == &amp;quot;mm_contradicts_units&amp;quot;:&lt;br /&gt;
        return U.mm_contradicts_units(i[&amp;quot;x1&amp;quot;], i[&amp;quot;u1&amp;quot;], i[&amp;quot;unit1&amp;quot;], i[&amp;quot;x2&amp;quot;], i[&amp;quot;u2&amp;quot;], i[&amp;quot;unit2&amp;quot;],&lt;br /&gt;
                                      i[&amp;quot;k&amp;quot;], i.get(&amp;quot;S&amp;quot;, 1.0))&lt;br /&gt;
    if fn == &amp;quot;lm_contradicts_units&amp;quot;:&lt;br /&gt;
        return U.lm_contradicts_units(i[&amp;quot;x_l&amp;quot;], i[&amp;quot;unit_l&amp;quot;], i[&amp;quot;x_m&amp;quot;], i[&amp;quot;u_m&amp;quot;], i[&amp;quot;unit_m&amp;quot;],&lt;br /&gt;
                                      i[&amp;quot;k&amp;quot;], i.get(&amp;quot;S&amp;quot;, 1.0))&lt;br /&gt;
    if fn == &amp;quot;sr8_scale_factor_units&amp;quot;:&lt;br /&gt;
        return U.sr8_scale_factor_units(i[&amp;quot;measurements&amp;quot;])&lt;br /&gt;
    raise KeyError(fn)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
bad = 0&lt;br /&gt;
for c in cases:&lt;br /&gt;
    got = S.canon(dispatch(c[&amp;quot;fn&amp;quot;], c[&amp;quot;input&amp;quot;]))&lt;br /&gt;
    if got != c[&amp;quot;expect&amp;quot;]:&lt;br /&gt;
        bad += 1&lt;br /&gt;
        print(&amp;quot;MISMATCH&amp;quot;, c[&amp;quot;id&amp;quot;], &amp;quot;\n  expect&amp;quot;, c[&amp;quot;expect&amp;quot;], &amp;quot;\n  got   &amp;quot;, got)&lt;br /&gt;
if bad:&lt;br /&gt;
    sys.exit(&amp;quot;refusing to write: %d mismatches&amp;quot; % bad)&lt;br /&gt;
&lt;br /&gt;
corpus = {&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;tpc_units_corpus&amp;quot;, &amp;quot;version&amp;quot;: &amp;quot;0.1.1&amp;quot;,&lt;br /&gt;
    &amp;quot;status&amp;quot;: &amp;quot;SELECTED D103.1, D104.1, D105.1 (2026-09-22); VERIFIED (both residences)&amp;quot;,&lt;br /&gt;
    &amp;quot;conforms_tps&amp;quot;: (&amp;quot;0.1.0 revision 4: SR3 and SR8 as amended by D40.1 (TPS 4.4.4), C-32 (TPS 3.2.9); &amp;quot;&lt;br /&gt;
                     &amp;quot;unit grammar and KIND text (tpm_units 0.2.0) enters TPS at revision 5&amp;quot;),&lt;br /&gt;
    &amp;quot;module&amp;quot;: &amp;quot;tpc_units 0.1.1 (proposed) (tpc_zone 0.4.1, tpc_strike 0.1.1)&amp;quot;,&lt;br /&gt;
    &amp;quot;note&amp;quot;: (&amp;quot;Expectations hand-derived: spellings and DIMENSIONs from the catalogue, scales from the SI &amp;quot;&lt;br /&gt;
             &amp;quot;Brochure&amp;#039;s exact values, SR3 results worked on paper. Both residences MUST reproduce every &amp;quot;&lt;br /&gt;
             &amp;quot;expect. 0.1.1 (S15) appends the s15/ cases and changes no earlier case: a DIMENSION &amp;quot;&lt;br /&gt;
             &amp;quot;whose bases sum outside -9999..9999 is refused with the reason, and the audit of &amp;quot;&lt;br /&gt;
             &amp;quot;tpc_units&amp;#039; own sums is pinned.&amp;quot;)&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;cases&amp;quot;: cases&lt;br /&gt;
}&lt;br /&gt;
with open(os.path.join(HERE, &amp;quot;vectors&amp;quot;, &amp;quot;units_corpus.json&amp;quot;), &amp;quot;w&amp;quot;, encoding=&amp;quot;utf-8&amp;quot;,&lt;br /&gt;
          newline=&amp;quot;\n&amp;quot;) as f:&lt;br /&gt;
    f.write(json.dumps(corpus, indent=1, ensure_ascii=False) + &amp;quot;\n&amp;quot;)&lt;br /&gt;
print(&amp;quot;wrote&amp;quot;, len(cases), &amp;quot;units cases; all match literal expectations&amp;quot;)&lt;br /&gt;
&lt;/div&gt;</summary>
		<author><name>BFP Rauch</name></author>
	</entry>
</feed>