YONAPO RESEARCH
研究記録
MedDSL(仮称)

RESEARCH / RECORD

MedDSL(仮称)独立確認・レビューAI-001

追加検査(AI-001):compare 経路・split_roles・Python 3.11

原文 docs/research/18-additional-checks-ai-001.md

11 KB

GitHubで見る

版 be280c0

この文書の目次 5項目

作成日:2026-10-19。契約版:p0-draft-2。状態:AI-001 の単独・内部実施の追加検査。独立レビューではない。完了記録 17 の §8 に挙げた未確認点のうち、次の三つを埋めた記録です。実装と契約は変更していません(新しいテストと補助モジュールを加えただけ)。

未確認点(17 の §8) 結果
P0 比較(compare.py)の変異検査 実施。27変異(compare.py 20、validate_compare 7)、すべて検出。欠陥は見つからず、検査の見逃し4件を追加の検査で閉じた(§1)
事象の split_roles 診断経路の乱数検査 実施。誤った役割結合を200ケースで検出し、独立オラクルと一致。欠陥なし(§2)
Python 3.11 での実行 実施。3.11.17 で全系列・評価・監査が通り、全131例の結果が 3.14 と同一(§3)

追加したもの(すべて tests/review/、レビュー系列。固定済みの169ファイルと231テストの分母には加えない):reference_oracle.py(独立オラクルと生成器)、test_compare_paths.py(6テスト)、test_event_paths.py(6テスト)。レビュー系列は 40 → 52 テスト。

1. compare 経路(喪失・追加・比較不能・根拠・予算の共有)

方法

独立オラクル(reference_oracle.py)は、PO04 の集合定義(可視・確認済み・訂正・採用・未知能力)、単項 Horn の不動点、全探索の結合を、実装の関数を使わずに書き直したものです。これで前後それぞれの回答を計算し、compare の各行を次のとおり導いて照合します。

項目 オラクルの期待
比較不能 片側でも conflict/unassessed なら incomparable。差分・共通・根拠は null。理由に側付きの状態(before_conflict 等)。incomplete に列挙
喪失・追加・共通 支持された binding の集合の差・積。supported 以外は空集合。undetermined/opposed の行も「差分なし」と断言せず、状態を両側に返す
順序 結果は query ID の順(入力の順に依らない)。各リストは binding の辞書順
根拠 lost_evidence は前、added_evidence は後の台帳の参照。各根拠は採用された主張だけで構成され、その主張・確認だけで同じ binding が支持される(根拠の十分性を、最小の台帳で再計算して確認)
文脈の対応 後側の文脈の別名と context_map の組(211ケース)で、before_context_ref/after_context_ref が正しい
入力の hash・参照 各側の snapshot_sha256、package_ref、ledger_ref
予算 左右で一つの予算を共有する。全予算で、完了した行は無制限実行と同一。完了できなかった行は差分なしにせず、step_limit を理由に挙げる

400ケースの生成器は、前の台帳に削除・確度や符号の変更・新規の追加を加えて後の台帳を作り、台帳にある atom から問い合わせを作るので、前後の答えが重なります。衝突の経路を通すため、一部に確認済みの肯定と否定を共存させます。生成された2,120行(compared 1,768、incomparable 352)のうち、喪失あり27・追加あり11・共通あり33、before_conflict 111・after_conflict 116・before_unassessed 105・after_unassessed 121 と、各分岐を実際に通ります(テストが各分岐の回数を要求)。

結果

400ケースで実装とオラクルは一致し、欠陥は見つからなかった。そのほか、前後を入れ替えると喪失と追加が入れ替わる、同じ snapshot を両側に置くと差分がない、という性質も確認した。

27変異の検出:既存のテストと固定例が23件を検出し、4件を見逃していた(追加のテストが検出)。

変異 内容 見逃しの意味
C14 後側の snapshot_sha256 に前側の hash を入れる 結果が指す入力の hash を取り違えても検出されない
C16 理由コードの重複除去・整列をやめる 比較不能の理由の形が変わっても検出されない
C19 返す view を空にする 比較した参照時点が結果に残らなくても検出されない
C20 後側の package_ref を別の値にする 同上(パッケージの参照)

いずれも比較の意味(喪失・追加)には影響せず、結果の記録の完全性に関わる S2 相当の見逃しだった。追加のテストで閉じた。なお、validate_compare の7変異(文脈の再定義・対応の不一致・非単射・重複・未解決の対応、台帳参照の再定義、述語の再定義)は既存のテストが検出していた。

2. split_roles(誤った役割結合)

split_roles は、四役割を別々の事象から取る既知の誤訳です(comparison.certificate は常に不認定)。次の性質を200ケースで確認した。

