YONAPO RESEARCH
研究記録
MedDSL(仮称)

RESEARCH / RECORD

P2-f:単位つき数量の意味設計

原文 docs/research/34-p2-f-design.md

20 KB

GitHubで見る

版 be280c0

この文書の目次 9項目

作成日:2026-10-20。状態:作成者側の設計草案。runtime・native仕様・登録宣言・実行用fixtureは未実装。計画30 と P2-eの結果 を受け、候補CをP2-fとして進めます。手指定の条件 と 一次資料の確認記録 を併せて読みます。独立確認と評価用正解の凍結は未実施です。

1. 今回の問いと判断

問いは、数量を新しい値の型として加えるとき、数値の同値、区間が表す情報、単位の解釈、臨床の主張をどう分けて保つかです。数値が換算できたことを、観察の正しさや臨床的同等性の根拠にしません。

判断 初回に採る設計 理由・見直す条件
QT-D1 数値リテラルの換算・比較を専用のR2モジュールにする 新しい型と数値の意味を先に検査する。基底の主張・台帳は読まず、採用も行わない
QT-D2 量の種類、次元、単位の倍率を別に持つ 次元の一致だけでは量の種類の一致は分からない。型の不一致を換算で消さない
QT-D3 正確な有理数の点、または端点の開閉を明示した有限区間 浮動小数点への丸めと、区間を代表値へ潰す操作を入れない
QT-D4 正の有理倍率だけを持つ架空の単位表をnative仕様に固定 単位構文・実マスター・オフセット・対数・手法依存の換算を一度に取り込まない
QT-D5 測定の不確かさは not_evaluated と明示。丸め表示は別の射影 数値リテラルの正確な計算と、現実の測定精度を区別する
QT-D6 単位・種類のIDはprofileと仕様hashに局所化する 既存の所有欄に単位や種類を「述語」として偽装登録せず、同じ名前の別定義も混ぜない

一次資料では、VIMが次元と量の種類を区別し、FHIR R5が比較子・精度・表示単位と符号化を区別しています。これらは設計上の区別を確認する材料です。初回のschemaや架空の単位表を、FHIR・UCUM・VIMの実装や適合仕様とはしません。VIM 1.2、FHIR R5 Quantity

2. 三つの設計案の比較

案 扱えること 今回の判断
P0原子に数値の意味を直接追加 既存の採用から数量を読む P0原子の引数は参照文字列で、数値の型や換算の意味を持たない。文字列を読み替えると旧意味が変わるため採らない
確認済みの原子に別添えの数値を結ぶ 基底の採用と数量を接続 元の人の確認が別添えの数値・単位まで確認した証拠にはならない。全体の同一性・訂正・確認を扱う別契約が必要
専用のリテラル型を計算する 数値領域と換算・比較の意味を分離して検査 初回に選定。台帳・観察・確認との接続は対象外と明示する

既存の forecast.py は有理数を使いますが、重みは0以上1以下で総和1という固有の意味を持ちます。数量の値には1を超える数や負数も必要なので、その検証関数を流用しません。共用する場合も、JSON・整数・予算等の構造上の契約と、値の意味を区別します。

これは数量を臨床的な記録から切り離し続ける最終設計ではありません。まず型の意味を確立し、その後に、数量・測定対象・検体・方法・時点・由来・人の確認を一体として識別する契約を研究する順序です。

3. 初回の架空の意味表

次元ベクトルは架空の二つの軸についての指数です。SIの次元や実測定項目へ対応させません。

量の種類の局所ID 次元
k_a [1, 0]
k_b [1, 0]。k_aとは別種類
k_c [0, 1]
k_ratio_a [0, 0]
k_ratio_b [0, 0]。k_ratio_aとは別種類
単位の局所ID 次元 当該次元の基準表現への正の倍率s
u_base [1, 0] 1
u_ten [1, 0] 10
u_third [1, 0] 1/3
u_half [1, 0] 1/2
v_base [0, 1] 1
w_base [0, 0] 1
w_hundredth [0, 0] 1/100

表は要求から変更できません。IDは文字列の略号ではなく、(profile, native仕様hash, 局所ID) で解釈します。大小文字・表示名・似た綴りから別単位へ補正しません。同じ局所IDでも別profile・別仕様の意味を自動的に同一視しません。

表の更新で仕様hashを変えた場合、旧hashの要求を受け付け続ける保証は自動的には得られません。旧要求の可用性まで保つには、旧表を残して版ごとに解釈を選ぶ等の設計が必要です。後述のQT-L5は意味上の保存であり、hash一致の検査を飛ばして新版を受理する根拠にはしません。

