依存型で型付けされた 副作用のある関数のための 型保存コンパイラ

Preview:

DESCRIPTION

依存型で型付けされた 副作用のある関数のための 型保存コンパイラ. 渡邊 裕貴 コンピュータ科学専攻 米澤研究室. そのコンパイラ、バグってない ?. 足し算をするプログラムをコンパイルしたら引き算をするアセンブリが出てきた. 最適化をかけたら プログラムの動作がおかしくなった. コンパイラの検証. ソースの 意味論. ソース コード. 意味論が 一致することを 証明. 構文の変換. アセンブリの 意味論. アセンブリ コード. 既存研究. Lambda Tamer A. Chlipala in PLDI 2007 - PowerPoint PPT Presentation

Citation preview

依存型で型付けされた副作用のある関数のための

型保存コンパイラ

渡邊 裕貴コンピュータ科学専攻 米澤研究室

1

そのコンパイラ、バグってない ?

足し算をするプログラムをコンパイルしたら引き算をするアセンブリが出てきた

最適化をかけたらプログラムの動作がおかしくなった

2

コンパイラの検証

構文の変換

ソース コード

アセンブリ コード

3

ソースの意味論

アセンブリの

意味論

意味論が一致すること

を証明

既存研究• Lambda Tamer

• A. Chlipala in PLDI 2007

– 単純型付きラムダ計算のコンパイラの作成・検証– http://ltamer.sourceforge.net/

• CompCert• X. Leroy in POPL 2006• S. Blazy et al. in FM 2006

– C のサブセットから PowerPC アセンブリへのコンパイラの作成・検証

– http://compcert.inria.fr/• …

意味論を扱う証明はとても複雑になりがち4

本研究のアプローチ

5

コードの挙動を

規定できる型

型保存コンパイル

コードの挙動を規定できる型• 関数の持つ副作用を表す論理式を

型の中に書くコードの挙動を型でチェック

– Hoare Type Theory– A. Nanevski et al. in ICFP 2006

– 依存型– R. Burstall and B. Lampson 1984

– Separation logic– J.C. Reynolds in LICS 2002

6

コードの挙動を規定できる型の例

7

コード :

λp. v = *p; *p = v + 1; return v

型 : Πp:ptr.{ ∃x:int. p ↦ x } v:int { p ↦ v ⊸ p ↦ v + 1 }

型保存コンパイル• 型およびその導出木も変換する

• G. Morrisett et al. 1999

8

ソース コード

アセンブリ コード

型導出木

型導出木

本研究での型保存コンパイル• 型に含まれる論理式が意味論の一致を保

9

ソース コード

アセンブリ コード

型導出木

型導出木

意味論

意味論

実装法• コンパイラは Coq を使って書く– 書いた証明が正しいか検証するプログラム– http://coq.inria.fr/

• 型保存性を Coq で証明

10

実装の進捗• CPS 変換– 単純型付きラムダ計算 : 実装済– 依存型 : 実装中– Separation logic: 未着手

• クロージャ変換 : 未着手• Hoisting: 未着手• レジスタ割当 : 未着手

11

まとめ : 型保存コンパイラの作成

• 目的– コンパイルの過程でコードの挙動が変わって

いないことを保証– 意味論の保存の証明をより簡単に

• 手法– コードの挙動を規定できる型– 型保存コンパイル

• 進捗– 最初の CPS 変換の部分を実装中

12

13

コンパイラの構成

14

ソース コード

アセンブリ コード

CPS 変換

クロージャ変換

Hoisting

レジスタ割当

型導出木

型導出木

依存型• コードの挙動を型で規定するための基礎

• R. Burstall and B. Lampson 1984

– 型の中に論理式を書けるようにする

恒等関数のコード :

λx. x

恒等関数の型 :

Πx:int. { true } v:int { x = v }

15

Separation Logic

• メモリの読み書きに関する挙動を規定• J.C. Reynolds in LICS 2002

– メモリ状態を表す論理式を導入{ true }

p1 = malloc(); *p1 = 3;{ p1 3↦ }

p2 = malloc(); *p2 = 5;{ p1 3 * ↦ p2 5↦ }

incr p1;{ p1 4 * ↦ p2 5↦ }

incr p2;{ p1 4 * ↦ p2 6↦ }

16

Hoare Type Theory

• 型付きラムダ計算 + メモリの読み書き• A. Nanevski et al. in ICFP 2006

– 関数の挙動を型の中の論理式で表し検証– 依存型 + separation logic

17

インクリメント関数のコード : λp. do v = *p; *p = v + 1; return ()

インクリメント関数の型 :

Πp:nat. ∀v:nat. { p ↦nat v } r:unit { p ↦nat v + 1 }

18

既存研究との比較本研究 Lambda Tamer CompCert

ラムダ計算 + メモリ操作

単純型付きラムダ計算 C のサブセット

仮想アセンブリ 仮想アセンブリ PowerPC アセンブリ

Coq で証明 Coq で証明 Coq で証明

型安全 型安全 非型安全

型で意味論を規定 型と意味論は無関係 型と意味論は無関係

ソースの定義 ( 仮 )

副作用のない項t ::= x

t tλx. tzerosucc tt + tdo E

19

副作用のある文E ::= return t

x = eval t; Ex = malloc; Ex = *t; E*t = t; E

項の型T ::= nat

Πx:T. T{P} x:T {P}

アセンブリの定義 ( 仮 )

命令I ::= jump v

if r jump vmove r vadd r v vload r rstore r r

20

値v ::= r レジスタ

n 整数リテラル

l ラベル

命令の型T ::= α 型変数∀ α. T

int{ rn : Tn | P }

Theorem cps_preserves_typing' : forall (C : sctxt) (t : sterm) (T : stype), C |-s t : T -> forall (C' : cctxt), cctxt_sctxt C C' (vars_in_sterm t) -> forall (t' : cterm), C' |-c t' : cps_type T --> ctbottom -> C' |-c cps t t' : ctbottom.Proof. intros until t; revert C. induction t as [ x | v IH | t1 IH1 t2 IH2 t3 IH3 | t1 IH1 t2 IH2 | b | x t1 IH ] using sterm_ind' with (P2 := fun v => forall (C : sctxt) (T : stype), C |-sv v : T -> forall (C' : cctxt), cctxt_sctxt C C' (vars_in_sterm v) -> C' |-cv cps_value v : cps_type T).

(* case stref *) intros C T H1 C' H2 t' H3. inversion_clear H1 as [ C'' x' T' H' | | | ]. apply (cttapp _ _ _ (cps_type T) _ H3); apply cttref. apply H2. left; reflexivity. assumption.

21

Recommended