実際の正式なプログラム検証


66

ソフトウェアエンジニアとして、工業製品用のコードをたくさん書いています。クラス、スレッド、いくつかの設計作業、およびパフォーマンスの妥協を伴う比較的複雑なもの。私は多くのテストを行い、テストにうんざりしているので、Coq、Isabelleなどの正式な証明ツールに興味を持ちました...これらのいずれかを使用して、コードにバグがないことを正式に証明できますか?それと?-しかし、これらのツールの1つをチェックアウトするたびに、日常のソフトウェアエンジニアリングに使用できると確信せずに立ち去ります。今、それは私だけである可能性があり、私はそれについてのポインタ/意見/アイデアを探しています:-)

特に、これらのツールの1つを機能させるには、検討中のプログラムのオブジェクト、メソッドなどを証明者に適切に定義するために莫大な投資が必要になるという印象を受けます。それから、証明者は、対処しなければならないすべてのサイズを考えると、蒸気が尽きないのではないかと思います。または、副作用を取り除く必要があるかもしれません(これらの証明ツールは宣言型言語で本当にうまくいくようです)、それが高速ではないため使用できない「実証済みのコード」になるかどうか疑問に思います十分に小さい。また、使用する言語を変更する余裕はありません。JavaまたはC ++である必要があります。OXXXmlでコードを作成するのは上司に伝えることはできません。コードの正確性を証明できます...

フォーマルプルーフツールの経験が豊富な人はコメントできますか?再び-私なりLOVE正式な証明ツールを使用して、私は彼らが素晴らしいと思いますが、私は彼らが私は、Java / C ++の卑しい溝から到達することはできません象牙の塔にいるという印象を持っている...(PS:IまたLOVEハスケル、OCamlは...間違った考え方得ることはありません:私は、宣言型言語や形式的な証明のファンですが、私は)私は現実的ソフトウェア工学にその便利を作ることができる方法を確認しようとしています

更新:これはかなり広いので、次のより具体的な質問を試してみましょう:1)証明者を使用して産業用Java / C ++プログラムの正確性を証明する例はありますか?2)Coqはそのタスクに適していますか?3)Coqが適切な場合、最初にCoqでプログラムを作成し、次にCoqからC ++ / Javaを生成する必要がありますか?4)このアプローチは、スレッド化とパフォーマンスの最適化を処理できますか?


3
私はあなたの問題を理解しますが、この質問が何であるかはわかりません(SEの投稿として)。討論?経験?どちらもSEには適していません。「私にできることは何ですか?」口調は、これがあまりにも広すぎる質問であると感じさせます。
ラファエル

3
なるほど...この質問は明確に定式化されていないことに同意します。それでは、1)証明者を使用して産業用Java / C ++プログラムの正確性を証明する例はありますか?2)Coqはそのタスクに適していますか?3)Coqが適切な場合、最初にCoqでプログラムを作成してから、CoqからC ++ / Javaを生成する必要がありますか?4)このアプローチは、スレッド化とパフォーマンスの最適化に対処できますか?
フランク

2
それでは4つの質問です。1)ここで(多くの)業界の専門家に出会う可能性は低いため、ソフトウェアエンジニアリングの方がおそらく良いでしょう。2)多少主観的ですが、客観的な視点を提供できる人がいる可能性があります。3)私の知る限り、完全に主観的です。4)このサイトに対するいい質問です。要約すると、質問を分けて、最初の質問でソフトウェアエンジニアリングにアクセスし、投稿する前に客観的な(!)回答が期待できるかどうか(!)をよく考えてください。
ラファエル

10
あなたは正式な検証の夢を説明していますが、私たちはそこから遠く離れています。私の知る限り、プログラムの検証は非日常的なタスクであり、非常に単純なプログラムにのみ適用されます。そうは言っても、この質問はサイトのスポットオンであると思います。そして、その分野の限界を認め、最新技術と限界を説明する地域の誰かに感謝します(おそらく、いくつかの調査にリンクすることによって)。
ユヴァルフィルマス

