Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion docs/NOW.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# NOW -- Trinity t27 sync

Last updated: 2026-06-08
Last updated: 2026-06-13

## fix-parser-bias-formula -- handle bias formulas in numeric format SSOT (Closes #1064)

- **WHERE** (codegen only): `tools/gen_formats_catalog.py` parser extended to handle bias formulas like `2^N-1` (gf512, gf1024) which were previously dropped on `int(s)` cast. No `specs/` edits, no `gen/` edits in this PR (codegen runs auto-regenerate on master post-merge). The fix raises live regen output from 81 to 83 rows, matching the SSOT raw-line count at HEAD `6ecad30`.
- **Why**: count-drift audit (#1064) showed four divergent counts across the catalog pipeline -- paper 84 / SSOT 83 / regen 81 / shipped gen 77. Root cause for the 83 -> 81 drop was a parser that treated bias as `int(value)` and silently dropped two rows on `2^N-1`. After this fix lands and codegen reruns, gen/ artefacts and the HF mirror at `playra/numeric-format-catalog` converge on 83. The paper-84 vs SSOT-83 difference is the historical paper expansion plan recorded as a separate row that was never materialised in the SSOT; treated as an honest documentation note in arXiv:2606.09686 §11. L6 gf16 SSOT untouched. L2 gen/ untouched in this PR (will auto-regen). Closes #1064.
- **Anchor**: phi^2 + phi^-2 = 3

## funding-json-trinity-s3ai -- maintainer block + ORCID + project_info anchor (Closes #1062)

Expand Down
38 changes: 36 additions & 2 deletions tools/gen_formats_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ class Format:
s_bits: int
e_bits: int
m_bits: int
bias: int
bias: int # -2 sentinel = value exceeds int64, see bias_formula
bias_formula: str # raw SSOT bias string (literal int or formula like '2^194-1')
phi_distance: float # -1.0 == undefined
storage: str
cluster: str
Expand All @@ -70,19 +71,52 @@ def parse_kv_line(line: str) -> dict[str, str]:
return out


def parse_bias(s: str) -> tuple[int, str]:
"""Parse a bias field.

Returns (bias_int, bias_formula). bias_formula is the raw SSOT string
(e.g. '2^194-1' for gf512); bias_int is the int() of s when possible,
else -1 sentinel meaning 'see bias_formula'. This lets the int-typed
bias field stay backwards-compatible with all downstream emitters
(Rust i64, C int64_t, TS number) while preserving the rule-derived
formulas for the limit-of-ladder GF rungs (gf512 bias 2^194-1,
gf1024 bias 2^390-1) that were added by PR #1051. See issue #1064.
"""
try:
return int(s), s
except ValueError:
# Try to evaluate simple 2^N-1 / 2^N+1 / 2^N forms; if the
# exponent stays within range, return the literal int.
m = re.match(r"^2\^(\d+)([+-]\d+)?$", s.strip())
if m:
exp = int(m.group(1))
off = int(m.group(2)) if m.group(2) else 0
if exp <= 1024: # python int is arbitrary precision but i64 isn't
val = (1 << exp) + off
# Only return as int if it fits signed 64-bit; otherwise
# downstream emitters (Rust i64, C int64_t) overflow.
if -(1 << 63) <= val < (1 << 63):
return val, s
# Cannot lift to int; record formula, use sentinel -2 meaning
# "value lives in bias_formula field, exceeds int64".
return -2, s


def parse_t27(text: str) -> list[Format]:
formats: list[Format] = []
for m in CATALOG_LINE.finditer(text):
fields = parse_kv_line(m.group(1))
try:
bias_int, bias_formula = parse_bias(fields["bias"])
fmt = Format(
id=fields["id"],
name=fields["name"],
bits=int(fields["bits"]),
s_bits=int(fields["s"]),
e_bits=int(fields["e"]),
m_bits=int(fields["m"]),
bias=int(fields["bias"]),
bias=bias_int,
bias_formula=bias_formula,
phi_distance=float(fields["phi_distance"]),
storage=fields["storage"],
cluster=fields["cluster"],
Expand Down
Loading