大学で 形式体系 について教えられましたが、実際の言葉で使われていないように見えてがっかりしました。
テストではなく、proofによって、いくつかのコード(オブジェクト、関数など)が機能することを知ることができるというアイデアが好きです。
私たちは皆、物理工学とソフトウェア工学の間に存在しない類似点に精通していると確信しています(鋼は予想通りに動作し、ソフトウェアは何でもできます-誰が知っていますか!)、そして私は何か言語があるかどうか知りたいです実際のWordで使用できます(Webフレームワークを要求しすぎて要求できませんか?)
Scalaのような関数型言語のテスト可能性について興味深いことを聞いたことがあります。
ソフトウェアエンジニアとして、どのようなオプションがありますか?
はい、確かに正しいソフトウェアを書くために設計された言語があります。いくつかは産業でさえ使用されます。 Spark Ada がおそらく最も顕著な例です。私は、Boingsで実行されるコード(エンジン監視用)にそれを使用したPraxis Critical Systems Limitedの数人と話をしましたが、それは非常に素晴らしいようです。 (ここに素晴らしい 言語の要約/説明 があります。)この言語とそれに付随する証明システムは、以下に説明する2番目の手法を使用します。動的メモリ割り当てもサポートしていません!
私の印象と経験は、正しいソフトウェアを書くための2つのテクニックがあるということです。
テクニック1:使い慣れた言語(C、C++またはJavaなど)でソフトウェアを作成します。そのような言語の正式な仕様を取り、プログラムが正しいことを証明します。
あなたの野心が100%正しいことである場合(これは自動車/航空宇宙産業で最も頻繁に必要とされる)、プログラミングにほとんど時間を費やさず、証明に多くの時間を費やすことになります。
テクニック2:ソフトウェアを少し厄介な言語(たとえば、AdaのサブセットまたはOCamlの微調整バージョン)で記述し、途中で正当性の証明を記述します。ここでは、プログラミングと証明が密接に関連しています。 Coqでのプログラミングは、それらを完全に同一視します。 ( カリー-ハワード対応 を参照)
これらのシナリオでは、常に正しいプログラムになります。 (バグは仕様に根ざしていることが保証されます。)プログラミングにより多くの時間を費やす可能性がありますが、その一方で、途中でそれが正しいことを証明しています。
どちらのアプローチも、正式な仕様が手元にあるという事実(正しい/間違った動作を他にどのように伝えるか)と、言語の正式に定義されたセマンティクス(実際の動作を他にどのように伝えることができるか)に依存することに注意してくださいあなたのプログラムの)です。
正式なアプローチの例をさらにいくつか示します。それが「現実世界」であるかどうかは、あなたが誰に尋ねるかによります:-)
私は「おそらく正しい」Webアプリケーション言語を1つだけ知っています: [〜#〜] ur [〜#〜] 。 「コンパイラを通過する」Urプログラムは、次のことを行わないことが保証されています。
この質問に答えるには、「証明可能」とはどういう意味かを定義する必要があります。リッキーが指摘したように、型システムを備えた言語は、プログラムをコンパイルするたびに実行されるプルーフシステムが組み込まれた言語です。これらの証明システムは、ほとんどの場合、悲しいことに無力です— String
対Int
のような質問に答え、「リストはソートされていますか?」のような質問を避けます。 —しかし、それでもなお、それらは証明システムです。
残念ながら、証明の目標が洗練されているほど、証明をチェックできるシステムを使用するのは難しくなります。チューリングマシンでは決定不可能な問題のクラスの大きさを考えると、これは非常に迅速に決定不能にエスカレートします。確かに、ソートアルゴリズムの正しさを証明するなどの基本的なことは理論的には実行できますが、それ以上のことは非常に薄い氷の上を踏むことになります。
ソートアルゴリズムの正しさのような単純なものを証明するためにも、比較的洗練された証明システムが必要です。 (注:型システムは言語に組み込まれた証明システムであることをすでに確立しているので、もっと激しく手を振るのではなく、型理論の観点から物事について話します)私はかなり確信していますリストの並べ替えに関する完全な正しさの証明には、何らかの形式の依存型が必要です。そうでない場合、型レベルで相対値を参照する方法がありません。これは、決定不可能であることが示されている型理論の領域にすぐに侵入し始めます。したがって、リストの並べ替えアルゴリズムで正しいことを証明できる場合もありますが、それを行う唯一の方法は、検証できない証明を表現できるシステムを使用することです。個人的には、これは非常に当惑させられます。
先ほど触れた使いやすさもあります。型システムが洗練されているほど、使い心地が悪くなります。これは難しいルールではありませんが、ほとんどの場合当てはまると思います。また、他の正式なシステムと同様に、最初に実装を作成するよりも、証明を表現する方が作業が多く(そしてエラーが発生しやすく)なることがよくあります。
これらすべてが邪魔にならないので、Scalaの型システム(Haskellのような)はチューリング完全であることに注意する価値があります。つまり、理論的に使用してコードがそのような証明に適した方法で記述されている場合は、コードに関する決定可能なプロパティを証明します。 Haskellはほぼ間違いなくJavaよりも優れた言語です(Haskellの型レベルのプログラミングはPrologに似ているのに対し、Scala SMLに似ています)ScalaまたはHaskellのタイプシステムをこのように使用することはお勧めしません(アルゴリズムの正しさの正式な証明)が、理論的にはオプションが利用可能です。
要するに、あなたが「現実の世界」で形式的なシステムを見なかった理由は、形式的な証明システムが実用主義の容赦ない専制政治に屈したという事実に起因すると思います。私が言ったように、あなたの正しさの証明を作ることには非常に多くの努力が必要なので、それはほとんど価値がありません。業界はずっと前に、あらゆる種類の分析的な正式な推論プロセスを経るよりも、アドホックテストを作成する方が簡単であると判断しました。
型付き言語は、特定のカテゴリの障害がないことを証明します。型システムが高度であるほど、障害がないことを証明できる障害が多くなります。
プログラム全体が機能することを証明するために、はい、数学とプログラミングが出会う通常の言語の境界の外に出て、握手してから、プログラマーがギリシャ語の記号を処理できない方法についてギリシャ語の記号を使用して話します。それはとにかくそれのΣについてです。
あなたは私たちの多くが何年にもわたって尋ねてきた質問をしている。私が良い答えを持っているかどうかはわかりませんが、ここにいくつかの部分があります:
今日使用されていることが証明される可能性のある、よく理解されている言語があります。 ACL2を介したLISPはその1つであり、もちろん、Schemeにはよく理解されている正式な定義もあります。
多くのシステムが、純粋な関数型言語、またはHaskellのようなほぼ純粋な言語を使用しようとしました。 Haskellではかなりの形式手法が機能します。
20年以上前にさかのぼると、形式言語のハンドプルーフを使用するための短命なことがあり、それはその後、コンパイルされた言語に厳密に翻訳されました。いくつかの例は、IBMのソフトウェアクリーンルーム、ACL、ジプシー、および計算ロジックからのローズ、ジョン・マックヒューと私の信頼できるCのコンパイルに関する作業、およびCシステムプログラミングのハンドプルーフに関する私自身の作業でした。これらはすべていくらかの注目を集めましたが、どれもそれをあまり実践しませんでした。
興味深い質問は、正式なアプローチを実践するための十分条件は何かということだと思います。私はいくつかの提案を聞きたいです。
そのような証明可能な言語の実際の使用は、残材を書き、理解するのが非常に難しいでしょう。ビジネスの世界では、すぐに機能するソフトウェアが必要です。
「証明可能な」言語は、大規模なプロジェクトのコードベースの書き込み/読み取りに対応するための拡張性がなく、小規模で孤立したユースケースでのみ機能するようです。
私は2つの証明可能な言語に関わっています。 1つ目は、ソフトウェアを指定し、改良し、コードを生成するためのシステムであるPerfectDeveloperでサポートされている言語です。 PD自体を含むいくつかの大規模なシステムで使用されており、多くの大学で教えられています。私が関わっている2番目の証明可能な言語は、MISRA-Cの証明可能なサブセットです。-を参照してください。 C/C++検証ブログ 詳細。
要件の1つが証明可能性である場合に使用される、Haskellのような純粋に関数型言語を調査できます。
This 関数型プログラミング言語と純粋な関数型プログラミング言語に興味があるなら、これは楽しい読み物です。
確かに正しいコードのコンテキストでの「実世界」の私の(物議を醸す)定義は次のとおりです。
上記は比較的普遍的な要件です。命令型コードをモデル化する機能や、高階関数が正しいことを証明する機能など、その他の機能は、すべてではありませんが、一部のタスクにとって重要または不可欠な場合があります。
これらの点を考慮すると、 私のこのブログ投稿 にリストされているツールの多くは便利かもしれませんが、ほとんどすべてが新しく実験的であるか、大多数の業界プログラマーにはなじみがありません。ただし、そこには非常に成熟したツールがいくつか含まれています。
Scalaは「現実の世界」であることが意図されているため、Scalaを証明できるようにするための努力はなされていません。 Scalaでできることは、関数型コードを生成することです。関数型コードはテストがはるかに簡単です。これは、「実世界」と証明可能性の間の良い妥協点です。
編集===== MLが「証明可能」であるという私の誤った考えを削除しました。
Idris と Agda はどうですか?実世界で十分ですか?
実例として、検証済みのHTTP RESTライブラリをAgdaで記述したLemmachine: https://github.com/larrytheliquid/Lemmachine)を提供することを目的としたプロジェクトがあります。