コードの正当性の証明は主流になりますか?[閉まっている]


14

最も些細なプログラム以外はすべてバグで満たされているため、それらを削除することを約束するものは非常に魅力的です。現時点では、正当性の証明はコードが非常に難解です。これは主にこれを学ぶことが難しく、プログラムが正しいことを証明するために余分な労力がかかるためです。コードの証明はこれから始まると思いますか?

回答:


8

そういう意味ではありませんが、この分野では純粋な関数型プログラミングが適しています。Haskellを使用している場合、コードがコンパイルされていればプログラムが正しい可能性があります。IOを除いて、優れた型システムは良い助けです。

また、契約するプログラミングも役立ちます。Microsoft Code Contractsをご覧ください


6
すみません-私は「現実世界」のHaskellをあまりしませんでしたが、いくつかの生涯にわたって十分なチュートリアル演習をしました。コンパイルされたからといって、動作する可能性が高いとは限りません。たとえばAda(厳密に静的に型付けされた命令型言語であるために選択)と比較して、Haskellは少し簡単ですが、主に簡潔である(循環的複雑度が低い)ためです。IOモナドを扱う場合、Haskellは作ることができる厄介があるより多くの権利を取得することは困難-それはちょうどそれが当然のように行うことができないものがあることが必須なスタイルが異なるだけで十分です。
Steve314

「自然にできない」では、「while」ループを検討してください。はい、自分でロールバックできますが、ループ本体の副作用に反応する必要があるため、while条件はモナド内になければなりません。これは、while条件内で副作用を引き起こす許可が与えられたことを意味するだけでなく、whileループを使用するのが面倒です。最終結果-IOモナドコードでも再帰を使用する方が一般的に簡単です-つまり、特定の方法で物事を構造化する必要があります。
Steve314

14

最も些細なプログラムを除くすべて

妥当な努力を払って正しいことを完全に証明することはできません。正式な正当性の証明には、少なくとも正式な仕様が必要であり、その仕様は完全かつ正確でなければなりません。これは通常、ほとんどの実際のプログラムで簡単に作成できるものではありません。たとえば、このディスカッションサイトのユーザーインターフェースのような仕様を作成してみてください。そうすれば、私が何を言っているかわかります。

ここで、このトピックに関する素晴らしい記事を見つけました。

http://www.encyclopedia.com/doc/1O11-programcorrectnessproof.html


正しい-すべてのプログラミングプロジェクトで、問題の非公式な記述から正式なもの(通常はプログラム形式)への移行がありますが、それはなくなりません。
デビッドソーンリー

astree.ens.frアスレの産業用途はこちらをご覧ください
zw324

@ZiyaoWei:このようなツールは便利ですが、正式なエラーはわずかしか見つかりません。のような1行のプログラムprintf("1")が正しいかどうか(たとえば、要件が「1〜6の均等に分散された乱数を出力する」であったため)は、このような静的アナライザーでは決定できません。
ドックブラウン

10

正式な証明の問題は、問題を1ステップだけ戻すことです。

プログラムが正しいと言うことは、プログラムがすべきことをするということと同じです。プログラムが何をすべきかをどのように定義しますか?指定します。そして、仕様がカバーしていないエッジケースでプログラムが何をすべきかをどのように定義しますか?それでは、仕様をより詳細にする必要があります。

したがって、プログラム全体のあらゆる側面の正しい動作を説明するのに十分な仕様がついに詳細になったとしましょう。次に、証明ツールにそれを理解させる方法が必要です。そのため、証明ツールが理解できる形式の言語に仕様を翻訳する必要があります...ちょっと待ってください!


2
また..「上記のコードのバグに注意してください。私はそれが正しいことを証明しただけで、試したことはありません。」-ドナルドクヌース
ブレンダン

8

正式な検証は長い道のりを歩んできましたが、通常、業界/広く使用されているツールは最新の研究より遅れています。この方向での最近の取り組みは次のとおりです。

Spec#http://research.microsoft.com/en-us/projects/specsharp/ これは、コードコントラクト(事前/事後条件および不変条件)をサポートし、これらのコントラクトを使用してさまざまなタイプの静的分析を実行できるC#の拡張機能です。 。

JML for javaなど、他の言語にもこれと同様のプロジェクトが存在し、Eiffelにはこれがほとんど組み込まれています。

さらに進むと、slamblastなどのプロジェクトを使用して、最小限のプログラマーアノテーション/介入で特定の動作プロパティを確認できますが、それでも現代言語の完全な一般性に対処することはできません(整数オーバーフロー/ポインター演算のようなものはモデル化されていません)。

私は、これらのテクニックの多くが将来実際に使用されるようになると信じています。主な障壁は、手動の注釈なしではプログラムの不変式を推測することが困難であり、プログラマーは通常、これらの注釈を提供するのは面倒で時間がかかるため嫌いです。


4

大規模な開発者の作業なしにコードを自動的に証明する方法が発生しない限り、そうではありません。


経済的な議論を考えてみてください。ソフトウェアエラーのためにお金を失うよりも、開発者が正確性を証明して時間を「無駄にする」方が良いかもしれません。
アンドレスF.

