抽象機械

λ計算などの高レベル計算モデルを、状態遷移で機械的に実行するための仮想機械。評価戦略(CBV/CBN/遅延)を明示の状態に落とし込み、インタプリタ・コンパイラ・継続の扱いの土台になる。

代表的な機械

機械由来特徴
SECDLandin 1964Stack/Environment/Control/Dump。λ計算を実行する最初の抽象機械
CEKFelleisen & FriedmanControl/Environment/Kontinuation。継続を状態として明示。CBV
KrivineKrivinecall-by-name / 弱頭正規形。極めて簡潔
CAMCousineau らCategorical Abstract Machine。Caml の語源
STGPeyton JonesSpineless Tagless G-machine。GHC(Haskell)のコア、遅延評価
ZAMLeroyOCaml バイトコードの実行モデル
WAMWarrenWarren Abstract Machine。Prolog の実行モデル

CEK 機械の状態遷移(具体)

CEK の状態は3つ組 ⟨ C, E, K ⟩:

値はクロージャ ⟨λx.body, E⟩(λ本体+捕捉した環境)。継続フレームは2種類だけ:

K ::= Done                       -- 最終。値が出たら停止
    | Arg(e, E') · K             -- 「関数を評価中、出たら引数 e を E' で評価せよ」
    | Fun(⟨λx.body, E'⟩) · K     -- 「引数を評価中、出たらこのクロージャを適用せよ」

遷移規則(CBV・左から評価):

⟨ x,       E, K ⟩  ↦  ⟨ v,    E'', K ⟩          where E(x) = v=⟨_,E''⟩   -- 変数参照
⟨ (e1 e2), E, K ⟩  ↦  ⟨ e1,   E,   Arg(e2,E)·K ⟩                         -- 適用: 先に関数部
⟨ λx.b,    E, Arg(e2,E')·K ⟩ ↦ ⟨ e2, E', Fun(⟨λx.b,E⟩)·K ⟩              -- 関数値が出た → 引数へ
⟨ v,       _, Fun(⟨λx.b,E'⟩)·K ⟩ ↦ ⟨ b, E'[x↦v], K ⟩                    -- 引数値が出た → β適用

例: (λx.x) y を E = {y ↦ v} の下で評価する全ステップ。

⟨ (λx.x) y,  E, Done ⟩
↦ ⟨ λx.x,     E, Arg(y,E)·Done ⟩            -- (適用) 関数部 λx.x へ
↦ ⟨ y,        E, Fun(⟨λx.x,E⟩)·Done ⟩       -- 関数値 → 引数 y を評価
↦ ⟨ v,        E, Fun(⟨λx.x,E⟩)·Done ⟩       -- (変数) y を v に解決
↦ ⟨ x,        {x↦v}, Done ⟩                 -- (β) クロージャ適用、本体 x を新環境で
↦ ⟨ v,        E, Done ⟩                     -- (変数) x を v に解決 → Done で停止

ポイントは K が明示のスタックなので、再帰呼び出しを使わず純粋な while ループで評価器が書けること。継続を第一級データにすれば call/cc・例外・末尾呼び出し(K を伸ばさず付け替える)が同じ枠組みで自然に表現できる。

なぜ使うか

実用言語の処理系は事実上いずれかの抽象機械をコアに持つ(GHC=STG、OCaml=ZAM、Prolog=WAM)。

押さえどころ(カード化候補)

関連

Graph