9
C ++プログラムの検証に関する問題は、C ++が明確に定義された言語ではないことです。ソフトウェアシステムの多くの部分(OS、ライブラリ、プログラミング言語)が検証をサポートするために実際に再設計されるまで、大規模な検証は不可能だと思います。よく知られているように、200000行のコードを誰かにダンプして、「verify!」と言うことはできません。一緒にコードを検証して記述する必要があり、検証するという事実にプログラミング習慣を適応させる必要があります。
アンドレイバウアー

回答:


35

私はあなたの質問のいくつかに簡潔な答えをしようとします。これは厳密に私の研究分野ではないため、私の情報の一部は古くなったり間違っている可能性があります。

  1. JavaおよびC ++のプロパティを正式に証明するために特別に設計された多くのツールがあります。

    ただし、ここで少し余談しなければなりません。プログラムの正しさを証明することはどういう意味ですか?Java型チェッカーは、Javaプログラムの正式な特性、つまりa floatやanの追加などの特定のエラーintが決して発生しないことを証明します!あなたはもっと強い特性、つまりあなたのプログラムが望ましくない状態に陥ることができないこと、または特定の関数の出力が特定の数学的仕様に準拠すること、に興味があると思います。簡単に言えば、単純なセキュリティプロパティから、プログラムが詳細な仕様を満たしていることを完全に証明するまで、「プログラムの正しいことを証明する」という意味には大きな勾配があります。

    ここで、プログラムについて強力な特性を証明することに興味があると仮定します。セキュリティプロパティに関心がある場合(プログラムが特定の状態に到達できない場合)、一般的にはモデルチェックが最善のアプローチと思われます。ただし、Javaプログラムの動作を完全に指定する場合は、その言語の仕様言語、たとえばJMLを使用するのが最善の策です。ACSLなど、Cプログラムの動作を指定するための言語はありますが、C ++については知りません。

  2. 仕様が決まったら、プログラムがその仕様に準拠していることを証明する必要があります。

    このためには、適切な定理、つまりプログラムの実行が仕様を尊重することを表現するために、仕様と言語の動作セマンティクス(JavaまたはC ++)の両方を正式に理解するツールが必要です。

    このツールを使用すると、その定理の証明を定式化または生成することもできます。現在、これらのタスク(指定と証明)はどちらも非常に難しいため、多くの場合2つに分けられます。

    • コード、仕様を解析し、適切な定理を生成する1つのツール。フランクが述べたように、クラカトアはそのようなツールの例です。

    • 定理を証明する1つのツール。自動またはインタラクティブに。Coqはこの方法でKrakatoaと対話し、Z3などの強力な自動化ツールも使用できます。

    1つ(小さな)ポイント:自動化された方法では証明するのが難しすぎる定理がいくつかあります。また、自動定理証明器には、信頼性を低下させる健全性のバグがあることが知られています。これは、Coqが比較して輝いている領域です(ただし、自動ではありません!)。

  3. Ocamlコードを生成する場合は、必ず最初にCoq(Gallina)を記述してから、コードを抽出してください。ただし、Coqは、可能な場合でもC ++またはJavaの生成がひどいです。

  4. 上記のツールはスレッド化とパフォーマンスの問題を処理できますか?おそらくそうではありませんが、パフォーマンスとスレッドの問題は特に難しい問題であるため、特別に設計されたツールで処理するのが最適です。Martin HofmannのPolyNIプロジェクトは興味深いようですが、ここで推奨するツールがあるかどうかはわかりません

結論として、「実世界」のJavaおよびC ++プログラムの正式な検証は、大きく発達した分野であり、Coqはそのタスクの一部に適しています。たとえば、ここで概要を確認できます。


この投稿と追加した参考文献に感謝します。私見、ソフトウェアエンジニアの目標は、1)常に正しい結果を提供し、2)失敗しないシステムを迅速にリリースできるようにすることです。ここで回帰の問題を見ることができます。仕様自体が「バグがない」ことを証明したい場合があります。そのため、言語、そしてもう一つ...
フランク