現行のmanifestの owns は操作・schema・profile・回答型・述語・能力を扱い、独立した単位や量の種類の所有欄を持ちません。初回はprofile内部の閉じた表として所有し、単位・種類を共有の語彙として輸出しません。将来、拡張間で共有する単位登録表を作る場合には、所有・同一性・依存を別途拡張する必要があります。

4. 入力型の設計

以下は予約案で、現在のCLIが受け付ける要求ではありません。

項目 設計
profile / 要求schema p2-quantity-literal-draft-1 / p2-quantity-request-draft-1
操作 / 回答型 evaluate_quantities / quantity_literal_result
要求 schema_version, operation, consumer, quantities, queries, budget
consumer profile, profile_spec_sha256, operations。操作一覧は当該操作のみ
quantities 1〜64件。各要素は id, quantity_kind_ref, unit_ref, magnitude, uncertainty, origin, required_capabilities
magnitude:点 {kind: point, value: {numerator, denominator}}
magnitude:有限区間 {kind: interval, lower: 有理数, upper: 有理数, lower_closed: bool, upper_closed: bool}
uncertainty {kind: not_evaluated} が必須。測定の不確かさが0という意味ではない
origin {kind: literal / imported_literal / ai_candidate, ref: 非空参照}。参照先の真実性を保証する仕組みではない
required_capabilities 当該profileが必須。未知の追加能力は、その数量を読む行を停止する
convertのquery id, kind: convert, quantity_ref, target_unit_ref
compareのquery id, kind: compare, left_ref, right_ref
共通上限 queriesは1〜64件、入力1 MiB・深さ64、予算は整数0〜100,000。boolを整数として受け付けない

分子は符号つき整数、分母は正整数。abs(numerator).bit_length() と denominator.bit_length() は63以下です。未約分の入力も受け付けますが、原入力を保持し、計算した有理数だけを正の分母・既約形で返します。JSONの小数、指数表記、数値文字列を自動変換する機能は含めません。

区間は下端≦上端。等しい場合は両端が閉じた単一点だけを許し、空集合は不正です。意味領域は有理端点で記述した実数の集合で、整数だけの集合や整数個数とは扱いません。

4.1 数値領域と測定の不確かさ

点は「入力された数値リテラルがこの一点を表す」、区間は「入力に明示された数値上の制約」を意味します。どちらも測定値の真値や確率分布を決定しません。not_evaluated は原入力と出力へ残します。

標準不確かさ、確率付きの区間、検出限界による片側の値、範囲不明を、点・有限区間へ黙って置き換えません。これらの専用表現は初回には未対応です。VIMの確率付き包含区間を、必ずその中に真値が入る集合制約へ読み替えることも行いません。VIM 2.26、VIM 2.36

初回の全入力は未確認の数値リテラルです。AI由来でも計算はできますが、計算結果は候補入力に依存した数学的な結果に留まります。人の確認済み事実へ採用したり、候補という由来を消したりしません。この計算経路は臨床の採用を実装しないため、人の確認の省略を許したとは扱いません。

5. 換算・比較の作業定義

既知の種類と単位は次元が一致する必要があります。入力の種類と入力単位が既知なのに次元が食い違う場合は、要求自体が invalid_input です。一方、異なる次元・種類の妥当な二入力を比較する問いには not_comparable を返します。

5.1 正の倍率による換算

入力単位uから目標単位vへの換算を次で定義します。同じ次元に限ります。

C_u(x) = x × s(u)                       # 基準表現
T_{u→v}(x) = x × s(u) / s(v)             # 目標単位での表現
T_{u→v}(I) = {T_{u→v}(x) | x ∈ I}       # 区間への点ごとの適用

sは正なので、区間の順序と端点の開閉は保持されます。零でないオフセットを持つ単位、対数尺度、手法依存単位、分子量等の追加情報を使う種類間の換算は初回の表にありません。未知のIDには停止し、既知の倍率や同じ表示名で代用しません。これらの拡張が必要なことは UCUMの特殊単位・任意単位 を参照して確認しましたが、UCUMの表や構文を取り込んではいません。

5.2 比較は関係の集合を返す

種類が等しく、次元が一致する既知単位の二入力を基準表現の領域L/Rへ換算します。異なるIDの入力では、与えられた制約の範囲で次を返します。

relations(L,R) = {rel(x,y) | x ∈ L, y ∈ R}
rel(x,y) ∈ {less, equal, greater}