性質 結果
旧(legacy)・正しい翻訳・split_roles の三つの結果が、独立オラクルの三つの期待(split_roles は役割ごとの値の直積)と一致 一致(ずれ 0)
正しい翻訳の binding は split_roles に残る(喪失なし)。追加された binding が反例 成立。反例の集合はオラクルの「追加された binding」と完全に一致(過不足 0)
反例の型(truth_in_listed_model、旧は偽、正しい翻訳は偽、誤訳は真) 全反例で一致
反例があれば理由は satisfaction_condition_failed、なければ unsupported_translation。常に not_certified 一致
事象が一つしかなければ役割を混ぜられず、反例は出ない 30ケースで確認
正しい翻訳(shared_event)は反例を出さず、常に不認定(有限照合のため) 80ケースで確認
打切り(行が積で増える)では、認定も反例の断定も出さず unassessed 16ケース

生成器は、別々の四つ組の値を混ぜた問い合わせを意図的に作る。200ケースのうち184が完了し、88で実際に誤った結合が起き、すべて検出された(16は資源上限で未評価)。

加えて、鎖の認定について:(1) 乱数200ケースで、認定は「すべての答えが完了(支持・未決・否定)」と一致(認定100超、不認定10超で空振りでない)。(2) 誤訳を主張する票(split_roles の翻訳後 Q 範囲の hash を、両段で整合させて入れた票)は、段の接続検査を通っても、実体からの再計算で stage_1.target_scope_sha256 と stage_2.source_scope_sha256 が不一致になり不認定になる。

検出力(変異検査)

役割結合に関わる9変異(native の事象化で役割ごとに別の事象にする W1、全関係で一つの事象を共有する W2、内部変数を公開 binding に漏らす W4、split_roles を正しい翻訳に変える S2、反例の型・理由・認定・出力の取り違え S7〜S11)はすべて検出された。S7(split_roles なら常に satisfaction_condition_failed にする)は、追加のテストだけが検出した(既存のテストは見逃していた)。

限界

  • split_roles は事象ごとに四つの変数を持つので、行が積で増える。大きな履歴では上限に達して unassessed になり、診断として使えない(上の16ケース)。診断は小さな例のための道具である。
  • 反例は「指定した有限の履歴の listed model」の意味での真偽で、任意のモデルでの誤りの証明ではない。

3. Python 3.11(対応下限)での再現

環境

項目 内容
インタプリタ Python 3.11.17。micromamba(conda-forge)で、リポジトリ外の隔離した作業場所に作成した。python.org の公式ビルドではない
OS Linux 6.18.33.1-microsoft-standard-WSL2 x86_64
比較対象 Python 3.14.4(既存の基準)
コミット 028b40a(draft-2 の固定。作業ツリーは clean)

結果(3.11.17)

対象 結果
開発テスト 231/231
レビュー系列 40/40(追加後は 52/52)
追加監査 8/8、拡張 600・単項 256・存在規則 32・PR01 1
P1-d の CLI 評価 P1 20/20条件・80/80 JSON・417/417必須パス、P0 37/37・221/221。117例すべてで API/CLI 一致。実行記録の python は 3.11.17
全131例(P0 37+P1 80+レビュー14)の結果 canonical digest が 3.14 と全例で同一(131/131)
乱数照合・掃引 独立オラクル(1,500ケース)、予測(800)、予算掃引(21,855評価)、拡張の保存性(700)、入力の乱数改変(4,680):不一致・偽認定・未捕捉例外 0

以前の記録の「ast.parse(feature_version=(3,11)) が通る」という静的確認は、これで実行による確認に置き換わった。

限界

3.11 の他のパッチ版・他のビルド(python.org、OS 配布版)、他の OS(Windows・macOS)、3.12/3.13 は未実行。random を使う照合は、seed が同じでも random の実装差で生成が変わり得るため、3.11 と 3.14 の乱数照合は同じ入力を使った比較ではない(それぞれの結果が独立に不一致 0)。全例の結果の同一性(上の131例)は、同じ入力による比較である。

4. 17 の未確認点の更新

17 の §8 項目5 の未確認点のうち、次を閉じた:Python 3.11 での実行、P0 比較の変異、事象の split_roles の乱数検査。残る未確認点は、独立の確認者、他の OS・ビルド・Python 版、417必須パスの人手の再導出、領域3以上の参考意味、形式証明。

5. 再現

python3 -m unittest discover -s tests/review -v      # 52テスト。compare/split_roles/鎖の照合を含む
# Python 3.11(例:micromamba)
MAMBA_ROOT_PREFIX=/path/to/root micromamba create -y -p /path/to/py311 -c conda-forge --override-channels python=3.11
/path/to/py311/bin/python -B -m unittest discover -s tests && /path/to/py311/bin/python -B -m unittest discover -s tests/review

変異検査と結果の digest の script・ログは data/research/review-001/(Git管理外)にあります(mutrun_final.py、result_digest.py、logs/)。

AI-001

同じ区分の文書