形式的技法によるプログラム検証fujita/nagamiya080310_html/... · krakatoa+coq...

52
形式的技法によるプログラム検証 JavaCard における適用例 永宮 悠大 群馬大学大学院工学研究科情報工学専攻 藤田研究室 Email : [email protected] 形式的技法によるプログラム検証 – p.1/41

Upload: others

Post on 28-Aug-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

形式的技法によるプログラム検証JavaCardにおける適用例

永宮悠大

群馬大学大学院工学研究科情報工学専攻藤田研究室Email : [email protected]

形式的技法によるプログラム検証 – p.1/41

Page 2: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

概要

■ 形式的技法

■ Hoare論理

■ Javaプログラムの検証

■ まとめと今後の課題

形式的技法によるプログラム検証 – p.2/41

Page 3: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

形式的技法 (formal method)

■ 形式的仕様記述 (formal specification)

❑ プログラムの仕様を形式的 (formal)に記述すること

– 論理や代数を用いる– JML, D, VDM, · · ·

■ 形式的検証 (formal method)

❑ プログラムが仕様を満たすことを形式的に証明すること

– 論理的な推論(定理証明技法)– オートマトンによる全数検査(モデル検査技法)

形式的技法によるプログラム検証 – p.3/41

Page 4: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

概要

■ 形式的技法

■ Hoare論理

■ Javaプログラムの検証

■ まとめと今後の課題

形式的技法によるプログラム検証 – p.4/41

Page 5: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

事前条件と事後条件

プログラムの実行前に満たしているべき条件

プログラムの実行後に満たされるべき条件

プログラム(文)

事前条件(precondition)

事後条件(postcondition)

形式的技法によるプログラム検証 – p.5/41

Page 6: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

Hoare論理

■ [[φ]] P [[ψ]]

❑ φ, ψは論理式で,P はプログラム(文)

❑ 事前条件φを満たした状態でプログラムP を実行し,P の実行が停止するならば,実行後の状態は事後条件ψを満たす(部分正当性)

❑ [[φ]] P [[ψ]]はプログラムP の部分正当性に関する検証文と呼ばれる

形式的技法によるプログラム検証 – p.6/41

Page 7: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

代入文の公理

[[ψ[E/x]]] x = E [[ψ]]

■ ψ[E/x]はψ中の変数 xを式Eで置き換えたもの

■ 例:[[x+ 1 > 1]] x = x + 1 [[x > 1]]

形式的技法によるプログラム検証 – p.7/41

Page 8: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

複合文の規則

[[φ]] C1 [[η]] [[η]] C2 [[ψ]]

[[φ]] C1;C2 [[ψ]]

C1

C2

φ

η

ψ

形式的技法によるプログラム検証 – p.8/41

Page 9: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

帰結の規則

`AR φ′ → φ [[φ]] C [[ψ]] `AR ψ → ψ′

[[φ′]] C [[ψ′]]

形式的技法によるプログラム検証 – p.9/41

Page 10: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

証明の例

`AR > → 0 = 0 [[0 = 0]] x = 0 [[x = 0]]

[[>]] x = 0 [[x = 0]] [[x = 0]] y = x [[y = 0]]

[[>]] x = 0; y = x [[y = 0]]

形式的技法によるプログラム検証 – p.10/41

Page 11: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

証明の例

`AR > → 0 = 0 [[0 = 0]] x = 0 [[x = 0]]

[[>]] x = 0 [[x = 0]] [[x = 0]] y = x [[y = 0]]

[[>]] x = 0; y = x [[y = 0]]

[[>]]

[[0 = 0]]

x = 0;

[[x = 0]]

y = x;

[[y = 0]]

形式的技法によるプログラム検証 – p.11/41

Page 12: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

if文の規則

[[φ ∧B]] C1 [[ψ]] [[φ ∧ ¬B]] C2 [[ψ]]

[[φ]] if B {C1} else {C2} [[ψ]]

B

C1 C2

true false

φ

ψ

φ ∧B φ ∧ ¬B

形式的技法によるプログラム検証 – p.12/41

Page 13: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

while文の規則[[ψ ∧B]] C [[ψ]]

[[ψ]] while B {C} [[ψ ∧ ¬B]]

