Files
sim-numerics/PREREG_prestep_gate_2026-09-21.md

70 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` с логом; замороженная копия скрипта; числа показываются немедленно.