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
17 changes: 17 additions & 0 deletions docs/research/recursive-invoice-preflight.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,23 @@ python3 -B scripts/compare_recursive_invoices.py \
The second is a declared single-H4 edit to the complete source invoice, illustrating
the unfiltered retiming's algebra; it is not a newly emitted physical supplier.

## Inspect a tariff witness

To show exact old and new costs for the strongest positive and negative hinges:

```sh
python3 -B scripts/explain_recursive_invoices.py OLD.json NEW.json
```

Each witness gives a cap `k` and the tariff `min(r,k)`. The report debits target
credits and binds both input files by SHA256. No witness is emitted for zero cost
change. The comparator and its source bytes remain unchanged.

For old paid jobs `{"2":2}` and new paid jobs `{"1":1,"4":1}`, cap 2 gives
costs 4 and 3; cap 4 gives costs 4 and 5. Thus neither invoice wins for every
concave tariff. This does not imply a power crossing: their power-cost difference
is `(2^t-1)^2`, which is positive for every `0<t<1`.

## Certificate and bounds

Set d_r=Δpaid_r-Δtargets_r. The report gives K(k)=Σ d_r min(r,k) at every support
Expand Down
61 changes: 61 additions & 0 deletions scripts/explain_recursive_invoices.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
"""Show exact capped-linear tariff witnesses for a declared invoice comparison.

The method is the classical concave order used by compare_recursive_invoices
and mightyOil's t16-moment-order-audit. No new theorem is claimed.
Prepared for aliromman with OpenAI Codex assistance.
"""
import argparse
import json
from pathlib import Path
import sys

sys.path.insert(0, str(Path(__file__).resolve().parent))
try:
from compare_recursive_invoices import compare_invoices, load_invoice
finally:
sys.path.pop(0)


def tariff_cost(invoice, cap):
return sum(min(int(r), cap) * n for r, n in invoice['paid'].items()) - sum(
min(int(r), cap) * n for r, n in invoice['targets'].items())


def explain_invoices(old, new):
report = compare_invoices(old, new)
witnesses = {}
for direction, choose, sign in (('negative_change', min, -1), ('positive_change', max, 1)):
hinge = choose(report['hinges'], key=lambda row: row['value'])
if sign * hinge['value'] <= 0:
continue
cap = hinge['rank']
before, after = tariff_cost(old, cap), tariff_cost(new, cap)
witnesses[direction] = {'tariff': 'min(r, cap)', 'cap': cap,
'old_paid_minus_targets': before, 'new_paid_minus_targets': after,
'new_minus_old': after - before}
report['concave_tariff_witnesses'] = witnesses
report['witness_scope'] = ('These are increasing concave tariffs. Opposite signs do not prove '
'a crossing for powers r^t, a legal circuit or a kappa improvement.')
return report


def main(argv=None):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('old'); parser.add_argument('new')
args = parser.parse_args(argv)
try:
old, old_pin = load_invoice(args.old)
new, new_pin = load_invoice(args.new)
report = explain_invoices(old, new)
report['inputs'] = {'old': old_pin, 'new': new_pin}
except (OSError, ValueError, TypeError, RecursionError) as exc:
print(json.dumps({'status': 'INVALID_RECURSIVE_INVOICE', 'error': str(exc)}), file=sys.stderr)
return 2
print(json.dumps(report, indent=2, sort_keys=True))
return 0


if __name__ == '__main__':
raise SystemExit(main())
71 changes: 71 additions & 0 deletions tests/test_recursive_invoice_witnesses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""Replay tariff witnesses by direct paid and credited sums."""
import hashlib
import itertools
import json
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest

ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / 'scripts'))
import explain_recursive_invoices as explain
sys.path.pop(0)


def invoice(paid=None, targets=None):
return {'schema': 'integer-mult-recursive-invoice/v1',
'contract': {'model': 'fixture', 'rank_semantics': 'rank', 'ambient_rank': 10, 'boundary': 'same'},
'paid': {str(r): n for r, n in (paid or {}).items()},
'targets': {str(r): n for r, n in (targets or {}).items()}}


class TariffWitnessTests(unittest.TestCase):
def test_mixed_signs_have_two_explicit_costs(self):
report = explain.explain_invoices(invoice({2: 2}), invoice({1: 1, 4: 1}))
self.assertEqual(report['classification'], 'inconclusive')
witnesses = report['concave_tariff_witnesses']
self.assertEqual((witnesses['negative_change']['cap'], witnesses['negative_change']['new_minus_old']), (2, -1))
self.assertEqual((witnesses['positive_change']['cap'], witnesses['positive_change']['new_minus_old']), (4, 1))
self.assertEqual(witnesses['negative_change']['old_paid_minus_targets'], 4)
self.assertEqual(witnesses['negative_change']['new_paid_minus_targets'], 3)

def test_exhaustive_small_signed_invoices_replay_every_witness(self):
for delta in itertools.product(range(-2, 3), repeat=4):
old = invoice({r: -d for r, d in enumerate(delta, 1) if d < 0}, {3: 2})
new = invoice({r: d for r, d in enumerate(delta, 1) if d > 0}, {3: 2})
report = explain.explain_invoices(old, new)
for key, witness in report['concave_tariff_witnesses'].items():
cap = witness['cap']
expected = sum(d * min(r, cap) for r, d in enumerate(delta, 1))
self.assertEqual(witness['new_minus_old'], expected)
self.assertTrue(expected < 0 if key == 'negative_change' else expected > 0)
self.assertEqual(len(report['concave_tariff_witnesses']),
0 if not any(delta) else 2 if report['classification'] == 'inconclusive' else 1)

def test_surrendered_target_is_debited(self):
report = explain.explain_invoices(invoice({1: 1, 8: 1}, {9: 1}), invoice())
witness = report['concave_tariff_witnesses']['negative_change']
self.assertEqual(witness['old_paid_minus_targets'], 1)
self.assertEqual(witness['new_paid_minus_targets'], 0)

def test_cli_binds_inputs_under_isolated_optimized_python(self):
with tempfile.TemporaryDirectory() as tmp:
paths = [Path(tmp) / name for name in ('old.json', 'new.json')]
for path, value in zip(paths, (invoice({2: 2}), invoice({1: 1, 4: 1}))):
path.write_text(json.dumps(value))
result = subprocess.run([sys.executable, '-I', '-O', '-B', str(ROOT / 'scripts/explain_recursive_invoices.py'),
*map(str, paths)], text=True, capture_output=True, check=True)
report = json.loads(result.stdout)
self.assertEqual(report['inputs']['old']['sha256'], hashlib.sha256(paths[0].read_bytes()).hexdigest())
self.assertEqual(len(report['concave_tariff_witnesses']), 2)

def test_mismatched_contract_is_not_explained(self):
old, new = invoice(), invoice(); new['contract']['boundary'] = 'different'
with self.assertRaisesRegex(ValueError, 'contracts differ'):
explain.explain_invoices(old, new)


if __name__ == '__main__':
unittest.main()
Loading