less    が可能 ⇔ lower(L) < upper(R)
greater が可能 ⇔ upper(L) > lower(R)
equal   が可能 ⇔ L ∩ R ≠ ∅             # 接する境界では端点の開閉も調べる

関係の出力順序は less, equal, greater。一つだけなら certain_relation にその関係を置き、複数ならnullにします。区間が重なったことだけで、値が等しいと断定しません。

同じ数量IDを左右で参照する場合は、同一の値変数として扱い、既知・解釈可能で非空の領域なら {equal} です。異なるIDに追加の相関・同一性の制約は与えられていません。直積は、この限定した意味での可能性の集合であり、測定誤差が統計的に独立だという仮定ではありません。現実の二観察の関係を完全に表したという主張もありません。

この型が返すのは数値リテラルの関係です。測定対象・検体・方法・時点・個体が臨床的に比較可能かは評価しません。差が統計的・医学的に有意かも返しません。

5.3 停止と不一致の順序

全要求の構造・参照・数値・区間の妥当性を、予算に依らず先に検査します。既知の入力種類と単位の不整合もここで拒否します。各行では次の順に判定します。

  1. 参照する数量の未知能力 → unassessed / unknown_capability。
  2. 未知の種類・入力単位・目標単位 → unassessed。unknown_quantity_kind と unknown_unit を区別し、同居すれば全理由を保持。
  3. convertの目標単位、またはcompareの左右の次元不一致 → not_comparable / incompatible_dimension。
  4. compareで次元が等しくても種類が違う → not_comparable / incompatible_quantity_kind。
  5. 換算・比較を完成させる。

同じIDや同じ文字列を比較する場合も、この停止を飛ばしません。未使用の数量は保持だけを行い、その未知能力を無関係の計算行へ適用しません。ここで扱うのは台帳の文脈ではないため、P0/P2-eの「可視の主張が文脈を停止する」方針を緩めたものではありません。

6. 出力、丸め、保存

出力 意味
status: computed 当該入力の数値的な結果が完成した
convertの converted_domain 目標単位での下端・上端・開閉。点も閉じた単一点の領域として返す
compareの relation_set, certain_relation 可能な順序の集合と、一意な場合だけの順序
not_comparable / unassessed 値の欄はnull。差ゼロ・空集合・偽を返さない
共通の根拠 読んだ数量ID・原入力hash・種類/単位の局所ID・profile/仕様hash・換算倍率・origin
共通の境界 clinical_confirmation: not_evaluated, uncertainty_propagated: false, converted_to_base: false, clinical_assertions_added: []

元の数量オブジェクトを変更せず保持します。source_refやoriginがあることだけで、外部の原文や測定過程を復元できるとは言いません。schema内の有理数に約分を施した結果と、原入力の構文上の違いを分けます。

初回は丸め表示の操作を実装しません。丸めた表示が失う区別は D01/D02 の別反例とし、将来、表示の射影をR4として設計するときは表示そのものを対象にします。原入力や正確な値を別添えしても、表示が失った区別を保持したと呼びません。外部の小数の末尾桁を読んで精度を保持する取込も別課題です。

7. クラス・保存条件・手作業の導出

R2-1(書き込みなし)、R2-2(基底へ導出なし)、R2-4(別の回答型)、R2-5(未知能力を無視しない)を要求します。R2-3は基底の状態を全く読まないため、初回では空の前提に対して満たします。 この結果から、臨床台帳へ接続したモジュールの採用の保存が示されたとは言いません。核に接続する段階で再検証します。

旧要求の保存範囲Qは従来の妥当な要求、Eとρは恒等、観測は certifier を除く旧回答です。専用handlerと閉じた局所表を追加し、旧validator・採用・既存handlerを変更しないことを実体と前後比較で確認します。新しい数量の問いへの保存認定や臨床的正しさの認定は発行しません。

導出 前提と結論 範囲外
QT-L1:換算の可逆性 有理数の演算を正確に行いs(u),s(v)>0なら、T(v→u)(T(u→v)(x))=x。区間の集合と開閉も戻る 原構文・測定の不確かさ・外部観察の復元を意味しない
QT-L2:換算と比較の整合 正の倍率は大小と等号を保存する。同じ基準表現で比較すれば単位の選択に依らない 負の倍率・オフセット・対数の一般処理
QT-L3:区間の関係集合 非空の有限区間では§5.2の三条件が直積上の関係に必要十分。端点を含むかが接触時の等号を決める 実世界の相関を持つ二観察の完全性
QT-L4:同一参照 同じIDは一つの値変数なので、非空ならx=x。未知能力・未知定義の停止が優先 IDが異なることから現実の独立性を導かない
QT-L5:局所表の拡張 二つの表の間で、同名の局所IDの種類・次元・倍率が不変なら、その対応を使う完成した数値演算の結果は同じ profile/hashを含む完全な識別や根拠、要求の受理の一致は含まない。未知の新版を自動受理しない

