直接的な関係を意識せずに考えていた次のようなトピック、
- git
- JavaScriptのモジュール方式(CJS, ESM)
- NPMパッケージ
- 概念設計とコース設計
- ストリング図とオープングラフ
などが、同一の問題なのだと気付いた。有向グラフの取り扱いと利用法の問題だった。
内容:
関与の有向グラフによる表現
まず、有向グラフ≒ストリング図の応用について述べる。関与〈エンゲージメント〉は 関与宣言 - (新) 檜山正幸のキマイラ飼育記 メモ編 で述べた概念。メイヤーは、顧客と業者のあいだの契約という比喩を使ったが、システムとコンポネント(広義)のあいだの関与関係〈エンゲージメント・リレーション〉は、類似だが別種の比喩を提供する。
なかなか説明が難しいが、最初に用語とその描画法:
概念 | 描画法 |
---|---|
環境 | 境界枠付きのキャンバス |
ユニット | 適当な形のノード |
項目〈アイテム〉 | ノードから出るポート〈ピン〉 |
入れ子ユニット | ノードの集まりを囲むポート付き境界枠と内部ワイヤー |
項目の仕様 | ポートに「名前:型」のラベル |
オープンエンド | 終端しないワイヤー |
ダングリングエンド | 点線で描かれた終端ノードを持つワイヤー |
注意事項:
- キャンバスも内側のポートを持ち、キャンバス=環境内のユニットはキャンバスの持つポート=項目を自由に使ってよい。
- ノード=ユニットの境界から出るポートは公開〈expose〉された機能性〈フィーチャー〉を表す。
- ノード=ユニットは、同じ環境内の他のユニットの公開された項目を使ってよい。
- ノード=ユニットは、自分の公開された〈publicな〉項目と、非公開〈private, hidden〉な項目を使ってよい。
次のもので構成される図をフィーチャー図〈feature diagram〉と呼ぶことにする。
- キャンバス〈環境〉とその内向き(内部への提供用)ポート〈環境からの項目〉
- ノード〈ユニット〉とその公開ポート〈ユニットからの提供項目〉
- 入れ子ノードを構成する内部ワイヤー〈公開指定 | expose specification〉
キャンバスは円環状にする必要があって、環境の項目は、円環状のどちらかの境界円周上に乗る。別な境界円周上に全体としての公開ポート達が乗る。環境が提供するポートを、キャンバスの内部の環境ノードにしたほうがいいかも知れない。Simple Planar Tangle だ。
依存グラフ〈dependency graph〉は、フィーチャー図にワイヤーを追加して描く。ワイヤーの方向は「提供者〈provider〉側 → 消費者〈consumer〉側」。ポートはいくらでもコピーしてよいとする。0個のコピーは利用しないことを表す。
依存グラフでは、出るワイヤーが提供〈provide〉、入るワイヤーが利用〈use | consume〉を表す。
依存グラフから単一のユニット(入れ子ユニットでもよい)を取り出すと、それはユニットの仕様になる。ユニットを切り出すとき、ワイヤーを切らなくてはならない。ワイヤーの切り口〈スタブ | stub〉には次の種類がある。
- 型またはインターフェース: スタブの接続先は実体として指定されてない。仕様として指定されている。
- ロケーションパス: 接続先のロケーションを指している。同じロケーションに別な実体が入るかも知れない。
- 個体ID : ロケーションではなくてIDを指定する。IDで指定された個体が変容する可能性はある。
- 個体IDスナップショット : 凍結されるので変容しない。
依存グラフから切り出したノードは、そのノード〈ユニット〉が環境や他のノード達とどう関与するかを記述しているので、関与記述〈エンゲージメント記述〉と呼ぶ。
有向グラフの落し穴/ハマリ所
- 有向グラフは、プレ順序集合を定義する〈誘導する〉。同一視していいが、混同はダメ。
- プレ順序集合は順序集合を定義する〈誘導する〉。同一視していいが、混同はダメ。
- 有向グラフのノードは、プレ順序に関する下方集合と上方集合を定義する。ノードと下方/上方集合を混同しない。
- 逆{プレ}順序を定義できる。もとの順序と逆順序を混同しない。
- サブグラフのファミリーがあるとき、ひとつのサブグラフと、ファミリーにおける固有部分(他のサブグラフには所属しない)を混同しない。
- 不完全グラフが生じる。不完全グラフは不完全エッジを持つ。不完全エッジは:
- 型やインターフェースでラベルされたオープンエッジ
- ロケーションパスや個体IDでラベルされたダングリングエッジ
- グラフはグラフティングできる。オープンエッジによるグラフティングと、ダングリングエッジによるグラフティングは違う。ダングリングエッジは接合先の実体IDかロケーションを指定している。
- ノード達をクラスターとして入れ子にするときがある。クラスターノードはノードだが、内部にグラフを持つ。
- ハブノードとクラスターノードの区別は難しい。
関連する話題は:
- gitのブランチヘッドコミットと、ブランチ履歴とブランチ固有履歴が混同される。
- ツリーのノードとサブツリーが混同される。treeオブジェクトとファイルツリーがその例。
- コミットの「ツリー」とか「依存ツリー」とかは誤用だが、ルートを固定しての被覆展開を想定しているのだろう。
- ラベルによる参照と、参照先のノード自体が混同される。
- ラベルの名前(例:HEAD)と、ノードの特性(ヘッドであること)が混同される。
- node.jsのモジュールはディレクトリを指し、ESMのモジュールはファイルを指す。これを相互運用するには、マッピング機構かハブモジュールが必要になる。
- gitのワーキングツリーと、ワーキングツリーをホストするディレクトリは違うが混同される。ホストディレクトリのツリーのサブツリーがワーキングツリーとなり、ワーキングツリーを作るときに .gitignore が参照される。
- DOMの document node と root element node は別。
- gitのcommitオブジェクトとそのファイルツリーのルートノードであるtreeオブジェクトは別。
- gitのルートtreeオブジェクトとファイルツリーは別。
時間性
グラフに時間性が入るか? 時間性がない(静的な)グラフにどうやって時間性を入れるか? 難しい問題だ。
- 概念設計やトピック設計は非時間的であるような気がする。
- コース設計はフローグラフの作成で時間方向に展開している。
- しかし線形時間ではなくて、ケース分岐を持つ時間。
- 時間方向に展開するとき、非時間的〈静的 | 空間的〉構造に制約される。運動は、空間から自由にはできない。
- ひとつの空間的制約に対して、その時間方向への展開は膨大にあるだろう。