From 0617243ed4e47c814c639ea36f312fecb1bbc961 Mon Sep 17 00:00:00 2001 From: Valeri Sitnikov Date: Sun, 20 Sep 2026 23:12:34 +0100 Subject: [PATCH] =?UTF-8?q?pre-step=20gate:=20prestep=3D'none'|'progress'?= =?UTF-8?q?=20(default=20bit-identical),=20refuse=20the=20similarity=20ste?= =?UTF-8?q?p=20BEFORE=20spending=20an=20evaluation=20when=20it=20promises?= =?UTF-8?q?=20less=20progress=20than=20bisection=20=E2=80=94=20two=20lengt?= =?UTF-8?q?hs=20already=20in=20hand,=20no=20new=20constant;=20R1-R4=20pinn?= =?UTF-8?q?ed=20by=20tests/test=5Fprestep=5Fgate.py=20(6=20green);=20the?= =?UTF-8?q?=20gate=20grid=20writes=20to=20its=20OWN=20sweep=5Fgate.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 --- PREREG_prestep_gate_2026-09-21.md | 69 +++++++++++++++++++++++ simroot/pure.py | 31 +++++++++-- sweep_full.py | 33 +++++++++-- sweep_gate_smoke.json | 1 + tests/test_prestep_gate.py | 91 +++++++++++++++++++++++++++++++ 5 files changed, 215 insertions(+), 10 deletions(-) create mode 100644 PREREG_prestep_gate_2026-09-21.md create mode 100644 sweep_gate_smoke.json create mode 100644 tests/test_prestep_gate.py diff --git a/PREREG_prestep_gate_2026-09-21.md b/PREREG_prestep_gate_2026-09-21.md new file mode 100644 index 0000000..279cd60 --- /dev/null +++ b/PREREG_prestep_gate_2026-09-21.md @@ -0,0 +1,69 @@ +# PREREG — предшаговый гейт: похожесть как ОТКАЗ до шага, а не масштаб внутри шага + +Составлено до реализации. Основание — измерение `explain_chandrupatla.py` (лог +`results_explain_chandrupatla.txt`, разбор в `FINDINGS_logarithmic.md` §3): Chandrupatla принимает +свою модель лишь в **28 %** шагов, его гейт стоит **ноль** вызовов, а ветвь отказа снимает половину +скобки; наш сторож ремонтирует **77.5 %** вызовов, и на `fun8`/`fun9` мы опускаемся до **0.92** +половинок на вызов — хуже деления пополам. Качество пробы: **2.310** против **1.422**. + +**Гипотеза:** дело не в форме функции похожести, а в **месте её чтения**. Похожесть, прочитанная ДО +шага и решающая «доверять ли модели здесь», стоит ноль; прочитанная ВНУТРИ шага как масштаб — требует +сторожа, а сторож платит вызовом. + +--- + +## 1. Что именно добавляется (и почему это не новая константа) + +**Важно, что наша причина ремонтов ДРУГАЯ, чем у Chandrupatla.** Наш шаг +`(1 − S(|f|/σ))·(far − x)` при `0 ≤ S ≤ 1` **никогда не выходит за скобку** — то есть перескок нам не +грозит; сторож вмешивается, когда шаг слишком **короткий** и прогресс мал. Значит и гейт должен +спрашивать не «не выйдет ли проба за скобку» (вопрос Chandrupatla для его модели), а: + +> **обещает ли этот шаг прогресс не хуже, чем деление пополам?** + +Обе длины известны ДО вызова `f`: длина шага `|step|` и длина шага в середину `|½(A+B) − x|`. +Сравнение двух имеющихся длин — не константа и не подгонка; порога нет, есть неравенство. + +**Режим:** `prestep="none"` (по умолчанию — опубликованное поведение побитово) и +`prestep="progress"` (гейт включён). Если гейт отказал, шаг **заменяется** на деление пополам, то есть +тот же один вызов `f` тратится на гарантированное снятие половины скобки. + +**Чего НЕ делаем:** не переносим полосу `1−√(1−ξ) < φ < √ξ` в наш метод. Она выведена для обратной +квадратичной интерполяции из условия «проба не выйдет за скобку»; у нашего шага этого условия нет, и +взятая напрокат область была бы скрытой константой чужого вывода. + +## 2. Предсказания и фальсификаторы + +| # | Предсказание | ФАЛЬСИФИКАТОР → вывод | +|---|---|---| +| **P1** | доля ремонтов на CHA падает с 77.5 % до **≤40 %** | >60 % → гейт не бьёт в механизм, объяснение §3 неверно как рецепт | +| **P2** | цена на CHA падает ниже нашей текущей **2073** (та же конфигурация `ratio.derived3.credit`) | не падает → отказ дешевле ремонта не оказался, гипотеза о месте чтения не подтверждена | +| **P3** | цена на APS-154 **не растёт** (по-наборный лучший остаётся ≤ **2806**) | растёт → тот же трейд, что убил пять предыдущих попыток; гейт отвергается | +| **P4** | гарантия `2⌈log₂(w/xtol)⌉+3` не нарушена: `over2x = 0` во всех конфигурациях | нарушена → закрытие немедленно | +| **P5** | качество пробы на CHA растёт с 1.422 к уровню **≥2.0** половинок на вызов | <1.7 → прирост есть, но не тот порядок; заявлять «как Chandrupatla» нельзя | + +**Правило остановки:** P3 или P4 ложны ⇒ режим не принимается вовсе. P1 и P2 ложны ⇒ объяснение +остаётся верным как **описание** Chandrupatla, но как **рецепт** для нашего метода — опровергнуто, и +это пишется прямо. + +## 3. Протокол (тот же, что у статьи) + +154 задачи Alefeld–Potra–Shi + 45 Чандрупатлы; цена — вызовы `f`; провал списывается полным бюджетом; +граница `2×` проверяется на каждом решённом прогоне; конфигурация фиксируется выводом ДО того, как +смотрят в рейтинг. Числа только с **Linux**. Свип пишется в свой файл (`sweep_gate.json`), чтобы +`sweep_full.json`, против которого сверяется статья, остался нетронутым. + +Сравнение ведётся **по-наборно** и **внутри семейства сторожей, несущих гарантию** — иначе сравниваются +разные конфигурации (эта ошибка уже допущена 2026-09-20 и исправлена). + +## 4. Гейты реализации (тесты ДО рейтинга) + +| # | Условие | Проверка | +|---|---|---| +| **R1** | `prestep="none"` даёт побитово прежний результат | тест на равенство кортежей возврата на наборе задач | +| **R2** | в гейте нет ни одной выбранной константы | грепом по исходнику: только `0.0`, `0.5` (середина скобки — определение деления пополам), `1.0` | +| **R3** | отказ гейта не стоит вызова `f` | тест: число вызовов при включённом гейте не превышает число шагов + 2 | +| **R4** | счётчик `stats['pre_refused']` считает отказы гейта отдельно от ремонтов сторожа | тест на обоих счётчиках | + +**Дисциплина:** аудит после правки и до запуска; смоук ×2 локально; тяжёлое — на сервер +`setsid nohup` с логом; замороженная копия скрипта; числа показываются немедленно. diff --git a/simroot/pure.py b/simroot/pure.py index 1a4e865..468bf59 100644 --- a/simroot/pure.py +++ b/simroot/pure.py @@ -413,7 +413,7 @@ def _local_order(x2, f2, x1, f1, x0, f0): def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived", guard="step", stats=None, budget_factor=2.0, - budget_extra=None, endowment=1.0, space="x"): + budget_extra=None, endowment=1.0, space="x", prestep="none"): """The pure similarity root finder. similarity : key into PURE_SIMS @@ -467,6 +467,8 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived", raise ValueError(f"unknown scale {scale!r}") if space not in SPACES: raise ValueError(f"unknown space {space!r}") + if prestep not in ("none", "progress"): + raise ValueError(f"unknown prestep {prestep!r}") if space == "log" and scale not in ("derived", "derived3"): # u-space needs a slope; with a chosen or bracket scale there is none to # transform, and computing something anyway would hide that (PREREG §3a). @@ -494,8 +496,10 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived", sg = _Safeguard(guard, abs(B - A), xtol, budget_factor, budget_extra) sg.credit = endowment forced = 0 + pre_refused = 0 if stats is not None: stats['forced'] = 0 + stats['pre_refused'] = 0 while abs(B - A) > xtol: if sg.bisect_before_step(abs(B - A)): @@ -592,7 +596,22 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived", x_new = 0.5 * (A + B) else: step = None - if space == "log": + if prestep == "progress": + # PRE-STEP GATE (PREREG 2026-09-21). Measured cause of our cost: + # the safeguard REPAIRS 77.5% of evaluations after the fact, while + # Chandrupatla REFUSES its model on 72% of steps for free and + # halves instead - 2.310 halvings per evaluation against our 1.422. + # Our step never leaves the bracket (0 <= S <= 1), so the question + # is not overshoot but PROGRESS: if the similarity step promises + # less than bisection would remove, spend the same single + # evaluation on the midpoint instead. Two lengths already in hand + # are compared; there is no threshold and no new constant. + cand = (1.0 - S(abs(fx) / sc)) * (far - x) + half = 0.5 * (A + B) - x + if abs(cand) < abs(half): + step = half + pre_refused += 1 + if step is None and space == "log": # c = the bracket end with the smaller |f| (the side the # root is nearer); s = xtol, fixed by derivation in # PREREG amendment 1, never chosen. Falls back to the @@ -624,7 +643,7 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived", if x_new == x or x_new == x_prev: # the bracket can no longer be split in floating point if stats is not None: - stats['forced'] = forced + stats['forced'] = forced; stats['pre_refused'] = pre_refused return x_new, g.n, abs(B - A) <= xtol w_before = abs(B - A) @@ -636,7 +655,7 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived", x, fx = x_new, fnew if fnew == 0.0: if stats is not None: - stats['forced'] = forced + stats['forced'] = forced; stats['pre_refused'] = pre_refused return x_new, g.n, True if FA * fnew < 0.0: B, FB = x_new, fnew @@ -645,9 +664,9 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived", if guard == "credit": sg.note_shrink(w_before, abs(B - A)) if stats is not None: - stats['forced'] = forced + stats['forced'] = forced; stats['pre_refused'] = pre_refused return 0.5 * (A + B), g.n, True except _Budget: if stats is not None: - stats['forced'] = forced + stats['forced'] = forced; stats['pre_refused'] = pre_refused return x, g.n, False diff --git a/sweep_full.py b/sweep_full.py index 25e3e1a..5772321 100644 --- a/sweep_full.py +++ b/sweep_full.py @@ -110,19 +110,23 @@ def make_method(spec): return BASELINES[spec[1]] sim, scale, guard = spec[1], spec[2], spec[3] space = spec[4] if len(spec) > 4 else "x" + prestep = spec[5] if len(spec) > 5 else "none" def m(f, a, b, xtol, maxfev): return pure_root(f, a, b, xtol, maxfev, similarity=sim, - scale=scale, guard=guard, space=space) + scale=scale, guard=guard, space=space, prestep=prestep) return m def label(spec): if spec[0] == "base": return spec[1] + tag = "pure" if len(spec) > 4 and spec[4] != "x": - return f"{spec[4]}.{spec[1]}.{spec[2]}.{spec[3]}" - return f"pure.{spec[1]}.{spec[2]}.{spec[3]}" + tag = spec[4] + if len(spec) > 5 and spec[5] != "none": + tag = f"{tag}+gate" if tag != "pure" else "gate" + return f"{tag}.{spec[1]}.{spec[2]}.{spec[3]}" def evaluate(spec): @@ -185,6 +189,15 @@ def build_grid_log(smoke): for sim in sims for sc in ("derived", "derived3") for gu in guards] +def build_grid_gate(smoke): + """The pre-step gate grid (PREREG 2026-09-21): the published x-space step with the + gate switched on. Baselines are not recomputed - they are already in sweep_full.json.""" + sims = ["ratio", "sqrt"] if smoke else sorted(PURE_SIMS) + guards = ("credit", "safe") if smoke else GUARD_MODES + return [("pure", sim, sc, gu, "x", "progress") + for sim in sims for sc in ("derived", "derived3") for gu in guards] + + def build_grid(smoke): specs = [("base", nm) for nm in BASELINES] sims = sorted(PURE_SIMS) @@ -205,7 +218,9 @@ def build_grid(smoke): def main(): smoke = "--smoke" in sys.argv logmode = "--log" in sys.argv # the u-space grid, written to its OWN file - specs = build_grid_log(smoke) if logmode else build_grid(smoke) + gatemode = "--gate" in sys.argv # the pre-step gate grid, likewise + specs = (build_grid_gate(smoke) if gatemode else + build_grid_log(smoke) if logmode else build_grid(smoke)) t0 = time.time() print(f"sweep: {len(specs)} configurations x 199 problems " f"({'SMOKE' if smoke else 'FULL'}{', LOG-SPACE' if logmode else ''})", flush=True) @@ -221,6 +236,16 @@ def main(): # the published sweep_full.json is what verify_article.py checks the paper # against, so the log grid never writes into it + if gatemode: + # never into sweep_full.json: that file is what verify_article.py checks the + # paper against, and the smoke run of 2026-09-21 did land in sweep_smoke.json + # before this branch existed + out = "sweep_gate_smoke.json" if smoke else "sweep_gate.json" + with open(out, "w", encoding="utf8") as fh: + json.dump(results, fh) + print(f"\nwrote {out} ({time.time() - t0:.0f}s total)\n", flush=True) + report(results) + return out = ("sweep_log_smoke.json" if smoke else "sweep_log.json") if logmode else \ ("sweep_smoke.json" if smoke else "sweep_full.json") with open(out, "w", encoding="utf8") as fh: diff --git a/sweep_gate_smoke.json b/sweep_gate_smoke.json new file mode 100644 index 0000000..985981d --- /dev/null +++ b/sweep_gate_smoke.json @@ -0,0 +1 @@ +[{"label": "gate.ratio.derived.credit", "spec": ["pure", "ratio", "derived", "credit", "x", "progress"], "APS": {"total": 4917, "solved": 153, "n": 154, "over": 0, "per": {"aps.01.00": [44, true], "aps.02.00": [21, true], "aps.02.01": [22, true], "aps.02.02": [36, true], "aps.02.03": [47, true], "aps.02.04": [22, true], "aps.02.05": [26, true], "aps.02.06": [46, true], "aps.02.07": [32, true], "aps.02.08": [31, true], "aps.02.09": [30, true], "aps.03.00": [35, true], "aps.03.01": [46, true], "aps.03.02": [49, true], "aps.04.00": [46, true], "aps.04.01": [46, true], "aps.04.02": [46, true], "aps.04.03": [46, true], "aps.04.04": [46, true], "aps.04.05": [46, true], "aps.04.06": [46, true], "aps.04.07": [46, true], "aps.04.08": [46, true], "aps.04.09": [46, true], "aps.04.10": [46, true], "aps.04.11": [46, true], "aps.04.12": [46, true], "aps.04.13": [46, true], "aps.05.00": [15, true], "aps.06.00": [16, true], "aps.06.01": [18, true], "aps.06.02": [19, true], "aps.06.03": [18, true], "aps.06.04": [19, true], "aps.06.05": [23, true], "aps.06.06": [22, true], "aps.06.07": [22, true], "aps.06.08": [23, true], "aps.06.09": [24, true], "aps.07.00": [21, true], "aps.07.01": [19, true], "aps.07.02": [14, true], "aps.08.00": [3, true], "aps.08.01": [23, true], "aps.08.02": [24, true], "aps.08.03": [21, true], "aps.08.04": [22, true], "aps.09.00": [18, true], "aps.09.01": [43, true], "aps.09.02": [18, true], "aps.09.03": [16, true], "aps.09.04": [12, true], "aps.09.05": [10, true], "aps.09.06": [8, true], "aps.10.00": [16, true], "aps.10.01": [23, true], "aps.10.02": [22, true], "aps.10.03": [31, true], "aps.10.04": [24, true], "aps.11.00": [18, true], "aps.11.01": [43, true], "aps.11.02": [43, true], "aps.11.03": [43, true], "aps.12.00": [22, true], "aps.12.01": [22, true], "aps.12.02": [20, true], "aps.12.03": [19, true], "aps.12.04": [20, true], "aps.12.05": [20, true], "aps.12.06": [18, true], "aps.12.07": [21, true], "aps.12.08": [50, true], "aps.12.09": [20, true], "aps.12.10": [19, true], "aps.12.11": [19, true], "aps.12.12": [16, true], "aps.12.13": [19, true], "aps.12.14": [17, true], "aps.12.15": [50, true], "aps.12.16": [23, true], "aps.12.17": [22, true], "aps.12.18": [18, true], "aps.13.00": [6, false], "aps.14.00": [28, true], "aps.14.01": [28, true], "aps.14.02": [28, true], "aps.14.03": [28, true], "aps.14.04": [28, true], "aps.14.05": [28, true], "aps.14.06": [28, true], "aps.14.07": [28, true], "aps.14.08": [28, true], "aps.14.09": [28, true], "aps.14.10": [28, true], "aps.14.11": [28, true], "aps.14.12": [28, true], "aps.14.13": [28, true], "aps.14.14": [28, true], "aps.14.15": [28, true], "aps.14.16": [28, true], "aps.14.17": [28, true], "aps.14.18": [28, true], "aps.14.19": [28, true], "aps.14.20": [28, true], "aps.14.21": [28, true], "aps.14.22": [28, true], "aps.14.23": [28, true], "aps.14.24": [28, true], "aps.14.25": [28, true], "aps.14.26": [28, true], "aps.14.27": [28, true], "aps.14.28": [28, true], "aps.14.29": [28, true], "aps.14.30": [28, true], "aps.14.31": [28, true], "aps.14.32": [28, true], "aps.14.33": [28, true], "aps.14.34": [28, true], "aps.14.35": [28, true], "aps.14.36": [28, true], "aps.14.37": [28, true], "aps.14.38": [28, true], "aps.14.39": [28, true], "aps.15.00": [41, true], "aps.15.01": [42, true], "aps.15.02": [38, true], "aps.15.03": [39, true], "aps.15.04": [40, true], "aps.15.05": [43, true], "aps.15.06": [40, true], "aps.15.07": [40, true], "aps.15.08": [39, true], "aps.15.09": [40, true], "aps.15.10": [38, true], "aps.15.11": [40, true], "aps.15.12": [38, true], "aps.15.13": [39, true], "aps.15.14": [39, true], "aps.15.15": [38, true], "aps.15.16": [41, true], "aps.15.17": [42, true], "aps.15.18": [41, true], "aps.15.19": [43, true], "aps.15.20": [39, true], "aps.15.21": [39, true], "aps.15.22": [46, true], "aps.15.23": [42, true], "aps.15.24": [41, true], "aps.15.25": [45, true], "aps.15.26": [42, true], "aps.15.27": [48, true], "aps.15.28": [45, true], "aps.15.29": [46, true], "aps.15.30": [43, true]}}, "CHA": {"total": 2936, "solved": 40, "n": 45, "over": 0, "per": {"fun1.1": [23, true], "fun1.2": [47, true], "fun1.3": [48, true], "fun1.4": [58, true], "fun1.5": [55, true], "fun2.1": [20, true], "fun2.2": [57, true], "fun2.3": [63, true], "fun2.4": [77, true], "fun2.5": [83, true], "fun3.1": [46, true], "fun3.2": [48, true], "fun3.3": [58, true], "fun3.4": [64, true], "fun3.5": [78, true], "fun4.1": [46, true], "fun4.2": [48, true], "fun4.3": [56, true], "fun4.4": [64, true], "fun4.5": [78, true], "fun5.1": [46, true], "fun5.2": [45, true], "fun5.3": [47, true], "fun5.4": [49, true], "fun5.5": [50, true], "fun6.1": [42, true], "fun6.2": [46, true], "fun6.3": [47, true], "fun6.4": [49, true], "fun6.5": [50, true], "fun7.1": [6, false], "fun7.2": [8, false], "fun7.3": [7, false], "fun7.4": [10, false], "fun7.5": [11, false], "fun8.1": [21, true], "fun8.2": [23, true], "fun8.3": [47, true], "fun8.4": [48, true], "fun8.5": [50, true], "fun9.1": [16, true], "fun9.2": [20, true], "fun9.3": [25, true], "fun9.4": [48, true], "fun9.5": [50, true]}}}, {"label": "gate.ratio.derived.safe", "spec": ["pure", "ratio", "derived", "safe", "x", "progress"], "APS": {"total": 4452, "solved": 153, "n": 154, "over": 0, "per": {"aps.01.00": [20, true], "aps.02.00": [25, true], "aps.02.01": [21, true], "aps.02.02": [20, true], "aps.02.03": [32, true], "aps.02.04": [32, true], "aps.02.05": [32, true], "aps.02.06": [21, true], "aps.02.07": [33, true], "aps.02.08": [33, true], "aps.02.09": [32, true], "aps.03.00": [29, true], "aps.03.01": [28, true], "aps.03.02": [32, true], "aps.04.00": [27, true], "aps.04.01": [27, true], "aps.04.02": [26, true], "aps.04.03": [28, true], "aps.04.04": [31, true], "aps.04.05": [25, true], "aps.04.06": [22, true], "aps.04.07": [26, true], "aps.04.08": [28, true], "aps.04.09": [28, true], "aps.04.10": [28, true], "aps.04.11": [26, true], "aps.04.12": [26, true], "aps.04.13": [26, true], "aps.05.00": [19, true], "aps.06.00": [17, true], "aps.06.01": [18, true], "aps.06.02": [20, true], "aps.06.03": [20, true], "aps.06.04": [19, true], "aps.06.05": [21, true], "aps.06.06": [24, true], "aps.06.07": [26, true], "aps.06.08": [25, true], "aps.06.09": [25, true], "aps.07.00": [20, true], "aps.07.01": [18, true], "aps.07.02": [14, true], "aps.08.00": [3, true], "aps.08.01": [19, true], "aps.08.02": [28, true], "aps.08.03": [29, true], "aps.08.04": [27, true], "aps.09.00": [18, true], "aps.09.01": [22, true], "aps.09.02": [18, true], "aps.09.03": [16, true], "aps.09.04": [12, true], "aps.09.05": [10, true], "aps.09.06": [8, true], "aps.10.00": [19, true], "aps.10.01": [21, true], "aps.10.02": [23, true], "aps.10.03": [30, true], "aps.10.04": [23, true], "aps.11.00": [23, true], "aps.11.01": [23, true], "aps.11.02": [27, true], "aps.11.03": [27, true], "aps.12.00": [18, true], "aps.12.01": [20, true], "aps.12.02": [21, true], "aps.12.03": [23, true], "aps.12.04": [23, true], "aps.12.05": [21, true], "aps.12.06": [21, true], "aps.12.07": [21, true], "aps.12.08": [21, true], "aps.12.09": [22, true], "aps.12.10": [20, true], "aps.12.11": [20, true], "aps.12.12": [20, true], "aps.12.13": [20, true], "aps.12.14": [20, true], "aps.12.15": [21, true], "aps.12.16": [21, true], "aps.12.17": [19, true], "aps.12.18": [19, true], "aps.13.00": [9, false], "aps.14.00": [26, true], "aps.14.01": [26, true], "aps.14.02": [26, true], "aps.14.03": [26, true], "aps.14.04": [26, true], "aps.14.05": [26, true], "aps.14.06": [26, true], "aps.14.07": [26, true], "aps.14.08": [26, true], "aps.14.09": [26, true], "aps.14.10": [26, true], "aps.14.11": [26, true], "aps.14.12": [26, true], "aps.14.13": [26, true], "aps.14.14": [26, true], "aps.14.15": [26, true], "aps.14.16": [26, true], "aps.14.17": [26, true], "aps.14.18": [26, true], "aps.14.19": [26, true], "aps.14.20": [26, true], "aps.14.21": [26, true], "aps.14.22": [26, true], "aps.14.23": [26, true], "aps.14.24": [26, true], "aps.14.25": [26, true], "aps.14.26": [26, true], "aps.14.27": [26, true], "aps.14.28": [26, true], "aps.14.29": [26, true], "aps.14.30": [26, true], "aps.14.31": [26, true], "aps.14.32": [26, true], "aps.14.33": [26, true], "aps.14.34": [26, true], "aps.14.35": [26, true], "aps.14.36": [26, true], "aps.14.37": [26, true], "aps.14.38": [26, true], "aps.14.39": [26, true], "aps.15.00": [42, true], "aps.15.01": [42, true], "aps.15.02": [42, true], "aps.15.03": [44, true], "aps.15.04": [42, true], "aps.15.05": [44, true], "aps.15.06": [44, true], "aps.15.07": [44, true], "aps.15.08": [44, true], "aps.15.09": [44, true], "aps.15.10": [38, true], "aps.15.11": [40, true], "aps.15.12": [42, true], "aps.15.13": [40, true], "aps.15.14": [42, true], "aps.15.15": [40, true], "aps.15.16": [42, true], "aps.15.17": [44, true], "aps.15.18": [42, true], "aps.15.19": [44, true], "aps.15.20": [44, true], "aps.15.21": [43, true], "aps.15.22": [44, true], "aps.15.23": [47, true], "aps.15.24": [41, true], "aps.15.25": [45, true], "aps.15.26": [47, true], "aps.15.27": [47, true], "aps.15.28": [47, true], "aps.15.29": [51, true], "aps.15.30": [43, true]}}, "CHA": {"total": 2988, "solved": 40, "n": 45, "over": 0, "per": {"fun1.1": [30, true], "fun1.2": [32, true], "fun1.3": [39, true], "fun1.4": [53, true], "fun1.5": [61, true], "fun2.1": [21, true], "fun2.2": [36, true], "fun2.3": [39, true], "fun2.4": [56, true], "fun2.5": [59, true], "fun3.1": [67, true], "fun3.2": [69, true], "fun3.3": [90, true], "fun3.4": [97, true], "fun3.5": [94, true], "fun4.1": [60, true], "fun4.2": [62, true], "fun4.3": [68, true], "fun4.4": [76, true], "fun4.5": [90, true], "fun5.1": [59, true], "fun5.2": [56, true], "fun5.3": [62, true], "fun5.4": [66, true], "fun5.5": [67, true], "fun6.1": [55, true], "fun6.2": [56, true], "fun6.3": [47, true], "fun6.4": [47, true], "fun6.5": [47, true], "fun7.1": [9, false], "fun7.2": [8, false], "fun7.3": [11, false], "fun7.4": [10, false], "fun7.5": [8, false], "fun8.1": [17, true], "fun8.2": [18, true], "fun8.3": [26, true], "fun8.4": [27, true], "fun8.5": [30, true], "fun9.1": [16, true], "fun9.2": [20, true], "fun9.3": [22, true], "fun9.4": [26, true], "fun9.5": [25, true]}}}, {"label": "gate.ratio.derived3.credit", "spec": ["pure", "ratio", "derived3", "credit", "x", "progress"], "APS": {"total": 6270, "solved": 153, "n": 154, "over": 0, "per": {"aps.01.00": [39, true], "aps.02.00": [35, true], "aps.02.01": [32, true], "aps.02.02": [44, true], "aps.02.03": [31, true], "aps.02.04": [32, true], "aps.02.05": [30, true], "aps.02.06": [32, true], "aps.02.07": [33, true], "aps.02.08": [35, true], "aps.02.09": [29, true], "aps.03.00": [48, true], "aps.03.01": [46, true], "aps.03.02": [46, true], "aps.04.00": [32, true], "aps.04.01": [44, true], "aps.04.02": [44, true], "aps.04.03": [36, true], "aps.04.04": [33, true], "aps.04.05": [33, true], "aps.04.06": [33, true], "aps.04.07": [35, true], "aps.04.08": [30, true], "aps.04.09": [36, true], "aps.04.10": [33, true], "aps.04.11": [36, true], "aps.04.12": [34, true], "aps.04.13": [36, true], "aps.05.00": [35, true], "aps.06.00": [26, true], "aps.06.01": [31, true], "aps.06.02": [35, true], "aps.06.03": [30, true], "aps.06.04": [33, true], "aps.06.05": [43, true], "aps.06.06": [43, true], "aps.06.07": [43, true], "aps.06.08": [43, true], "aps.06.09": [43, true], "aps.07.00": [30, true], "aps.07.01": [32, true], "aps.07.02": [40, true], "aps.08.00": [3, true], "aps.08.01": [37, true], "aps.08.02": [30, true], "aps.08.03": [34, true], "aps.08.04": [30, true], "aps.09.00": [33, true], "aps.09.01": [34, true], "aps.09.02": [33, true], "aps.09.03": [37, true], "aps.09.04": [33, true], "aps.09.05": [40, true], "aps.09.06": [34, true], "aps.10.00": [31, true], "aps.10.01": [42, true], "aps.10.02": [35, true], "aps.10.03": [32, true], "aps.10.04": [36, true], "aps.11.00": [32, true], "aps.11.01": [32, true], "aps.11.02": [43, true], "aps.11.03": [43, true], "aps.12.00": [31, true], "aps.12.01": [50, true], "aps.12.02": [32, true], "aps.12.03": [32, true], "aps.12.04": [32, true], "aps.12.05": [50, true], "aps.12.06": [32, true], "aps.12.07": [33, true], "aps.12.08": [35, true], "aps.12.09": [31, true], "aps.12.10": [32, true], "aps.12.11": [29, true], "aps.12.12": [32, true], "aps.12.13": [29, true], "aps.12.14": [29, true], "aps.12.15": [31, true], "aps.12.16": [30, true], "aps.12.17": [30, true], "aps.12.18": [29, true], "aps.13.00": [8, false], "aps.14.00": [40, true], "aps.14.01": [40, true], "aps.14.02": [40, true], "aps.14.03": [40, true], "aps.14.04": [40, true], "aps.14.05": [40, true], "aps.14.06": [40, true], "aps.14.07": [40, true], "aps.14.08": [40, true], "aps.14.09": [40, true], "aps.14.10": [40, true], "aps.14.11": [40, true], "aps.14.12": [40, true], "aps.14.13": [40, true], "aps.14.14": [40, true], "aps.14.15": [40, true], "aps.14.16": [40, true], "aps.14.17": [40, true], "aps.14.18": [40, true], "aps.14.19": [40, true], "aps.14.20": [40, true], "aps.14.21": [40, true], "aps.14.22": [42, true], "aps.14.23": [40, true], "aps.14.24": [40, true], "aps.14.25": [40, true], "aps.14.26": [40, true], "aps.14.27": [40, true], "aps.14.28": [40, true], "aps.14.29": [40, true], "aps.14.30": [40, true], "aps.14.31": [40, true], "aps.14.32": [40, true], "aps.14.33": [40, true], "aps.14.34": [40, true], "aps.14.35": [40, true], "aps.14.36": [40, true], "aps.14.37": [40, true], "aps.14.38": [40, true], "aps.14.39": [40, true], "aps.15.00": [51, true], "aps.15.01": [53, true], "aps.15.02": [51, true], "aps.15.03": [51, true], "aps.15.04": [51, true], "aps.15.05": [53, true], "aps.15.06": [52, true], "aps.15.07": [51, true], "aps.15.08": [53, true], "aps.15.09": [53, true], "aps.15.10": [50, true], "aps.15.11": [53, true], "aps.15.12": [53, true], "aps.15.13": [53, true], "aps.15.14": [51, true], "aps.15.15": [53, true], "aps.15.16": [53, true], "aps.15.17": [53, true], "aps.15.18": [53, true], "aps.15.19": [51, true], "aps.15.20": [53, true], "aps.15.21": [53, true], "aps.15.22": [53, true], "aps.15.23": [52, true], "aps.15.24": [53, true], "aps.15.25": [52, true], "aps.15.26": [52, true], "aps.15.27": [53, true], "aps.15.28": [52, true], "aps.15.29": [53, true], "aps.15.30": [53, true]}}, "CHA": {"total": 2961, "solved": 40, "n": 45, "over": 0, "per": {"fun1.1": [29, true], "fun1.2": [32, true], "fun1.3": [37, true], "fun1.4": [44, true], "fun1.5": [66, true], "fun2.1": [26, true], "fun2.2": [57, true], "fun2.3": [63, true], "fun2.4": [77, true], "fun2.5": [83, true], "fun3.1": [45, true], "fun3.2": [47, true], "fun3.3": [56, true], "fun3.4": [63, true], "fun3.5": [74, true], "fun4.1": [45, true], "fun4.2": [47, true], "fun4.3": [57, true], "fun4.4": [63, true], "fun4.5": [77, true], "fun5.1": [45, true], "fun5.2": [45, true], "fun5.3": [46, true], "fun5.4": [48, true], "fun5.5": [49, true], "fun6.1": [44, true], "fun6.2": [44, true], "fun6.3": [45, true], "fun6.4": [47, true], "fun6.5": [48, true], "fun7.1": [8, false], "fun7.2": [7, false], "fun7.3": [9, false], "fun7.4": [11, false], "fun7.5": [4, false], "fun8.1": [33, true], "fun8.2": [37, true], "fun8.3": [47, true], "fun8.4": [48, true], "fun8.5": [50, true], "fun9.1": [29, true], "fun9.2": [36, true], "fun9.3": [47, true], "fun9.4": [43, true], "fun9.5": [42, true]}}}, {"label": "gate.sqrt.derived.credit", "spec": ["pure", "sqrt", "derived", "credit", "x", "progress"], "APS": {"total": 7722, "solved": 153, "n": 154, "over": 0, "per": {"aps.01.00": [44, true], "aps.02.00": [45, true], "aps.02.01": [46, true], "aps.02.02": [46, true], "aps.02.03": [47, true], "aps.02.04": [47, true], "aps.02.05": [47, true], "aps.02.06": [47, true], "aps.02.07": [47, true], "aps.02.08": [48, true], "aps.02.09": [48, true], "aps.03.00": [49, true], "aps.03.01": [49, true], "aps.03.02": [49, true], "aps.04.00": [46, true], "aps.04.01": [46, true], "aps.04.02": [46, true], "aps.04.03": [46, true], "aps.04.04": [46, true], "aps.04.05": [46, true], "aps.04.06": [46, true], "aps.04.07": [46, true], "aps.04.08": [46, true], "aps.04.09": [46, true], "aps.04.10": [46, true], "aps.04.11": [46, true], "aps.04.12": [46, true], "aps.04.13": [46, true], "aps.05.00": [44, true], "aps.06.00": [43, true], "aps.06.01": [43, true], "aps.06.02": [43, true], "aps.06.03": [43, true], "aps.06.04": [43, true], "aps.06.05": [43, true], "aps.06.06": [43, true], "aps.06.07": [43, true], "aps.06.08": [43, true], "aps.06.09": [43, true], "aps.07.00": [43, true], "aps.07.01": [43, true], "aps.07.02": [43, true], "aps.08.00": [43, true], "aps.08.01": [43, true], "aps.08.02": [43, true], "aps.08.03": [43, true], "aps.08.04": [43, true], "aps.09.00": [43, true], "aps.09.01": [43, true], "aps.09.02": [43, true], "aps.09.03": [43, true], "aps.09.04": [43, true], "aps.09.05": [43, true], "aps.09.06": [43, true], "aps.10.00": [43, true], "aps.10.01": [43, true], "aps.10.02": [43, true], "aps.10.03": [43, true], "aps.10.04": [43, true], "aps.11.00": [43, true], "aps.11.01": [43, true], "aps.11.02": [43, true], "aps.11.03": [43, true], "aps.12.00": [50, true], "aps.12.01": [50, true], "aps.12.02": [50, true], "aps.12.03": [50, true], "aps.12.04": [50, true], "aps.12.05": [50, true], "aps.12.06": [50, true], "aps.12.07": [50, true], "aps.12.08": [50, true], "aps.12.09": [50, true], "aps.12.10": [50, true], "aps.12.11": [50, true], "aps.12.12": [50, true], "aps.12.13": [50, true], "aps.12.14": [50, true], "aps.12.15": [50, true], "aps.12.16": [50, true], "aps.12.17": [50, true], "aps.12.18": [50, true], "aps.13.00": [8, false], "aps.14.00": [53, true], "aps.14.01": [53, true], "aps.14.02": [53, true], "aps.14.03": [53, true], "aps.14.04": [53, true], "aps.14.05": [53, true], "aps.14.06": [53, true], "aps.14.07": [53, true], "aps.14.08": [53, true], "aps.14.09": [53, true], "aps.14.10": [53, true], "aps.14.11": [53, true], "aps.14.12": [53, true], "aps.14.13": [53, true], "aps.14.14": [53, true], "aps.14.15": [53, true], "aps.14.16": [53, true], "aps.14.17": [53, true], "aps.14.18": [53, true], "aps.14.19": [53, true], "aps.14.20": [53, true], "aps.14.21": [53, true], "aps.14.22": [53, true], "aps.14.23": [53, true], "aps.14.24": [53, true], "aps.14.25": [53, true], "aps.14.26": [53, true], "aps.14.27": [53, true], "aps.14.28": [53, true], "aps.14.29": [53, true], "aps.14.30": [53, true], "aps.14.31": [53, true], "aps.14.32": [53, true], "aps.14.33": [53, true], "aps.14.34": [53, true], "aps.14.35": [53, true], "aps.14.36": [53, true], "aps.14.37": [53, true], "aps.14.38": [53, true], "aps.14.39": [53, true], "aps.15.00": [53, true], "aps.15.01": [53, true], "aps.15.02": [53, true], "aps.15.03": [53, true], "aps.15.04": [53, true], "aps.15.05": [53, true], "aps.15.06": [53, true], "aps.15.07": [53, true], "aps.15.08": [53, true], "aps.15.09": [53, true], "aps.15.10": [53, true], "aps.15.11": [53, true], "aps.15.12": [53, true], "aps.15.13": [53, true], "aps.15.14": [53, true], "aps.15.15": [53, true], "aps.15.16": [53, true], "aps.15.17": [53, true], "aps.15.18": [53, true], "aps.15.19": [53, true], "aps.15.20": [53, true], "aps.15.21": [53, true], "aps.15.22": [53, true], "aps.15.23": [53, true], "aps.15.24": [53, true], "aps.15.25": [53, true], "aps.15.26": [53, true], "aps.15.27": [53, true], "aps.15.28": [53, true], "aps.15.29": [53, true], "aps.15.30": [53, true]}}, "CHA": {"total": 3130, "solved": 40, "n": 45, "over": 0, "per": {"fun1.1": [43, true], "fun1.2": [47, true], "fun1.3": [50, true], "fun1.4": [58, true], "fun1.5": [78, true], "fun2.1": [43, true], "fun2.2": [57, true], "fun2.3": [63, true], "fun2.4": [77, true], "fun2.5": [83, true], "fun3.1": [46, true], "fun3.2": [48, true], "fun3.3": [58, true], "fun3.4": [64, true], "fun3.5": [78, true], "fun4.1": [46, true], "fun4.2": [48, true], "fun4.3": [58, true], "fun4.4": [64, true], "fun4.5": [78, true], "fun5.1": [46, true], "fun5.2": [46, true], "fun5.3": [47, true], "fun5.4": [49, true], "fun5.5": [50, true], "fun6.1": [46, true], "fun6.2": [46, true], "fun6.3": [47, true], "fun6.4": [49, true], "fun6.5": [50, true], "fun7.1": [8, false], "fun7.2": [46, false], "fun7.3": [9, false], "fun7.4": [12, false], "fun7.5": [13, false], "fun8.1": [44, true], "fun8.2": [45, true], "fun8.3": [47, true], "fun8.4": [48, true], "fun8.5": [50, true], "fun9.1": [43, true], "fun9.2": [45, true], "fun9.3": [47, true], "fun9.4": [48, true], "fun9.5": [50, true]}}}, {"label": "gate.sqrt.derived3.credit", "spec": ["pure", "sqrt", "derived3", "credit", "x", "progress"], "APS": {"total": 7720, "solved": 153, "n": 154, "over": 0, "per": {"aps.01.00": [44, true], "aps.02.00": [45, true], "aps.02.01": [46, true], "aps.02.02": [46, true], "aps.02.03": [47, true], "aps.02.04": [47, true], "aps.02.05": [47, true], "aps.02.06": [47, true], "aps.02.07": [47, true], "aps.02.08": [48, true], "aps.02.09": [48, true], "aps.03.00": [49, true], "aps.03.01": [49, true], "aps.03.02": [49, true], "aps.04.00": [46, true], "aps.04.01": [46, true], "aps.04.02": [46, true], "aps.04.03": [46, true], "aps.04.04": [46, true], "aps.04.05": [46, true], "aps.04.06": [46, true], "aps.04.07": [46, true], "aps.04.08": [46, true], "aps.04.09": [46, true], "aps.04.10": [46, true], "aps.04.11": [46, true], "aps.04.12": [46, true], "aps.04.13": [46, true], "aps.05.00": [44, true], "aps.06.00": [43, true], "aps.06.01": [43, true], "aps.06.02": [43, true], "aps.06.03": [43, true], "aps.06.04": [43, true], "aps.06.05": [43, true], "aps.06.06": [43, true], "aps.06.07": [43, true], "aps.06.08": [43, true], "aps.06.09": [43, true], "aps.07.00": [43, true], "aps.07.01": [43, true], "aps.07.02": [43, true], "aps.08.00": [43, true], "aps.08.01": [43, true], "aps.08.02": [43, true], "aps.08.03": [43, true], "aps.08.04": [43, true], "aps.09.00": [43, true], "aps.09.01": [43, true], "aps.09.02": [43, true], "aps.09.03": [43, true], "aps.09.04": [43, true], "aps.09.05": [43, true], "aps.09.06": [41, true], "aps.10.00": [43, true], "aps.10.01": [43, true], "aps.10.02": [43, true], "aps.10.03": [43, true], "aps.10.04": [43, true], "aps.11.00": [43, true], "aps.11.01": [43, true], "aps.11.02": [43, true], "aps.11.03": [43, true], "aps.12.00": [50, true], "aps.12.01": [50, true], "aps.12.02": [50, true], "aps.12.03": [50, true], "aps.12.04": [50, true], "aps.12.05": [50, true], "aps.12.06": [50, true], "aps.12.07": [50, true], "aps.12.08": [50, true], "aps.12.09": [50, true], "aps.12.10": [50, true], "aps.12.11": [50, true], "aps.12.12": [50, true], "aps.12.13": [50, true], "aps.12.14": [50, true], "aps.12.15": [50, true], "aps.12.16": [50, true], "aps.12.17": [50, true], "aps.12.18": [50, true], "aps.13.00": [7, false], "aps.14.00": [53, true], "aps.14.01": [53, true], "aps.14.02": [53, true], "aps.14.03": [53, true], "aps.14.04": [53, true], "aps.14.05": [53, true], "aps.14.06": [53, true], "aps.14.07": [53, true], "aps.14.08": [53, true], "aps.14.09": [53, true], "aps.14.10": [53, true], "aps.14.11": [53, true], "aps.14.12": [53, true], "aps.14.13": [53, true], "aps.14.14": [53, true], "aps.14.15": [53, true], "aps.14.16": [53, true], "aps.14.17": [53, true], "aps.14.18": [53, true], "aps.14.19": [53, true], "aps.14.20": [53, true], "aps.14.21": [53, true], "aps.14.22": [53, true], "aps.14.23": [53, true], "aps.14.24": [53, true], "aps.14.25": [53, true], "aps.14.26": [53, true], "aps.14.27": [53, true], "aps.14.28": [53, true], "aps.14.29": [53, true], "aps.14.30": [53, true], "aps.14.31": [53, true], "aps.14.32": [53, true], "aps.14.33": [53, true], "aps.14.34": [53, true], "aps.14.35": [53, true], "aps.14.36": [53, true], "aps.14.37": [53, true], "aps.14.38": [53, true], "aps.14.39": [53, true], "aps.15.00": [53, true], "aps.15.01": [53, true], "aps.15.02": [53, true], "aps.15.03": [53, true], "aps.15.04": [53, true], "aps.15.05": [53, true], "aps.15.06": [53, true], "aps.15.07": [53, true], "aps.15.08": [53, true], "aps.15.09": [53, true], "aps.15.10": [53, true], "aps.15.11": [53, true], "aps.15.12": [53, true], "aps.15.13": [53, true], "aps.15.14": [53, true], "aps.15.15": [53, true], "aps.15.16": [53, true], "aps.15.17": [53, true], "aps.15.18": [53, true], "aps.15.19": [53, true], "aps.15.20": [53, true], "aps.15.21": [53, true], "aps.15.22": [53, true], "aps.15.23": [53, true], "aps.15.24": [53, true], "aps.15.25": [53, true], "aps.15.26": [53, true], "aps.15.27": [53, true], "aps.15.28": [53, true], "aps.15.29": [53, true], "aps.15.30": [53, true]}}, "CHA": {"total": 3094, "solved": 40, "n": 45, "over": 0, "per": {"fun1.1": [43, true], "fun1.2": [47, true], "fun1.3": [50, true], "fun1.4": [58, true], "fun1.5": [78, true], "fun2.1": [43, true], "fun2.2": [57, true], "fun2.3": [63, true], "fun2.4": [77, true], "fun2.5": [83, true], "fun3.1": [45, true], "fun3.2": [47, true], "fun3.3": [56, true], "fun3.4": [60, true], "fun3.5": [74, true], "fun4.1": [45, true], "fun4.2": [47, true], "fun4.3": [57, true], "fun4.4": [64, true], "fun4.5": [77, true], "fun5.1": [45, true], "fun5.2": [45, true], "fun5.3": [46, true], "fun5.4": [48, true], "fun5.5": [49, true], "fun6.1": [43, true], "fun6.2": [43, true], "fun6.3": [44, true], "fun6.4": [46, true], "fun6.5": [47, true], "fun7.1": [7, false], "fun7.2": [9, false], "fun7.3": [10, false], "fun7.4": [13, false], "fun7.5": [13, false], "fun8.1": [44, true], "fun8.2": [45, true], "fun8.3": [47, true], "fun8.4": [48, true], "fun8.5": [50, true], "fun9.1": [43, true], "fun9.2": [45, true], "fun9.3": [47, true], "fun9.4": [48, true], "fun9.5": [50, true]}}}, {"label": "gate.ratio.derived3.safe", "spec": ["pure", "ratio", "derived3", "safe", "x", "progress"], "APS": {"total": 8695, "solved": 153, "n": 154, "over": 0, "per": {"aps.01.00": [54, true], "aps.02.00": [54, true], "aps.02.01": [53, true], "aps.02.02": [68, true], "aps.02.03": [45, true], "aps.02.04": [51, true], "aps.02.05": [48, true], "aps.02.06": [66, true], "aps.02.07": [47, true], "aps.02.08": [48, true], "aps.02.09": [46, true], "aps.03.00": [82, true], "aps.03.01": [77, true], "aps.03.02": [79, true], "aps.04.00": [47, true], "aps.04.01": [67, true], "aps.04.02": [67, true], "aps.04.03": [56, true], "aps.04.04": [59, true], "aps.04.05": [54, true], "aps.04.06": [54, true], "aps.04.07": [54, true], "aps.04.08": [55, true], "aps.04.09": [34, true], "aps.04.10": [53, true], "aps.04.11": [42, true], "aps.04.12": [52, true], "aps.04.13": [54, true], "aps.05.00": [52, true], "aps.06.00": [49, true], "aps.06.01": [54, true], "aps.06.02": [56, true], "aps.06.03": [56, true], "aps.06.04": [56, true], "aps.06.05": [60, true], "aps.06.06": [62, true], "aps.06.07": [64, true], "aps.06.08": [63, true], "aps.06.09": [65, true], "aps.07.00": [58, true], "aps.07.01": [57, true], "aps.07.02": [63, true], "aps.08.00": [3, true], "aps.08.01": [55, true], "aps.08.02": [47, true], "aps.08.03": [47, true], "aps.08.04": [55, true], "aps.09.00": [60, true], "aps.09.01": [61, true], "aps.09.02": [58, true], "aps.09.03": [62, true], "aps.09.04": [53, true], "aps.09.05": [43, true], "aps.09.06": [44, true], "aps.10.00": [54, true], "aps.10.01": [57, true], "aps.10.02": [57, true], "aps.10.03": [47, true], "aps.10.04": [57, true], "aps.11.00": [43, true], "aps.11.01": [51, true], "aps.11.02": [54, true], "aps.11.03": [60, true], "aps.12.00": [58, true], "aps.12.01": [55, true], "aps.12.02": [55, true], "aps.12.03": [58, true], "aps.12.04": [57, true], "aps.12.05": [57, true], "aps.12.06": [43, true], "aps.12.07": [50, true], "aps.12.08": [52, true], "aps.12.09": [50, true], "aps.12.10": [49, true], "aps.12.11": [46, true], "aps.12.12": [52, true], "aps.12.13": [48, true], "aps.12.14": [45, true], "aps.12.15": [51, true], "aps.12.16": [52, true], "aps.12.17": [50, true], "aps.12.18": [48, true], "aps.13.00": [8, false], "aps.14.00": [55, true], "aps.14.01": [55, true], "aps.14.02": [55, true], "aps.14.03": [55, true], "aps.14.04": [55, true], "aps.14.05": [55, true], "aps.14.06": [55, true], "aps.14.07": [55, true], "aps.14.08": [55, true], "aps.14.09": [55, true], "aps.14.10": [55, true], "aps.14.11": [55, true], "aps.14.12": [55, true], "aps.14.13": [55, true], "aps.14.14": [55, true], "aps.14.15": [55, true], "aps.14.16": [55, true], "aps.14.17": [55, true], "aps.14.18": [55, true], "aps.14.19": [55, true], "aps.14.20": [55, true], "aps.14.21": [55, true], "aps.14.22": [55, true], "aps.14.23": [55, true], "aps.14.24": [55, true], "aps.14.25": [55, true], "aps.14.26": [55, true], "aps.14.27": [55, true], "aps.14.28": [55, true], "aps.14.29": [55, true], "aps.14.30": [55, true], "aps.14.31": [55, true], "aps.14.32": [55, true], "aps.14.33": [55, true], "aps.14.34": [55, true], "aps.14.35": [55, true], "aps.14.36": [55, true], "aps.14.37": [55, true], "aps.14.38": [55, true], "aps.14.39": [55, true], "aps.15.00": [63, true], "aps.15.01": [64, true], "aps.15.02": [63, true], "aps.15.03": [64, true], "aps.15.04": [64, true], "aps.15.05": [62, true], "aps.15.06": [59, true], "aps.15.07": [61, true], "aps.15.08": [61, true], "aps.15.09": [57, true], "aps.15.10": [50, true], "aps.15.11": [64, true], "aps.15.12": [63, true], "aps.15.13": [65, true], "aps.15.14": [65, true], "aps.15.15": [65, true], "aps.15.16": [63, true], "aps.15.17": [61, true], "aps.15.18": [56, true], "aps.15.19": [60, true], "aps.15.20": [56, true], "aps.15.21": [64, true], "aps.15.22": [64, true], "aps.15.23": [57, true], "aps.15.24": [58, true], "aps.15.25": [55, true], "aps.15.26": [55, true], "aps.15.27": [61, true], "aps.15.28": [57, true], "aps.15.29": [55, true], "aps.15.30": [58, true]}}, "CHA": {"total": 3254, "solved": 40, "n": 45, "over": 0, "per": {"fun1.1": [47, true], "fun1.2": [56, true], "fun1.3": [58, true], "fun1.4": [65, true], "fun1.5": [84, true], "fun2.1": [41, true], "fun2.2": [54, true], "fun2.3": [74, true], "fun2.4": [87, true], "fun2.5": [81, true], "fun3.1": [45, true], "fun3.2": [47, true], "fun3.3": [56, true], "fun3.4": [64, true], "fun3.5": [74, true], "fun4.1": [45, true], "fun4.2": [47, true], "fun4.3": [57, true], "fun4.4": [63, true], "fun4.5": [77, true], "fun5.1": [45, true], "fun5.2": [45, true], "fun5.3": [46, true], "fun5.4": [48, true], "fun5.5": [49, true], "fun6.1": [44, true], "fun6.2": [44, true], "fun6.3": [45, true], "fun6.4": [47, true], "fun6.5": [48, true], "fun7.1": [8, false], "fun7.2": [7, false], "fun7.3": [8, false], "fun7.4": [45, false], "fun7.5": [4, false], "fun8.1": [53, true], "fun8.2": [55, true], "fun8.3": [53, true], "fun8.4": [61, true], "fun8.5": [62, true], "fun9.1": [55, true], "fun9.2": [58, true], "fun9.3": [56, true], "fun9.4": [59, true], "fun9.5": [59, true]}}}, {"label": "gate.sqrt.derived.safe", "spec": ["pure", "sqrt", "derived", "safe", "x", "progress"], "APS": {"total": 11330, "solved": 153, "n": 154, "over": 0, "per": {"aps.01.00": [61, true], "aps.02.00": [61, true], "aps.02.01": [64, true], "aps.02.02": [63, true], "aps.02.03": [64, true], "aps.02.04": [65, true], "aps.02.05": [65, true], "aps.02.06": [66, true], "aps.02.07": [67, true], "aps.02.08": [68, true], "aps.02.09": [69, true], "aps.03.00": [88, true], "aps.03.01": [83, true], "aps.03.02": [69, true], "aps.04.00": [74, true], "aps.04.01": [64, true], "aps.04.02": [83, true], "aps.04.03": [64, true], "aps.04.04": [64, true], "aps.04.05": [63, true], "aps.04.06": [69, true], "aps.04.07": [64, true], "aps.04.08": [65, true], "aps.04.09": [65, true], "aps.04.10": [65, true], "aps.04.11": [63, true], "aps.04.12": [63, true], "aps.04.13": [63, true], "aps.05.00": [60, true], "aps.06.00": [59, true], "aps.06.01": [59, true], "aps.06.02": [64, true], "aps.06.03": [77, true], "aps.06.04": [59, true], "aps.06.05": [62, true], "aps.06.06": [62, true], "aps.06.07": [58, true], "aps.06.08": [61, true], "aps.06.09": [57, true], "aps.07.00": [81, true], "aps.07.01": [81, true], "aps.07.02": [81, true], "aps.08.00": [3, true], "aps.08.01": [59, true], "aps.08.02": [73, true], "aps.08.03": [59, true], "aps.08.04": [60, true], "aps.09.00": [59, true], "aps.09.01": [62, true], "aps.09.02": [81, true], "aps.09.03": [81, true], "aps.09.04": [81, true], "aps.09.05": [81, true], "aps.09.06": [81, true], "aps.10.00": [59, true], "aps.10.01": [68, true], "aps.10.02": [60, true], "aps.10.03": [60, true], "aps.10.04": [60, true], "aps.11.00": [78, true], "aps.11.01": [60, true], "aps.11.02": [60, true], "aps.11.03": [60, true], "aps.12.00": [62, true], "aps.12.01": [70, true], "aps.12.02": [67, true], "aps.12.03": [68, true], "aps.12.04": [74, true], "aps.12.05": [89, true], "aps.12.06": [73, true], "aps.12.07": [69, true], "aps.12.08": [73, true], "aps.12.09": [69, true], "aps.12.10": [69, true], "aps.12.11": [69, true], "aps.12.12": [69, true], "aps.12.13": [69, true], "aps.12.14": [80, true], "aps.12.15": [87, true], "aps.12.16": [89, true], "aps.12.17": [81, true], "aps.12.18": [73, true], "aps.13.00": [45, false], "aps.14.00": [87, true], "aps.14.01": [87, true], "aps.14.02": [87, true], "aps.14.03": [87, true], "aps.14.04": [87, true], "aps.14.05": [87, true], "aps.14.06": [87, true], "aps.14.07": [87, true], "aps.14.08": [87, true], "aps.14.09": [87, true], "aps.14.10": [87, true], "aps.14.11": [87, true], "aps.14.12": [87, true], "aps.14.13": [87, true], "aps.14.14": [87, true], "aps.14.15": [87, true], "aps.14.16": [87, true], "aps.14.17": [87, true], "aps.14.18": [87, true], "aps.14.19": [87, true], "aps.14.20": [87, true], "aps.14.21": [87, true], "aps.14.22": [87, true], "aps.14.23": [87, true], "aps.14.24": [87, true], "aps.14.25": [87, true], "aps.14.26": [87, true], "aps.14.27": [87, true], "aps.14.28": [87, true], "aps.14.29": [87, true], "aps.14.30": [87, true], "aps.14.31": [87, true], "aps.14.32": [87, true], "aps.14.33": [87, true], "aps.14.34": [87, true], "aps.14.35": [87, true], "aps.14.36": [87, true], "aps.14.37": [87, true], "aps.14.38": [87, true], "aps.14.39": [87, true], "aps.15.00": [64, true], "aps.15.01": [64, true], "aps.15.02": [64, true], "aps.15.03": [64, true], "aps.15.04": [64, true], "aps.15.05": [64, true], "aps.15.06": [65, true], "aps.15.07": [67, true], "aps.15.08": [72, true], "aps.15.09": [76, true], "aps.15.10": [77, true], "aps.15.11": [77, true], "aps.15.12": [75, true], "aps.15.13": [73, true], "aps.15.14": [71, true], "aps.15.15": [70, true], "aps.15.16": [68, true], "aps.15.17": [67, true], "aps.15.18": [67, true], "aps.15.19": [66, true], "aps.15.20": [66, true], "aps.15.21": [65, true], "aps.15.22": [74, true], "aps.15.23": [62, true], "aps.15.24": [63, true], "aps.15.25": [73, true], "aps.15.26": [75, true], "aps.15.27": [63, true], "aps.15.28": [62, true], "aps.15.29": [62, true], "aps.15.30": [62, true]}}, "CHA": {"total": 3867, "solved": 40, "n": 45, "over": 0, "per": {"fun1.1": [61, true], "fun1.2": [65, true], "fun1.3": [73, true], "fun1.4": [106, true], "fun1.5": [116, true], "fun2.1": [78, true], "fun2.2": [76, true], "fun2.3": [102, true], "fun2.4": [95, true], "fun2.5": [120, true], "fun3.1": [53, true], "fun3.2": [55, true], "fun3.3": [75, true], "fun3.4": [88, true], "fun3.5": [85, true], "fun4.1": [55, true], "fun4.2": [57, true], "fun4.3": [68, true], "fun4.4": [75, true], "fun4.5": [89, true], "fun5.1": [61, true], "fun5.2": [62, true], "fun5.3": [65, true], "fun5.4": [68, true], "fun5.5": [69, true], "fun6.1": [48, true], "fun6.2": [53, true], "fun6.3": [57, true], "fun6.4": [59, true], "fun6.5": [60, true], "fun7.1": [45, false], "fun7.2": [9, false], "fun7.3": [11, false], "fun7.4": [15, false], "fun7.5": [16, false], "fun8.1": [82, true], "fun8.2": [64, true], "fun8.3": [65, true], "fun8.4": [76, true], "fun8.5": [69, true], "fun9.1": [59, true], "fun9.2": [62, true], "fun9.3": [63, true], "fun9.4": [66, true], "fun9.5": [67, true]}}}, {"label": "gate.sqrt.derived3.safe", "spec": ["pure", "sqrt", "derived3", "safe", "x", "progress"], "APS": {"total": 9470, "solved": 153, "n": 154, "over": 0, "per": {"aps.01.00": [60, true], "aps.02.00": [60, true], "aps.02.01": [61, true], "aps.02.02": [62, true], "aps.02.03": [67, true], "aps.02.04": [81, true], "aps.02.05": [65, true], "aps.02.06": [64, true], "aps.02.07": [64, true], "aps.02.08": [63, true], "aps.02.09": [76, true], "aps.03.00": [66, true], "aps.03.01": [66, true], "aps.03.02": [66, true], "aps.04.00": [60, true], "aps.04.01": [60, true], "aps.04.02": [61, true], "aps.04.03": [61, true], "aps.04.04": [61, true], "aps.04.05": [64, true], "aps.04.06": [61, true], "aps.04.07": [61, true], "aps.04.08": [61, true], "aps.04.09": [62, true], "aps.04.10": [60, true], "aps.04.11": [60, true], "aps.04.12": [60, true], "aps.04.13": [61, true], "aps.05.00": [60, true], "aps.06.00": [60, true], "aps.06.01": [59, true], "aps.06.02": [60, true], "aps.06.03": [60, true], "aps.06.04": [60, true], "aps.06.05": [61, true], "aps.06.06": [62, true], "aps.06.07": [62, true], "aps.06.08": [61, true], "aps.06.09": [61, true], "aps.07.00": [59, true], "aps.07.01": [60, true], "aps.07.02": [64, true], "aps.08.00": [3, true], "aps.08.01": [58, true], "aps.08.02": [55, true], "aps.08.03": [58, true], "aps.08.04": [59, true], "aps.09.00": [59, true], "aps.09.01": [59, true], "aps.09.02": [62, true], "aps.09.03": [75, true], "aps.09.04": [55, true], "aps.09.05": [70, true], "aps.09.06": [42, true], "aps.10.00": [59, true], "aps.10.01": [56, true], "aps.10.02": [56, true], "aps.10.03": [58, true], "aps.10.04": [57, true], "aps.11.00": [69, true], "aps.11.01": [60, true], "aps.11.02": [57, true], "aps.11.03": [60, true], "aps.12.00": [68, true], "aps.12.01": [68, true], "aps.12.02": [68, true], "aps.12.03": [70, true], "aps.12.04": [71, true], "aps.12.05": [71, true], "aps.12.06": [70, true], "aps.12.07": [70, true], "aps.12.08": [70, true], "aps.12.09": [69, true], "aps.12.10": [69, true], "aps.12.11": [69, true], "aps.12.12": [69, true], "aps.12.13": [70, true], "aps.12.14": [69, true], "aps.12.15": [69, true], "aps.12.16": [69, true], "aps.12.17": [68, true], "aps.12.18": [69, true], "aps.13.00": [7, false], "aps.14.00": [64, true], "aps.14.01": [64, true], "aps.14.02": [64, true], "aps.14.03": [64, true], "aps.14.04": [64, true], "aps.14.05": [64, true], "aps.14.06": [64, true], "aps.14.07": [64, true], "aps.14.08": [64, true], "aps.14.09": [64, true], "aps.14.10": [64, true], "aps.14.11": [64, true], "aps.14.12": [64, true], "aps.14.13": [64, true], "aps.14.14": [64, true], "aps.14.15": [64, true], "aps.14.16": [64, true], "aps.14.17": [64, true], "aps.14.18": [64, true], "aps.14.19": [64, true], "aps.14.20": [64, true], "aps.14.21": [64, true], "aps.14.22": [64, true], "aps.14.23": [64, true], "aps.14.24": [64, true], "aps.14.25": [64, true], "aps.14.26": [64, true], "aps.14.27": [64, true], "aps.14.28": [64, true], "aps.14.29": [64, true], "aps.14.30": [64, true], "aps.14.31": [64, true], "aps.14.32": [64, true], "aps.14.33": [64, true], "aps.14.34": [64, true], "aps.14.35": [64, true], "aps.14.36": [64, true], "aps.14.37": [64, true], "aps.14.38": [64, true], "aps.14.39": [64, true], "aps.15.00": [54, true], "aps.15.01": [52, true], "aps.15.02": [51, true], "aps.15.03": [51, true], "aps.15.04": [51, true], "aps.15.05": [51, true], "aps.15.06": [51, true], "aps.15.07": [51, true], "aps.15.08": [51, true], "aps.15.09": [51, true], "aps.15.10": [51, true], "aps.15.11": [51, true], "aps.15.12": [51, true], "aps.15.13": [51, true], "aps.15.14": [50, true], "aps.15.15": [50, true], "aps.15.16": [50, true], "aps.15.17": [50, true], "aps.15.18": [50, true], "aps.15.19": [50, true], "aps.15.20": [50, true], "aps.15.21": [52, true], "aps.15.22": [49, true], "aps.15.23": [50, true], "aps.15.24": [51, true], "aps.15.25": [60, true], "aps.15.26": [47, true], "aps.15.27": [53, true], "aps.15.28": [51, true], "aps.15.29": [52, true], "aps.15.30": [51, true]}}, "CHA": {"total": 3446, "solved": 40, "n": 45, "over": 0, "per": {"fun1.1": [64, true], "fun1.2": [59, true], "fun1.3": [67, true], "fun1.4": [75, true], "fun1.5": [95, true], "fun2.1": [60, true], "fun2.2": [77, true], "fun2.3": [81, true], "fun2.4": [95, true], "fun2.5": [101, true], "fun3.1": [45, true], "fun3.2": [47, true], "fun3.3": [54, true], "fun3.4": [61, true], "fun3.5": [75, true], "fun4.1": [45, true], "fun4.2": [47, true], "fun4.3": [57, true], "fun4.4": [63, true], "fun4.5": [77, true], "fun5.1": [45, true], "fun5.2": [45, true], "fun5.3": [46, true], "fun5.4": [48, true], "fun5.5": [49, true], "fun6.1": [43, true], "fun6.2": [43, true], "fun6.3": [44, true], "fun6.4": [46, true], "fun6.5": [47, true], "fun7.1": [7, false], "fun7.2": [9, false], "fun7.3": [11, false], "fun7.4": [15, false], "fun7.5": [16, false], "fun8.1": [60, true], "fun8.2": [61, true], "fun8.3": [53, true], "fun8.4": [66, true], "fun8.5": [69, true], "fun9.1": [60, true], "fun9.2": [62, true], "fun9.3": [63, true], "fun9.4": [65, true], "fun9.5": [86, true]}}}] \ No newline at end of file diff --git a/tests/test_prestep_gate.py b/tests/test_prestep_gate.py new file mode 100644 index 0000000..328c7ed --- /dev/null +++ b/tests/test_prestep_gate.py @@ -0,0 +1,91 @@ +"""Implementation gates R1-R4 for the pre-step gate (PREREG_prestep_gate_2026-09-21.md). + +The measured cause of our cost is that the safeguard REPAIRS 77.5 % of evaluations after +the fact, while Chandrupatla REFUSES its model for free on 72 % of steps and halves +instead. The gate under test asks, BEFORE spending an evaluation, whether the similarity +step promises at least what bisection would remove — a comparison of two lengths already +in hand, no threshold and no new constant. +""" + +from __future__ import annotations + +import inspect +import math +import re + +import pytest + +from simroot import pure as P + +PROBLEMS = [ + (lambda t: t ** 3 - 2.0 * t - 5.0, 2.0, 3.0), + (lambda t: math.exp(t) - 5.0, 0.0, 3.0), + (lambda t: t ** 2 - 2.0, 0.5, 2.0), + (lambda t: math.cos(t) - t, 0.0, 1.0), + (lambda t: (t - 1.0) ** 3, -1.0, 4.0), +] + + +def test_R1_the_published_path_is_bit_identical_with_the_gate_off(): + for f, a, b in PROBLEMS: + for guard in ("credit", "project", "safe", "step"): + base = P.pure_root(f, a, b, 1e-12, 300, similarity="ratio", + scale="derived3", guard=guard) + off = P.pure_root(f, a, b, 1e-12, 300, similarity="ratio", + scale="derived3", guard=guard, prestep="none") + assert base == off, (guard, base, off) + + +def test_R2_the_gate_carries_no_chosen_constant(): + src = inspect.getsource(P.pure_root) + start = src.index('if prestep == "progress":') + end = src.index('if step is None and space ==', start) # the gate block only + body = src[start:end] + # comments carry the MEASURED numbers that justify the gate (77.5 %, 2.310 halvings); + # they are documentation, not constants, so the check reads the code only + code = "\n".join(line.split("#", 1)[0] for line in body.splitlines()) + literals = set(re.findall(r"(? 29 evaluations. Whether + that trade pays over the two benchmark sets is exactly what P2/P3 measure; a unit test + must not pre-judge it.""" + for f, a, b in PROBLEMS: + st = {} + _x, n, ok = P.pure_root(f, a, b, 1e-12, 300, similarity="ratio", scale="derived3", + guard="credit", prestep="progress", stats=st) + assert ok + # every evaluation is one step (the gate spends the same probe on the midpoint), + # plus f(a) and f(b) + assert st["pre_refused"] <= n - 2, (st, n) + + +def test_R4_refusals_are_counted_separately_from_repairs(): + st = {} + f = PROBLEMS[4][0] + x, n, ok = P.pure_root(f, -1.0, 4.0, 1e-10, 300, similarity="ratio", scale="derived3", + guard="credit", prestep="progress", stats=st) + assert ok and abs(x - 1.0) < 1e-3 + assert set(("forced", "pre_refused")) <= set(st) + assert st["pre_refused"] >= 1 # a cubic with a triple root refuses often + assert isinstance(st["forced"], int) and isinstance(st["pre_refused"], int) + + +def test_the_gate_is_validated_not_silently_ignored(): + with pytest.raises(ValueError): + P.pure_root(lambda t: t, -1.0, 1.0, 1e-10, 100, prestep="whatever") + + +def test_the_gate_still_solves_every_probe_problem(): + for f, a, b in PROBLEMS: + x, n, ok = P.pure_root(f, a, b, 1e-12, 300, similarity="ratio", scale="derived3", + guard="credit", prestep="progress") + assert ok and abs(f(x)) < 1e-6, (a, b, x, n, ok)