以上は作成者側の手作業の導出です。R2の必須欄だけでL1〜5を検査できるとは扱わず、数量固有の追加義務を宣言へ載せます。

追加義務 検査する内容 防護例の出発点
QT-1 profile・hash・局所表の所有と再定義の拒否 Q21/Q22、N07/N10
QT-2 有理数の正確性、負数、原入力と正規化の分離 Q01〜Q06、N01/N02/N06
QT-3 正の倍率、可逆性、換算と比較の整合 Q07〜Q09/Q17、種類/次元の不一致
QT-4 区間の開閉・非空性と関係集合の健全性・完全性 Q12〜Q16、N03
QT-5 種類と次元、明示的な比較不能 Q18〜Q20、N04
QT-6 不確かさ・丸め・臨床採用・AI候補の境界 Q24、N05/N08/N09/N12、D01/D02
QT-7 未知・資源の停止、値を持たない未完了行 Q21〜Q23、B01〜B04
QT-8 決定性・旧経路の非干渉・仕様変更時の再検証 N12、旧版との比較・順序の入替え

8. 予算と算術の上限

入力検査は予算外で先に完了させます。意味計算の課金案は、要求開始1、数量の準備1件につき1、行の開始1、オペランドの出現ごとに基準表現の二端点で2、convertは目標単位の二端点で2、compareは三関係の判定で3、行の確定1です。点も二端点、同じIDの二重参照も二オペランドとして払い、キャッシュ割引を設けません。

完了必要量 = 1 + N_quantities + 6 × N_convert + 9 × N_compare

これは上限内の固定課金モデルで、CPU命令数ではありません。停止や比較不能の行も同じ行コストを予約し、計算前に走査・演算分を払い、確定分を払ってから公開します。queryはID順。同じ要求で共通予算を使い、未完了は値・関係集合・完成根拠をnullにします。完成済みの行は保持します。

入力の分子/分母は各63bit以下、初回の固定倍率の分子/分母は各7bit以下です。基準化は各70bit以下、さらに目標単位へ移す積は各77bit以下、二つの基準値の比較の交差積は140bit以下で収まる、という上界を導けます。256bit未満を初回の算術上界として検査する案です。これは初回の表と二操作に対する上界で、新しい倍率・式・演算へ自動的に延長しません。大きな整数を浮動小数点へ落として上限内に見せません。

9. 実装・内部評価への受入条件

  1. Q24/N12/B4の手指定条件を実行例へ固定し、その後にnative仕様・専用handler・R2宣言を作る。期待をruntimeから生成しない。
  2. 点・区間、開閉、負数、未約分、1/3、入力整数の境界、同じ次元で異なる種類、無次元の異なる種類、同一/異なる参照を照合する。
  3. 換算の参照計算と比較の参照計算を実装から分ける。例えば整数の交差積と、有理数ライブラリによる計算を照合する。関係集合は端点と各隣接領域内の二点から作る証人とも比較する。
  4. 浮動小数点化、区間の中点化、境界の開閉の無視、種類の無視、単位倍率の逆転、未知IDの同名扱い、AI結果の事実化、予算停止時の値の漏れを変異で検出する。
  5. 同じ予算・入力順序の入替えで決定性を検査し、0から完了境界の少し上まで掃引する。型・参照・入力上限の拒否が予算に依らないことも検査する。
  6. 旧P0/P1/P2の要求・期待・kernelを保持し、427ファイルの現snapshotを履歴から再現できるようにしてから、新しい評価対象を明示的に追加する。旧分母を新結果へ差し替えない。
  7. Python 3.11/3.14でAPI・CLI・生成器・新系列・既存回帰を実行し、ファイル数・必須パス・hash・実行環境と未対応を記録する。
  8. 結果を受け、数量を臨床記録へ結ぶ契約、時間/概念分割との併用、丸め表示のR4のうち、次に検査する境界を選ぶ。独立確認は現在の進行条件にしない。

今回の終了点は設計と実装前の条件です。UCUMの採用、FHIRの入出力、統計的な不確かさの伝播、臨床的な閾値・診断・会計への射影、永続する意味の一般証明は完了していません。数量を型付きで追加する実験を、医療コード体系そのものの確立の代わりにはしません。

P2-f

同じ区分の文書