360 likes | 537 Views
CPS 変換における 型保存の証明に関する研究. 渡邊裕貴 コンピュータ科学専攻 米澤研究室. コンパイラの検証. ソースの 意味論. ソース コード. 意味論が 一致することを 証明. 構文の変換. アセンブリの 意味論. アセンブリ コード. 依存型の型保存コンパイル. プログラムを依存型で型付け 依存型でプログラムの意味論を記述 コンパイル後も型付けが成り立つことを 保証 意味論の一致 Cf. CompCert [Leroy 2006, etc.] 型を保存しない Chlipala 2007 型を意味論の記述に使用しない.
E N D
CPS 変換における型保存の証明に関する研究 渡邊裕貴コンピュータ科学専攻 米澤研究室
コンパイラの検証 ソースの意味論 ソース コード 意味論が一致することを証明 構文の変換 アセンブリの意味論 アセンブリ コード
依存型の型保存コンパイル • プログラムを依存型で型付け • 依存型でプログラムの意味論を記述 • コンパイル後も型付けが成り立つことを保証 • 意味論の一致 • Cf. • CompCert [Leroy 2006, etc.] • 型を保存しない • Chlipala 2007 • 型を意味論の記述に使用しない
本研究では CPS 変換を扱う 典型的なラムダ計算のコンパイルの流れ
CPS 変換 • ラムダ式を CPS に変換する (Continuation Passing Style) Plotkinによる call-by-value な CPS 変換の定義 [[x]] = λk. kx [[λx. t]] = λk. k (λx. [[t]]) [[t1t2]] = λk. [[t1]] (λv1. [[t2]] (λv2. v1v2k)) • G.D. Plotkin. “Call-by-name, call-by-value and the lambda-calculus.” 1975
CPS 変換における型保存 • CPS 変換前の項が型付けされているなら変換後の項も必ず型付けされること If Γ ⊢ t : T then Γ′ ⊢ [[t]] : T′ for some Γ′ and T′
依存型の型保存を証明するための課題 • 証明の中で項の等価性を示す必要がある • 通常の依存型の定義では条件が不十分 v2 = t2が必要 … ⊢v1v2 : (T[x↦ v2] → ⊥) → ⊥ … ⊢k : T[x↦ t2] → ⊥ … ⊢v1v2k : ⊥ ⋮ Call-by-name な CPS 変換ではこのような問題はない [Barthe et al. 1999]
本研究の貢献 • CPS 変換の型保存の証明法の研究 • 依存型 → 依存型 + シングルトン型 • シングルトン型を使うことで証明に必要な等価性を導くやり方を示した • 単純型 → 単純型 + シングルトン型 • 型保存を Coq でほぼ証明した • 単純型 → 単純型 • 型保存を Coq で証明した • Two-sorted locally nameless な定式化を初めて使った • 定式化による証明の違いを比較した
単純型 • 単純型付きラムダ計算の型 • 関数 • X→ Y • プリミティブ型 • Nat, Int, Unit, ⊥, …
ラムダ計算の定式化 • 色々なやり方がある • Named (普通の書き方) • λx. λy. xzy • De Bruijn index • λ. λ. 1 2 0 • Locally nameless • λ. λ. 1 z 0 変数を名前で区別 変数を番号で区別 Named + de Bruijn index 置換を扱いやすい N.G. de Bruijn. “Lambda calculus notation with nameless dummies, a tool for automatic formula manipulation, with application to the Church-Rosser theorem.” 1972. B. Aydemir, et al. “Engineering formal metatheory.” 2008.
CPS 変換の定式化 • ナイーブな定式化では証明が面倒 • 変数名の制約を明示的に扱わないといけない [[x]] = λk. kx (k ≠ x) [[λx. t]] = λk. k (λx. [[t]]) (k ∉ FV(λx. t)) [[t1t2]] = λk. [[t1]] (λv1. [[t2]] (λv2. v1v2k)) (k ∉ FV(t1t2))(v1 ≠ k, v1 ∉ FV(t2))(v2 ≠ k, v2 ≠ v1) 新しく導入される変数名の重複を避ける制約
Two-Sorted Representation • 変数名の制約がなくなり証明が楽 • 名前だけでなく「′」の有無でも変数を区別 [[x]] = λk′. k′ x [[λx. t]] = λk′. k′ (λx. [[t]]) [[t1t2]] = λk′. [[t1]] (λv1′. [[t2]] (λv2′. v1′ v2′ k)) 新しく導入される変数には「′」を付ける Z. Dargaye and X. Leroy. “Mechanized verification of CPS transformations.” 2007.
CPS 変換の型保存を Coq で証明した(単純型 → 単純型) • Two-sorted & locally nameless な定式化 • Two-sorted が型保存の証明に使えることを実証 If Γ ⊢ t : T then [[Γ]]; Γ′ ⊢ [[t]] : ([[T]] → ⊥) → ⊥ 証明は Γ ⊢ t : Tの導出に対する帰納法による
各定式化での証明の比較 • Locally nameless では行数が増えているが…… • Opening という操作に関する補題が要る • 単純型では項の置換が不要 • 置換はシングルトン型や依存型で必要 • 置換があると named や de Bruijn は不利
CPS 変換での型保存単純型 → 単純型 + シングルトン型
シングルトン型 • 項の値を直接表す型 ⊢ (1 + 2) : {3 : Nat} シングルトン型 D. Aspinall. “Subtyping with singleton types.” 1995.
CPS 変換後の項をシングルトン型で型付けする • 例: 変数の CPS 変換の型保存 (変換前) ⊢ 3 : Nat (変換後) ⊢ λk. k3 : ({3 : Nat} → ⊥) → ⊥ 継続が変数 xを受け取ることをシングルトン型で保証
型保存を Coq でほぼ証明した(単純型 → 単純型 + シングルトン型) • Two-sorted &locally nameless な定式化 • 項の置換を扱うので locally nameless が有利 If Γ ⊢ t : T then Γ′ ⊢ [[t]] : ({t′ : [[T]]} → ⊥) → ⊥ for properly defined Γ′ and t′
CPS 変換での型保存依存型 → 依存型 + シングルトン型
依存型 • 型の中に項がある ⊢ nil : List 0 ⊢ cons : Πn:Nat. String → List n→ List (n+1) ⊢ cons 0 “foo” nil : List 1 リストの型 List nはリストの長さを表す項 nを含んでいる R. Harper, et al. “A framework for defining logics.” 1993.
依存型の型付け規則 • 関数適用で、型に含まれる項が置換される ⊢ t1: Πx:T1. T2 ⊢ t2: T1 ⊢ t1t2 : T2[x↦ t2] 置換を扱うので locally nameless が有利
依存型の型保存を証明するための課題 • 証明の中で項の等価性を示す必要がある • 通常の依存型の定義では条件が不十分 v2 = t2が必要 … ⊢v1v2 : (T[x↦ v2] → ⊥) → ⊥ … ⊢k : T[x↦ t2] → ⊥ … ⊢v1v2k : ⊥ ⋮
シングルトン型で証明に必要な等価性を導いたシングルトン型で証明に必要な等価性を導いた 継続が受け取る値をシングルトン型で表す
まとめ • コンパイラの正しさの検証の一環としてCPS 変換の型保存の証明法を研究した • 依存型 → 依存型 + シングルトン型 • シングルトン型を使って証明に必要な等価性を導くやり方を示した • 単純型 → 単純型 + シングルトン型 • 型保存を Coq でほぼ証明した • 単純型 → 単純型 • 型保存を Coq で証明した • Two-sorted locally nameless な定式化を初めて使った
ラムダ計算の定式化 • Higher-order abstract syntax (HOAS) • 定式化する言語の変数で定式化される言語の変数を表す • F. Pfenning and C. Elliot. “Higher-order abstract syntax.” 1988. • Nominal logic • Alpha-equivalent な項を構文的に等しいとして公理化する • Andrew M. Pitts. “Nominal logic, a first order theory of names and binding.” 2003.
CPS 変換の検証 • CPS 変換の依存型の型保存の証明 • Call-by-name な CPS変換 • Gilles Barthe et al. “CPS transformations and applications: The cube and beyond.” 1999. • 型の中の項を型に変換 • ZhongShaoet al. “A type system for certified binaries.” 2005.
Certified Compiler • CompCert • C のサブセットから PowerPC アセンブリへ • http://compcert.inria.fr/ • Chlipala’s compiler • 単純型付きラムダ計算から抽象アセンブリへ • Adam Chlipala. “A certified type-preserving compiler from lambda calculus to assembly language.” 2007.
Coq • 定理証明支援系 • 人間が証明を書くのを対話的フロントエンドで補助する • 証明が正しいかどうかチェックする • http://coq.inria.fr/ 厳密な証明を書く必要がある
Theorem cps_term_preserves_typing : forall (Cs : sctxt) (T : stype) (t : sterm), sterm_typing Cs t T -> forall Cc : cctxt, cterm_typing (cps_ctxt Cs) Cc (cps_term t) (! ! cps_type T). Proof. induction 1 as [ Cs x T H1 H2 | Cs | Cs l TA TR t H1 IH1 | Cs TA TR tfta H1 IH1 H2 IH2 ]; intro Cc; simpl. (* case stt_fvar *) apply ctt_cabs with (l := domain_of_cctxt Cc). intros x1 H3. unfold open_cterm_c; simplopen_cterm_c_n. apply ctt_app with (TA := cps_type T). apply ctt_cfvar; auto_in constructor. apply ctt_sfvar. apply cps_ctxt_preserves_in, H1.
Continuation Passing Style (CPS) • 関数は継続を受け取り、継続に結果を渡す • 例: 整数のインクリメント λn.λk. k (n + 1) • 整数 nと継続 kを受け取り、kに n + 1 を渡す • Cf.: λn. n + 1
依存型の型保存を証明するための課題 • 関数適用の型付けで置換される項が一致しない v2 = 3 ? … ⊢v1v2 : ([[String → List v2 → List (v2+1)]] → ⊥) → ⊥ … ⊢k : [[String → List 3 → List (3+1)]] → ⊥ … ⊢v1v2k : ⊥ ⋮ k:[[String → List 3 → List (3+1)]] → ⊥⊢ [[cons]] (λv1. [[3]] (λv2. v1v2k)) : ⊥ ⊢ λk. [[cons]] (λv1. [[3]] (λv2. v1v2k)) : ([[String → List 3 → List (3+1)]] → ⊥) → ⊥
依存型の型付け規則 • 関数適用で、型に含まれる項が置換される ⊢ cons : Πn:Nat. String → List n→ List (n+1) ⊢ 3 : Nat ⊢ cons 3 : String → List 3→ List (3+1) 置換を扱うので locally nameless が有利