6
問題は、ユーザーが「望む」ものが通常、正式な言語で表現されていないことです!一般に、この質問に対する正式な回答はありません。「この正式な仕様は私の非公式のアイデアに適合していますか?」正式な仕様をテストし、特定の数学的特性があることを証明することは可能ですが、最終的には数学を非公式のプロセスである現実世界に関連付ける必要があります。
コーディ

はい、もちろん-正式な方法は明確に定義されたポイントからしか開始できないといつも思っていました。その仕様が現実のユーザーの意識的/無意識的/未発見のニーズに適合しているかどうかが別の問題であり、正式な方法では対処できません(しかし、確かにエンジニアにとっては問題です)。
フランク

定理は、定義により証明された命題です。したがって、おそらく「定理を証明する」つもりはありません。
-nbro

@nbro Wikipediaはあなたに同意しているようです。しかし、Mathworldは定理を「受け入れられた数学的操作によって真であることが証明できる」命題であると定義しています。この場合、定理の証明を与えることは可能であるだけでなく、それらを呼び出すことを正当化するために必要です!:)(これは、もちろん、counterquibbleある)
コーディ

15

産業用または非自明な実システムでの形式的手法/形式的検証ツールの3つの注目すべきアプリケーションに言及したいと思います。私はこのトピックについてほとんど経験がなく、論文を読むことからしか学習していないことに注意してください。

  1. 2005年にNASAによってリリースされたオープンソースツールJava Pathfinder(略してJPF)は、実行可能なJavaバイトコードプログラムを検証するシステムです(Java Pathfinder @ wikiを参照)。NASA AmesのK9 Roverのエグゼクティブソフトウェアの不整合を検出するために使用されています。

  2. このペーパー:モデルチェックを使用して深刻なファイルシステムエラーを検出する@ OSDI'04では、モデルチェックを使用してファイルシステムの重大なエラーを検出する方法を示します。FiSCと呼ばれるシステムは、広く使用され、テストされた3つのファイルシステムext3、JFS、およびReiserFSに適用され、32の重大なバグが見つかりました。ベストペーパー賞を受賞しました。

  3. このペーパー:Amazon Web ServicesがFormal Methods @ CACM'15を使用する方法では、AW​​SがS3、DynamoDB、EBS、内部分散ロックマネージャーなどの製品に正式なメソッドを適用する方法について説明しています。LamportのTLA +ツールに焦点を当てています。ところで、Lamportは自分のTLAツールボックスを集中的に使用しました。彼は、論文の付録で自分自身(および共著者)が提案したアルゴリズム/定理の(非常に完全な)正式な検証をTLAで頻繁に行います。


4

プログラムの正式な仕様は、(多かれ少なかれ)別のプログラミング言語で書かれたプログラムです。その結果、仕様には必ず独自のバグが含まれます。

フォーマル検証の利点は、プログラムと仕様が2つの別個の実装であるため、バグが異なることです。しかし、常にではありません。バグの一般的な原因の1つである、見落とされたケースは、しばしば一致します。したがって、正式な検証は万能薬ではありません。それでも、重要なバグを見逃す可能性があります。

フォーマル検証の欠点は、実装コストの2倍、おそらくそれ以上を課す可能性があることです(フォーマル仕様の専門家が必要であり、それに付属する多かれ少なかれ実験的なツールを使用する必要があります;安くはなりません) )。

テストケースとスキャフォールディングを設定して自動的に実行する方が、時間を有効に活用できると思います。


フォーマル検証の利点は...です。フォーマル検証の2番目の欠点は...混乱することです。
hengxin

仕様と非公式のタスクの不一致は、ソフトウェアの要件分析の問題であり、プログラミングの問題ではないと思います。
カベ

3

