notes mizzy.org

planはSSA的で直列化可能なIRである

確認済み 出典: explorations/2026-06-10-carina-type-system-type-theory/plan-as-compilation.md §4 作成/ 更新

中間表現としてのplanは、コンパイラのIRが持つ古典的な性質をいくつも備えている。単一定義性、直列化可能性、そして「検査済みであること」の三つである。

単一定義性。 各リソースはplan内でちょうど一つのノードとして定義され、他のノードはその属性を参照するだけである。SSA(静的単一代入)形式が変数の再代入を許さないのと同じ規律で、これが依存解析(DAG構築)を自明にしている。

直列化可能性。 plan --outはIRをファイルに書き出す。これはオブジェクトファイルに相当し、リンク前の成果物を持ち運べる。保存されたplanには生成時のstateの系譜(lineage)と版(serial)が記録され、apply側はロック下でそれを照合し、系譜不一致なら拒否、版のずれなら警告する — オブジェクトファイルのABI整合性検査に正確に対応する

検査済みであること。 型検査はIR生成の最中に完了しており、applyは型を見ない。「well-typedなIRだけがバックエンドに渡る」というコンパイラの標準的な契約である。ただしこの契約は再配置(applyでの値の代入)によって破られうる、というのが別に立つ論点になる。

plan — 中間表現 Effect 10種と依存DAG Create vpc Create subnet Update sg 単一定義性 各リソースはちょうど一つのノード。 他はその属性を参照するだけで、依存解析が自明になる。 検査済み 型検査はIR生成中に完了。 applyは型を見ない。 plan --out 保存されたplan = オブジェクトファイル lineage / serial apply側の照合 系譜が違えば拒否 版がずれていれば警告 = ABI整合性検査 IRに継続が残らない — 効果の結果に依存する構成は静的段階で済ませてある — ことが、この三つを同時に成立させている。
三つの性質は別々の話ではない。単一定義性がDAGを成立させ、継続が残らないことが直列化を可能にし、保存されたlineageとserialの照合がリンク時の整合性検査に対応する。

IRの中身は、Read / Create / Update / Delete / Import / Remove / Move / Wait / DeferredCreate / DeferredReplaceの10種のEffect値と依存DAGである(置換は命令ではなくCreate/Deleteの対に展開される — 差分計算は命令選択である)。効果は純粋な値であり、実行は解釈器(Provider)が動的段階で与える。IRに継続が残らない — 効果の結果に依存して次の効果を構成する部分は静的段階で済ませてある — ことが、planが検査可能・表示可能・保存可能であることを支えている。

ただし格納形式のVec<Effect>の順序は実行順ではなく、実行順はapply時にDAGとして導出される。DeferredCreate / DeferredReplaceの2変種は例外で、AST片を抱えてapply後に再展開される脱関数化された継続に当たる。「継続が残らない」が素直に成り立つのはこの2つを除いた部分である。

根拠の確度

Effectが10種であること、plan --outのlineage / serial照合の挙動はソースで確認済み(前者は2026-08-16に再確認)。SSA・オブジェクトファイルとの対応づけは解釈である。初稿は8種と書き、ReadとDeferredCreate / DeferredReplaceを落として実装に無いReplaceを含めていた。

#plan #ir #コンパイラ