回答:
そういう意味ではありませんが、この分野では純粋な関数型プログラミングが適しています。Haskellを使用している場合、コードがコンパイルされていればプログラムが正しい可能性があります。IOを除いて、優れた型システムは良い助けです。
また、契約するプログラミングも役立ちます。Microsoft Code Contractsをご覧ください
最も些細なプログラムを除くすべて
妥当な努力を払って正しいことを完全に証明することはできません。正式な正当性の証明には、少なくとも正式な仕様が必要であり、その仕様は完全かつ正確でなければなりません。これは通常、ほとんどの実際のプログラムで簡単に作成できるものではありません。たとえば、このディスカッションサイトのユーザーインターフェースのような仕様を作成してみてください。そうすれば、私が何を言っているかわかります。
ここで、このトピックに関する素晴らしい記事を見つけました。
http://www.encyclopedia.com/doc/1O11-programcorrectnessproof.html
printf("1")
が正しいかどうか(たとえば、要件が「1〜6の均等に分散された乱数を出力する」であったため)は、このような静的アナライザーでは決定できません。
正式な証明の問題は、問題を1ステップだけ戻すことです。
プログラムが正しいと言うことは、プログラムがすべきことをするということと同じです。プログラムが何をすべきかをどのように定義しますか?指定します。そして、仕様がカバーしていないエッジケースでプログラムが何をすべきかをどのように定義しますか?それでは、仕様をより詳細にする必要があります。
したがって、プログラム全体のあらゆる側面の正しい動作を説明するのに十分な仕様がついに詳細になったとしましょう。次に、証明ツールにそれを理解させる方法が必要です。そのため、証明ツールが理解できる形式の言語に仕様を翻訳する必要があります...ちょっと待ってください!
正式な検証は長い道のりを歩んできましたが、通常、業界/広く使用されているツールは最新の研究より遅れています。この方向での最近の取り組みは次のとおりです。
Spec#http://research.microsoft.com/en-us/projects/specsharp/ これは、コードコントラクト(事前/事後条件および不変条件)をサポートし、これらのコントラクトを使用してさまざまなタイプの静的分析を実行できるC#の拡張機能です。 。
JML for javaなど、他の言語にもこれと同様のプロジェクトが存在し、Eiffelにはこれがほとんど組み込まれています。
さらに進むと、slamやblastなどのプロジェクトを使用して、最小限のプログラマーアノテーション/介入で特定の動作プロパティを確認できますが、それでも現代言語の完全な一般性に対処することはできません(整数オーバーフロー/ポインター演算のようなものはモデル化されていません)。
私は、これらのテクニックの多くが将来実際に使用されるようになると信じています。主な障壁は、手動の注釈なしではプログラムの不変式を推測することが困難であり、プログラマーは通常、これらの注釈を提供するのは面倒で時間がかかるため嫌いです。
大規模な開発者の作業なしにコードを自動的に証明する方法が発生しない限り、そうではありません。
いくつかの正式なメソッドツール(たとえば、重要な組み込みCソフトウェアのFrama-Cなど)は、特定のソフトウェアの(正確性)証明を提供する(少なくとも確認する)と見なすことができます。(Frama-Cは、プログラムが何らかの形で形式化された仕様に従っていることを確認し、プログラム内の明示的な注釈付き不変条件を尊重します)。
一部のセクターでは、民間航空機の重要なソフトウェアのDO-178Cなど、このような正式な方法が可能です。そのため、場合によっては、このようなアプローチが可能かつ有用です。
もちろん、バグの少ないソフトウェアの開発には非常にコストがかかります。しかし、形式的な方法のアプローチは、ある種のソフトウェアにとって意味があります。悲観的であれば、バグはコードから正式な仕様に移行していると考えるかもしれません(ソフトウェアの意図された動作を正式にすることは難しく、エラーが発生しやすいため、「バグ」があるかもしれません)。
私はこの質問につまずいたが、このリンクは面白いかもしれないと思う:
2003年に130K行を超えるコードでAirbusが使用するシステムにRTEが存在しないことを証明することは悪くないようで、これが現実の世界ではないと言う人がいるかもしれません。
いいえ。これの一般的なことわざは、「理論的には理論と実践は同じです。実際にはそうではありません」です。
非常に簡単な例:タイプミス。
実際にユニットテストでコードを実行すると、そのようなことがすぐに見つかります。まとまったテストのセットは、正式な証明の必要性を無効にします。すべてのユースケース(良い、悪い、エラー、およびエッジケース)をユニットテストで列挙する必要があります。これは、コードとは別のそのような証明よりもコードが正しいことを証明します。
特に、要件が変更された場合、またはアルゴリズムがバグを修正するために更新された場合-コードのコメントが頻繁に取得するのと同じように、正式な証明が古くなる可能性が高くなります。
停止問題のために正当性証明に課せられた制限は、正当性証明が主流になるための最大の障壁かもしれないと思います。
すでにすべての人が使用しています。プログラミング言語の型チェックを使用するたびに、基本的にプログラムの正確さの数学的な証明を行っています。これはすでに非常にうまく機能します-使用するすべての関数とデータ構造に対して正しいタイプを選択するだけです。タイプが正確であればあるほど、より良いチェックが得られます。プログラミング言語で利用可能な既存のタイプには、ほとんどすべての可能な動作を記述するのに十分な強力なツールが既にあります。これは、使用可能なすべての言語で機能します。C ++および静的言語はコンパイル時にチェックを行うだけであり、Pythonのようなより動的な言語はプログラムの実行時にチェックを行います。このチェックは、これらすべての言語に引き続き存在します。(たとえば、c ++はhaskellと同じ方法で副作用のチェックを既にサポートしています。
mutable
またはを使用する場合、それらはまだ変更可能ですconst_cast
。確かにそこに描かれたつながりを見ることができますが、2つのアプローチの趣味は私とはかなり異なります。