ドメインモデルと不変条件
現在確定しているドメインモデル・不変条件・時刻境界をまとめる。ADR が決定の履歴(不変・追記型)であるのに対し、 本書は現在の姿(上書き型)を示す。判断の根拠は各 ADR を参照。
1. premise(ユビキタス言語の中核概念)
premise とは、ある式・節・句の解釈が成立するための先行条件の総称である。具体的には、暦法 (calendar-system)、軸、カレンダー、ロール規約、粒度、TZ、asof、WKST、出所(source)を含む。契約の前文 (recitals)が以降の条項の立つ前提を先に据えるのと同じ役割を、式に対して果たす(ADR-16)。
- 含まれるもの: 暦法・軸・カレンダー・ロール規約・粒度・TZ・asof・WKST・出所(source)。
- 含まれないもの: ストリーム(値)と演算子(動詞)。これらは premise の上で評価されるが premise ではない。
- 供給:
@名前は premise 束を引く軽量形(@TSEは一メンバー、@JPは多メンバー)、premise { ... }は 明示宣言する完全形。名前付き束はpremise 名前 { ... }で定義する(30-syntax §1.6)。同一の束縛操作の長短三形 (定義・軽量形・完全形)。 - 名前解決との関係: 名前は現在の premise の下で値に解決される。複数の premise が同名を与えるなら曖昧となり 修飾を要する(ADR-17)。「意味は premise 相対」は値だけでなく名前にも及ぶ。
- 命名:
frame・contextは IT 分野での多義により退け、「解釈が立つ先行条件」に意味が絞れるpremiseを採用。
2. 構成要素(DDD 語彙)
2.1 基底 Chronos(値オブジェクト・不変の土台)
TZ 非依存の単一絶対連続時間軸(うるう秒を持たない一様な理想化尺度=UTC の各日をちょうど 86,400 秒と数える。ADR-33)。TZ は chronos から市民座標への 版付き写像で、premise 相対の射影パラメータ(「錨」は基底でなく射影に付く。ADR-33)。全ての暦法・粒度は ここへの射影。相対化しない(ADR-09・ADR-10)。言語名 Kairos(基底から選ぶ意味ある時点)に対し、この連続基底を Chronos と呼ぶ。言語は Chronos から kairos の集合を 紡ぐところまでを担い、その集合を解釈して実際に発報するのは実装系(Chronos 上の実行)。
2.2 暦法 CalendarSystem(エンティティ)
基底上の入れ子の窓分割定義の集合。グレゴリオ暦も名前を持つ一インスタンスで標準ライブラリ同梱。差し替え可能
(ADR-07)。原始的定義と派生的定義がある(ADR-19)。原始的定義は窓生成語(一様分割 grid・可変集約 span・
可変分割 split・並列ラベル cycle)で軸を刻む。依存はボトムアップ集約を主とし(原子 day を month に、
month を year に束ねる。month が基本の括り)、year の従属窓(quarter)だけを split で割って year に
自動追従させる。ブロック top-level の束縛を公開語(Gregorian.month・monthStart 等)として持つ(30-syntax
§1.11)。閏(2 月の 28/29)は year という窓への依存ではなく month 序数から算出する値依存で、これゆえ
month を year 非依存に置け、派生で year を組み替えても循環しない。派生的定義は Base with { … }
(premise → premise 閉包)で base の公開語を上書きする。裸名は派生スコープで再解決し依存語は自動追従、
Base.word の修飾参照は base 値にピンする(機構 A・ADR-17。30-syntax §1.12)。派生が動かすのは窓の切れ目だけで
暦日は不動(解釈 P・基底固定 I1)。会計暦=Gregorian の year を month span 12 phase: 3 に組み替えるだけの
一行(quarter は自動追従。ピン・循環回避は不要)。
Gregorian は理想化された連続時間軸上の数学的モデルであり、歴史的事実(1582 年改暦の日付消失・重複、地域差、
うるう秒(正負とも。ADR-33)、暦の有効範囲)は負わない。それらは暦法純粋(ADR-20)の生成規則が背負う層ではなく、必要なら別
premise(歴史考証版)や asof/source 注釈で扱う(スコープ外。90-open-questions)。
2.3 窓 Window(値オブジェクト・二種)
軸を余さず分割するパーティション型と、マーカーで切る区間列型。保証する性質(網羅か否か)で型を分ける(ADR-08)。
2.4 粒度 Granularity(表示射影)
年・月・日・時・分・秒・週・四半期・カスタム。軸上の位置の表示形式であり、型には乗せない(ADR-11)。
2.5 時間ストリーム TemporalStream(値オブジェクト)
遅延・無限・順序付きの、基底上の点の列。同じ定義なら等価。本体層の唯一の第一級の値(ADR-04・ADR-05)。 外延(生成された点の列)であり、内包(生成規則=premise)とは別の型(ADR-18)。旧称 DateStream から改名。
2.6 カレンダー Calendar(エンティティ/集約ルート)
「東京決済カレンダー」のように名前で参照される。週末方針 → 法定祝日 → 組織休日/特別営業日のカスケードを 束ねる。asof で版が決まる。実体は「名前を付けてキャッシュした一本のストリーム式」であり特別な機構ではない (ADR-01・ADR-04)。横方向に和・積で合成可能(JointCalendar 相当)。
注意: 取引所カレンダー(例: TSE=東証)は「国の祝日」とは一致しない。祝日は premise の一層、TSE はその層に 組織固有の休場(年末年始等)を重ねた完成品のカレンダー。両者は別物。
2.7 演算子(ユビキタス言語の動詞)— core 族
本体層の core 族。糖衣(monthEnd・businessDays・nextWeekday 等)は core への展開で定義される(ADR-23)。
糖衣の定義は専用構文を持たず、既存の束縛 = の右辺に core のパイプ列を書く(前段はラムダ s => 明示、素直なら
省くポイントフリー略記。宣言印なし。30-syntax §1.13)。
- 生成子:
() → ストリーム。everyDay・everyInstant等。暦法純粋でカレンダーに依存しない(ADR-20・I8)。 正体は原始的定義の公開境界語(monthEnd = month |> last)で、別機構ではない(30-syntax §1.11)。 - 点変換: 点 → 点 をストリームに持ち上げたもの。
roll・shift。同じ族の二メンバーで、参照 premise を 引数(on:/unit:)で選ぶ。方向は符号で表す。各段が premise を自足する(ADR-21)。 - 結合子: ストリーム × ストリーム → ストリーム。横合成と例外日。記号は
|(和)・&(積)・\(差、 U+005C=バックスラッシュ、円記号 ¥ ではない)。優先度付き上書き(カスケード)は和・差の左結合順序適用で 表し専用記号を持たない(ADR-01・30-syntax §1.8)。 - フィルタ: 述語で間引く。「営業日に当たるものだけ」
filter(on: bizDay)(軸を名指し、在圏のcalendarに解決)。カレンダー依存はここ以降(I8)。premise 述語filter(on: …)に加え、値式述語filter(y => …)も取る(whereを統合。ADR-25)。 - 窓: 期間で束ねて部分ストリームにする。
within(...)。パーティション型・区間列型(ADR-06・ADR-08・ADR-24)。 - 選択子: 窓内で第 N 番・最後を選ぶ。
first・nth・last。窓相対(I4)。「第 N」は窓の起点(WKST 等)に 依存する二段依存(ADR-24)。 - ストライド: 走査して間引く状態付きオンライン変換。選択子と別族(窓を消費せず境界無視で連続)。入力
カウント
stride(n)(入力の点を n ごと・軸引数なし=ADR-38。何を数えるかは前段が決める)と 幅刻みstrideBy(w)(複数軸の物理量、例 1 sol)の二演算子(ADR-11/38・30-syntax §1.9)。
2.8 ロール規約(軸非依存の演算子修飾)
Following / Preceding と、上位窓を引数に取る Modified 修飾。営業日にも DST にも同じ体系が乗る(ADR-13・ADR-14)。
2.9 二層構造と型
言語は premise 層(暦法・カレンダーを組み立てる。多行・宣言的可)と本体層(スケジュールを紡ぐ。一行・パイプ的)の 二層で、SQL の DDL/DML に対応(ADR-18)。両層は同じストリーム語彙を共有するが型は分かれる。
- 時間ストリーム型(本体層の第一級値。外延)。層内では型は一本(ADR-05、本体層限定)。本体層はさらに core 族と糖衣に分かれ、糖衣は core への片方向依存(ADR-23)。
- premise 型(内包・生成規則)。原始的定義と派生的定義があり、派生は
premise → premiseの閉包で premise 型 内に閉じる。原始と派生は同じ型(ADR-19)。 - 値型(数値・論理・列挙・リスト・文字列〈ADR-32〉・時点〈ADR-43〉)。原始的定義の規則(閏年など)・演算子の
引数(
shift(n)のn)・値関数と変数(ADR-25/28)で使う。時間ストリーム型・premise 型と並ぶ第三の型。 ADR-05 の「型は一本」は本体層内に限定(ADR-25)。
両層は非対称の関係。premise を評価すると時間ストリームが出る(逆は不可)。加えて境界に一本の管があり、基底座標 (asof・TZ・粒度スケール・データ位相)が premise を確定する(ADR-19/26)。
3. 不変条件
- I1 基底固定: 全要素は単一基底(TZ 非依存の絶対時間軸。TZ は市民座標への premise 相対の写像=ADR-33) 上の点。全暦法・粒度はその射影。→ 異種暦間の合成 可能性を保証(ADR-09・ADR-10)。相対論的な複数時間軸の調停はこの単一性を守るためスコープ外(ADR-19)。
- I2 閉包: 全演算子は
(ストリーム…, premise) → ストリーム。型から逃げない(ADR-04・ADR-05)。 - I3 明示解決: 無効・不在に着地し得る演算子は、ロール規約と錨解決を必須引数に取る。既定で黙って選ばない。 → サイレントバグを構文上不能にする(ADR-12・ADR-14)。ADR-16 の「省略の統治」により、危険な premise の 未解決は静的エラー。
- I4 窓相対: 選択子は常に包含窓に相対的。窓なしの
nthは型エラー(ADR-06)。「第 N」は窓の起点にも依存 (二段依存。ADR-24)。 - I5 網羅性検証: パーティション型窓は軸の網羅と無重複が検査可能。区間列型は隙間の意味を明示。→ 自前暦を 検査可能にする(ADR-08)。
- I6 文脈流し: TZ・WKST・asof、および範囲外の出自(区間註釈)は、要素データでなく評価文脈・評価註釈 として流す(ADR-15・改訂=「空の出自」から「区間の出自」への一般化。具体化=輸送表・分類器・器の二形は ADR-37)。
- I7 純粋・遅延: 無限ストリーム上で各演算子はオンラインに定義される。実行起点に相対な窓(過去の実行結果に 依存するもの)はこの前提を壊すためスコープ外(ADR-10)。
- I8 生成子純粋: 生成子は暦法だけに依存し、カレンダー(営業日・祝日)に依存しない。カレンダー依存は後段の
点変換(roll/shift)・フィルタ・結合子以降に限る(ADR-20。差
\がカレンダー依存の入口になる形= bizDay 標準導出は ADR-35)。
4. 時刻に関する境界
- 時刻(位置)は粒度として表示射影で扱う(ADR-11)。
- 幅(オフセット量)は演算子の規約引数。経過時間/市民時の別と、市民時側の DST ロールを持つ(ADR-12)。
- 壁時計上に定義できる窓(固定境界で切るセッション窓など)は扱う。実行起点に相対な窓(「最初に使った瞬間から
5 時間」「前回完了から 5 時間」。systemd の
OnUnitActiveSec相当)は扱わない(I7)。