作成日:2026-10-21。状態:P2-o の臨床ライブラリを一度だけ実行し、満たされた exchange の行が出力先の構造で、丸めず・閉じず・補わずに表せるかを診断する合成の専用 R5 を実装し、両 Python 版の全体回帰を通過。設計67、手指定期待68、接地の監査66 に従いました(利用者の承認:2026-10-21「推奨案で進めてください」。U1〜U3 は設計67の推奨どおり)。67・68 の「未実装」という記載は設計時点の記録として保持します。独立確認・評価用正解の凍結は未実施で、independent_review / evaluation_frozen は false のままです。数値・単位・property・識別子はすべて架空です。構造の事実だけ、取得した FHIR R5 v5.0.0 のページ(台帳に記録、Git 管理外)の読み取りです。FHIR への適合は主張しません。
1. 行ったこと
| 項目 |
内容 |
| 実装 |
structure_grounding.py↗ と native 仕様 structure_grounding_spec.json↗。P2-o の run_library を子として一度だけ呼び(子の予算は P2-o の全体の料金 M_lib を先払いし、使い切りを照合)、satisfied の exchange の行に、値・期間・文脈の3つの写像の可否を判定する。それ以外の行は P2-o の行のまま通す。構造の事実は仕様の表(出典のページ id・SHA-256・目印の語)に持つ |
| 実行例 |
examples/p2-grounding/↗:97 JSON・1,998必須パス(G27・P5・C6・R4・D4・N12・B3条件)。生成器↗は native を import せず、射影・流れ・料金を手指定する |
| 宣言 |
p2-structure-grounding.json↗:R5、17義務(共通4+R5の3+GR-1〜10)、防護例17。証拠は checked_native_template 9・finite_check 8。依存:P2-o。継承は宣言しない |
| 別計算 |
grounding_oracle.py↗:基の行は P2-o の別計算を再利用し、有限小数の判定と表記は Decimal の除算が正確に終わるか(モジュールの整数の掛け算とは別の道)、桁数は文字列の長さ、期間の端は datetime、流れの表は手書きで持つ |
| 検査 |
test_grounding.py↗ 14テスト(手指定・値の格子の全数・期間と文脈の列挙・基の行との差分・丸めず閉じず足さない・出典の結び付き・料金・予算の掃引・子の失敗の原子性・静的検査・型破損・順序と不変性・検査器・変異) |
| 検査器 |
共通部品 p2_checks.py↗ の未完了行の値の検査に、新しい欄2つ(grounding・base_status)を足した。変異の表に B19 を足し、B17・B18 の対象文字列を更新した(検査器の変異は73件と対照) |
| 台帳 |
追加で取得した FHIR のページ7件を 台帳↗ に記録済み(66)。仕様の事実の出典のハッシュは、この台帳と一致する |
| 登録の入口 |
既存の実装・仕様・宣言・旧実行例は変更していない。変更したのは登録の入口と、手で保つ期待の一覧(W1) |
2. 予測の結果(設計67の W1〜W10)
| ID |
予測 |
結果 |
| W1 |
既存の実装・仕様・宣言・旧実行例を一つも変えずに実装できる |
成立。既存の src/med_dsl で変更したのは host.py の2行。既存の examples/p2-* と宣言は0件変更(索引に1行追加)。P2-o の実装・仕様・宣言・例は無変更 |
| W2 |
値の判定は手導出の規則に一致する(分母1〜40の格子の全数) |
成立。分子−24〜24・分母1〜40の1,187点×2つの対象と、端の開閉4通りの120区間×2つの対象(計2,614要求)が、別計算(Decimal)と一致。小数で書ける分母は素因数が2・5だけ(独立な素因数分解の判定と一致) |
| W3 |
通す行は P2-o の行と一致し、表せる行の P2-o の欄は同一 |
成立。乱数300要求で、P2-o 単独の実行と比べ、通す行は全欄が同じ。表せる行・表せない行は選択・要素が同じ。表せる行の出力は同じ |
| W4 |
規約を宣言しないと半開区間は全て表せない。宣言すると端が1秒戻り、仮定が added に出る |
成立。期間の規約3通りの列挙と、すべての半開区間 [day s, day e)(44通り)で確認 |
| W5 |
区別の損失の数は、運ぶ欄のうち known でない欄の数に等しい。確認と出自は常に失う |
成立。method・specimen の3状態×運ぶ欄の5通り×期間の規約3通りの135通りの全数 |
| W6 |
料金 M = 2 + M_lib + 3N が全要求で成り立つ。P2-o の実費は M_lib |
成立。固定例5件の呼び出しの追跡(M=37・42・65・93・108)と、乱数60要求で別計算と一致。実費の不一致は拒否、子の資源停止は全行を原子的に止める |
| W7 |
呼び出し側が構造の事実を変えられない。出典の目印が手元のページに存在する |
成立。要求に事実の欄がなく(追加すると unknown_field)、仕様の6事実が台帳のハッシュと一致し、手元のページに全ての目印がある |
| W8 |
義務は R5 と必須欄で足りる。クラスも書式も増えない。GR-9 は既存の主題に収まらない |
成立。クラスも書式も増えなかった。GR-9(外部の資料に結んだ事実)は、A〜H のどれにも置けず、意味固有に置いた(F18) |
| W9 |
affected():P2-o の変更が、依存によってこの拡張を列挙する |
成立。P2-i・P2-f・P2-j・P2-m・P2-o の変更が及ぶ全ての場合に、この拡張も列挙される(例:measurement.py の変更が及ぶ拡張は6件から7件)。この拡張の変更は他に及ばない |
| W10 |
「18桁」の境界の例は、保守側の解釈に依る。例に明記される |
成立。G33(先頭の 0 を数えて18桁)と G34(19桁)。ページの記述だけでは数え方を決められないことを例に明記した |
3. 反例の結果(設計67の Z1〜Z9)
| ID |
内容 |
結果 |
| Z1 |
2/3 を range へ |
小数に丸めず not_decimal_representable(G03・G08・G25)。失うのは exact_value |
| Z2 |
半開区間を range へ |
端を閉じず open_boundary_not_representable(G22〜G24・G26)。失うのは interval_bounds |
| Z3 |
区間を quantity へ |
中点に潰さず interval_not_representable_as_quantity(G10・G12・G13)。失うのは interval_width |
| Z4 |
桁数 |
18桁は表せ(G30・G32)、19桁は digits_exceed_limit(G31)。境界(G33・G34)は解釈に依ると明記 |
| Z5 |
期間の規約 |
宣言なしは表せず(P01)、宣言すると end を1秒戻し、仮定を added に出す(P02・P06)。表せない行は仮定を足さない(P05) |
| Z6 |
unknown と unspecified |
どちらも不在として運び、区別が落ちたと lost に出す(C01・C02) |
| Z7 |
対象のない出力先 |
not_declared(P2-o の行のまま。D01〜D03) |
| Z8 |
line・trend の出力先に対象 |
静的に拒否(unsupported_grounding_output_kind。N11) |
| Z9 |
P2-o が needs_information の行 |
そのまま通し not_evaluated(依頼は変わらない。R01・R04)。表せない行・評価不能の行も同じ(R02・R03) |
4. 分かったこと
- 構造の事実を仕様の表に出典のハッシュ付きで持つと、どの事実がどのページの記述に由来するかを辿れる。 ただし、事実の正しさ(ページの記述を私が正しく読んだか)は、同じ作成者の目の検査に限られる。目印の語がページに存在することの検査は、取り違えを防ぐだけで、意味の検証ではない。
- 表せない理由を区別して返すと、失う区別を行ごとに残せる。 丸め・閉じる・潰す・補うのどれもせず、理由ごとに
exact_value・interval_bounds・interval_width・validity_end を失うものとして返す。
- 仮定を足す規約は、呼び出し側が宣言したときだけ使い、足したことを流れに残す。 期間の端の規約(
exclusive_end_as_last_second)は秒の粒度の上でだけ正確で、FHIR の dateTime の精度の意味づけは検証していない。
- 合成は既存を変えずに足せた。 P2-m の閉包の問題(前段の出力を後段の入力にする不整合)は、この拡張では起きない(出力を入力に戻さない)。
- 運べない区別は、ライブラリの出力でなく、出力先の構造の側に原因がある。 確認・出自・文脈の三状態は、取得した Observation のページの要素では運べない(Provenance・拡張は別)。この拡張はそれを
lost に残すだけで、運ぶ方法は決めない。
新しい発見
| ID |
発見 |
根拠 |
限界 |
| F17 |
設計の矛盾を、手指定の期待を書く段階で見つけた。 設計67は「表せる行の流れは P2-o の exchange の流れに差分を足す」としたが、P2-o の流れは quantity_kind と context:property を「保持」とする。この拡張の射影は運ばないので矛盾する。手指定で、射影が運ぶものから作り直す規則(S1)と、流れの項目名の統一(S2)に直した |
68 の§0(S1〜S8の8決定) |
実装前の決定なので、実行結果に合わせた変更ではない。手指定の段階で見つかったのは、期待を実行の前に書いたことによる |
| F18 |
外部の資料に結んだ事実を持つ義務(GR-9)は、A〜H のどれにも収まらない。 三つの拡張で、それぞれ一つの義務が主題の外に出た:P2-m の接続面の閉包(LC-12)、P2-o の要求を宣言として持つこと(CL-9)、P2-p の外部資料に結んだ事実(GR-9)。いずれも意味固有(I)に置いた |
各設計の予測(H2)と実装後の割り当て。n=3 |
主題の分類は作成者による。新しい主題を立てるかは判断(外部の資料・宣言・接続面の三つはまとまらない) |
| F19 |
合成の拡張の宣言は、入れ子の要求が埋め込む他の仕様の hash の pin も持つ。 子(P2-o)の要求を包むので、例が P2-i・P2-f の仕様の hash を含む。既存の契約の検査(embedded_in の網羅)が初回に失敗して気づいた。pin を二つ足して解消 |
test_embedded_in_covers_every_artifact_that_embeds_a_pinned_hash の失敗 |
手で書く宣言の項目。入れ子が深くなると増える |
| F20 |
判定の誤りで無限に回る箇所が、変異を選ぶ段階で見つかった。 有限小数の判定が誤ると、小数の表記の生成が止まらない。入力の上限(256bit)から導いた境界(256桁)で、資源停止にした |
変異(素因数3を許す)の設計。注入の検査 |
境界は入力の上限からの導出で、通常の入力では届かない |
| F21 |
新しい拡張を足す手で保つ一覧が、また約11ファイル。 P2-o と同程度(F15)。今回は、継承を宣言しない拡張でも、affected() の列挙の期待(約7箇所)と独立な組の数が変わった |
変更したファイルの一覧 |
一覧は検査が漏れを教える。作業は残る |
実装の最中に直した誤り
- 実装の誤り:0件。97例の手指定の期待は、初回の実行ですべて満たされた。14テストも初回に通過した。
- 検査側の調整:(1)静的検査のテストの予算の置換に、予算欄そのものの不正を含めていた。範囲外として除いた。(2)C06 を、手指定の段階(実行前)で、変異(順序依存)を検出できる記録に強めた。実行結果を見ての変更ではない。(3)宣言の
embedded_in の網羅(F19)。
- 同値な変更:なし。
5. 検査の強さ
- 別計算との比較:値の格子(1,187点×2、120区間×2)の全2,614要求、期間の規約と文脈の135通り、36の半開区間、乱数300要求、固定例。別計算は Decimal の除算を使うので、モジュールの整数の掛け算と別の道だが、P2-o の別計算は再利用しており、P2-o と同じ読み違いは共有する。
- 差分:P2-o 単独の実行との差分(乱数300要求)。丸めず・閉じず・補わないことの性質検査(表せる行の小数を有理数に戻すと元の端と一致する)。
- 変異:20件。関数の差し替え19件(開いた端の受理、区間を数量へ、桁数の検査の削除、符号を桁に数える、先頭の 0 を数えない、素因数3を許す、規約の黙った使用、仮定の欠落、端を戻さない、区別の損失の欠落、確認・出自の損失の欠落、運ぶ欄の順序依存、low/high の入れ替え、
not_declared を表せると言う、不足の行を判定する、先払いの削除、完成料金の削除、推測で補った情報、認定の誤り)と、定数1件(自前の料金)。全件検出(例外で壊れるものも検出に数える)。
- 検査器の変異:B09・B15・B17・B18・B19 を実行(結果は§6)。
- 子の呼び出しの注入:P2-o の資源停止(全行を原子的に止める)、実費の不一致、2行目の資源停止(先に完成した行は保持)。いずれも期待どおり。
- 型破損:要求の全ノード×6種の値で、状態は ok/invalid_input/unsupported_profile/resource_limit のいずれかで例外なし。入力不正は予算に依らず同じ結果。
- 出典:仕様の6事実が台帳のハッシュと一致。手元のページがあれば、ハッシュと目印の語を照合する(なければ台帳との照合だけ)。
6. 検証
Python 3.14.4 と 3.11.17 で、全テスト系列と統合評価を実行しました。
| 系列 |
件数 |
Python 3.14.4 |
Python 3.11.17 |
| 開発 |
231 |
通過 |
通過 |
| 追加レビュー系列 |
52 |
通過 |
通過 |
| 保存監査 |
8 |
通過 |
通過 |
| P2 |
418(P2-oの404に、構造への写像の可否14を追加) |
通過 |
通過 |
| 統合評価 |
P1/P0・拡張・全P2・予算・版比較(2記録) |
通過 |
通過 |
| P1-d の CLI 照合・保存監査・登録検査 |
P1 20条件・80 JSON・417必須パス、別枠 P0 の37 JSON・221必須パス、監査600+256+32+1 |
通過 |
通過 |
| 統合評価の対象 |
P2-p 追加後の分母 |
| 登録・義務・防護例 |
22宣言・295義務・477防護例参照(P2-oの21宣言・278義務・460から、17義務と防護例17を追加) |
| 証拠の強さ |
checked_native_template 190、finite_check 97、hand_derivation 8 |
| 防護例のない義務 |
既存の3件のまま |
| 独立な拡張の組 |
175/210(P2-oは158/190)。この拡張は基底を除く他の20件と20組をつくり、依存(推移)で結ばれる3件(P2-o・数量・期間つき数量)を除く17組が独立(手で数えた値と一致) |
| 継承 |
12項目・証人46・理由つきの欠落2(変更なし。この拡張は継承を宣言しない) |
| 構造への写像の可否の系列 |
97 JSON・1,998必須パス。他の系列の分母は変更なし |
| 予算 |
1,347要求・掃引28,345回、違反0(P2-oは1,251要求・24,895回)。掃引の回数は実測で、予測ではない |
予測した分母(宣言・義務・防護例・独立な組・継承・要求の数)は、実行の前に手で導いた値が全て一致しました(掃引の回数だけは実測)。旧い22,052件の挙動 digest と、生成器による全例・宣言のバイト一致(追加した生成器を含む)も通過しました。検査器の変異 Z0(対照、失敗0)・B09・B15・B17・B18・B19 は、いずれも検出されました。固定対象に、設計67・期待68・構造への写像の可否の例・検査・別計算・生成器を加えました。作成者 snapshot で、independent_review / evaluation_frozen は false です。
- 新 native 仕様 hash:構造への写像の可否
cec41a2d…(先頭8桁)。既存の仕様(P2-o 9f9c6363…、数量 f52ea526… ほか)は変更なし
- 追加前(
9e01802、P2-pの設計の追加後):1,510ファイル、manifest d8376bfc…、束 defeef15…
- 追加後:1,617ファイル、manifest
28e6495c…、束 47191fe4…(この文書の追加で固定対象は変わらない)
7. 限界と次
- 構造は一つだけ(
fhir-r5-observation)で、判定は値・期間・文脈の運び方に限ります。status・code(必須の要素)、値のない記録(dataAbsentReason)、検体の状態、Quantity の comparator、コード化した単位、Provenance への出力、Timing・instant、他の資源は範囲外です。FHIR の資源の生成も、適合の検査もしません。
- 「18桁」の数え方は、ページの記述だけでは決まらず、保守側の解釈(先頭の 0 を数える)を採りました。FHIR が許す境界とは主張しません。
- 期間の規約は、ライブラリの時刻が秒の粒度であることに依ります。FHIR の dateTime の精度の意味づけは検証していません。
- ページを読んだのは作成者一人です。事実の読み違いは、同じ作成者の目の検査(目印の語、台帳のハッシュ)では見つかりません。別計算も P2-o の別計算を再利用しています。独立確認はありません。
- 医療者の負担が減ることの証明ではありません。 構造への写像の可否を診断する一つの断片です。
- 次の候補は、
status・code の写像と Provenance への出力(取得済みのページで読めるが、判断が要る)、CPC の版の監査、複数の出力先への射影の拡張です。着手前に利用者の確認を取ります。独立確認は将来の英語の別リポジトリで行います。