■ ψはループ不変条件 (loop invariant)と呼ばれる

B

C

true false

ψ

ψ ∧ ¬B

ψ ∧B

形式的技法によるプログラム検証 – p.13/41

Page 14: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

例:階乗

y = 1;

z = 0;

l1: while (z != x) {

z = z + 1;

y = y * z;

l2: }

形式的技法によるプログラム検証 – p.14/41

Page 15: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

事前・事後条件の設定

[[>]]

y = 1;

z = 0;

l1: while (z != x) {

z = z + 1;

y = y * z;

l2: }

[[y = x!]]

形式的技法によるプログラム検証 – p.15/41

Page 16: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

ループ不変条件の設定■ x = 6の場合:

ループ回数 z at l1 y at l1 z 6= x! at l1

0 0 1 true

1 1 1 true

2 2 2 true

3 3 6 true

4 4 24 true

5 5 120 true

6 6 720 false

形式的技法によるプログラム検証 – p.16/41

Page 17: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

ループ不変条件の設定■ x = 6の場合:

ループ回数 z at l1 y at l1 z 6= x! at l1

0 0 1 true

1 1 1 true

2 2 2 true

3 3 6 true

4 4 24 true

5 5 120 true

6 6 720 false

ループ不変条件は y = z!

形式的技法によるプログラム検証 – p.16/41

Page 18: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

while文の規則の適用[[>]]

y = 1;

z = 0;

[[y = z!]]

l1: while (z != x) {

[[y = z! ∧ z 6= x]]

z = z + 1;

y = y * z;

[[y = z!]]

l2: }

[[y = z! ∧ z = x]]

[[y = x!]]

形式的技法によるプログラム検証 – p.17/41

Page 19: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

代入文の公理の適用[[>]]

y = 1;

z = 0;

[[y = z!]]

l1: while (z != x) {

[[y = z! ∧ z 6= x]]

z = z + 1;

[[y · z = z!]]

y = y * z;

[[y = z!]]

l2: }

[[y = z! ∧ z = x]]

[[y = x!]]

形式的技法によるプログラム検証 – p.18/41

Page 20: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

代入文の公理の適用[[>]]

y = 1;

z = 0;

[[y = z!]]

l1: while (z != x) {

[[y = z! ∧ z 6= x]]

[[y · (z + 1) = (z + 1)!]]

z = z + 1;

[[y · z = z!]]

y = y * z;

[[y = z!]]

l2: }

[[y = z! ∧ z = x]]

[[y = x!]]

形式的技法によるプログラム検証 – p.19/41

Page 21: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

代入文の公理の適用[[>]]

y = 1;

[[y = 0!]]

z = 0;

[[y = z!]]

l1: while (z != x) {

[[y = z! ∧ z 6= x]]

[[y · (z + 1) = (z + 1)!]]

z = z + 1;

[[y · z = z!]]

y = y * z;

[[y = z!]]

l2: }

[[y = z! ∧ z = x]]

[[y = x!]]

形式的技法によるプログラム検証 – p.20/41

Page 22: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

代入文の公理の適用[[>]]

[[1 = 0!]]

y = 1;

[[y = 0!]]

z = 0;

[[y = z!]]

l1: while (z != x) {

[[y = z! ∧ z 6= x]]

[[y · (z + 1) = (z + 1)!]]

z = z + 1;

[[y · z = z!]]

y = y * z;

[[y = z!]]

l2: }

[[y = z! ∧ z = x]]

[[y = x!]]

形式的技法によるプログラム検証 – p.21/41

Page 23: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

帰結の規則の適用[[>]]

[[1 = 0!]] `AR > → 1 = 0!

y = 1;

[[y = 0!]]

z = 0;

[[y = z!]]

l1: while (z != x) {

[[y = z! ∧ z 6= x]] `AR (y = z! ∧ z 6= x) →

[[y · (z + 1) = (z + 1)!]] (y · (z + 1) = (z + 1)!)

z = z + 1;

[[y · z = z!]]

y = y * z;

[[y = z!]]

l2: }

[[y = z! ∧ z = x]]

