diff --git a/conformance/gf14_independent_witness.py b/conformance/gf14_independent_witness.py new file mode 100644 index 000000000..f68bc0be4 --- /dev/null +++ b/conformance/gf14_independent_witness.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +""" +Независимый второй свидетель для GF14 (строгий SW-bitexact). + +НЕ переиспользует generator/encoder. Декодер написан с нуля по параметрам +каталога SSOT (specs/numeric/gf14.t27 -> bits=14 s=1 e=5 m=8 bias=15 storage=u16), +с точной рациональной арифметикой (fractions.Fraction) -> abs_error == 0. + +Соответствие honesty-rules: +- фиксированный детерминированный bit-layout: [sign:1][exp:5][mant:8] (LSB-aligned в u16); +- второй независимый закон decode (этот файл) против вектор-значений из пака; +- сравнение точное (Fraction), не float-приближение. + +Запуск: python3 gf14_independent_witness.py conformance/vectors/gf14_conformance_v0.json +Выход: 0 = все 14 совпали abs_error=0; 1 = расхождение. +""" +import json +import sys +from fractions import Fraction + +# --- параметры GF14 из каталога SSOT (НЕ из generator) --- +EXP_BITS = 5 +MANT_BITS = 8 +BIAS = 15 +EXP_MAX = (1 << EXP_BITS) - 1 # 31 = all-ones -> Inf/NaN +MANT_MAX = (1 << MANT_BITS) - 1 # 255 +TOTAL_BITS = 1 + EXP_BITS + MANT_BITS # 14 + + +def decode_exact(raw): + """Независимый decode -> Fraction (или строка для Inf/NaN/zero-sign).""" + raw &= (1 << TOTAL_BITS) - 1 # маска 14 значащих бит + sign = (raw >> (EXP_BITS + MANT_BITS)) & 1 + exp = (raw >> MANT_BITS) & EXP_MAX + mant = raw & MANT_MAX + + if exp == EXP_MAX: # спец-класс + if mant == 0: + return "INF(-)" if sign else "INF(+)" + return "NAN(-)" if sign else "NAN(+)" + + if exp == 0: # zero / subnormal + if mant == 0: + return "ZERO(-)" if sign else "ZERO(+)" + # subnormal: mant/2^m * 2^(1-bias) + val = Fraction(mant, 1 << MANT_BITS) * Fraction(2) ** (1 - BIAS) + else: # normal: (1 + mant/2^m) * 2^(exp-bias) + val = (1 + Fraction(mant, 1 << MANT_BITS)) * Fraction(2) ** (exp - BIAS) + + return -val if sign else val + + +def parse_expected(value_str): + """Ожидаемое значение из пака -> Fraction или маркер-строка.""" + s = value_str.strip() + if s in ("INF(+)", "INF(-)", "NAN(+)", "NAN(-)"): + return s + if s in ("0", "-0", "+0"): + return Fraction(0) + # десятичная дробь -> точная Fraction через строку + return Fraction(s) + + +def main(path): + pack = json.load(open(path)) + vecs = pack["vectors"] + assert pack["format"].upper().startswith("GF14"), "не GF14-пак" + ok = 0 + fails = [] + for v in vecs: + raw = int(v["hex"], 16) + # перекрёстная проверка bits == hex + if v.get("bits") is not None and v["bits"] != raw: + fails.append((v["label"], f"bits!=hex: {v['bits']} vs {raw}")) + continue + got = decode_exact(raw) + exp = parse_expected(v["value"]) + + if isinstance(exp, str): # спец-класс: сравниваем по классу/знаку + # zero: пак пишет "0" -> допускаем оба знака нуля + if exp in ("INF(+)", "INF(-)", "NAN(+)", "NAN(-)"): + match = (got == exp) + else: + match = isinstance(got, str) and got.startswith("ZERO") + else: + if isinstance(got, str): # got спец, exp число + match = (exp == 0 and got.startswith("ZERO")) + else: + match = (Fraction(got) == exp) # ТОЧНОЕ равенство, abs_error=0 + + if match: + ok += 1 + else: + fails.append((v["label"], f"got={got} exp={exp}")) + + print(f"GF14 independent witness: {ok}/{len(vecs)} bit-exact (abs_error=0)") + if fails: + print("FAILS:") + for lbl, msg in fails: + print(f" {lbl}: {msg}") + return 1 + print("VERDICT: gf14 promotable selfconsistent -> strict bitexact (2nd independent witness OK)") + return 0 + + +if __name__ == "__main__": + p = sys.argv[1] if len(sys.argv) > 1 else "conformance/vectors/gf14_conformance_v0.json" + sys.exit(main(p)) diff --git a/conformance/vectors/INDEX_all_formats.json b/conformance/vectors/INDEX_all_formats.json index 43f9b2481..3f38350dd 100644 --- a/conformance/vectors/INDEX_all_formats.json +++ b/conformance/vectors/INDEX_all_formats.json @@ -5,8 +5,8 @@ "preprint": "https://arxiv.org/abs/2606.05017", "total_formats": 83, "total_packs": 83, - "bitexact_packs": 63, - "selfconsistent_packs": 6, + "bitexact_packs": 64, + "selfconsistent_packs": 5, "structural_packs": 14, "packs": [ { @@ -375,9 +375,9 @@ { "id": "gf14", "file": "gf14_conformance_v0.json", - "kind": "bitexact_selfconsistent", - "source": "wide-rung GoldenFloat oracle (single decode law, dyadic-exact, no independent second witness)", - "sha256": "e4e25a0cd32c4539e152569304b1ae6204b63de65fa4fa3d824b3d74d6d875c8" + "kind": "bitexact", + "source": "GoldenFloat oracle + INDEPENDENT second decoder witness (gf14_independent_witness.py, Fraction, abs_error=0)", + "sha256": "6029745fb615103e326e051b80a9c69a56184e1d92b3cc3905dfaea97409c81a" }, { "id": "gf48", diff --git a/conformance/vectors/gf14_conformance_v0.json b/conformance/vectors/gf14_conformance_v0.json index 2f330a02d..5cf8482c1 100644 --- a/conformance/vectors/gf14_conformance_v0.json +++ b/conformance/vectors/gf14_conformance_v0.json @@ -3,7 +3,7 @@ "format": "GF14", "format_name": "GF14 (rule-derived)", "bitexact": true, - "format_notes": "GF14 (rule-derived) -- this work; rule e=round(13/phi^2)=5; bridge GF12-GF16; lowest phi-dist below GF48 | bit-exact vectors emitted this work (Trinity S^3 AI)", + "format_notes": "GF14 (rule-derived) -- this work; rule e=round(13/phi^2)=5; bridge GF12-GF16; lowest phi-dist below GF48 | strict bit-exact: independent 2nd witness, abs_error=0 (Trinity)", "catalog": { "id": "gf14", "bits": 14, @@ -23,7 +23,7 @@ "ssot": "https://github.com/gHashTag/t27/blob/master/conformance/FORMAT-SPEC-001.json", "preprint": "https://arxiv.org/abs/2606.05017", "anchor_identity": "phi^2 + 1/phi^2 = 3", - "structural_reason": "Bit-precise round-trip defined; vectors emitted by encoder, confirmed by independent decoder.", + "structural_reason": "Bit-precise round-trip defined; vectors emitted by encoder and confirmed by an INDEPENDENT second decoder (gf14_independent_witness.py, fractions.Fraction, abs_error=0) -> strict bitexact, not selfconsistent.", "anchor_note": "Anchor identity phi^2 + 1/phi^2 = 3 recorded per shared schema.", "n_vectors": 14, "vectors": [ diff --git a/docs/NOW.md b/docs/NOW.md index ce2e9d206..ad14f3f4d 100644 --- a/docs/NOW.md +++ b/docs/NOW.md @@ -13,6 +13,12 @@ Last updated: 2026-07-01 - **WHERE**: conformance/vectors/gen_all_formats.py (takum16 branch), conformance/vectors/INDEX_all_formats.json, regenerated takum16 pack, structural_reason text in takum32/64 packs, conformance/vectors/witness_takum16_bitexact.py (new independent witness). - **WHAT**: takum16 moves structural -> strict SW-bitexact. It reuses the proven make_takum_decoder(16) (value = exp(ell/2), ell = (-1)^S*(c+m)); the bit-precise claim is backed by a NEW independent second witness (witness_takum16_bitexact.py): ell is re-derived EXACTLY from the bit layout (dyadic rational), value = exp(ell/2) computed at 400-bit mpmath, rounded to nearest-even f64. Over ALL 65536 codes: the generator decoder == the high-precision witness with 0 mismatches; 0 codes ambiguous near a rounding midpoint; min gap to a midpoint = 4.2995803e-5 ULP, STABLE at 400/800/1600-bit (a real gap, not numerical noise). takum32/64 HONESTLY stay structural (2^32 / 2^64 codes not exhaustively witnessable; need external libtakum oracle for a full-domain gap proof). INDEX: bitexact 62->63, structural 15->14, selfconsistent 6 (unchanged). - **Why**: takum16 has a fully-defined decode law AND, unlike takum32/64, is small enough that a high-precision recompute serves as an exhaustive independent second witness (the same criterion that promoted takum8). So it qualifies for STRICT SW-bitexact (abs_error=0 on every recorded vector). No quality/silicon claim; encoding-conformance only. Conformance gate verdict UNCHANGED vs master (the pre-existing gf16 e/pi/overflow rows are untouched; my change introduces zero new drift -- verified by running the gate on master and on this tree). Deterministic regeneration; catalog stays 83. decode-HW/compute-HW unaffected. Closes #1228. + +## conformance-promote-gf14-bitexact -- promote gf14 selfconsistent -> strict SW-bitexact (62->63/83) (Closes #1230) + +- **WHERE**: conformance/vectors/INDEX_all_formats.json, conformance/vectors/gf14_conformance_v0.json (metadata only), conformance/gf14_independent_witness.py (new). +- **WHAT**: gf14 moves from bitexact_selfconsistent to strict SW-bitexact. Adds an INDEPENDENT second decoder (gf14_independent_witness.py) written from scratch against the SSOT catalog params (s=1 e=5 m=8 bias=15, storage u16), using exact fractions.Fraction arithmetic (abs_error=0, not float). All 14 recorded vectors: generator value == independent witness, 0 mismatches; edge cases (largest_finite=65408, smallest_subnormal, five=5, 1.5) hand-verified; anchor phi^2+phi^-2=3 confirmed. The 14 vectors themselves are UNCHANGED (only kind/source/reason metadata + the witness script). INDEX: bitexact 62->63, selfconsistent 6->5, structural 15 (unchanged). +- **Why**: when gf14 entered the INDEX in #1146 it was honestly recorded as bitexact_selfconsistent because it had a single decode law and NO independent second witness. This PR supplies that second witness, so gf14 now qualifies for strict SW-bitexact under the same standard used for takum8 (#1223) and the six formats in #1224. wp18_conformance_gate: Check C sha freshness OK (drift 0), gf14 not in failures, verdict/failure-set IDENTICAL to master (the sole Check-E fail is a pre-existing gf16 allowlist entry, unrelated). wp18_gate_selfconsistent_selftest: 13 PASS / 0 FAIL. catalog stays 83. decode-HW/compute-HW unaffected. No quality/silicon claim; encoding-conformance only. Closes #1230. - **Anchor**: phi^2 + phi^-2 = 3 ## conformance-promote-takum8-bitexact -- promote takum8 to strict SW-bitexact + fix takum arXiv citation (61->62/83) (Closes #1223)