Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
対話的定理証明支援系によるミドルウェア検証
今井 敬吾 今井 宜洋 小笠原 啓有限会社ITプランニング
第9回 クリティカルソフトウェアワークショップ
2011年 11月 17日 パシフィコ横浜
概要• 定理証明ツールCoqの活用事例を紹介
• 定理証明=形式手法の一種
• 表現能力の高さが特徴
• ソースコードを直接検証できる
• ミドルウェアにおけるメッセージ変換の正しさを検証
2
アジェンダ• 定理証明とは
• 適用対象ミドルウェアと検証項目
• 証明の実際
• 検証コスト(経験年数、必要工数等)
• 議論(問題点、他の手法との比較等)
• 他の定理証明系:Agda 等
3
定理証明とは• ソースコードの動作を1ステップずつ厳密に確認することにより、ソフトウェアの正しさ(定理)を検証(証明)する手法
• 定理証明のツール:自動証明系と対話的証明系がある
• 自動:PVS, ACL2, NuPRL など
• 対話的:Coq, Agda, Isabelle/HOL など
4
参考文献(Coq’Art):Y. Bertot and P. Castéran, Interactive Theorem Proving and Program Development: Coq'Art: The Calculus of
Inductive Constructions, Springer, 2004.
なぜ定理証明か• 定理証明は形式手法で最も表現力が大きい
• モデル検査と比較して:無限の状態空間を扱える(有限であってもより素直に扱える)
• ソースコードを直接検証できる
5
定理証明の得失
6
モデル検査 定理証明
状態数 ×有限 ○無限
検証は自動? ○全自動 ×半自動/手動
表現能力 ×低い有限のモデル記述言語のみ
○高いソースコードを対象にできる
• 高階論理の一つ Calculus of Inductive Constructionsに基づく
• フランス国立情報学自動制御研究所 (INRIA) で開発された
• 特徴:①証明のための言語「タクティック」 (tactic) を備えている②関数プログラミング言語(OCaml,Haskell,Scheme)のソースコードを生成できる
• 利用事例:
Java Card の検証、 Cコンパイラの検証(CompCert)、他多数
対話的定理証明器Coq
参考Webサイト:The Coq Proof Assistant http://coq.inria.fr/ Java Card: http://www.oracle.com/technetwork/java/javacard/
CompCertプロジェクト: http://compcert.inria.fr/
7
Coqによる証明付きプログラミング
• 証明付きのプログラムを記述できる
• 記述したプログラムから、OCaml 言語のソースコードを抽出できる(他:Haskell, Schemeなど)
8
Coq証明つきプログラム
例(階乗):(*階乗関数factの定義*)Fixpoint fact x := match x with O => 1 | S y => x * fact y end.
(*定理:階乗の結果は常に0以上である)*)Theorem fact_0 : forall x,fact x>0.Proof. intro x; induction x; ...Qed.
(*抽出*)Extraction "fact.ml" fact.
OCamlプログラム
OCamlコンパイラ
実行形式
関数型プログラム
タクティックによる証明
抽出
適用対象: “iZE Smart Desktop”
ミドルウェア• 特定用途向けデスクトップ環境 (cf. Gnome, KDE, etc.)
• タブレットやSTB等のクラウド端末に搭載される
• Adobe Flashベースの専用アプリが動作
9
製品Webサイト: iZE Smart Desktop http://smartdesktop.ize.co.jp/
開発:株式会社アイズ (三重県津市)
iZE Smart Desktop:三層アーキテクチャとミドルウェア
10
ハードウェア(Linux ネイティブ)電源、ネットワーク接続、USB、etc
Flashアプリ
iSDミドルウェア(Coq+OCamlで記述)
Flashアプリにハードウェア制御機能を提供
HW機能の呼出
HWの変更をアプリに通知
iSDミドルウェア• 機能:テキスト(JSON)形式のメッセージをバイナリ形式のHW操作コマンド(D-Bus形式)に変換
11
ヘッダ 11 o p e n ... 34 4 a r g s \0 e1 ... e2 ... 7 t i m e o u ...
iSDミドルウェア(Coq+OCamlで記述)
“openDevice {‘args’:[e1,e2],‘timeout’:100.0}”
JSON形式
D-Busメッセージ形式(バイナリ)
Flashアプリで扱いやすい
(逆方向変換も行う)高速、コンパクト
• 変換のコア部分を検証(文字列処理とバイナリ処理は対象外)
検証対象:変換コア関数
12
ヘッダ 11 o p e n ... 34 4 a r g s \0 e1 ... e2 ... 7 t i m e o u ...
“openDevice {‘args’:[e1,e2],‘timeout’:100.0}”
変換コア関数
バイナリ入出力部 (OCaml-dbus)
JSONパーサー/プリンター
←検証対象iSDミドルウェア
JSON形式
D-Busメッセージ形式(バイナリ)
• 変換のコア部分を検証(文字列処理とバイナリ処理は対象外)
検証内容:変換の網羅性
13
ヘッダ 11 o p e n ... 34 4 a r g s \0 e1 ... e2 ... 7 t i m e o u ...
“openDevice {‘args’:[e1,e2],‘timeout’:100.0}”
変換コア関数
バイナリ入出力部 (OCaml-dbus)
JSONパーサー/プリンター
←検証対象iSDミドルウェア
JSON形式
D-Busメッセージ形式(バイナリ)
すべてのコマンドをアプリ側で発行できるか?
発行できないコマンド→Flashアプリの機能制限に
つながる
検証項目: すべてのコマンドをアプリ側から発行できるか?
• 「正しい」メッセージをエラーとして扱っていないか?
14
iSDミドルウェア(Coq+OCamlで記述)
iSDミドルウェア(Coq+OCamlで記述)
• JSONで表現できないD-Busデータは無いか?
דmsg {args:...}” “msg {args:...}”?
定理証明の実際
開発規模• Coq 1,400行
• Coq 変換コード本体 400行弱
• 証明 700行強
• OCaml 1,600行
16
• 実動環境(例):CPU : Atom 1GHz Mem : 1GBOS : Linuxベース
OCamlとの連携
• メッセージ変換は関数として表現しやすい
• Coqの制限:変数の再代入ができない、I/Oができない等• ネットワーク通信、配列操作等はCoqで直接表現できない
• 入力・出力はOCamlで記述
17
変換関数(Coq)
変換関数(Coq)
出力(OCaml)
入力(OCaml)
• 証明の都合で変換関数をさらに2つに分割変換コード本体(700行程度)
18
JSON-中間形式変換関数intermediate_of_json
dbus型
json型JObj[{key=”args”;value=[e1;e2]};...]
Array(Dicts(“string”,””)[{key=”args”;value=[e1;e2]};...]
中間形式-DBus形式変換関数dbus_of_intermediate
パーサーから
DBUSバイナリ出力へ
• 証明の見通しを向上させるため
• 中間データを経由によるパフォーマンス悪化は軽微
2つの相互再帰型, DBUS形式
再帰型、JSON形式
(より厳密だが、扱いづらい型)
変換コア関数dbus_of_json
• 証明の都合で変換関数をさらに2つに分割変換コード本体(700行程度)
18
JSON-中間形式変換関数intermediate_of_json
dbus型
json型JObj[{key=”args”;value=[e1;e2]};...]
Array(Dicts(“string”,””)[{key=”args”;value=[e1;e2]};...]
中間形式-DBus形式変換関数dbus_of_intermediate
パーサーから
DBUSバイナリ出力へ
• 証明の見通しを向上させるため
• 中間データを経由によるパフォーマンス悪化は軽微
2つの相互再帰型, DBUS形式
再帰型、JSON形式
(より厳密だが、扱いづらい型)
• 証明の都合で変換関数をさらに2つに分割変換コード本体(700行程度)
18
JSON-中間形式変換関数intermediate_of_json
dbus型
json型JObj[{key=”args”;value=[e1;e2]};...]
Array(Dicts(“string”,””)[{key=”args”;value=[e1;e2]};...]
中間形式-DBus形式変換関数dbus_of_intermediate
パーサーから
DBUSバイナリ出力へ
• 証明の見通しを向上させるため
• 中間データを経由によるパフォーマンス悪化は軽微
2つの相互再帰型, DBUS形式
再帰型、JSON形式
intermediate型IArray[IDict
{key=”args”;value=[e1;e2]};...]
再帰型、DBUS形式 (扱いやすい型)
(より厳密だが、扱いづらい型)
変換コア関数dbus_of_json
DBUS
JSON
全射性による検証項目の定式化• 検証項目:すべてのD-Busコマンドをアプリ側から発行できるか?
• 定式化:dbus_of_json は全射(surjective) か?
19
Theorem surjection : ∀db, ∃js, dbus_of_json js = db.
Coq
全D-Busコマンドの網羅=変換関数の全射性
全射
(すべてのD-Busコマンド対して、 変換元のJSON値が存在する)
証明(700行程度)
• 全射の合成性を活用• 全射関数の合成は全射である
• 各補助関数の全射性を証明→全体の全射性を証明
20
JSON-中間形式変換関数intermediate_of_json
中間形式-DBus形式変換関数dbus_of_intermediate
JSON
D-Bus
全射?
全射?
中間形式
Lemma surjection_ij : ∀it, ∃js, itermediate_of_json js = it.Proof. (*約120行*) Qed.Lemma surjection_di : ∀db, ∃it, dbus_of_intermediate it = db.Proof. (*約200行*) Qed.
不具合の発見• JSONで表現できないD-Busコマンドがあった(変換仕様の抜け漏れ)
• D-Busの配列:ヘッダに a(型名) と書く
21
ai 3 -1 3 -5ヘッダ:長さ3の整数(i) 配列
配列[-1,3,-5]
• 不具合:バイト型以外の空の配列を作成できない• (長さ0の配列はバイト型の配列に決め打ちされていた)
ay 0“[]” 変換JSON:空の配列(int型の配列を意図)
D-Bus:長さ0のバイト型(y) 配列
• 修正:配列構文に型指定を追加 “{type:‘int’,array=[]}”
検証のコスト工数 (変換コアのみ)
• 実装コードの記述:0.1人月
• 証明:0.4人月
→比較的短期間、妥当な工数
行数
• 全1,400行
• 変換本体400行, 証明700行,
抽出300行
実施者の能力等
• 入社3年目 (当時)
• 入社後にプログラミング(OCaml)を習得
• 数学科出身
• 大学院在籍時にCoqを習得
(週1回Coq’Artを輪読,1年間)
22
考察1. 他手法との比較
• 最低限のテスト入力数(概算):約500通り
• 同値分割:D-Busの全プリミティブ型 (12種)の連想配列(2乗)の組み合わせ
• C0カバレッジ:OCaml-dbusの全型(15種)+全配列型(17種)
• テスト困難な数ではない
• 「長さ0の配列 問題」→ 境界値テストでカバーできる
• しかしテストは網羅的になり得ず、抜け漏れの不安は残る
• 網羅的な形式手法(定理証明)で検証済みである信頼感は他では代え難い
23
考察2. 必要なスキル
• 定理証明を扱える技術者は稀少→プロジェクト規模に対してスケールしにくい
• 仮説:今回の規模であれば育成は数ヶ月~1年程度の学習でも可能ではないか?(関数型プログラミングか、形式手法の基礎知識を前提)
• 複雑な証明技法やドメイン知識を(今回は)使用しなかった
➡定理証明を使える技術者を育成するため、公私にわたり定理証明の普及活動(勉強会・セミナー)を継続中(今井宜洋)
• ProofCafe (http://proofcafe.org/), 国立情報学研究所 TopSE セミナーなど
24
他の定理証明支援系:Agda
• スウェーデン・Chalmers大学で開発されている
• プログラムの記述性がやや高い(型推論がやや強力)
• 証明支援の方法が異なる• 証明支援言語(タクティック)がない(証明自動化の支援がない)
• emacs上で証明項を構築する方式
• Agdaでも今回の検証を容易に模倣可能だと考えられる
• ただし、証明の方法が異なるため別途訓練が必要
25
参考Webサイト:The Agda wiki (Agdaの公式サイト) http://wiki.portal.chalmers.se/agda/
今後の課題• 適用範囲の拡大• 配列操作を伴うプログラム:より時間効率・空間効率の良いコードを対象に
• C言語プログラムの検証➡ ホーア論理・分離論理を扱う必要あり
• Coq to Scala:開発中
• CoqのコードからScala言語のコードを抽出する
• 利点:JVM上で検証済みコードが動作する→定理証明の実践例の拡大
• 国立情報学研究所様との共同研究
26
結び
• 対話的定理証明系Coqでメッセージ変換ミドルウェアの検証を行った
• 定式化:変換の網羅性=関数の全射性
• 仕様の抜け漏れを発見:空の配列の扱い
• 課題:適用範囲の拡大
27