STEP 1631 — invariance-checker v0.1
1. 契機
chat-Claude 2026-08-31 「三つの候補を挙げるが、 最初の一枚を出すのが (1) 表現不変性チェッカーになる。 同じ問いを別の同値関係で再符号化した時、 モデルの結論が保存されるか。 空 (śūnyatā) を思想ではなく test として実装する骨。」
3 候補 (invariance / discard-log / falsification-gate) のうち、 時間の物理 (最短で一枚のテーブルが出る)、 既存部品 (STEP 1371/1376/1379 primitive の domain wrap)、 候補競合なし (paraphrase robustness は先行あるが 「商空間の取り替え」 として定式化した先行なし) の 3 理由で (1) を採択。
2. 実装
2.1 モジュール構成 src/aios/invariance-checker/
types.ts— EquivalenceRelation / ModelAnswer / AnswerEquivalence / 3 payload / erroranswer-equivalence.ts— 3 built-in comparator:exactMatch/numericMatch/setMatchinvariance-verdict.ts—singleInvarianceVerdict/aggregateInvarianceVerdict/statisticalInvarianceVerdict/binomialOneTailedLowerindex.ts— public API
2.2 依存 (既存 primitive の domain wrap)
mapMultiTrialToD8(STEP 1371、 BH-FDR aggregate) — statistical wrapper で delegateseven-logic.ts— 8 値定義- 循環依存 なし
2.3 決定表 I (per-pair、 first-match)
| # | Condition | Verdict | Reason |
|---|---|---|---|
| I1 | comparator not provided | NEITHER N | comparator_not_set |
| I2a | equivalent=null, reason=both_answers_absent | ZERO 〇 | both_answers_absent |
| I2b | equivalent=null (それ以外) | NEITHER N | <comparator reason preserved> |
| I3 | equivalent=true | TRUE ⊤ | invariant_preserved:<reason> |
| I4 | equivalent=false | FALSE ⊥ | invariance_violated:<reason> |
| I5 | comparator threw | NEITHER N | comparator_threw:<msg> |
2.4 決定表 A (aggregate, per-problem × K transforms)
| # | Condition | Verdict | Reason |
|---|---|---|---|
| A0 | K = 0 | ZERO 〇 | no_transforms |
| A1 | trueCount = K | TRUE ⊤ | invariant_holds_across_all |
| A2 | falseCount = K | FALSE ⊥ | invariance_fails_across_all |
| A3 | trueCount > 0 かつ falseCount > 0 | BOTH B | partial_invariance |
| A4 | zeroCount = K | ZERO 〇 | all_pairs_absent |
| A5 | 全 NEITHER (+ 任意 ZERO)、 T/F なし | NEITHER N | insufficient_evidence |
| A6 ★ | T > 0、 F = 0、 NEITHER あり | NEITHER N | partial_evidence_no_violation |
| A7 ★ | F > 0、 T = 0、 NEITHER あり | FALSE ⊥ | violation_with_partial_evidence |
A6/A7 の非対称性: 一つの反例で FALSE、 だが 「T のみ + 一部 NEITHER」 は TRUE ではなく NEITHER に降格。 Popper 的 asymmetry の直接実装 (証拠不足で反例なし ≠ 不変性成立)。
3. 統計 wrapper (stochastic model)
statisticalInvarianceVerdict は 1 pair に対して N 個の (before, after) sample を受け取り:
- 各 sample に comparator 適用 → equivalent k 個、 not-equivalent (n-k) 個、 判定不能 = invalid
- 一側 exact binomial:
p = P(X ≤ k | n, 0.5)— H0: 「等価率は偶然以上」 を左裾で棄却 - 得た単一 p-value を
mapMultiTrialToD8(STEP 1371) に 1 件だけ渡して delegate - ZERO は「入力あり かつ 全 invalid」 なら NEITHER に降格
多問題横断 BH-FDR aggregate は caller 側で: 各 (problem × relation) の pValue を集めて mapMultiTrialToD8({trials, fdrQ, alpha}) に直接投げる。 v0.1 primitive は 一段目 まで。
4. 順序原則 (定数化禁止)
alpha/fdrQ/absTolerance/relToleranceは 引数注入強制、 module 内定数化禁止EquivalenceRelation.asserterfield で 「誰が この pair を等価と主張したか」 を記録 (self/peer-review/oracle/undecided)、 v0.1 は marker のみ- Comparator 未指定 (I1) と tolerance 未指定 (numericMatch) は 両方 NEITHER で abstain —
feedback_one_reproduction_over_ten_unverified継承
5. Test
npm run test:step1631 — 48/48 PASS (8 section):
- exactMatch (case sensitivity + normalize + null absence)
- numericMatch (tolerance 未設定 discipline + abs/rel + text-extract + provided-numeric priority)
- setMatch (unordered + size differ + empty tokens + token-normalize)
- singleInvarianceVerdict I1-I5 全 rule + invalid-input
- aggregateInvarianceVerdict A0-A7 全 rule (非対称 A6/A7 含む)
- binomialOneTailedLower (k=0, k=n/2, k=n, n=0 の boundary)
- statisticalInvarianceVerdict (comparator absent / 10/10 equivalent → FALSE / 0/10 → TRUE / 全 invalid / fdrQ missing)
- spec table dump + honestScope 確認
6. 反証条件 (Popper self-application)
本 primitive が 偽である と言える条件:
- Comparator に恒等 pair (before=after) を投入したのに TRUE 以外を返す
- 完全 mismatch pair (無関係な文字列) に exact-match comparator が TRUE を返す
mapSamplePairToD8/mapMultiTrialToD8の decision table と矛盾する verdictstatisticalInvarianceVerdictの p-value が閉じた区間 [0, 1] を逸脱
(1)(2) は test Section 1-3 で cover、 (3)(4) は Section 6-7 で cover。 全 48 test PASS で 全 4 反証条件が 現時点で 発火せず。
7. Honest scope (v0.1)
- Primitive は 「答え A と答え B が来た。 comparator が こう言った」 まで の主張のみ。 「本当に この二つは等価か」 の judgment は primitive 外
- LLM 呼出 layer は 実装しない (別 STEP)
- Transformation library (問題書換機械) は 実装しない (別 STEP)
- Semantic equivalence (LLM-as-judge / embedding) は v0.1 scope 外
- v0.1 activate 4-5/8 値 (TRUE / FALSE / NEITHER / ZERO / BOTH)。 INFINITY / FLOWING / SELF は 予約
- Aggregate A6 の 「T + NEITHER → NEITHER 降格」 は 意図的 (Popper asymmetry)、 「T + NEITHER = TRUE」 が欲しい場合は別 aggregator
8. Next
- STEP 1632+ candidate: LLM 呼出 layer (Ollama / Claude API / OpenAI) を 追加、 GSM8K/MATH/HumanEval 100 問 × 3 変換 × 3 モデル の first empirical run
- STEP 1633+ candidate: transformation library (variable rename / algebraic normalize / natural↔formal / temporal shift)
- STEP 1634+ candidate: LLM-as-judge comparator (self-referential ゆえ discipline 必要、 陰性対照必須)
- rei-preregister (STEP 1359) 連携 — alpha / fdrQ / relation の 「先に決めた」 evidence chain 記録