[[y = x!]] `AR (y = z! ∧ z = x) → (y = x!)

形式的技法によるプログラム検証 – p.22/41

Page 24: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

帰結の規則の適用[[>]]

[[1 = 0!]] `AR > → 1 = 0!

y = 1;

[[y = 0!]]

z = 0;

[[y = z!]]

l1: while (z != x) {

[[y = z! ∧ z 6= x]] `AR (y = z! ∧ z 6= x) →

[[y · (z + 1) = (z + 1)!]] (y · (z + 1) = (z + 1)!)

z = z + 1;

[[y · z = z!]]

y = y * z;

[[y = z!]]

l2: }

[[y = z! ∧ z = x]]

[[y = x!]] `AR (y = z! ∧ z = x) → (y = x!)

Q.E.D形式的技法によるプログラム検証 – p.23/41

Page 25: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

概要

■ 形式的技法

■ Hoare論理

■ Javaプログラムの検証

■ まとめと今後の課題

形式的技法によるプログラム検証 – p.24/41

Page 26: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

契約による設計 (Design by contract)

■ [[φ]] P [[ψ]]をメソッド呼出し側と実装側の間の契約(contract)と考える

❑ 呼出し側がφを満たした状態でメソッドP を呼出すことを約束するならば,実装側はP を実行した結果がψを満たすことを保証する

❑ φが満たされなかったときは,メソッド呼出し側にバグがある

❑ ψが満たされなかったときは,メソッド内部にバグがある

形式的技法によるプログラム検証 – p.25/41

Page 27: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

契約

■ 事前条件 (precondition)❑ メソッドの入力引数の検査

■ 事後条件 (postcondition)❑ メソッドの返り値,副作用の検査

■ クラス不変条件 (invariant)❑ 常に真でなければならないクラスの性質を記述

形式的技法によるプログラム検証 – p.26/41

Page 28: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

Java Modeling Language

■ Javaプログラムの形式的な仕様を記述するための言語

■ Design by contractの考えに基づいている

形式的技法によるプログラム検証 – p.27/41

Page 29: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

JMLによる仕様の記述

■ JML仕様はソースコードの中に@マーク付きのコメントとして記述

//@ ...

/*@ ...*@ ...*@/

形式的技法によるプログラム検証 – p.28/41

Page 30: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

JMLの構文

■ 事前・事後条件:requiresと ensures

❑ //@ requires array.length >=1;

❑ //@ ensures \result >= x;

■ クラス不変条件:invariant

❑ //@ public invariant balance >= 0;

■ フレーム条件:modefiable

❑ メソッドによって変更される変数

❑ //@ modifiable array[x];

形式的技法によるプログラム検証 – p.29/41

Page 31: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

JMLのキーワード

■ メソッドの返り値: \result

■ メソッド実行前の式Eの値: \old(E)

■ 量化記号: \forall, \exists

形式的技法によるプログラム検証 – p.30/41

Page 32: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

Krakatoa+Coq

Krakatoa Why Coq

Java + JML検証文

(Ocaml)proof obligation

(述語論理)

■ Krakatoa: Java/JMLソース 7→検証文

■ Why: 検証文 7→Hoare proof obligation

■ Coq: proof obligationを対話的に証明

proof obligationが証明できる⇒プログラムが仕様を満たす

形式的技法によるプログラム検証 – p.31/41

Page 33: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

Krakatoa+Coq

Krakatoa Why Coq

Java + JML検証文

(Ocaml)proof obligation

(述語論理)

■ Krakatoa: Java/JMLソース 7→検証文

■ Why: 検証文 7→Hoare proof obligation

■ Coq: proof obligationを対話的に証明

proof obligationが証明できる⇒プログラムが仕様を満たす形式的技法によるプログラム検証 – p.31/41

Page 34: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

Gemplusの電子財布

■ JavaCardの検証のための現実的な例として開発されたアプリケーション

■ 入金,出金,外貨両替

■ アプレット間通信

■ 本人認証 (IDとパスワード)

■ ロイヤリティ・ポイント

形式的技法によるプログラム検証 – p.32/41

Page 35: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

電子財布のクラス図

UtilsパッケージJour 日Mois 月Annee 年Decimal 残高に関する演算

PcpcapinterfacesパッケージPurseLoyaltyInterface Loyaltyアプレットとの通信TransactionInterface Shareableインタフェース

形式的技法によるプログラム検証 – p.33/41

Page 36: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

電子財布のクラス図

UtilsパッケージJour 日Mois 月Annee 年Decimal 残高に関する演算

PcpcapinterfacesパッケージPurseLoyaltyInterface Loyaltyアプレットとの通信TransactionInterface Shareableインタフェース

形式的技法によるプログラム検証 – p.33/41

Page 37: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

Decimalクラスによる残高の表現

setValue

¥ 3.493

submul

add

oppose

DecimalintPart = 3

decPart = 493

■ JavaCardには int型,浮動小数点型が

ない

■ intPart, decPartは short型の変数

■ decPartの有効桁数は 3桁

❑ 0 <= decPart &&

decPart < PRECISION

❑ PRECISIONは short型の定数

1000

形式的技法によるプログラム検証 – p.34/41

Page 38: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドprivate void add(short e, short f) {

intPart += e;

decPart += f;

if (decPart <= -PRECISION) {

decPart += PRECISION;

intPart--;

}

else if (decPart >= PRECISION) {

decPart -= PRECISION;

intPart++;

}

}形式的技法によるプログラム検証 – p.35/41

Page 39: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドの仕様を考える

setValue

submul

add

oppose

DecimalintPart = 3

decPart = 493 setValue

submul

add

oppose

DecimalintPart = 4

decPart = –507

¥ 3.493

intPart * PRECISION + decPart = 3493

形式的技法によるプログラム検証 – p.36/41

Page 40: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドの仕様

/*@ private normal_behavior

@ requires -PRECISION < f && f < PRECISION &&

@ -MAX_DECIMAL_NUMBER <= e && e <= MAX_DECIMAL_NUMBER &&

@ -MAX_DECIMAL_NUMBER <= e + intPart - 1 &&

@ e + intPart + 1 <= MAX_DECIMAL_NUMBER;

@ modifiable intPart, decPart;

@ ensures intPart * PRECISION + decPart ==

@ (\old(intPart) + e) * PRECISION + \old(decPart) + f;

@*/

private void all (short e, short f) { ... }

形式的技法によるプログラム検証 – p.37/41

Page 41: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドの検証

論理式 コード

private void add(short e, short f) {

intPart += e;

decPart += f;

if (decPart <= -PRECISION) {

decPart += PRECISION;

intPart--;

}

else if (decPart >= PRECISION) {

decPart -= PRECISION;

intPart++;

}

}

形式的技法によるプログラム検証 – p.38/41

Page 42: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドの検証

論理式 コード

private void add(short e, short f) {

intPart += e;

decPart += f;

if (decPart <= -PRECISION) {

decPart += PRECISION;

intPart--;

}

else if (decPart >= PRECISION) {

decPart -= PRECISION;

intPart++;

}

}intPart · PRECISION + decPart

= (intPart0 + e) · PRECISION

+ decPart0 + f

形式的技法によるプログラム検証 – p.38/41

Page 43: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドの検証

論理式 コード

private void add(short e, short f) {

intPart += e;

decPart += f;

if (decPart <= -PRECISION) {

decPart += PRECISION;

intPart--;

}

else if (decPart >= PRECISION) {

decPart -= PRECISION;

intPart++;

}

}

intPart · PRECISION + decPart

= (intPart0 + e) · PRECISION

+ decPart0 + f

intPart · PRECISION + decPart

= (intPart0 + e) · PRECISION

+ decPart0 + f

形式的技法によるプログラム検証 – p.38/41

Page 44: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドの検証

論理式 コード

private void add(short e, short f) {

intPart += e;

decPart += f;

if (decPart <= -PRECISION) {

decPart += PRECISION;

intPart--;

}

else if (decPart >= PRECISION) {

decPart -= PRECISION;

intPart++;

}

}

(intPart + 1) · PRECISION + decPart

= (intPart0 + e) · PRECISION

+ decPart0 + f

intPart · PRECISION + decPart

= (intPart0 + e) · PRECISION

+ decPart0 + f

形式的技法によるプログラム検証 – p.38/41

Page 45: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドの検証

論理式 コード

private void add(short e, short f) {

intPart += e;

decPart += f;

if (decPart <= -PRECISION) {

decPart += PRECISION;

intPart--;

}

else if (decPart >= PRECISION) {

decPart -= PRECISION;

intPart++;

}

}

(intPart + 1) · PRECISION

+(decPart − PRECISION )

= (intPart0 + e) · PRECISION

+ decPart0 + f

intPart · PRECISION + decPart

= (intPart0 + e) · PRECISION

+ decPart0 + f

形式的技法によるプログラム検証 – p.38/41

Page 46: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドの検証

論理式 コード

private void add(short e, short f) {

intPart += e;

decPart += f;

if (decPart <= -PRECISION) {

decPart += PRECISION;

intPart--;

}

else if (decPart >= PRECISION) {

decPart -= PRECISION;

intPart++;

}

}

(intPart + 1) · PRECISION

+(decPart − PRECISION )

= (intPart0 + e) · PRECISION

+ decPart0 + f

(intPart − 1) · PRECISION + decPart

= (intPart0 + e) · PRECISION

+ decPart0 + f

形式的技法によるプログラム検証 – p.38/41

Page 47: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドの検証

論理式 コード

private void add(short e, short f) {

intPart += e;

decPart += f;

if (decPart <= -PRECISION) {

decPart += PRECISION;

intPart--;

}

else if (decPart >= PRECISION) {

decPart -= PRECISION;

intPart++;

}

}

(intPart + 1) · PRECISION

+(decPart − PRECISION )

= (intPart0 + e) · PRECISION

+ decPart0 + f

(intPart − 1) · PRECISION

+(decPart + PRECISION )

= (intPart0 + e) · PRECISION

+ decPart0 + f

形式的技法によるプログラム検証 – p.38/41

Page 48: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドの検証

論理式 コード

private void add(short e, short f) {

intPart += e;

decPart += f;

if (decPart <= -PRECISION) {

decPart += PRECISION;

intPart--;

}

else if (decPart >= PRECISION) {

decPart -= PRECISION;

intPart++;

}

}

(decPart ≤ −PRECISION ) →

(intPart − 1) · PRECISION

+(decPart + PRECISION )

= (intPart0 + e) · PRECISION

+ decPart0 + f

(decPart > −PRECISION ) ∧ (decPart ≥

PRECISION ) →

(intPart + 1) · PRECISION

+(decPart − PRECISION )

= (intPart0 + e) · PRECISION

+ decPart0 + f

形式的技法によるプログラム検証 – p.38/41

Page 49: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

addメソッドの検証

論理式 コード

private void add(short e, short f) {

intPart += e;

decPart += f;

if (decPart <= -PRECISION) {

decPart += PRECISION;

intPart--;

}

else if (decPart >= PRECISION) {

decPart -= PRECISION;

intPart++;

}

}

(decPart ≤ −PRECISION ) →

(intPart − 1) · PRECISION

+(decPart + PRECISION )

= (intPart0 + e) · PRECISION

+ decPart0 + f

(decPart > −PRECISION ) ∧ (decPart ≥

PRECISION ) →

(intPart + 1) · PRECISION

+(decPart − PRECISION )

= (intPart0 + e) · PRECISION

+ decPart0 + f

Q.E.D

形式的技法によるプログラム検証 – p.38/41

Page 50: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

概要

■ 形式的技法

■ Hoare論理

■ Javaプログラムの検証

■ まとめと今後の課題

形式的技法によるプログラム検証 – p.39/41

Page 51: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

まとめと今後の課題

まとめ:

■ Krakatoaを用いて addメソッドを検証した

■ proof obligation =証明タブローで最後に残る証明(帰結の規則)

今後の課題:

■ より複雑な例の検証

❑ mulメソッド

❑ インサーション・ソート,セレクション・ソート

■ 証明タブローを構成するアルゴリズムの実装

形式的技法によるプログラム検証 – p.40/41

Page 52: 形式的技法によるプログラム検証fujita/nagamiya080310_html/... · Krakatoa+Coq Krakatoa Why Coq Java + JML 検証文 (Ocaml) proof obligation (述語論理) Krakatoa:

Thank You!

形式的技法によるプログラム検証 – p.41/41