私はfishtoasterに同意します。リソース集約度が大幅に低くならない限り、通常のビジネスソフトウェアの多くは、そのレベルの正確性をサポートするためのコスト/メリットがありません。囚われの聴衆へのLOBアプリでバグレポートに関するコストのために、時にはほとんどのビジネスの利益は「それを行うません」と言うドキュメントに行を追加している
ビル・

3

いくつかの正式なメソッドツール(たとえば、重要な組み込みCソフトウェアのFrama-Cなど)は、特定のソフトウェアの(正確性)証明を提供する(少なくとも確認する)と見なすことができます。(Frama-Cは、プログラムが何らかの形で形式化された仕様に従っていることを確認し、プログラム内の明示的な注釈付き不変条件を尊重します)。

一部のセクターでは、民間航空機の重要なソフトウェアのDO-178Cなど、このような正式な方法が可能です。そのため、場合によっては、このようなアプローチが可能かつ有用です。

もちろん、バグの少ないソフトウェアの開発には非常にコストがかかります。しかし、形式的な方法のアプローチは、ある種のソフトウェアにとって意味があります。悲観的であれば、バグはコードから正式な仕様に移行していると考えるかもしれません(ソフトウェアの意図された動作を正式にすることは難しく、エラーが発生しやすいため、「バグ」があるかもしれません)。


3

私はこの質問につまずいたが、このリンクは面白いかもしれないと思う:

Astréeの産業用途

2003年に130K行を超えるコードでAirbusが使用するシステムにRTEが存在しないことを証明することは悪くないようで、これが現実の世界ではないと言う人がいるかもしれません。


2

いいえ。これの一般的なことわざは、「理論的には理論と実践は同じです。実際にはそうではありません」です。

非常に簡単な例:タイプミス。

実際にユニットテストでコードを実行すると、そのようなことがすぐに見つかります。まとまったテストのセットは、正式な証明の必要性を無効にします。すべてのユースケース(良い、悪い、エラー、およびエッジケース)をユニットテストで列挙する必要があります。これは、コードとは別のそのような証明よりもコードが正しいことを証明します。

特に、要件が変更された場合、またはアルゴリズムがバグを修正するために更新された場合-コードのコメントが頻繁に取得するのと同じように、正式な証明が古くなる可能性が高くなります。


3
違う。すべての可能なパラメーターをカバーできる単体テストはありません。このようにコンパイラが「単体テスト」され、パスがセマンティクスを変更しないことを確認してください。
SKロジック

3
ユニットテストは...聖杯ではありません
Ryathal

1
@Winston Ewert、検証済みのコンパイラー(およびさらに多くの検証済みのアセンブラー)があります。また、ハードウェアは、ソフトウェアよりもはるかに頻繁に正式に検証されます。こちらをご覧ください:gallium.inria.fr/~xleroy/publi/compiler-certif.pdf
SK-logic

1
@SKロジック しかし、実際に使用しているコンパイラはどうでしょうか?ほとんどのコンパイラは、さまざまな形式の自動テストを使用してチェックされ、正式な正しい証明はほとんど行われていません。
ウィンストンイーバート

1
@Winston Ewert、正確さの証明は実用的であり、実際に広く使用されています。あまり実用的ではないのは、現代の主流言語のほとんどです。それらがすべて消滅することを願っていますので、正確性の証明の価値は将来増加するでしょう。
SKロジック

1

停止問題のために正当性証明に課せられた制限は、正当性証明が主流になるための最大の障壁かもしれないと思います。


8
停止の問題は、任意のプログラムが停止したかどうかを判断できないことを示しています。これらのプログラムは、すべての整数をテストしてメルセンヌ素数であるかどうかを確認するなど、奇妙なことを行うことができます。通常のプログラムではこれを行いません!
ケースバッシュ

1
@Casebash、問題は停止する問題を解決できるプログラムの有用なサブセットがあるかどうかです。それは決して明確ではありません。つまり、有用なタスクを実行する能力を損なうことなくすべての整数をテストするようなことをできないように、プログラムを制限できますか?
ウィンストンイーバート

1

すでにすべての人が使用しています。プログラミング言語の型チェックを使用するたびに、基本的にプログラムの正確さの数学的な証明を行っています。これはすでに非常にうまく機能します-使用するすべての関数とデータ構造に対して正しいタイプを選択するだけです。タイプが正確であればあるほど、より良いチェックが得られます。プログラミング言語で利用可能な既存のタイプには、ほとんどすべての可能な動作を記述するのに十分な強力なツールが既にあります。これは、使用可能なすべての言語で機能します。C ++および静的言語はコンパイル時にチェックを行うだけであり、Pythonのようなより動的な言語はプログラムの実行時にチェックを行います。このチェックは、これらすべての言語に引き続き存在します。(たとえば、c ++はhaskellと同じ方法で副作用のチェックを既にサポートしています。


C ++の副作用について少し説明すると、constの正確性について言及していますか?
ウィンストンユワート

はい、const + constメンバー関数。すべてのメンバー関数がconstである場合、オブジェクト内のすべてのデータは変更できません。
tp1

mutableまたはを使用する場合、それらはまだ変更可能ですconst_cast。確かにそこに描かれたつながりを見ることができますが、2つのアプローチの趣味は私とはかなり異なります。
ウィンストンイーバート

それが、それを使用することを選択する必要がある理由です-それを回避する方法は常にあります。しかし、重要なことは、コンパイラーにこの領域の問題をチェックさせる方法です。
tp1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.