21
依依依依依依依依依依 依依依依依依依依依依依依 依依依依依依依依 依依 依依 依依依依依依依依依依 依依依依依 1

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

  • Upload
    merv

  • View
    29

  • Download
    0

Embed Size (px)

DESCRIPTION

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

Citation preview

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

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

型保存コンパイラ

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

1

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

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

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

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

2

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

コンパイラの検証

構文の変換

ソース コード

アセンブリ コード

3

ソースの意味論

アセンブリの

意味論

意味論が一致すること

を証明

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

既存研究• 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

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

本研究のアプローチ

5

コードの挙動を

規定できる型

型保存コンパイル

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

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

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

– 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

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

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

7

コード :

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

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

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

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

• G. Morrisett et al. 1999

8

ソース コード

アセンブリ コード

型導出木

型導出木

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

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

9

ソース コード

アセンブリ コード

型導出木

型導出木

意味論

意味論

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

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

• 型保存性を Coq で証明

10

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

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

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

11

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

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

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

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

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

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

12

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

13

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

コンパイラの構成

14

ソース コード

アセンブリ コード

CPS 変換

クロージャ変換

Hoisting

レジスタ割当

型導出木

型導出木

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

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

• R. Burstall and B. Lampson 1984

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

恒等関数のコード :

λx. x

恒等関数の型 :

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

15

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

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

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

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 }

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

18

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

ラムダ計算 + メモリ操作

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

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

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

型安全 型安全 非型安全

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

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

ソースの定義 ( 仮 )

副作用のない項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}

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

アセンブリの定義 ( 仮 )

命令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 }

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

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