From 1391427065829965bf3eb83dac022f4de6c82c48 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 20 Oct 2026 02:51:08 +0000 Subject: [PATCH] Record the three-hub extremal actual-reader charge. The complete extremal table of the PR3573 star has minimum charges 48, 128 and 256 at one, two and three hubs. The excess is 4h(h+1) through three hubs, from crossed two-bearing rows, and is not the 21-premise K3,2 excess of 12. Co-authored-by: unpaidmoon --- research/p112-third-hub-extremal/PROOF.md | 167 ++++++++ research/p112-third-hub-extremal/README.md | 89 ++++ research/p112-third-hub-extremal/SOURCES.json | 18 + research/p112-third-hub-extremal/TASK.json | 66 +++ research/p112-third-hub-extremal/VERIFY.json | 36 ++ .../p112-third-hub-extremal/independent.py | 379 ++++++++++++++++++ .../p112-third-hub-extremal/test_controls.py | 95 +++++ research/p112-third-hub-extremal/verify.py | 374 +++++++++++++++++ 8 files changed, 1224 insertions(+) create mode 100644 research/p112-third-hub-extremal/PROOF.md create mode 100644 research/p112-third-hub-extremal/README.md create mode 100644 research/p112-third-hub-extremal/SOURCES.json create mode 100644 research/p112-third-hub-extremal/TASK.json create mode 100644 research/p112-third-hub-extremal/VERIFY.json create mode 100644 research/p112-third-hub-extremal/independent.py create mode 100644 research/p112-third-hub-extremal/test_controls.py create mode 100644 research/p112-third-hub-extremal/verify.py diff --git a/research/p112-third-hub-extremal/PROOF.md b/research/p112-third-hub-extremal/PROOF.md new file mode 100644 index 0000000000..1e62423c1a --- /dev/null +++ b/research/p112-third-hub-extremal/PROOF.md @@ -0,0 +1,167 @@ +# The third hub adds crossed two-bearing rows + +## Statement + +Work over any field of characteristic zero. For an integer \(h \ge 1\), take +independent marks \(E,F\) and independent internal potentials \(G,V_0,\ldots,V_{h-1}\). +Index \(3+3h\) queries by + +\[ +g=G,\quad d=E+F,\quad t=E+F+G, +\] +\[ +v_j=V_j,\quad x_j=E+G-V_j,\quad y_j=F+G-V_j. +\] + +This is the one-hub star of PR3573 when \(h=1\), and it is that star with the +hubs \(k,z,w\) of PR3583 adjoined when \(h=2\). The third hub is \(h=3\). + +A subset of queries is a **minimal reader** for a mark when the mark lies in +the span of those queries and in no proper subset. It is a **maximal source** +when the mark lies outside the span of the other mark and those queries, but +enters that span after every added query. The relaxed literal actual-reader +model is the one minimized in PR3698 and again for \(h=1\) in the single-hub +charge argument: each extremal row chooses an evaluator with value 1 on its +mark and 0 on the other mark, and a reader supported on a minimal reader set +of its mark (the row's own premise, if the row is itself a reader). The cost +of a row is the number of queries where the reader coefficient and the +evaluator are both nonzero. The charge is twice the sum of the row costs. +Companions contribute a zero port, so the one-unit baseline is twice the +number of rows. + +**Theorem.** In this model, for every \(h \ge 1\), the charge exceeds the +one-unit baseline by at least \(4h(h+1)\). For \(h \le 3\) the excess is +exactly that number, and the minimum charges are + +| hubs | rows | baseline | minimum charge | excess | +| --- | ---: | ---: | ---: | ---: | +| 1 | 20 | 40 | 48 | 8 | +| 2 | 52 | 104 | 128 | 24 | +| 3 | 104 | 208 | 256 | 48 | + +At three hubs there are 24 two-bearing rows, not only the four rows +\((d,x_0,y_0)\) and \((g,t,x_0,y_0)\). Twelve of them are crossed five-query +readers, two for each pair of hubs. The excess 48 is not the twelve-unit +\(K_{3,2}\) excess. That twelve is the separate 21-premise certificate of +PR3583/PR3698, whose charge this package recomputes as 54. + +## The two-bearing families + +Write \(\phi\) for an evaluator with \(\phi(E)=1\) and \(\phi(F)=0\). Then +\(\phi(d)=1\), \(\phi(t)-\phi(g)=1\) and \(\phi(x_j)-\phi(y_j)=1\). The same +identities with the marks exchanged cover \(F\). + +**Family A.** For each hub \(j\), the three queries \(d,x_j,y_j\) are linearly +independent: the minor on coordinates \(E,F,G\) equals \(-2\). The unique +expression of \(E\) is +\[ +E=\tfrac12 d+\tfrac12 x_j-\tfrac12 y_j. +\] +Every coefficient is nonzero, so the triple is a minimal reader, and every +admissible reader uses all three queries. Since \(\phi(d)=1\) and +\(\phi(x_j)-\phi(y_j)=1\), at least two of the three evaluator values are +nonzero. The cost is at least 2. The evaluator with every free coordinate 0 +kills \(y_j\) and leaves \(d\) and \(x_j\), so the cost is exactly 2. The same +triple is a minimal \(F\)-reader of cost 2. + +**Family B.** For each hub \(j\), the four queries \(g,t,x_j,y_j\) are +linearly independent on \(E,F,G,V_j\). The unique expression of \(E\) is +\[ +E=-\tfrac12 g+\tfrac12 t+\tfrac12 x_j-\tfrac12 y_j, +\] +so the quadruple is a minimal reader and every reader uses all four queries. +The two differences above force at least one visible query in \(\{g,t\}\) and +at least one in \(\{x_j,y_j\}\). The cost is at least 2, and the same zero +free coordinates attain 2. The quadruple is likewise an \(F\)-reader of cost 2. + +**Family C.** For each pair \(i 1: + for j in range(dim): + matrix[i][j] //= common + used += 1 + column += 1 + return used + + +def contains(vecs, mask, target, dim, cache): + key = (mask, target) + if key not in cache: + rows = [vecs[i] for i in bits(mask)] + cache[key] = rank(rows + [target], dim) == rank(rows, dim) + return cache[key] + + +def hub_index(h, j): + base = 3 + 3 * j + return base, base + 1, base + 2 + + +def predicted(h): + """Return (E readers, F readers, E sources, F sources) as sorted masks.""" + def mask(indices): + value = 0 + for i in indices: + value |= 1 << i + return value + + def bundle(anchor, choices): + indices = [anchor] + for j, choice in enumerate(choices): + v, x, y = hub_index(h, j) + if anchor == 0 and choice == 0: + indices.append(x) + elif anchor == 0 and choice == 1: + indices.extend([v, y]) + elif anchor == 2 and choice == 0: + indices.extend([v, x]) + else: + indices.append(y) + return mask(indices) + + e_readers = [] + for j in range(h): + v, x, y = hub_index(h, j) + e_readers.extend([ + mask([0, v, x]), + mask([1, 2, v, x]), + mask([0, 1, v, y]), + mask([2, v, y]), + mask([1, x, y]), + mask([0, 2, x, y]), + ]) + for i in range(h): + vi, xi, yi = hub_index(h, i) + for j in range(i + 1, h): + vj, xj, yj = hub_index(h, j) + e_readers.extend([ + mask([1, vi, yi, vj, xj]), + mask([2, xi, yi, vj, xj]), + mask([1, vi, xi, vj, yj]), + mask([0, xi, yi, vj, yj]), + mask([2, vi, xi, xj, yj]), + mask([0, vi, yi, xj, yj]), + ]) + # F readers are the E readers with each hub's x and y exchanged. + swap = {} + for j in range(h): + v, x, y = hub_index(h, j) + swap[x] = y + swap[y] = x + f_readers = [] + for value in e_readers: + flipped = 0 + for i in bits(value): + flipped |= 1 << swap.get(i, i) + f_readers.append(flipped) + e_sources = [] + f_sources = [] + for code in range(1 << h): + choices = [(code >> j) & 1 for j in range(h)] + e_sources.append(bundle(0, choices)) + e_sources.append(bundle(2, choices)) + for value in e_sources: + # Exchange g=0 with t=2. + flipped = 0 + for i in bits(value): + flipped |= 1 << (2 if i == 0 else 0 if i == 2 else i) + f_sources.append(flipped) + return tuple(sorted(set(group)) for group in (e_readers, f_readers, e_sources, f_sources)) + + +def census(h): + names, vecs, E, F, dim = star(h) + n = len(names) + cache = {} + readers = [[], []] + sources = [[], []] + marks = (E, F) + for mask in range(1 << n): + for m, mark in enumerate(marks): + other = marks[1 - m] + if contains(vecs, mask, mark, dim, cache): + minimal = mask != 0 and all( + not contains(vecs, mask ^ (1 << i), mark, dim, cache) for i in bits(mask) + ) + if minimal: + readers[m].append(mask) + generators = [other] + [vecs[i] for i in bits(mask)] + outside = rank(generators + [mark], dim) != rank(generators, dim) + if outside: + maximal = all( + not ( + rank([other] + [vecs[i] for i in bits(mask | (1 << j))] + [mark], dim) + != rank([other] + [vecs[i] for i in bits(mask | (1 << j))], dim) + ) + for j in range(n) if (mask >> j) & 1 == 0 + ) + if maximal: + sources[m].append(mask) + return names, vecs, E, F, dim, [sorted(group) for group in readers], [sorted(group) for group in sources] + + +def spans(vecs, indices, target, dim): + return rank([vecs[i] for i in indices] + [target], dim) == rank([vecs[i] for i in indices], dim) + + +def separated(vecs, killed, mark, other, dim): + rows = [other] + [vecs[i] for i in killed] + return rank(rows + [mark], dim) != rank(rows, dim) + + +def reader_cost(vecs, mask, mark, other, dim): + indices = bits(mask) + best = None + width = len(indices) + for support_code in range(1 << width): + support = [indices[i] for i in range(width) if (support_code >> i) & 1] + if not spans(vecs, support, mark, dim): + continue + for paid_code in range(1 << len(support)): + paid = [support[i] for i in range(len(support)) if (paid_code >> i) & 1] + if len(paid) > 2 and best is not None and best <= 2: + continue + killed = [i for i in support if i not in paid] + if separated(vecs, killed, mark, other, dim): + best = len(paid) if best is None else min(best, len(paid)) + if best == 1: + return 1 + if best is None: + raise AssertionError("reader premise does not span its mark") + return best + + +def source_cost(vecs, mask, reader_masks, mark, other, dim): + premise = bits(mask) + best = None + for reader in reader_masks: + allowed = bits(reader) + width = len(allowed) + for support_code in range(1 << width): + support = [allowed[i] for i in range(width) if (support_code >> i) & 1] + if not spans(vecs, support, mark, dim): + continue + for paid_code in range(1 << len(support)): + paid = [support[i] for i in range(len(support)) if (paid_code >> i) & 1] + if len(paid) > 1 and best == 1: + continue + killed = premise + [i for i in support if i not in paid] + if separated(vecs, killed, mark, other, dim): + best = len(paid) if best is None else min(best, len(paid)) + if best == 1: + return 1 + if best is None: + raise AssertionError("source row has no admissible reader") + return best + + +def cost_two_masks(h): + """Masks whose both mark-rows are forced to cost 2 by the written pairing.""" + def mask(indices): + value = 0 + for i in indices: + value |= 1 << i + return value + out = [] + for j in range(h): + v, x, y = hub_index(h, j) + out.append(mask([1, x, y])) + out.append(mask([0, 2, x, y])) + for i in range(h): + vi, xi, yi = hub_index(h, i) + for j in range(i + 1, h): + vj, xj, yj = hub_index(h, j) + out.append(mask([1, vi, yi, vj, xj])) + out.append(mask([1, vi, xi, vj, yj])) + return sorted(set(out)) + + +def summarize(h): + names, vecs, E, F, dim, readers, sources = census(h) + expect = predicted(h) + if (readers[0], readers[1], sources[0], sources[1]) != expect: + raise AssertionError(f"h={h} extremal table does not match the predicted list") + marks = (E, F) + forced = set(cost_two_masks(h)) + total = 0 + forced_rows = 0 + for m, mark in enumerate(marks): + other = marks[1 - m] + for mask in readers[m]: + cost = reader_cost(vecs, mask, mark, other, dim) + if mask in forced: + if cost != 2: + raise AssertionError(f"h={h} forced reader cost {cost}") + forced_rows += 1 + elif cost != 1: + raise AssertionError(f"h={h} unexpected reader cost {cost}") + total += cost + for mask in sources[m]: + cost = source_cost(vecs, mask, readers[m], mark, other, dim) + if cost != 1: + raise AssertionError(f"h={h} source cost {cost}") + total += cost + rows = sum(len(group) for group in readers) + sum(len(group) for group in sources) + charge = 2 * total + baseline = 2 * rows + return { + "h": h, + "rows": rows, + "readers_per_mark": len(readers[0]), + "sources_per_mark": len(sources[0]), + "sum_cost": total, + "charge": charge, + "baseline": baseline, + "excess": charge - baseline, + "forced_rows": forced_rows, + "names": names, + } + + +def k32_charge(): + """The twenty-one PR3583 premises, not the full two-hub extremal table.""" + names, vecs, E, F, dim = star(2) + index = {name: i for i, name in enumerate(names)} + def mask(*labels): + value = 0 + for label in labels: + value |= 1 << index[label] + return value + readers = { + E: [ + mask("g", "v0", "x0"), mask("g", "v1", "x1"), mask("t", "v0", "y0"), + mask("t", "v1", "y1"), mask("d", "x0", "y0"), mask("d", "x1", "y1"), + mask("g", "t", "x0", "y0"), + ], + F: [ + mask("g", "v0", "y0"), mask("g", "v1", "y1"), mask("t", "v0", "x0"), + mask("t", "v1", "x1"), mask("d", "x0", "y0"), mask("d", "x1", "y1"), + mask("g", "t", "x0", "y0"), + ], + } + sources = { + E: [mask("g", "v0", "v1"), mask("v0", "x0"), mask("g", "x0"), mask("g", "v0", "x1")], + F: [mask("g", "v0", "v1"), mask("g", "y0"), mask("v0", "y0")], + } + total = 0 + count = 0 + for mark, other in ((E, F), (F, E)): + for value in readers[mark]: + total += reader_cost(vecs, value, mark, other, dim) + count += 1 + for value in sources[mark]: + total += source_cost(vecs, value, readers[mark], mark, other, dim) + count += 1 + if count != 21: + raise AssertionError(count) + return 2 * total + + +def main(): + summaries = [summarize(h) for h in (1, 2, 3)] + expected = { + 1: {"rows": 20, "readers_per_mark": 6, "sources_per_mark": 4, "charge": 48, "excess": 8, "forced_rows": 4}, + 2: {"rows": 52, "readers_per_mark": 18, "sources_per_mark": 8, "charge": 128, "excess": 24, "forced_rows": 12}, + 3: {"rows": 104, "readers_per_mark": 36, "sources_per_mark": 16, "charge": 256, "excess": 48, "forced_rows": 24}, + } + for summary in summaries: + h = summary["h"] + for key, value in expected[h].items(): + if summary[key] != value: + raise AssertionError(f"h={h} {key}={summary[key]} expected {value}") + formula_rows = 2 * (3 * h * (h + 1) + 2 ** (h + 1)) + formula_excess = 4 * h * (h + 1) + if summary["rows"] != formula_rows or summary["excess"] != formula_excess: + raise AssertionError("closed form mismatch") + certificate = k32_charge() + if certificate != 54: + raise AssertionError(certificate) + third = summaries[2] + print( + PASS, + f"h3_rows={third['rows']}", + f"h3_charge={third['charge']}", + f"h3_excess={third['excess']}", + f"h2_excess={summaries[1]['excess']}", + f"h1_charge={summaries[0]['charge']}", + f"k32_charge={certificate}", + f"two_bearing_h3={third['forced_rows']}", + "no_new_kappa", + ) + + +if __name__ == "__main__": + main() diff --git a/research/p112-third-hub-extremal/test_controls.py b/research/p112-third-hub-extremal/test_controls.py new file mode 100644 index 0000000000..1fba00b901 --- /dev/null +++ b/research/p112-third-hub-extremal/test_controls.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 +"""Rejection controls. Imports both checkers and does not change their proofs.""" +import independent +import verify + + +def require(condition, message): + if not condition: + raise SystemExit("CONTROL_FAILED " + message) + + +def test_programs_agree(): + for hubs in (1, 2, 3): + left = verify.summarize(hubs) + right = independent.summarize(hubs) + for key in ("rows", "charge", "excess", "forced_rows", "readers_per_mark", "sources_per_mark"): + require(left[key] == right[key], f"h={hubs} {key}") + require(verify.k32_charge() == 54, "fraction K3,2") + require(independent.k32_charge() == 54, "integer K3,2") + + +def test_rank_methods_agree_on_two_hubs(): + names, vecs, _E, _F, dim = verify.star(2) + for mask in range(1 << len(names)): + rows = [vecs[i] for i in verify.bits(mask)] + require(verify.rank(rows, dim) == independent.rank(rows, dim), f"rank mask {mask}") + + +def test_triple_is_minimal_and_costs_two(): + _names, vecs, E, F, dim = verify.star(1) + triple = [1, 4, 5] # d, x0, y0 + require(verify.spans(vecs, triple, E, dim), "triple spans E") + require(verify.reader_cost(vecs, (1 << 1) | (1 << 4) | (1 << 5), E, F, dim) == 2, "triple cost") + for omitted in range(3): + proper = [triple[i] for i in range(3) if i != omitted] + require(not verify.spans(vecs, proper, E, dim), "proper subset spans E") + + +def test_crossed_row_is_not_the_k32_certificate(): + full = verify.summarize(2) + require(full["charge"] == 128 and full["excess"] == 24, "full two-hub charge") + require(verify.k32_charge() == 54, "21-premise charge stays 54") + require(full["charge"] != verify.k32_charge(), "certificates differ") + + +def determinant(rows): + size = len(rows) + if size == 1: + return rows[0][0] + total = 0 + for column in range(size): + minor = [ + [rows[i][k] for k in range(size) if k != column] + for i in range(1, size) + ] + total += (-1) ** column * rows[0][column] * determinant(minor) + return total + + +def test_written_determinants(): + # PROOF.md: family A minor on E,F,G and family C minor on E,F,G,Vi,Vj. + family_a = ((1, 1, 0), (1, 0, 1), (0, 1, 1)) + family_c = ( + (1, 1, 0, 0, 0), + (0, 0, 0, 1, 0), + (0, 1, 1, -1, 0), + (0, 0, 0, 0, 1), + (1, 0, 1, 0, -1), + ) + require(determinant(family_a) == -2, "family A minor") + require(determinant(family_c) == -2, "family C minor") + + +def test_dropping_a_third_hub_row_breaks_the_census(): + _names, _vecs, _E, _F, _dim, readers, sources = verify.census(3) + expect = verify.predicted(3) + require(readers[0] == expect[0], "census matches before the mutation") + forced = verify.cost_two_masks(3) + require(forced[0] in readers[0], "forced row present") + mutated = [mask for mask in readers[0] if mask != forced[0]] + require(mutated != expect[0], "dropped row still matched") + + +def main(): + test_programs_agree() + test_rank_methods_agree_on_two_hubs() + test_triple_is_minimal_and_costs_two() + test_crossed_row_is_not_the_k32_certificate() + test_dropping_a_third_hub_row_breaks_the_census() + test_written_determinants() + print("PASS_THIRD_HUB_EXTREMAL_CONTROLS mutations=6 no_new_kappa") + + +if __name__ == "__main__": + main() diff --git a/research/p112-third-hub-extremal/verify.py b/research/p112-third-hub-extremal/verify.py new file mode 100644 index 0000000000..c95e9bf914 --- /dev/null +++ b/research/p112-third-hub-extremal/verify.py @@ -0,0 +1,374 @@ +#!/usr/bin/env python3 +"""Exact extremal actual-reader charges for one, two and three hubs. + +Fraction row reduction. independent.py repeats the census with integer +elimination and does not import this file. +""" +from fractions import Fraction + +PASS = "PASS_THIRD_HUB_EXTREMAL" + + +def bits(mask): + out = [] + while mask: + bit = mask & -mask + out.append(bit.bit_length() - 1) + mask ^= bit + return out + + +def star(h): + dim = 3 + h + def unit(i): + row = [0] * dim + row[i] = 1 + return tuple(row) + E, F, G = unit(0), unit(1), unit(2) + names = ["g", "d", "t"] + vecs = [ + G, + tuple(E[i] + F[i] for i in range(dim)), + tuple(E[i] + F[i] + G[i] for i in range(dim)), + ] + for j in range(h): + V = unit(3 + j) + names.extend([f"v{j}", f"x{j}", f"y{j}"]) + vecs.append(V) + vecs.append(tuple(E[i] + G[i] - V[i] for i in range(dim))) + vecs.append(tuple(F[i] + G[i] - V[i] for i in range(dim))) + return names, vecs, E, F, dim + + +def rank(rows, dim): + matrix = [list(map(Fraction, row)) for row in rows if any(row)] + height = len(matrix) + used = 0 + column = 0 + while used < height and column < dim: + pivot = next((i for i in range(used, height) if matrix[i][column] != 0), None) + if pivot is None: + column += 1 + continue + matrix[used], matrix[pivot] = matrix[pivot], matrix[used] + scale = matrix[used][column] + for j in range(column, dim): + matrix[used][j] /= scale + for i in range(height): + if i != used and matrix[i][column] != 0: + factor = matrix[i][column] + for j in range(column, dim): + matrix[i][j] -= factor * matrix[used][j] + used += 1 + column += 1 + return used + + +def contains(vecs, mask, target, dim, cache): + key = (mask, target) + if key not in cache: + rows = [vecs[i] for i in bits(mask)] + cache[key] = rank(rows + [target], dim) == rank(rows, dim) + return cache[key] + + +def hub_index(h, j): + base = 3 + 3 * j + return base, base + 1, base + 2 + + +def predicted(h): + """Return (E readers, F readers, E sources, F sources) as sorted masks.""" + def mask(indices): + value = 0 + for i in indices: + value |= 1 << i + return value + + def bundle(anchor, choices): + indices = [anchor] + for j, choice in enumerate(choices): + v, x, y = hub_index(h, j) + if anchor == 0 and choice == 0: + indices.append(x) + elif anchor == 0 and choice == 1: + indices.extend([v, y]) + elif anchor == 2 and choice == 0: + indices.extend([v, x]) + else: + indices.append(y) + return mask(indices) + + e_readers = [] + for j in range(h): + v, x, y = hub_index(h, j) + e_readers.extend([ + mask([0, v, x]), + mask([1, 2, v, x]), + mask([0, 1, v, y]), + mask([2, v, y]), + mask([1, x, y]), + mask([0, 2, x, y]), + ]) + for i in range(h): + vi, xi, yi = hub_index(h, i) + for j in range(i + 1, h): + vj, xj, yj = hub_index(h, j) + e_readers.extend([ + mask([1, vi, yi, vj, xj]), + mask([2, xi, yi, vj, xj]), + mask([1, vi, xi, vj, yj]), + mask([0, xi, yi, vj, yj]), + mask([2, vi, xi, xj, yj]), + mask([0, vi, yi, xj, yj]), + ]) + # F readers are the E readers with each hub's x and y exchanged. + swap = {} + for j in range(h): + v, x, y = hub_index(h, j) + swap[x] = y + swap[y] = x + f_readers = [] + for value in e_readers: + flipped = 0 + for i in bits(value): + flipped |= 1 << swap.get(i, i) + f_readers.append(flipped) + e_sources = [] + f_sources = [] + for code in range(1 << h): + choices = [(code >> j) & 1 for j in range(h)] + e_sources.append(bundle(0, choices)) + e_sources.append(bundle(2, choices)) + for value in e_sources: + # Exchange g=0 with t=2. + flipped = 0 + for i in bits(value): + flipped |= 1 << (2 if i == 0 else 0 if i == 2 else i) + f_sources.append(flipped) + return tuple(sorted(set(group)) for group in (e_readers, f_readers, e_sources, f_sources)) + + +def census(h): + names, vecs, E, F, dim = star(h) + n = len(names) + cache = {} + readers = [[], []] + sources = [[], []] + marks = (E, F) + for mask in range(1 << n): + for m, mark in enumerate(marks): + other = marks[1 - m] + if contains(vecs, mask, mark, dim, cache): + minimal = mask != 0 and all( + not contains(vecs, mask ^ (1 << i), mark, dim, cache) for i in bits(mask) + ) + if minimal: + readers[m].append(mask) + generators = [other] + [vecs[i] for i in bits(mask)] + outside = rank(generators + [mark], dim) != rank(generators, dim) + if outside: + maximal = all( + not ( + rank([other] + [vecs[i] for i in bits(mask | (1 << j))] + [mark], dim) + != rank([other] + [vecs[i] for i in bits(mask | (1 << j))], dim) + ) + for j in range(n) if (mask >> j) & 1 == 0 + ) + if maximal: + sources[m].append(mask) + return names, vecs, E, F, dim, [sorted(group) for group in readers], [sorted(group) for group in sources] + + +def spans(vecs, indices, target, dim): + return rank([vecs[i] for i in indices] + [target], dim) == rank([vecs[i] for i in indices], dim) + + +def separated(vecs, killed, mark, other, dim): + rows = [other] + [vecs[i] for i in killed] + return rank(rows + [mark], dim) != rank(rows, dim) + + +def reader_cost(vecs, mask, mark, other, dim): + indices = bits(mask) + best = None + width = len(indices) + for support_code in range(1 << width): + support = [indices[i] for i in range(width) if (support_code >> i) & 1] + if not spans(vecs, support, mark, dim): + continue + for paid_code in range(1 << len(support)): + paid = [support[i] for i in range(len(support)) if (paid_code >> i) & 1] + if len(paid) > 2 and best is not None and best <= 2: + continue + killed = [i for i in support if i not in paid] + if separated(vecs, killed, mark, other, dim): + best = len(paid) if best is None else min(best, len(paid)) + if best == 1: + return 1 + if best is None: + raise AssertionError("reader premise does not span its mark") + return best + + +def source_cost(vecs, mask, reader_masks, mark, other, dim): + premise = bits(mask) + best = None + for reader in reader_masks: + allowed = bits(reader) + width = len(allowed) + for support_code in range(1 << width): + support = [allowed[i] for i in range(width) if (support_code >> i) & 1] + if not spans(vecs, support, mark, dim): + continue + for paid_code in range(1 << len(support)): + paid = [support[i] for i in range(len(support)) if (paid_code >> i) & 1] + if len(paid) > 1 and best == 1: + continue + killed = premise + [i for i in support if i not in paid] + if separated(vecs, killed, mark, other, dim): + best = len(paid) if best is None else min(best, len(paid)) + if best == 1: + return 1 + if best is None: + raise AssertionError("source row has no admissible reader") + return best + + +def cost_two_masks(h): + """Masks whose both mark-rows are forced to cost 2 by the written pairing.""" + def mask(indices): + value = 0 + for i in indices: + value |= 1 << i + return value + out = [] + for j in range(h): + v, x, y = hub_index(h, j) + out.append(mask([1, x, y])) + out.append(mask([0, 2, x, y])) + for i in range(h): + vi, xi, yi = hub_index(h, i) + for j in range(i + 1, h): + vj, xj, yj = hub_index(h, j) + out.append(mask([1, vi, yi, vj, xj])) + out.append(mask([1, vi, xi, vj, yj])) + return sorted(set(out)) + + +def summarize(h): + names, vecs, E, F, dim, readers, sources = census(h) + expect = predicted(h) + if (readers[0], readers[1], sources[0], sources[1]) != expect: + raise AssertionError(f"h={h} extremal table does not match the predicted list") + marks = (E, F) + forced = set(cost_two_masks(h)) + total = 0 + forced_rows = 0 + for m, mark in enumerate(marks): + other = marks[1 - m] + for mask in readers[m]: + cost = reader_cost(vecs, mask, mark, other, dim) + if mask in forced: + if cost != 2: + raise AssertionError(f"h={h} forced reader cost {cost}") + forced_rows += 1 + elif cost != 1: + raise AssertionError(f"h={h} unexpected reader cost {cost}") + total += cost + for mask in sources[m]: + cost = source_cost(vecs, mask, readers[m], mark, other, dim) + if cost != 1: + raise AssertionError(f"h={h} source cost {cost}") + total += cost + rows = sum(len(group) for group in readers) + sum(len(group) for group in sources) + charge = 2 * total + baseline = 2 * rows + return { + "h": h, + "rows": rows, + "readers_per_mark": len(readers[0]), + "sources_per_mark": len(sources[0]), + "sum_cost": total, + "charge": charge, + "baseline": baseline, + "excess": charge - baseline, + "forced_rows": forced_rows, + "names": names, + } + + +def k32_charge(): + """The twenty-one PR3583 premises, not the full two-hub extremal table.""" + names, vecs, E, F, dim = star(2) + index = {name: i for i, name in enumerate(names)} + def mask(*labels): + value = 0 + for label in labels: + value |= 1 << index[label] + return value + readers = { + E: [ + mask("g", "v0", "x0"), mask("g", "v1", "x1"), mask("t", "v0", "y0"), + mask("t", "v1", "y1"), mask("d", "x0", "y0"), mask("d", "x1", "y1"), + mask("g", "t", "x0", "y0"), + ], + F: [ + mask("g", "v0", "y0"), mask("g", "v1", "y1"), mask("t", "v0", "x0"), + mask("t", "v1", "x1"), mask("d", "x0", "y0"), mask("d", "x1", "y1"), + mask("g", "t", "x0", "y0"), + ], + } + sources = { + E: [mask("g", "v0", "v1"), mask("v0", "x0"), mask("g", "x0"), mask("g", "v0", "x1")], + F: [mask("g", "v0", "v1"), mask("g", "y0"), mask("v0", "y0")], + } + total = 0 + count = 0 + for mark, other in ((E, F), (F, E)): + for value in readers[mark]: + total += reader_cost(vecs, value, mark, other, dim) + count += 1 + for value in sources[mark]: + total += source_cost(vecs, value, readers[mark], mark, other, dim) + count += 1 + if count != 21: + raise AssertionError(count) + return 2 * total + + +def main(): + summaries = [summarize(h) for h in (1, 2, 3)] + expected = { + 1: {"rows": 20, "readers_per_mark": 6, "sources_per_mark": 4, "charge": 48, "excess": 8, "forced_rows": 4}, + 2: {"rows": 52, "readers_per_mark": 18, "sources_per_mark": 8, "charge": 128, "excess": 24, "forced_rows": 12}, + 3: {"rows": 104, "readers_per_mark": 36, "sources_per_mark": 16, "charge": 256, "excess": 48, "forced_rows": 24}, + } + for summary in summaries: + h = summary["h"] + for key, value in expected[h].items(): + if summary[key] != value: + raise AssertionError(f"h={h} {key}={summary[key]} expected {value}") + formula_rows = 2 * (3 * h * (h + 1) + 2 ** (h + 1)) + formula_excess = 4 * h * (h + 1) + if summary["rows"] != formula_rows or summary["excess"] != formula_excess: + raise AssertionError("closed form mismatch") + certificate = k32_charge() + if certificate != 54: + raise AssertionError(certificate) + third = summaries[2] + print( + PASS, + f"h3_rows={third['rows']}", + f"h3_charge={third['charge']}", + f"h3_excess={third['excess']}", + f"h2_excess={summaries[1]['excess']}", + f"h1_charge={summaries[0]['charge']}", + f"k32_charge={certificate}", + f"two_bearing_h3={third['forced_rows']}", + "no_new_kappa", + ) + + +if __name__ == "__main__": + main()