"""places.py -- where a rationed reader's member sits against a greedy spend-all reader's: equal, a reversal, in a layer, or incomparable at a lower rank, and the last is a reversal over a member of the greedy reader's layer, so the two places compose and there is no third. QUESTION. rationed.py's greedy spend-all readers (both patiences 0, delta = INF) share one rank trace, so two of them differ only inside a layer; forecast.py found that without a resource limit a reader departs from the greedy one only at a reversal, a member strictly containing the greedy one's. A rationed reader that is patient, or draws a finite delta, is covered by neither. Where can its committed member sit against a greedy spend-all reader's, and does the side loss's stream enter at a new place? THE ARGUMENT (D1 to D3 written before the engine, D4 after the first run). (D1) RANK NEVER ABOVE THE GREEDY SPEND-ALL READER'S. Let X be any rationed reader at income B and cap W and G a greedy spend-all one. X's step spends s_n <= B + b_(n-1), its member holds J_n (a patient move holds J_(n-p), which holds J_n, images nesting) and so contains the bottom (learner.py's bottom lemma), whose rank r*(J_n) bounds it by rationed.py's (A); at a step where no member holds the image, an initial segment, r* = 0 and every reader sits at the root. With P = rank + bank, b_n = min(W, B + b_(n-1) - s_n) gives P^X_n = min(rho^X_n + W, P^X_(n-1) + B). G follows rho^G_n = min(r*(J_n), P^G_(n-1) + B) (rationed.py's (B)) and the same P recursion. From 0, 0, by induction, rho^X_n <= min(r*, P^X_(n-1) + B) <= rho^G_n, and then P^X_n <= P^G_n. (D2) THE FOUR CLASSES. By (A) the inner member of a strictly nested pair has the higher rank, so X's member is never strictly inside G's: it is EQUAL, strictly CONTAINS it (a REVERSAL), or is incomparable at G's rank (a LAYER) or below it (BELOW). BELOW needs rho^X < rho^G, so no two greedy spend-all readers make it. (D3) BELOW EXISTS. Holders (T_i, k) and (T_j, k') of one image with i < j <= i + k, k >= 1, are incomparable ((A)'s proof); the tile (0, 1), rank 1, and the root's S_2, (2/3, 3/2), rank 2, both hold (7/10, 9/10), and at its cut 4/5 the first forecasts left and the second right. (D4) BELOW IS A REVERSAL OVER A LAYER. Inside a holding member M = (T_i, k), every rank from i + k + 1 to r*(J) carries a holding member: the straddles (T_i, k'), k < k' <= k_i*, inside M as straddles at one vertex nest; and, if T_i is not the bottom tile, the path tiles T_j, j >= i + k + 1, and their straddles, a straddle lying inside its own tile. Those tiles exist and lie inside M: at k = 0 because M is T_i; at k >= 1 because J's closure misses v_i, so by (A)'s path T_(i+k+1) = (l + k v_i, v_i) holds J and shares S_k(v_i)'s left end. If T_i is the bottom tile its straddles alone reach r*. So when rho^X < rho^G, X's member strictly contains some member M' of G's rank, M' != G's member when the pair is BELOW: X is a reversal against M', a layer-mate of G's. Where members sit there is no third kind of place: the two compose. The hand pair: (0, 1) contains T_2 = (1/2, 1), rank 2, a layer-mate of S_2 of the root, and T_2 forecasts left at 4/5 (3/10 against 1/5) as (0, 1) does. THE RUN. rationed.py's nine rows, N = 120, counted steps 8 .. 119, the side truth by deepening to 320 (forecast.py). At each of the 16 settings (B = 1..4, W = 0, 2, 4, 8) every policy of space5(W) is run and set beside each of the four greedy spend-all readers, step by step, and classed EQUAL, REVERSAL, LAYER, BELOW, or BAD (strictly inside G's member, or of higher rank). PREDICTIONS AND KILLS (frozen before code). K1 BAD = 0 at every setting; one BAD site kills (D1) or (D2) here. K2 GAIN_BELOW, the sites (setting, row, step, policy) where the policy hits the side and U = (1, 1, 0, 0, INF) misses and the pair is BELOW, summed over the settings: predicted > 0, at most settings, by patient readers and by greedy ones with delta finite. 0 kills "met on the rows". Printed beside them: the gain sites by class per setting; BELOW sites split by patience and delta; the greedy spend-all policies never BELOW. Added after the first run, not frozen: D4's check at every BELOW site against U, and F4's arm, whether a member of U's layer inside the gaining reader's hits, with its null, the gains where those members all forecast one side. CONTROLS, read before any verdict: C0 the hand pair of (D3); C1 the refuser against U, REVERSAL one way and BAD the other; C1b at no income limit no LAYER and no BELOW; for D4, at the first 300 LAYER sites against U no mate inside, and at the first 300 REVERSAL sites below U's rank U's own member among them. FINDINGS. F0 The controls: the hand pair is BELOW, forecasting L and R; the refuser against U at (2, 2) differs at 1008 sites, every one REVERSAL one way and BAD the other (BAD's two arms, strictly inside and rank above, coincide by (A), so they are not told apart); at no income limit the 100,800 (policy, row, step) sites against U are 17,844 EQUAL and 82,956 REVERSAL, no LAYER, BELOW or BAD. F1 K1: BAD = 0 at all 16 settings, against all four greedy spend-all readers; no greedy spend-all policy is BELOW one. F2 K2: GAIN_BELOW = 3554, at 13 of the 16 settings (frozen as "> 0, at most settings"); none at (4, 0), (4, 4), (4, 8), where no layer gains either. Gains against U, reversal / layer / below, at six of the 13 (the rest in the print): (1, 0) 24899 / 2887 / 237, (1, 2) 52349 / 9437 / 833, (1, 8) 66113 / 28709 / 335, (2, 8) 81944 / 3686 / 19, (3, 8) 85471 / 1652 / 798, (4, 2) 53317 / 784 / 392; the reversal leads at every setting. F3 By (a patience other than 0, a refused kind counted; delta finite): BELOW sites, all four G, (no, yes) 3220, (yes, no) 31035, (yes, yes) 66192; BELOW gains against U 319, 875, 2360. Both frozen sources gain, so a reader of greedy patience drawing a finite delta goes below too: the rank gap, which both make, is what BELOW needs (necessary, not sufficient; reversals have it too). F4 D4 holds at all 6575 BELOW sites against U (and at the 3554 gains), its controls clean (300 LAYER sites with no mate, 300 REVERSAL sites below U's rank holding U's member). Not frozen, a count over the nine rows at the 16 settings, N = 120, against U only: at all 3554 BELOW gains the members of U's layer inside the gaining reader's forecast one side, and that side hits. So there the gain is the layer-mate's, a choice inside U's layer, and the reversal above it adds none. The mates' arms below find it forced at no level they pose it: a count, not a law. THE MATES (a second question, frozen before its arms' code). Is F4 forced? As geometry: for an image J held by the root, its cut c, and holders P, U, M of J with M strictly inside P, rank M = rank U > rank P, P and U incomparable and forecasting opposite sides of c, does M forecast P's side? A forecast is R iff the member's midpoint exceeds c. The incomparable holders are exactly (T_i, k), (T_j, k') with i < j <= i + k, k >= 1, so the higher member of a BELOW pair is a straddle. Ranks are tree depth plus index, the root at depth 0. THE WITNESS, by hand: J = (7/12, 10/17), a unimodular pair, c = 17/29 its vertex; P = S_1(root) = (1/2, 2), rank 1, midpoint 5/4, forecasts R; U = (T_1, 2) = (2/5, 3/5), T_1 = (0, 1), rank 3, midpoint 1/2, forecasts L; of the rank-3 members T_3 = (1/2, 2/3), U, (T_2, 1) = (3/5, 3/4) and S_3(root) = (3/4, 4/3) the last two miss J; M = T_3 lies inside P and forecasts L (7/12 < 17/29, 203 < 204), U's side. The reader reaches it: at B = 2, W = 0 on the history J0 = (3/10, 6/5), J1 = (1/3, 59/100), J2 = J, U commits T_1 at step 1 and chains to (T_1, 2) at step 2; X = (1, 1, 1, 0, INF) moves first at step 2, to S_1(root), its tree reference J1 lying in neither child. G over images J = (a/b, c/d), reduced, 0 < a/b < c/d, b, d <= 12, numerators < 36, cut the reduced mediant, every triple (P, U, M) as above: PRINTS the triples where M forecasts U's side, and their count. Predicted > 0, the witness among them (the positive control). Arm GT, J unimodular: > 0. One triple kills the geometric statement. H run_rationed on the history, U and X at (2, 0): PRINTS the two members, the place, and the forecasts of U's layer-mates inside X. Predicted: BELOW, X R, U L, the mate (1/2, 2/3) L. R id, sq, dbl on 12 seeded random streams each (a_0 = 1, a_i uniform in 1..6), N = 60, counted 8..59, truth by deepening to 200, the 16 settings, every policy of space5(W) against U: PRINTS F4_FAIL, the BELOW gains against U where some layer-mate of U inside the gainer misses. Predicted > 0, weakly: then F4 is the nine streams' count, not the maps'. The counter's control, read first: the same counting function on H's history (counted from step 2, truth R) prints 1. Changed from the frozen design, named: G's bound D = 12 held no image of the witness's denominator 17, so its control failed on the first run; D = 17, numerators < 51 (at D = 12 it printed G_BAD 1511, GT_BAD 631, so the change did not make the kill). G prints four triples and the count. Added after the first run, not frozen: R at digits {1, 2} (the same seeds, other draws), with the seeds that fail per map and, added at a later audit, the seeds with no BELOW gain. The rows' cut is the mediant as f writes the endpoints, G's the reduced one; they agree under id and sq (convergent endpoints are coprime) and can differ under dbl, which writes 2p/q unreduced, so G speaks to the geometry and R to the rows' maps. A gain with no layer-mate inside counts as a fail; D4 leaves none. FINDINGS OF THE MATES. F5 Controls: the witness triple is enumerated at D = 17 and classed bad; the counter on H's history prints 1 gain, 1 fail. F6 G: G_BAD = 10782 over 147,696 images held by the root, GT_BAD = 2807 over the 1021 unimodular ones. The geometric statement dies, on tile images cut at their vertex too. F7 H: as predicted. U (0, inf), (0, 1), (2/5, 3/5) at ranks 0, 1, 3; X (0, inf), (0, inf), (1/2, 2) at ranks 0, 0, 1; at step 2 BELOW, cut 17/29, X R, U L, its one mate (1/2, 2/3) L. So F4 fails for U's own member, the reader's code running it. F8 R: F4_FAIL = 4301 of 29,361 BELOW gains (id 1894 of 11,627, sq 762 of 3975, dbl 1645 of 13,759). F4 is forced neither by the geometry nor by U's route nor by the maps. The seeds failing, per map: id all 12, sq 10 (seeds 0 and 6 hold), dbl 11 (seed 8 holds), and every seed has a BELOW gain. At digits {1, 2}: F4_FAIL 152 of 5341 (id 0 of 2403, sq 152 of 1624, dbl 0 of 1314), the sq fails on seeds 1, 7 and 8 alone, and sq seeds 3, 5 and 11 have no BELOW gain: F4 holds with gains on every id and dbl row of digits 1 and 2 and on six of the twelve sq ones, as on the nine rows' two sq rows. So holding is a row's (a digit stream under a map): 30 of the 36 rows at digits 1 and 2 hold with gains (3 have none), 3 of 36 at digits 1 to 6 (sq seeds 0 and 6, dbl seed 8; no id row). RUN RECORD. Bare, through the gate: 13 of 13 checks, 155.0 s, its peak 12.0 MB; with the no-gain print, 13 of 13, 154.1 s, 11.8 MB. Exact integers in every decision. G's enumeration is sorted by float, which orders it exactly at D = 17 (distinct values differ by 1/289 at least) and decides nothing. No frozen prediction was changed. """ import random import sys from math import gcd from learner import (N0, INF, inside, holds, span, path_tiles, index_max, MAPS, lt) from rationed import (ROWS9, images9, run_rationed, space5, rank, relation, tiles_of_digits) from forecast import mediant, forecast, truth_deep N_MAIN = 120 N_DEEP = 320 INCOMES = [1, 2, 3, 4] CAPS = [0, 2, 4, 8] QUARTET = [(a, b, 0, 0, INF) for a in (0, 1) for b in (0, 1)] U = (1, 1, 0, 0, INF) PLACES = ["EQUAL", "REVERSAL", "LAYER", "BELOW", "BAD"] CHECKS = [] def check(name, ok, detail=""): CHECKS.append(bool(ok)) print(f" {'PASS' if ok else 'FAIL'} {name}" + (f" ({detail})" if detail else "")) def place(cx, cg): rel = relation(cx, cg) rx, rg = rank(cx), rank(cg) if rx > rg or rel == "inside": return "BAD" if rel == "equal": return "EQUAL" if rel == "contains": return "REVERSAL" return "LAYER" if rx == rg else "BELOW" def layer_inside(J, rho, mx): """The members of rank rho holding J strictly inside mx (D4).""" out = [] for t in path_tiles(J): k = rho - t[3] if 0 <= k <= index_max(t[0], t[1], J): m = (t[0], t[1], k, t[3]) if m != mx and inside(m, mx): out.append(m) return out def hits_of(trace, deep_row, truths_row): return [int(forecast(trace[n], mediant(deep_row[n])) == truths_row[n - N0]) for n in range(N0, N_MAIN)] def controls(imgs): print("\nC CONTROLS") tile01 = ((0, 1), (1, 1), 0, 1) s2root = ((0, 1), (1, 0), 2, 0) J = ((7, 10), (9, 10)) ok = (span(tile01) == ((0, 1), (1, 1)) and span(s2root) == ((2, 3), (3, 2)) and holds(tile01, J) and holds(s2root, J) and relation(tile01, s2root) == "incomparable" and rank(tile01) == 1 and rank(s2root) == 2 and place(tile01, s2root) == "BELOW" and forecast(tile01, mediant(J)) == "L" and forecast(s2root, mediant(J)) == "R") check("C0 the hand pair: a BELOW pair, forecasts L and R", ok) # C1: orientation on real runs, the refuser against U at (2, 2) ref = (0, 0, INF, INF, INF) differ = wrong = 0 for row in ROWS9: tu, _ = run_rationed(imgs[row], U, 2, 2) tr, _ = run_rationed(imgs[row], ref, 2, 2) for m in range(N0, N_MAIN): if tu[m] != tr[m]: differ += 1 wrong += not (place(tr[m], tu[m]) == "REVERSAL" and place(tu[m], tr[m]) == "BAD") check("C1 the refuser reads REVERSAL against U, U BAD against it", differ > 0 and wrong == 0, f"{differ} differing, {wrong} wrong") # C1b: unlimited readers, no LAYER and no BELOW seen = {p: 0 for p in PLACES} for row in ROWS9: g, _ = run_rationed(imgs[row], U, None, 0) for p in space5(0): tr, _ = run_rationed(imgs[row], p, None, 0) for m in range(N0, N_MAIN): seen[place(tr[m], g[m])] += 1 check("C1b no income limit: only EQUAL and REVERSAL", seen["LAYER"] == seen["BELOW"] == seen["BAD"] == 0 and seen["REVERSAL"] > 0, f"{seen}") X_W = (1, 1, 1, 0, INF) ROOT_S1 = ((0, 1), (1, 0), 1, 0) U_W = ((0, 1), (1, 1), 2, 1) M_W = ((1, 2), (2, 3), 0, 3) J_W = ((7, 12), (10, 17)) HISTORY = [((3, 10), (6, 5)), ((1, 3), (59, 100)), J_W] def holders(J): return [(t[0], t[1], k, t[3]) for t in path_tiles(J) for k in range(index_max(t[0], t[1], J) + 1)] def bad_triples(J, cut): """The (P, U, M) of the mates' question at which M forecasts U's side.""" hs = holders(J) fc = {h: forecast(h, cut) for h in hs} out = [] for p in hs: for u in hs: if rank(p) >= rank(u) or relation(p, u) != "incomparable": continue if fc[p] == fc[u]: continue for m in layer_inside(J, rank(u), p): if fc[m] == fc[u]: out.append((p, u, m)) return out def fr(x): return f"{x[0]}/{x[1]}" if x[1] else "inf" def mem(c): lo, hi = span(c) return f"({fr(lo)}, {fr(hi)})" def arm_g(): print("\nG THE MATES AS GEOMETRY") D = 17 # frozen 12; raised so the witness (denominator 17) is in it fr_ = sorted({(a // gcd(a, b), b // gcd(a, b)) for b in range(1, D + 1) for a in range(1, 3 * D)}, key=lambda x: x[0] / x[1]) n_img = n_bad = n_tile = n_tile_bad = 0 first = [] witness_seen = False for i, lo in enumerate(fr_): for hi in fr_[i + 1:]: J = (lo, hi) if not holds(((0, 1), (1, 0), 0, 0), J): continue cut = mediant(J) bt = bad_triples(J, cut) uni = hi[0] * lo[1] - lo[0] * hi[1] == 1 n_img += 1 n_bad += len(bt) n_tile += uni if uni: n_tile_bad += len(bt) if J == J_W and (ROOT_S1, U_W, M_W) in bt: witness_seen = True if bt and len(first) < 4: first.append((J, bt[0])) print(f" images {n_img}, of them unimodular {n_tile}") for J, (p, u, m) in first: c = mediant(J) print(f" J = ({fr(J[0])}, {fr(J[1])}), cut {fr(c)}: " f"P {mem(p)} {forecast(p, c)}, U {mem(u)} {forecast(u, c)}, " f"M {mem(m)} {forecast(m, c)}") check("G control: the witness triple is enumerated and classed bad", witness_seen) print(f" G_BAD = {n_bad} (triples where M forecasts U's side)") print(f" GT_BAD = {n_tile_bad} (of them on unimodular images)") def arm_h(): print("\nH THE READER ON A HISTORY") tu, _ = run_rationed(HISTORY, U, 2, 0) tx, _ = run_rationed(HISTORY, X_W, 2, 0) cut = mediant(J_W) for n in range(3): print(f" step {n}: U {mem(tu[n])} rank {rank(tu[n])}, " f"X {mem(tx[n])} rank {rank(tx[n])}") ms = layer_inside(J_W, rank(tu[2]), tx[2]) print(f" step 2: place {place(tx[2], tu[2])}, cut {fr(cut)}, " f"X {forecast(tx[2], cut)}, U {forecast(tu[2], cut)}, mates " f"{[(mem(m), forecast(m, cut)) for m in ms]}") check("H X is in space5(0)", X_W in space5(0)) def count_f4(imgs, cuts, truths, start, end, pols, B, W): """BELOW gains against U and, of them, those where some layer-mate of U inside the gainer's member misses (F4_FAIL).""" gu, _ = run_rationed(imgs, U, B, W) gains = fails = 0 first = None for p in pols: tr, _ = run_rationed(imgs, p, B, W) for n in range(start, end): t = truths[n] if not (forecast(tr[n], cuts[n]) == t and forecast(gu[n], cuts[n]) != t): continue if place(tr[n], gu[n]) != "BELOW": continue gains += 1 ms = layer_inside(imgs[n], rank(gu[n]), tr[n]) if any(forecast(m, cuts[n]) != t for m in ms) or not ms: fails += 1 if first is None: first = (p, n, tr[n], gu[n], ms) return gains, fails, first def arm_r(digset): print(f"\nR THE ROWS' MAPS ON SEEDED STREAMS, digits {list(digset)}") cuts = [mediant(J) for J in HISTORY] g, f, _ = count_f4(HISTORY, cuts, [None, None, "R"], 2, 3, [X_W], 2, 0) check("R control: the counter on H's history prints one fail", g == 1 and f == 1, f"gains {g}, fails {f}") if not all(CHECKS): print("A CONTROL FAILED: R is not read.") return N, DEEP = 60, 200 total_g = total_f = 0 shown = 0 for m in ("id", "sq", "dbl"): fmap = MAPS[m] mg = mf = 0 failing, nogain = [], [] for seed in range(12): rng = random.Random(1000 + seed) digits = [1] + [rng.choice(digset) for _ in range(DEEP - 1)] deep = [] for lo, hi in tiles_of_digits(digits): a, b = fmap(lo), fmap(hi) deep.append((a, b) if lt(a, b) else (b, a)) imgs = deep[:N] cuts = [mediant(J) for J in imgs] truths = [truth_deep(deep, n) if n >= N0 else None for n in range(N)] if any(t is None for t in truths[N0:]): print(f" {m} seed {seed}: an unresolved truth, skipped") continue sf = sg = 0 for B in INCOMES: for W in CAPS: g, f, first = count_f4(imgs, cuts, truths, N0, N, space5(W), B, W) mg += g sg += g sf += f if first and shown < 3: shown += 1 p, n, cx, cu, ms = first print(f" fail: {m} seed {seed} ({B}, {W}) step " f"{n} policy {p}: X {mem(cx)} U {mem(cu)} " f"cut {fr(cuts[n])} truth {truths[n]}, mates " f"{[(mem(x), forecast(x, cuts[n])) for x in ms]}") mf += sf if sf: failing.append(seed) if not sg: nogain.append(seed) print(f" {m}: BELOW gains against U {mg}, F4_FAIL {mf}, " f"failing seeds {failing}, seeds with no BELOW gain {nogain}") total_g += mg total_f += mf print(f" F4_FAIL = {total_f} of {total_g} BELOW gains") def main(): imgs = images9(N_MAIN) deep = images9(N_DEEP) truths = {row: [truth_deep(deep[row], n) for n in range(N0, N_MAIN)] for row in ROWS9} if any(t is None for row in ROWS9 for t in truths[row]): print("an unresolved truth: no verdict is read") sys.exit(1) controls(imgs) if not all(CHECKS): print("\nA CONTROL FAILED: nothing below is read.") sys.exit(1) print("\nK THE PLACES, per setting (B, W)") print(" setting sites(all G) BAD BELOW LAYER REVERSAL" " gain vs U: rev layer below") bad_total = gain_below_total = 0 quartet_below = 0 split = {} gsplit = {} no_mate = carried = one_side = one_side_hit = 0 d4_sites = d4_miss = 0 ctl = {"LAYER": [0, 0], "REVERSAL": [0, 0]} settings_with_gain_below = 0 for B in INCOMES: for W in CAPS: cnt = {p: 0 for p in PLACES} gain = {p: 0 for p in PLACES} for row in ROWS9: gtr = {g: run_rationed(imgs[row], g, B, W)[0] for g in QUARTET} ghit = hits_of(gtr[U], deep[row], truths[row]) for p in space5(W): tr = gtr[p] if p in gtr else \ run_rationed(imgs[row], p, B, W)[0] xhit = hits_of(tr, deep[row], truths[row]) for g in QUARTET: for j, n in enumerate(range(N0, N_MAIN)): pl = place(tr[n], gtr[g][n]) cnt[pl] += 1 if g == U and (pl == "BELOW" or ( pl in ctl and ctl[pl][0] < 300 and (pl == "LAYER" or rank(tr[n]) < rank(gtr[g][n])))): ms = layer_inside(imgs[row][n], rank(gtr[g][n]), tr[n]) if pl == "BELOW": d4_sites += 1 d4_miss += not ms elif pl == "LAYER": ctl[pl][0] += 1 ctl[pl][1] += bool(ms) else: ctl[pl][0] += 1 ctl[pl][1] += gtr[g][n] not in ms if pl == "BELOW": if p in QUARTET: quartet_below += 1 key = ((p[2], p[3]) != (0, 0), p[4] is not INF) split[key] = split.get(key, 0) + 1 if g == U and xhit[j] and not ghit[j]: gain[pl] += 1 if pl == "BELOW": key = ((p[2], p[3]) != (0, 0), p[4] is not INF) gsplit[key] = gsplit.get(key, 0) + 1 J = imgs[row][n] ms = layer_inside(J, rank(gtr[g][n]), tr[n]) no_mate += not ms cut = mediant(deep[row][n]) sides = {forecast(m, cut) for m in ms} hit = truths[row][n - N0] in sides carried += hit if len(sides) == 1: one_side += 1 one_side_hit += hit bad_total += cnt["BAD"] gain_below_total += gain["BELOW"] settings_with_gain_below += gain["BELOW"] > 0 print(f" ({B}, {W}) {sum(cnt.values()):10d} " f"{cnt['BAD']:3d} {cnt['BELOW']:8d} " f"{cnt['LAYER']:5d} {cnt['REVERSAL']:8d} " f"{gain['REVERSAL']:5d} {gain['LAYER']:5d} " f"{gain['BELOW']:5d}") print("\n below sites by (patient, delta finite):") for key in sorted(split): print(f" patient={key[0]!s:5s} finite_delta={key[1]!s:5s}" f" {split[key]}") print(" below gains against U by (patient, delta finite):") for key in sorted(gsplit): print(f" patient={key[0]!s:5s} finite_delta={key[1]!s:5s}" f" {gsplit[key]}") print(f" below gains with no layer-mate of U inside the reader's" f" member: {no_mate}; with one that hits too: {carried}") print(f" settings with a below gain: {settings_with_gain_below}" f" of 16") print(f" GAIN_BELOW = {gain_below_total}") check("K1 BAD = 0 at every setting", bad_total == 0, f"{bad_total}") check("D2 no greedy spend-all policy in a BELOW pair", quartet_below == 0, f"{quartet_below}") check("K2 GAIN_BELOW > 0 (BELOW met on the rows)", gain_below_total > 0, f"{gain_below_total}") print(f" of those, all layer-mates forecast one side at " f"{one_side}, and hit there at {one_side_hit}") print(f" D4 controls, the first 300 sites against U: LAYER " f"{ctl['LAYER']} (sites, with a mate), REVERSAL below U's rank " f"{ctl['REVERSAL']} (sites, U's member missing)") check("D4 every below gain contains a member of U's layer", no_mate == 0, f"{no_mate}") check("D4 at every BELOW site against U: a layer-mate inside", d4_sites > 0 and d4_miss == 0, f"{d4_sites} sites, {d4_miss}" f" without") check("D4 controls: no mate at a LAYER, U's member at a REVERSAL", ctl["LAYER"][0] > 0 and ctl["LAYER"][1] == 0 and ctl["REVERSAL"][0] > 0 and ctl["REVERSAL"][1] == 0, f"{ctl}") arm_g() arm_h() arm_r((1, 2, 3, 4, 5, 6)) arm_r((1, 2)) print() print(f"{sum(CHECKS)} of {len(CHECKS)} checks pass") sys.exit(0 if all(CHECKS) else 1) if __name__ == "__main__": main()