セーフティクリティカルな組み込みシステム向けに設計されたC ++のサブセットで記述されたプログラムの正式な検証が可能になりました。参照http://eschertech.com/papers/CanCPlusPlusBeMadeAsSafeAsSpark.pptを短いプレゼンテーションのために、そしてhttp://eschertech.com/papers/CanCPlusPlusBeMadeAsSafeAsSpark.pdf完全な紙のために。


5
リンクをありがとう。特にリンクが企業のWebサイトへのリンクであるため、リンクの腐敗を防ぐために、少なくともコンテンツの概要を簡単に説明すると役立ちます。
デビッドリチャービー14年

2

いくつかの異なる質問をします。産業/商業アプリケーションの正式な検証方法はそれほど一般的ではないと思われることに同意します。ただし、プログラムの正確性を判断するために、多くの「形式的検証」の原則がコンパイラに組み込まれていることを理解してください。ある意味では、最新のコンパイラーを使用している場合、フォーマル検証で最先端の多くを使用していることになります。

あなたは「テストにうんざりしている」と言いますが、正式な検証は実際にはテストの代わりではありません。ある意味では、テストのバリエーションです。

あなたはJavaに言及します。FindBugsと呼ばれるJava検証プログラムに組み込まれた多くの高度な形式検証方法がありますが、実際には大規模なコードベースで実行できます。「偽陽性と偽陰性」の両方が発生することに注意してください。結果は人間の開発者がレビュー/分析する必要があります。ただし、実際の機能的な欠陥を引き起こしていない場合でも、通常はコードで回避する必要がある「アンチパターン」を引き起こします。

「産業」以外の特定のアプリケーションについてはもう言及しません。実際の正式な検証は、特定のアプリケーションに依存する傾向があります。

EEでは、マイクロプロセッサの設計など、回路の正確性を証明するために正式な検証手法が広く使用されているようです。

ここに、ラースフィリップソンによるEE分野の正式な検証ツールの調査の例があります。


2
「プログラムの正しさを判断するために、多くの「正式な検証」原則がコンパイラに組み込まれている」と言うのは誤解を招きます。参照するのは、一部のコンパイラが行う静的な型チェックですが、その方法で検証されたプロパティはかなり単純です。たとえば、数値と文字列の追加を避けます。これは役立ちますが、「正式な検証」で通常理解されているものとはかけ離れています。
マーティンバーガー

2
静的型チェックを具体的に参照していませんでしたが、それは1つの単純/一般的な例です。広く普及しているimhoコンパイラ最適化手法は、最適化されたプログラムバリアントの等価性を判断/表示する高度な手法を含むため、正式な検証原理にほぼ類似しています。したがって、ここで「移動するゴールポスト」の問題を回避することが重要であり、単にコンパイラーがそれを行うか、正式な検証ではなく、コンパイラーに組み込まれていると仮定することは重要ではないようです。
vzn

2
これは一般的な理解ではないことに同意しました。最適化手法とは、おおよそ、ループまたはサブルーチンなどのプログラムの動作のモデルを作成し、そのモデルを最適化してから、同等であると証明できる新しいコードを生成することです。そのため、これらの最適化の一部はコードの再配置が非常に洗練されており、私にとっては正式な検証原則を利用しています。コンパイラには正式な検証方法の他の多くの例があるようです...元の質問は多くの人が指摘したように多くの異なる質問をしましたが、そこに含まれるすべての質問に答えようとはしていません。
vzn

2
ちなみに、JRE、Javaランタイムエンジンなどで使用されるいくつかの正式な検証原則もあるようです。たとえば、動的最適化などです
。– vzn

3
xy

1

おそらく、モデルチェッカーが役立つ場合があります。

http://alloytools.org/documentation.html Alloyはモデルチェッカーです。

Alloyを使用したモデル検査の概念を説明する素晴らしいプレゼンテーション:https : //www.youtube.com/watch?v=FvNRlE4E9QQ

同じファミリのツールには「プロパティベースのテスト」があり、それらはすべて、ソフトウェアの指定された仕様モデルの反例を見つけようとします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.