diff --git a/research/current-moment-integer-fastpath/PROOF.md b/research/current-moment-integer-fastpath/PROOF.md new file mode 100644 index 0000000000..5292b21703 --- /dev/null +++ b/research/current-moment-integer-fastpath/PROOF.md @@ -0,0 +1,41 @@ +# Exact equivalence of the integer kernel + +Fix any exact Fraction argument x. Negative arguments follow the unchanged +reciprocal branch; zero and positive arguments use exactly the predecessor's +halving loop until 0 <= x = p/q <= 1/64, q > 0. Thus both algorithms have the +same reduced argument and the same number of subsequent squarings. + +Write D_j = q^j j!, P_j = p^j, and S_j = sum_{i=0}^j x^i/i!. +Induction gives S_j = N_j / D_j with + + N_0 = D_0 = P_0 = 1 + P_j = p P_{j-1} + D_j = j q D_{j-1} + N_j = j q N_{j-1} + P_j. + +These are integer operations. They compute exactly the reference's forty +Fraction multiply/add steps without reducing intermediate numerator/denominator +pairs. The final term is P_40 / D_40. The reference's exact positive tail is + + R = (P_40/D_40) (p/q) / 41 / (1 - p/(42q)) + = 42 P_40 p / [41 D_40 (42q-p)]. + +The denominator is positive on the reduced domain, including p=0. Therefore +`taylor_parts` returns exact unreduced fractions for S_40 and S_40+R. No error +term or positive tail is dropped merely because it is usually below one grid unit. + +For M=10^65 and nonnegative integers a,b with b>0, the reference's grid floor +of a/b is floor(a M/b)/M and the grid ceiling is ceil(a M/b)/M. Python integer +`//` and `(a*M+b-1)//b` implement these exactly. Once a bound is represented +as n/M, flooring its square is floor(n^2/M)/M, and ceiling its square is +ceil(n^2/M)/M. Hence induction through every squaring gives the identical +pair of rational endpoints. The negative branch applies identical reciprocals +and identical outward rounding to identical endpoints. The unchanged logarithm, +power, moment, interval subtraction and strict allowance functions consequently +produce identical results for their supported exact inputs. + +This is an algebraic equivalence proof for the fixed authenticated engine, not +a new proof of its transcendental enclosure theorem or of integer multiplication. +The executable differential tests support the implementation of the recurrence; +finite tests alone are not the universal argument. Authentication, the original +rank checks, and explicit guards remain active under `python -O`. diff --git a/research/current-moment-integer-fastpath/README.md b/research/current-moment-integer-fastpath/README.md new file mode 100644 index 0000000000..8aa641be0f --- /dev/null +++ b/research/current-moment-integer-fastpath/README.md @@ -0,0 +1,82 @@ +# Exact integer fast path for the selected moment engine + +**Tooling result; no new κ.** An opt-in adapter returns the same exact rational +intervals as the selected #5413 caller's 72-term-log / 40-term-exp engine. +It removes intermediate Fraction reductions from the exponential sum. The +Taylor degree, positive remainder, range reduction, negative reciprocal, +10^65 grid, and every outward-rounded squaring stay identical. See [PROOF.md](PROOF.md). + +On Windows / CPython 3.12.2, three alternating fresh-process pairs give median +**4.1874 s → 0.2770 s (15.12×)** for 24 actual invoice ranks × 12 distinct +exponents, complete paid/productive moments and strict homogeneous allowances. +All six mathematical receipts have SHA256 +`fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd`. +[Final samples](benchmark-final-windows.json) and [earlier samples](benchmark-windows.json) +are retained. Timings exclude source loading/imports but include cold logarithm +and power caches. They measure this pricing workload, not a full caller replay. +The earlier instrumented 288-power profile took 4.538 s, with 3.345 s in gcd; +it motivated this change but is not used for the speedup ratio. + +## Reproduce and use + +Python 3.12 standard library only, from repository root: + +```sh +python3.12 -B scripts/research_package.py --package research/current-moment-integer-fastpath +python3.12 -B research/current-moment-integer-fastpath/benchmark.py --pairs 3 --output /tmp/fresh-moment-benchmark.json +``` + +The benchmark refuses an existing output path. Each sample uses a fresh subprocess +and fresh caches; a differing receipt aborts the timing comparison. No unstable +wall-time threshold is a CI acceptance condition. + +For exploratory pricing, put this directory on the Python import path and call +`from fast_moments import load_engine; engine = load_engine()`. +Use its unchanged `moment`, `minus`, `power` and `homogeneous_limit` interfaces. +`load_engine(False)` loads the authenticated reference. Both inputs are local +snapshots with SHA256 rejection before evaluation; no cached mathematical result +or external checkout is needed. Installing into arbitrary engines is unsupported. + +The verifier compares the complete workload, all 600 exponential invocation/result +records, 121 boundary/seeded rational arguments, exact unrounded polynomial and +remainder parts, and 35 signed/zero-exponent rank cases. It checks the selected +positive lower point and rejected raw ceiling. Executed degree, tail and inward +rounding mutations, source/fixture tampering, an omitted charge and an invalid +rank are detected. The same explicit checks run under normal and optimized Python. + +The frozen source and invoice provenance are in [SOURCES.json](SOURCES.json). +`inputs/invoice.json` is exactly the `histograms` object extracted from the pinned +invoice receipt. The unchanged source is copied byte for byte. The grid and source +hash are fixed deliberately: a new source version needs a new review, not a silent +cache reuse. The source's other acceptance logic remains compiled with assertions +enabled. Native identity, target independence, physical admission, full compiler, +precision and outer-theorem checks are outside this adapter. No full-caller, +whole-repository, Lean, or independent-human verification is claimed. + +## Overlap and credit + +Chris R / Clear1nsight supplies the exact arithmetic and #5413 completion. +Dillon, Ali Romman, Cao Yifan, Dugongue, Cinna Davis, zxv and the retained lineage +supply the selected construction. Their existing notices are preserved. + +This is an adaptation of a classical integer Taylor recurrence, not a new +mathematical method. Related exact-output integer kernels already occur in +[PR672](https://github.com/CrocSwap/integer-mult-bounds/pull/672) (a different, +degree-16 / 200-bit engine; its full owner check saved only 2–3%) and +[PR2552](https://github.com/CrocSwap/integer-mult-bounds/pull/2552). +This package targets the currently selected 72/40 engine and its actual invoice, +without editing a frozen predecessor or substituting one engine's truncation +parameters for another's. Live title/body overlap searches are partial coverage, +not a novelty proof. New material: Joseph Anglada with substantial OpenAI Codex +assistance, Apache-2.0; no independent human or proof-kernel review. + +## Open next questions + +- How much does this save in a complete caller replay? First build a source-bound + adapter that substitutes only this arithmetic and compare complete receipts in + matched fresh processes. Native validation and other replay costs may dominate; + a separate full replay budget and adapter review are needed. +- Can a changed physical word earn a better κ? First supply a literal changed word + and complete paid/target invoice, then use this kernel for exact screening. + Operator identity, independent targets, restoration, ordinary work, precision and + compiler/outer funding remain the gates. Faster pricing alone changes no κ. diff --git a/research/current-moment-integer-fastpath/SOURCES.json b/research/current-moment-integer-fastpath/SOURCES.json new file mode 100644 index 0000000000..df7877c0a4 --- /dev/null +++ b/research/current-moment-integer-fastpath/SOURCES.json @@ -0,0 +1,30 @@ +{ + "base_commit": "32890bc5de034ab8fc93ac88ead7279a6a416d04", + "files": [ + { + "git_blob": "fc3d4ba105e1f097d0d7d051a308281e86ab1446", + "path": "certificates/selected-result.json", + "sha256": "66974efdced4083c00025f97d95d83909a226cdf801edb9301c195c6641f6903", + "usage": "provenance" + }, + { + "git_blob": "f126dd2e2dad2b669e75d1d0d0bd05c600725602", + "path": "docs/research/agent-task-catalog.json", + "sha256": "f7a48bfa2659b88378282a8eee7d9fe52cdf505594124c4d1686b58510fffd72", + "usage": "provenance" + }, + { + "git_blob": "bf31af785122dea7cbceacbfa64c21e567e4fca7", + "path": "research/coupled-helper-neutral-completion/capsule/workspace/swarm-coupled-caller-sol-high-20261024/agents/invoice/exact_moments.py", + "sha256": "cf7439c9eb4095224126dd5eefc9f1c5dfe1968d6e8eca5b87d4a3897841182d", + "usage": "provenance" + }, + { + "git_blob": "d66216ad80b502c4042979269655bacb9f6668b9", + "path": "research/coupled-helper-neutral-completion/reports/expected/invoice.json", + "sha256": "e7df9fe1a7a00f67bbf35e9b155537fd26a0c05b61788653b878bd84d9006450", + "usage": "provenance" + } + ], + "schema_version": 1 +} diff --git a/research/current-moment-integer-fastpath/TASK.json b/research/current-moment-integer-fastpath/TASK.json new file mode 100644 index 0000000000..75ca99532b --- /dev/null +++ b/research/current-moment-integer-fastpath/TASK.json @@ -0,0 +1,67 @@ +{ + "actual_scope": "Accelerate the selected caller exact moment pricing kernel without changing any rational endpoint.", + "ai_assistance": "Substantial OpenAI Codex assistance in profiling, implementation, derivation and verification. No independent human or proof-kernel review.", + "author": "Joseph Anglada, with substantial OpenAI Codex assistance", + "base_commit": "32890bc5de034ab8fc93ac88ead7279a6a416d04", + "bottleneck_link": "Fraction normalization consumes about 74 percent of profiled pricing time. Integer Taylor recurrence permits more candidate invoices to be screened with exactly the same arithmetic acceptance.", + "budget_minutes": 60, + "evidence": "verify.py, PROOF.md, benchmark-final-windows.json; 600 exponential calls and complete moment/allowance outputs agree exactly.", + "open_questions": [ + { + "blocked_by": "Requires a separate scoped full-caller adapter and complete replay budget.", + "first_step": "Run matched fresh-process complete caller replays with only this engine substituted and compare complete receipts.", + "question": "How much does opt-in substitution save in a complete caller replay?", + "why_it_matters": "Kernel timing does not measure the rest of native validation, compiler and source checks." + }, + { + "blocked_by": "A legal changed word, independent targets and all physical and compiler charges are needed.", + "first_step": "Use load_engine() to screen a changed fully charged paid/target histogram, then verify its actual operator and fund compiler/outer costs.", + "question": "Can changed physical words produce a better complete signed invoice?", + "why_it_matters": "Unchanged arithmetic cannot improve the mathematical kappa." + } + ], + "original_card": { + "acceptance_gate": "Report before/after wall time on the same fixture, retained checks and invalidation behavior.", + "allowed_variations": [ + "Profile one stage or design one source-bound cache boundary." + ], + "bottleneck_link": "Faster trustworthy replays increase review throughput and let mechanism candidates be checked sooner.", + "first_experiment": "Measure one unchanged fixture, preserve check coverage, and test one optimization with invalidation controls.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Read the selected reproduction command and choose a single replay stage for profiling.", + "scope": "Positive control / source-bound orientation only; this is not a new construction or full cold replay." + }, + "id": "replay-runtime", + "methods": [ + "Profile one isolated replay and optimize the measured bottleneck.", + "Design source-bound reuse with explicit dependency invalidation and negative controls." + ], + "overlap_terms": [ + "replay runtime", + "cache invalidation", + "isolated tests" + ], + "question": "Can one measured replay bottleneck be sped up without dropping coverage?", + "scope_change_triggers": [ + "Skipping coverage or comparing different fixtures to claim speedup." + ], + "starting_points": [ + "scripts/run_isolated_tests.py", + "scripts/verify_replay_coverage.py", + "certificates/selected-result.json" + ] + }, + "outcome": "completed", + "priority_revision": 7, + "schema_version": 1, + "scope_change_reason": "Explicit user request to optimize checks and then resume changed-profile kappa exploration; profile selected moment arithmetic rather than unrelated replay routing.", + "scope_status": "refined", + "stop_rule": "Publish only after exact differential controls, paired fresh-process timing and package replay; do not infer full-caller speedup or a new kappa from kernel timing.", + "task_id": "replay-runtime" +} diff --git a/research/current-moment-integer-fastpath/VERIFY.json b/research/current-moment-integer-fastpath/VERIFY.json new file mode 100644 index 0000000000..98a2331b33 --- /dev/null +++ b/research/current-moment-integer-fastpath/VERIFY.json @@ -0,0 +1,28 @@ +{ + "commands": [ + { + "argv": [ + "{python}", + "-B", + "{package}/verify.py" + ], + "checks": "Complete exact pricing and invocation trace equality, unrounded Taylor and remainder oracle, signed powers, source/fixture tampering, paid-charge and executed kernel mutations.", + "timeout_seconds": 120 + }, + { + "argv": [ + "{python}", + "-O", + "-B", + "{package}/verify.py" + ], + "checks": "Same explicit checks under optimized Python; frozen source compiles with optimize=0.", + "timeout_seconds": 120 + } + ], + "inputs": [], + "python": "3.12", + "requirements": [], + "schema_version": 1, + "status": "ready" +} diff --git a/research/current-moment-integer-fastpath/benchmark-final-windows.json b/research/current-moment-integer-fastpath/benchmark-final-windows.json new file mode 100644 index 0000000000..6b23b6c4a1 --- /dev/null +++ b/research/current-moment-integer-fastpath/benchmark-final-windows.json @@ -0,0 +1,43 @@ +{ + "median_seconds": { + "fast": 0.2769799999659881, + "reference": 4.187386899953708 + }, + "median_speedup": 15.118011771492167, + "new_kappa": null, + "platform": "Windows-10-10.0.19045-SP0", + "python": "3.12.2 (tags/v3.12.2:6abddd9, Feb 6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)]", + "samples": [ + { + "mode": "reference", + "seconds": 4.04614740004763, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + }, + { + "mode": "fast", + "seconds": 0.2769799999659881, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + }, + { + "mode": "fast", + "seconds": 0.27250459999777377, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + }, + { + "mode": "reference", + "seconds": 4.766304199933074, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + }, + { + "mode": "reference", + "seconds": 4.187386899953708, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + }, + { + "mode": "fast", + "seconds": 0.3445142999989912, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + } + ], + "scope": "24 ranks x 12 exponents, complete moments and strict allowances; cold engine caches" +} diff --git a/research/current-moment-integer-fastpath/benchmark-windows.json b/research/current-moment-integer-fastpath/benchmark-windows.json new file mode 100644 index 0000000000..b869a5a563 --- /dev/null +++ b/research/current-moment-integer-fastpath/benchmark-windows.json @@ -0,0 +1,43 @@ +{ + "median_seconds": { + "fast": 0.2735154000110924, + "reference": 4.0972460000775754 + }, + "median_speedup": 14.979946284236323, + "new_kappa": null, + "platform": "Windows-10-10.0.19045-SP0", + "python": "3.12.2 (tags/v3.12.2:6abddd9, Feb 6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)]", + "samples": [ + { + "mode": "reference", + "seconds": 4.160859999945387, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + }, + { + "mode": "fast", + "seconds": 0.2735154000110924, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + }, + { + "mode": "fast", + "seconds": 0.34580119990278035, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + }, + { + "mode": "reference", + "seconds": 4.044113300042227, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + }, + { + "mode": "reference", + "seconds": 4.0972460000775754, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + }, + { + "mode": "fast", + "seconds": 0.2694238000549376, + "sha256": "fd2027763821b8623d579c37a7826a686d2725c0fdd18c193e59a64e481a98fd" + } + ], + "scope": "24 ranks x 12 exponents, complete moments and strict allowances; cold engine caches" +} diff --git a/research/current-moment-integer-fastpath/benchmark.py b/research/current-moment-integer-fastpath/benchmark.py new file mode 100644 index 0000000000..1939f75277 --- /dev/null +++ b/research/current-moment-integer-fastpath/benchmark.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +"""Fresh subprocess pairs; timings are evidence, never a CI acceptance threshold.""" +import argparse +import json +from pathlib import Path +import platform +import statistics +import subprocess +import sys +from time import perf_counter +import fast_moments +import workload + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument('--worker', choices=('reference', 'fast')) + ap.add_argument('--pairs', type=int, default=3) + ap.add_argument('--output', type=Path) + args = ap.parse_args() + if args.worker: + engine = fast_moments.load_engine(args.worker == 'fast') + start = perf_counter() + receipt = workload.run(engine) + print(json.dumps({'mode': args.worker, 'seconds': perf_counter()-start, + 'sha256': workload.digest(receipt)})) + return + if not 1 <= args.pairs <= 20: + ap.error('--pairs must be 1..20') + samples = [] + for j in range(args.pairs): + order = ('reference', 'fast') if j % 2 == 0 else ('fast', 'reference') + for mode in order: + output = subprocess.check_output([sys.executable, '-B', __file__, '--worker', mode], text=True) + samples.append(json.loads(output)) + if len({x['sha256'] for x in samples}) != 1: + raise ValueError('different mathematical outputs; timing comparison invalid') + medians = {mode: statistics.median(x['seconds'] for x in samples if x['mode'] == mode) + for mode in ('reference', 'fast')} + result = {'python': sys.version, 'platform': platform.platform(), 'samples': samples, + 'median_seconds': medians, 'median_speedup': medians['reference']/medians['fast'], + 'scope': '24 ranks x 12 exponents, complete moments and strict allowances; cold engine caches', + 'new_kappa': None} + encoded = json.dumps(result, sort_keys=True, indent=2)+'\n' + if args.output: + if args.output.exists(): + raise ValueError('refusing to overwrite benchmark evidence') + args.output.write_bytes(encoded.encode()) + print(encoded) + + +if __name__ == '__main__': + main() diff --git a/research/current-moment-integer-fastpath/fast_moments.py b/research/current-moment-integer-fastpath/fast_moments.py new file mode 100644 index 0000000000..c06eb473c1 --- /dev/null +++ b/research/current-moment-integer-fastpath/fast_moments.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +"""Opt-in, output-identical integer Taylor kernel for the frozen current engine. + +Preserves Chris R/Clear1nsight's logarithms, 40-term exponential, rational +remainder and every outward rounding. Integer recurrence is classical; see +the prior retained ceiling fast path PR2552. Joseph Anglada with substantial +OpenAI Codex assistance. Apache-2.0. No mathematical acceptance gate changed. +""" +from fractions import Fraction +from hashlib import sha256 +from pathlib import Path +import types + +SOURCE = Path(__file__).resolve().parent / 'inputs' / 'exact_moments.py' +SOURCE_SHA256 = 'cf7439c9eb4095224126dd5eefc9f1c5dfe1968d6e8eca5b87d4a3897841182d' + + +def taylor_parts(p, q): + """Unreduced S_40 and S_40 + R_40 for 0 <= p/q <= 1/64.""" + power = numerator = denominator = 1 + for j in range(1, 41): + power *= p + numerator = j * q * numerator + power + denominator *= j * q + factor = 41 * (42 * q - p) + return (numerator, denominator, + numerator * factor + power * p * 42, denominator * factor) + + +def load_engine(fast=True): + raw = SOURCE.read_bytes() + if sha256(raw).hexdigest() != SOURCE_SHA256: + raise ValueError('frozen moment source changed') + module = types.ModuleType('authenticated_moments') + module.__file__ = str(SOURCE) + exec(compile(raw, str(SOURCE), 'exec', dont_inherit=True, optimize=0), module.__dict__) + if fast: + install(module) + return module + + +def install(module): + original = module.expbound + precision = module.PRECISION + if precision != 10**65: + raise ValueError('unsupported rounding grid') + + def expbound(value): + # Keep the predecessor's behavior for values outside its internal + # exact-Fraction interface; discovery/acceptance uses Fraction only. + if type(value) is not Fraction: + return original(value) + if value < 0: + lo, hi = module.expbound(-value) + return module.floorq(1 / hi), module.ceilq(1 / lo) + squarings = 0 + while value > Fraction(1, 64): + value /= 2 + squarings += 1 + p, q = value.numerator, value.denominator + # T_40 = power/denominator, S_40 = numerator/denominator. + # Original remainder T_40*x/41/(1-x/42) has denominator + # denominator*41*(42*q-p), after cancelling its one factor q. + numerator, denominator, upper_num, upper_den = taylor_parts(p, q) + lo = numerator * precision // denominator + hi = (upper_num * precision + upper_den - 1) // upper_den + for _ in range(squarings): + lo = lo * lo // precision + hi = (hi * hi + precision - 1) // precision + return Fraction(lo, precision), Fraction(hi, precision) + + module.expbound = expbound + # A fresh loaded module has empty caches. Explicit installation on an + # existing engine also invalidates caches before any comparisons. + module.power.cache_clear() + module.logarithm.cache_clear() + return module diff --git a/research/current-moment-integer-fastpath/inputs/exact_moments.py b/research/current-moment-integer-fastpath/inputs/exact_moments.py new file mode 100644 index 0000000000..bf31af7851 --- /dev/null +++ b/research/current-moment-integer-fastpath/inputs/exact_moments.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +"""Independent directed-rational moment arithmetic for construction-sensitive invoices. + +No provider/candidate evaluator is imported. This does not establish reachability, +target autonomy, native phases, precision or any complete compiler admission. +Construction credit remains with the provider/controller/native predecessors. +Chris R/Clear1nsight with substantial OpenAI Codex assistance. Apache-2.0. +""" +from collections import Counter +from fractions import Fraction as F +from functools import lru_cache +from hashlib import sha256 +from pathlib import Path +import argparse +import json + +HERE = Path(__file__).resolve().parent +ROOT = HERE.parents[2] +PRECISION = 10 ** 65 + + +def need(x, text): + if not x: + raise ValueError(text) + + +def floorq(x): + return F(x.numerator * PRECISION // x.denominator, PRECISION) + + +def ceilq(x): + return -floorq(-x) + + +@lru_cache(None) +def logarithm(n): + need(type(n) is int and n >= 1, 'positive integer rank') + a = n.bit_length() - 1 + + def local(q): + z = (q - 1) / (q + 1) + need(0 <= z <= F(1, 3), 'log range') + total, term = F(0), z + for j in range(72): + total += 2 * term / (2 * j + 1) + term *= z * z + remainder = 2 * term / (145 * (1 - z * z)) + return floorq(total), ceilq(total + remainder) + + lo, hi = local(F(n, 2 ** a)) + l2, u2 = local(F(2)) + return lo + a * l2, hi + a * u2 + + +def expbound(q): + if q < 0: + lo, hi = expbound(-q) + return floorq(1 / hi), ceilq(1 / lo) + squarings = 0 + while q > F(1, 64): + q /= 2 + squarings += 1 + term = total = F(1) + for j in range(1, 41): + term *= q / j + total += term + remainder = term * q / 41 / (1 - q / 42) + lo, hi = floorq(total), ceilq(total + remainder) + for _ in range(squarings): + lo, hi = floorq(lo * lo), ceilq(hi * hi) + return lo, hi + + +@lru_cache(None) +def power(rank, exponent): + lo, hi = logarithm(rank) + a, b = sorted([lo * exponent, hi * exponent]) + return expbound(a)[0], expbound(b)[1] + + +def moment(profile, exponent): + lo = hi = F(0) + for rank, count in profile.items(): + a, b = power(int(rank), exponent) + lo += count * a + hi += count * b + return lo, hi + + +def minus(a, b): + return a[0] - b[1], a[1] - b[0] + + +def homogeneous_limit(budget, rank, exponent): + """Largest n with certified n*rank^exponent < budget lower bound.""" + lo, hi = power(rank, exponent) + n = budget[0] // hi + if n * hi >= budget[0]: + n -= 1 + need(n >= 0, 'negative strict allowance') + return {'certified_maximum': n, + 'accepted_upper': n * hi, + 'budget_lower': budget[0], + 'next_cost_lower': (n + 1) * lo, + 'next_rejected': (n + 1) * lo >= budget[1]} + + +def encode(x): + if isinstance(x, F): + return str(x) + if isinstance(x, dict): + return {str(k): encode(v) for k, v in x.items()} + if isinstance(x, (tuple, list)): + return [encode(v) for v in x] + return x + diff --git a/research/current-moment-integer-fastpath/inputs/invoice.json b/research/current-moment-integer-fastpath/inputs/invoice.json new file mode 100644 index 0000000000..a4f89cd62c --- /dev/null +++ b/research/current-moment-integer-fastpath/inputs/invoice.json @@ -0,0 +1,33 @@ +{ + "paid": { + "1": 41154, + "16": 448, + "2": 7416, + "24": 448, + "3": 9180, + "32": 448, + "4": 2286, + "40": 448, + "48": 448, + "5": 720, + "56": 448, + "64": 448, + "72": 224, + "8": 144 + }, + "productive": { + "145": 224, + "17": 448, + "25": 448, + "33": 448, + "4": 504, + "41": 448, + "49": 448, + "57": 448, + "65": 448, + "7": 126, + "73": 224, + "8": 990, + "9": 5724 + } +} diff --git a/research/current-moment-integer-fastpath/verify.py b/research/current-moment-integer-fastpath/verify.py new file mode 100644 index 0000000000..2fcad40e83 --- /dev/null +++ b/research/current-moment-integer-fastpath/verify.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +"""Exact differential checks against the authenticated Fraction implementation.""" +from fractions import Fraction as F +import json +import random +import types +from unittest.mock import patch +import fast_moments as fast +import workload + + +def need(value, message): + if not value: + raise ValueError(message) + + +def traced(engine): + calls = [] + original = engine.expbound + def wrapper(x): + result = original(x) + calls.append((x, result)) + return result + engine.expbound = wrapper + return calls + + +def main(): + reference, candidate = fast.load_engine(False), fast.load_engine(True) + left, right = traced(reference), traced(candidate) + expected, actual = workload.run(reference), workload.run(candidate) + need(expected == actual, 'complete pricing workload changed') + need(left == right, 'exponential invocation/result trace changed') + trace_count = len(left) + rng = random.Random(20261025) + values = {F(0), F(1, 64), F(1, 64)-F(1, 10**70), + F(1, 64)+F(1, 10**70), F(1, 10**100), F(42), F(100)} + values.update(F(2**j, 64) for j in range(15)) + values.update(F(rng.randrange(0, 100000), rng.randrange(1, 100000)) for _ in range(40)) + values |= {-x for x in values} + for x in sorted(values): + need(reference.expbound(x) == candidate.expbound(x), 'boundary/random exp mismatch') + reduced = abs(x) + while reduced > F(1, 64): + reduced /= 2 + term = total = F(1) + for j in range(1, 41): + term *= reduced / j + total += term + remainder = term * reduced / 41 / (1-reduced/42) + n, d, u, v = fast.taylor_parts(reduced.numerator, reduced.denominator) + need(F(n, d) == total and F(u, v) == total+remainder, 'unrounded Taylor/remainder mismatch') + for rank in (1, 2, 3, 8, 9, 72, 145): + for exponent in (F(-3, 2), F(0), F(1, 3), F(1), F(3, 2)): + need(reference.power(rank, exponent) == candidate.power(rank, exponent), 'signed power mismatch') + paid, targets = workload.profiles() + for k, sign in ((F(3027288235, 10**12), 1), (F(302728825, 10**11), -1)): + margin = candidate.minus(candidate.moment(targets, 1-k), candidate.moment(paid, 1-k)) + need(margin[0] > 0 if sign == 1 else margin[1] < 0, 'selected lower/ceiling bracket changed') + for action in (lambda: fast.load_engine(), workload.profiles): + with patch('pathlib.Path.read_bytes', return_value=b'tampered'): + try: + action() + except ValueError: + pass + else: + raise ValueError('missing source/fixture tamper rejection') + changed = dict(paid); changed[1] -= 1 + e = F(996972711765, 10**12) + need(candidate.moment(changed, e) != candidate.moment(paid, e), 'omitted charge invisible') + # Execute actual damaged implementations in memory. Check unrounded + # parts too: the tiny positive tail often fits below one output grid unit. + source = fast.SOURCE.parent.parent / 'fast_moments.py' + raw = source.read_text(encoding='utf-8') + for old, new in (('range(1, 41)', 'range(1, 40)'), + ('factor = 41 *', 'factor = 40 *'), + ('upper_num * precision + upper_den - 1', 'upper_num * precision')): + need(raw.count(old) == 1, 'mutation target changed') + mutant = types.ModuleType('mutant'); mutant.__file__ = str(source) + exec(compile(raw.replace(old, new), str(source), 'exec', optimize=0), mutant.__dict__) + parts = mutant.taylor_parts(1, 64) + oracle = fast.taylor_parts(1, 64) + detected = (F(parts[0], parts[1]), F(parts[2], parts[3])) != (F(oracle[0], oracle[1]), F(oracle[2], oracle[3])) + if not detected: + detected = mutant.load_engine().expbound(F(1, 64)) != reference.expbound(F(1, 64)) + need(detected, 'damaged kernel went undetected') + try: + candidate.logarithm(0) + except ValueError: + pass + else: + raise ValueError('positive-rank guard lost') + print(json.dumps({'status': 'PASS_IDENTICAL_RATIONAL_PRICING', + 'workload_sha256': workload.digest(actual), + 'workload_exponential_calls': trace_count, + 'boundary_and_random_values': len(values), + 'new_kappa': None}, sort_keys=True)) + + +if __name__ == '__main__': + main() diff --git a/research/current-moment-integer-fastpath/workload.py b/research/current-moment-integer-fastpath/workload.py new file mode 100644 index 0000000000..b365b7d11d --- /dev/null +++ b/research/current-moment-integer-fastpath/workload.py @@ -0,0 +1,34 @@ +"""Deterministic cold-cache workload from the selected caller's invoice.""" +from fractions import Fraction as F +from hashlib import sha256 +from pathlib import Path +import json + +HERE = Path(__file__).resolve().parent +INVOICE_SHA256 = 'b86b86f840e27acf1c56ae43a0b779f9708ec04c3ccaf3061d9034ed6288c401' + + +def profiles(): + raw = (HERE / 'inputs/invoice.json').read_bytes() + if sha256(raw).hexdigest() != INVOICE_SHA256: + raise ValueError('frozen invoice changed') + data = json.loads(raw) + return [{int(r): n for r, n in data[key].items()} for key in ('paid', 'productive')] + + +def run(engine): + paid, targets = profiles() + ranks = sorted(set(paid) | set(targets)) + rows = [] + for j in range(12): + exponent = F(9969727117 + j, 10**10) + powers = {r: engine.power(r, exponent) for r in ranks} + margin = engine.minus(engine.moment(targets, exponent), engine.moment(paid, exponent)) + allowance = engine.homogeneous_limit((F(1000), F(1001)), 145, exponent) + rows.append({'exponent': exponent, 'powers': powers, + 'margin': margin, 'allowance': allowance}) + return engine.encode(rows) + + +def digest(result): + return sha256(json.dumps(result, sort_keys=True, separators=(',', ':')).encode()).hexdigest()