ミッションクリティカルなソフトウェアの作成方法


15

私は正式な方法を自習しています。ミッションクリティカルなソフトウェア(原子炉コントローラー、航空機飛行コントローラー、宇宙探査機コントローラーなど)を作成するために、正式な方法が使用される(そして通常のみ使用される)と聞きました。それが私がそれを学ぶことに興味がある理由です:p

ただし、正式な方法(特にLTL、CTL、およびそれらの兄弟)を学習した後は、仕様の正確さ(安全性、活性、公平性など)を検証するためにのみ使用できると感じています。

しかし、ソフトウェア(仕様だけでなく)が実際に正しいことを確認する方法は?

免責事項:理論的なコンピューターサイエンスに関しては、私は90%のバカです。答えながら慈悲深くあってください。


2
「...ソフトウェアが本当に正しいことを...」とはどういう意味ですか?次の2つのうちどちらを意味しますか。1)ソフトウェアは仕様に準拠しています。2)コードの特定のブロックは、特定のプロパティまたは入力と出力の関係を尊重します。
ジョルジオカメラニ

@GiorgioCamerani:最初の1
fajrian

2
通常、プログラムの正確さは、(1)仕様と一貫性があり、(2)決してクラッシュしないことを意味します。ポイント(1)は、実際には、プログラム自体ではなく、ペア(プログラム、仕様)に関する記述です。さらに複雑なのは、プログラム自体がかなり複雑すぎるか、正確なセマンティクスを持っていないため、「プログラム」は通常「プログラムのモデル」の省略形であるということです。これを考えると、あなたはプログラムとそのモデルの間のギャップについて尋ねていると思いますが、私はよくわかりません。
ラドゥグリゴール

@RaduGRIGore:実際、私は「モデル」が何であるか理解していません。しかし、あなたは私の質問に非常に密接に取り組んでいると思います。基本的に、私が疑問に思っているのは、仕様とプログラムのソースコードのギャップです。プログラマー(私のような)が仕様を実装しているときに、多くの愚かなことが起こります。
fajrian

1
@fajrian:私が「モデル」と呼ぶものに対して「仕様」と言っているのではないかと思います。CやJavaなどの言語、さらにはマシンコードで記述されたプログラムで動作するツールがあります。(ただし、いくつかのセマンティクスを想定する必要があるため、これはまだモデルです。これ、コンパイラ/プロセッサの動作に対応する必要がありますが、対応しない場合があります。)
Radu GRIGore

回答:


11

問題はかなり広範です。合理的なスペースでそれに答えるために、私は多くの単純化を行います。

用語について同意しましょう。プログラムは、仕様を暗示しているときに正しいです。このあいまいな記述は、プログラムとは何か、仕様とは何かを特定することにより、多くの点で正確にされています。たとえば、モデル検査では、プログラムはKripke構造であり、仕様は多くの場合LTL式です。または、プログラムはPowerPC命令のリストであり、仕様は、たとえば1次論理で記述されたHoare-Floydアサーションのセットである可能性があります。非常に多くの可能なバリエーションがあります。1つのケース(Kripke構造)では実際のプログラムを検証しないのに対し、2番目のケース(PowerPC命令のリスト)では検証すると結論付けたいと思います。ただし、両方のケースで実際に数学的モデルを見ていることに気付くことが重要であり、これはまったく問題ありません。(状況は、たとえば古典力学が現実の数学モデルである物理学に非常に似ています。)

ほとんどの形式化では、プログラムの構文とセマンティクスが区別されます。つまり、それがどのように表現され、何を意味するのか。プログラムのセマンティクスは、プログラム検証の観点から重要なものです。ただし、プログラム(の構文表現)に意味を割り当てる明確な方法を持つことはもちろん重要です。2つの一般的な方法は次のとおりです。

  • (小さなステップ)操作上のセマンティクス:これは、インタープリターを作成してプログラミング言語を定義することに非常によく似ています。このためには、状態とは何かを言う必要があり、言語の各ステートメントの影響を受けます。(どの言語で通訳を書くのか疑問に思うかもしれませんが、そうではないふりをします。)
  • 公理的意味論:ここで、各ステートメントタイプには公理スキーマが付属しています。そのため、大まかに言うと、そのタイプの特定のステートメントが使用されるたびに、特定の公理を使用できるようになります。たとえば、割り当てはスキーマ{ P [ x / e ] }が付属しますx:=e ; 特定の割り当て x = x + 1には公理 { x + 1 = 1 }が付きます{P[x/e]}x:=e{P}x:=x+1P = x = 1 )でスキーマをインスタンス化する場合 { x = 1 }{x+1=1}x:=x+1{x=1}P=バツ=1

(他にもあります。表示のセマンティクスを省略すると特に悪いと感じますが、この答えはすでに長いです。)マシンコードと操作上のセマンティクスは、ほとんどの人が「本物のプログラム」と呼ぶものにかなり近いです。DEC Alphaマシンコードのサブセットにたまたま動作セマンティクスを使用している独創的な論文を次に示します。

公理のようなより高いレベルのセマンティクスを使用するのはなぜですか?正確性の証明を実行するハードウェアに依存させたくない場合。アプローチは、いくつかの便利な高レベルセマンティクスに関してアルゴリズムの正確性を証明し、次に実際のマシンにより近い低レベルセマンティクスに関してセマンティクスが適切であることを証明することです。

要約すると、あなたの質問につながった3つの理由を考えることができます。

  1. あなたはプログラムを呼び出すために使用されているもののように見えない高レベルのセマンティクスのみを見て、低レベルのものがあるかどうか疑問に思います。答えはイエスです。
  2. モデルが現実に対応していることをどのように証明するのか不思議に思うでしょう。物理学のように、あなたはしません。より良いモデルを思いついて、現実と比較するだけです。
  3. 構文とセマンティクスの違い、およびプログラムに意味を割り当てるさまざまな方法を見たことはありません。以前の 2つの質問には、いくつかの書籍がリストされています。

この答えは、私が質問を理解した3つの異なる方法を特定しようとしているだけです。これらのポイントのいずれかに深く入り込むには、多くのスペースが必要です。


8

プログラムとその仕様の間のギャップを減らすための1つのアプローチは、形式的なセマンティクスを持つ言語を使用することです。ここで興味深い例はEsterelです。GérardBerryのWebページを見て、正式な方法を現実の世界に取り入れた彼の作品についての興味深い話をご覧ください。 http://www-sop.inria.fr/members/Gerard.Berry/

psエアバスに乗ったことがありますか?正式な方法で飛行しました!


1
エアバスが正式な方法をどのように使用するかについての参考資料があれば役立つでしょう。(その独自の情報である可能性があることを理解してください。)
vzn

@RossDuncan BerryのWebページにアクセスしていくつか検索した後、このWebページを見つけました。これは、エアバスが使用していた正式な方法ですか?
scaaahu

エアバスによるEsterelの使用に関する内部情報はありません。私のコメントは、単に講義中にベリーが発言したことを繰り返しています。ただし、このページでは、エアバスでのSCADE製品の使用が成功したことを示しています。エステレルの歴史を見ると、かなり早い時期にダッソーによって採用されました。Googleはあなたの友達です。
ロスダンカン


7

「現実の世界」で信頼性の高いソフトウェアを構築する科学はまだ開発中であり、コンピューターやソフトウェアはバグを「引き起こさない」ため、本質的に文化的または人類学的な研究にある程度まで迫っています。この回答では、正式なソフトウェア検証を1つの要素とみなすことができる一般的なQ / Aアプローチに焦点を当てます。

注目に値するのは、多くの場合、「十分」でありながら「バギー」なソフトウェアが、市場でテストされているが機能性の低いソフトウェアよりも頻繁に売れるということです。言い換えれば、市場は常にソフトウェアの品質を重視しているわけではなく、ソフトウェアエンジニアリングの最新の技術は常に品質を重視しているわけではなく、それをいくらか反映しています。さらに、品質は最終製品に多大な費用を追加することがよくあります。これらの警告を使用して、基本をいくつか示します。

  • 冗長/フォールトトレラントシステム。これは幅広い研究分野です。フォールトトレランスと冗長性は、システムの多くのレイヤーに設計できます。たとえば、ルーター、サーバー、ディスクドライブなど。

  • テスト。ユニットテスト、統合テスト、ユーザー受け入れテスト、回帰テストなど、すべてのタイプ

  • 最近では、無人で実行できるテストスイートを介した自動テストの開発/重要性が高まっています。多くの場合、実行中のテストスイートはビルドツールと結合されます。

  • テストの重要な概念はコードカバレッジです。すなわち、テストで実行されるコード。テストは、テストによって「触れられていない」コードのバグを見つけることができません。

  • テストのもう1つの重要な概念は、簡単に直接アクセスできないコードを実行するテストハーネスです。

  • テストでは、ソフトウェアのすべてのレベルを実行する必要があります。ソフトウェアがモジュール化されていれば、これは難しくありません。より高いレベルのテストはコードに深く浸透する必要があります。小さなテスト設定で大量のコードを実行するテストでは、「テストのてこが増加します。

  • コードをできるだけ複雑にすることは、テストにとって重要です。テストは、アーキテクチャ設計において考慮すべき事項です。多くの場合、同じ機能を実装する方法は複数ありますが、テストカバレッジ/レバレッジに対してさまざまな意味があります。コード内のすべてのブランチについて、多くの場合、別のテストケースです。ブランチ内のブランチは、コードパスの指数関数的増加にエスカレートします。したがって、高度にネストされた/条件付きロジックを回避すると、テスト能力が向上します。

  • 勉強有名な(大規模な)ソフトウェア障害多くの例とケーススタディがあるうちは、歴史を理解し、品質上の考慮事項を指向の考え方を開発するために有用です。

  • テストに夢中になることができます!テストが少なすぎるか多すぎるという問題があります。「スイートスポット」があります。どちらの極端でもソフトウェアを正常にビルドすることはできません。

  • すべての基本的なツールを最も効果的な方法で使用します。デバッガ、コードプロファイラ、テストコードカバレッジツール、欠陥追跡システムなど!必ずしも固定にコミットするが、していないトラックのトラッキングソフトウェアでも、最小の欠陥を。

  • SCM、ソースコード管理、および分岐技術の注意深い使用は、回帰を回避し、修正を分離および進行させるなどにおいて重要です。

  • Nバージョンプログラミング:ミッションクリティカルなソフトウェアの開発によく使用されるプラクティス。このプラクティスの前提は、N個の独立して開発されたプログラムが同じ共通のバグ/障害を持つ可能性は低いということです。これはいくつかの論文で批判されています。ただし、 NVPは実践であり、理論的な概念ではありません。

物理学者のファインマンは、NASAが彼の著書「他の人がどう思うか気にかけますか?」のスペースシャトルシステムの信頼性を保証するために使用した方法について何らかの説明があると思います。—チームAとチームBの2つのチームがあると言いました。チームAはソフトウェアを構築しました。チームBは、チームAに敵対的なアプローチを取り、ソフトウェアを破壊しようとしました。

チームBが優れたソフトウェアエンジニアリングのバックグラウンドを持っている場合、つまり、コードハーネス/プログラムテストなどを作成できる場合に役立ちます。その場合、チームBはチームAとほぼ同じレベルのリソースを持っていました。一方、このアプローチは、ソフトウェアの構築コストをほぼ2倍にできるため、高価です。より一般的には、開発チームに比べてQAチームが小さくなります。


8
Shiftキーと文字を押すと大文字が生成されるという仕様に関して、誰かがOSをチェックする必要があります。
アンドレイバウアー

1
補遺:スケジュールの制約は品質に影響を与える可能性があります。範囲、コスト、品質のスケジュールで構成されるプロジェクト管理トライアングルも参照してください。3。すべての影響を受ける「領域」を参照してください。Nバージョンのアイテムを自分で追加しませんでした(他の回答も含まれています)が、ファインマンはNASAがスペースシャトルの設計でもそれを使用していると述べました。
vzn


1
別の興味深いケーススタディは、大量のコードを持ち、その多くが自動生成される火星探査車です。その場合、以前のローバーはほとんどのソフトウェアをフィールドでテストし、再利用されました。
vzn

6

古いアプローチ(ただし、一部のアプリケーションではまだ使用されています)は、Nバージョンプログラミングです。

ウィキペディアから:

マルチバージョンプログラミングとも呼ばれるNバージョンプログラミングNVP)は、ソフトウェアエンジニアリングにおける方法またはプロセスであり、複数の機能的に同等のプログラムが同じ初期仕様から独立して生成されます。Nバージョンプログラミングの概念は、1977年にLiming ChenとAlgirdas Avizienisによって「プログラミング作業の独立により、プログラムの2つ以上のバージョンで同一のソフトウェア障害が発生する確率が大幅に低下する」と推測されて導入されました。 NVPの目的は、フォールトトレランスまたは冗長性を組み込むことにより、ソフトウェア操作の信頼性を向上させることです。....

たとえば、「障害の構築における課題-民間航空機用の耐性飛行制御システム」を参照してください。


nバージョンのプログラミングが機能しないことに注意してください。基本的な仮定、つまり、ソフトウェア開発プロセスの繰り返し試行におけるエラーは独立しているということ完全に間違っています。この考えは理論的には意味がありません(実装が困難なアルゴリズムは、2番目の独立したチームにとって魔法のように簡単にはなりません)。また、実験的に暴かれています:独立性の仮定が統計的に有効ではないことを示すJohn KnightとNancy Levesonの実験は、ソフトウェアエンジニアリングで最も有名な論文の1つです。
ニールクリシュナスワミ14

@NeelKrishnaswami:同意します!ただし、動作しない(ただし私は専門家ではない)と置き換える必要があると思いますが、他のアプローチと比較すると信頼性はそれほど向上しません。K&Lを引用:「... Nバージョンプログラミングの有効性に関する決定の根拠として、結果を単独で使用することを決して提案しませんでした。単に注意が適切であると示唆しただけです...」。重要なシステム設計にNVPアプローチがどれほど役立つかについての議論はまだ開かれていると思います(Khoury et al。の最近の研究を参照)
Marzio De Biasi 14

4

fajrian、あなたがしたこの質問は、ソフトウェアエンジニアの研究における2つの最大の問題をカバーしています。それは、仕様とモデルの間、およびモデルとコードの間の適合性です。ここでシステムが何をするか、またはどのように行われるかの表現をモデル化します。システムをモデル化するための多くのレベルがあります。

だから、あなたの質問に対する最良の答えを見つけようとしている人がいます。モデルに基づいて、たとえば正式な方法を使用してソフトウェアの正確性をチェックすることは非常に難しいためです。私が知っているJMLはそれを行う方法ですが、私はその使用の限界を知りません。

まとめとして、コードの正確性を確認するのがどのように難しいか、人々は形式的な方法とテストを組み合わせて、たとえば仕様から自動的にテストを作成しようとします。リアルタイムシステムの1つの例は、入力/出力タイミングイベントに基づくTIOSTSです。

テストは正式な手法ではなく、信頼性を向上させますが、正確性はチェックしません。


3

2、3年前、私はソフトウェアに適用される正式な方法に目を向け始めました。これは、好奇心と、より長い時間をかけてプログラミングツールと方法を習得しなければならなかったという感覚に駆られた探求でした。Silver Bulletについて希望を抱いて夢見ていましたが、「正しいプログラムを書くにはどうすればよいか」という質問に対する答えはないと思いました。

いくつかのツール(Z、B、VHDL、およびエステル)を試した後のクエストのこの時点で、TLA +を使用しています。これは、モデルチェックおよびメカニックプルーフ用のソフトウェアツールを備えた時相論理のバリアントです。このアプローチを選んだのは、L。ランポートが背後にあり、構文が単純で、多くの例があり、コミュニティがそれを処理し、言語とツールがかなりよく文書化されていたからです。

最初の質問に関しては、完全な答えはないと思います。ただし、システムの一部を正式に指定することで成果を上げることを学ぶ価値があります。複雑なものをリバースエンジニアリングすることも非常に便利です。つまり、困難で重要な部分の青写真を作成することは効果的です。ただし、仕様をプログラミング言語またはフレームワークに自動的に変換する効果的な方法はないと思います(プロジェクトを非常に特定の環境に制限しない限り)。また、正式な仕様があると、ソフトウェアをテストできなくなるとは思いません。

一言で言えば、次の比phor(Lamportからの)は本当に強力だと思います。 。

このクエストの間に、私は次のリソースが役立つことを発見しました。

  • ソフトウェア仕様方法。この本は、既存の方法とツールの大まかな概要を提供します。そこでは、Z、SDL、TLA +、ペトリネット、Coqなどの基本的な説明と例を見つけることができます。
  • TLA +がニーズに合っていると思われる場合は、書籍Specifying Systemsをお勧めします。この本は無料で入手できますが、試してみてください:)。
  • 最近、私はいくつかの関連記事を読みました。これらの記事は、2つの異なる視点から形式手法の現状を示しています。 形式手法のためのケース、および正式に確認済み数学を

幸運を!


1

これまでの回答は、仕様とコードを相互に関連付ける方法の基礎について述べるべきことのほとんどをすでにカバーしていました。このスレッドのヘッダーの質問にアプローチする、より実用的なポイントを追加したいだけです。

ミッションクリティカルなソフトウェアの作成方法

エラー(仕様の違反、または「典型的なバグ」)についてコードを自動的に分析するツールがあります。私の知る限り、これらのメソッドは主に静的分析に基づいており、あなたが言及した理論(LTL / CTL / ...)にすぐに関連するわけではありませんが、実際のコードでエラーを見つけ、実用的な点からすでに実行可能ですビュー、産業プロジェクトでそのようなツールを使用する。私は個人的にそれらの多くを使用していませんが、これらのツールは開業医によって受け入れられ始めているようです。さらに読むには、次のブログ記事をお勧めします。

http://www.altdevblogaday.com/2011/12/24/static-code-analysis/


Javaによる実装例、オープンソースApache— findbugs
vzn

0

認証アルゴリズムは、ミッションクリティカルなソフトウェアを構築するときに役立ちます。

証明アルゴリズムとは、特定の出力がバグによって侵害されていないことを証明または証言(検証しやすい証明)を出力ごとに生成するアルゴリズムです。

この調査報告書で、McConnell、RM、Mehlhorn、K.、Naher、S.、Schweitzer、Pによる認証アルゴリズムをご覧ください


1998年、Pnueli、Siegel、およびSingermanは、翻訳の検証という名前でこのアイデアをコンパイラに適用したことを説明しましたコンパイラは本質的に高次であるため(入力はプログラムであり、出力はプログラムです)、検証が難しい傾向があります。しかし、とにかく検証済みのコンパイラーを開発するX. Leroyのようなクレイジーな人々がいます。(可能な限り最高の意味でクレイジー!)
ラドゥグリゴール

-2

しかし、ソフトウェア(仕様だけでなく)が実際に正しいことを確認する方法は?

ユニットテスト?仕様内のすべての要件に対してテストを作成し、実装内のすべてのメソッドをテストして、その出力/入力が仕様に準拠していることを確認します。これは自動化できるため、これらのテストを継続的に実行して、以前に機能していた機能が変更されないようにすることができます。

理論的に言えば、ユニットテストのコードカバレッジが100%の場合(つまり、コードのすべてのメソッドがテストされる場合)、テスト自体が正確で現実的であれば、ソフトウェアは正しいはずです。


5
合理的に複雑なプログラムでは、コードカバレッジ(テストによる)で正確性を保証できません。すべての可能な実行をカバーする必要があります。すべてのコード行では十分ではありません。
ラドゥグリゴール

1
コードカバレッジはあまりにも曖昧な概念です。たとえば、メソッドカバレッジ、ステートメントカバレッジ、ブランチカバレッジ、パスカバレッジなどを区別します。Raduが指摘しているように、重要なプログラムの場合、テストではしばしば組み合わせの爆発が発生します。とはいえ、航空ソフトウェアは非常に優れた実績があり、その正確性は多くの場合、広範なテストに基づいています。
マーティンバーガー

JUnitなどのツールによるテストを意味する場合、この種の標準的な自動テストではすべてのケースをカバーできるわけではありません(プログラムが非常に小さい場合を除く)。通常のアプリケーションでは、通常、この種のテストで十分です。しかし、ミッションクリティカルなアプリケーションの場合、これで十分かどうかわかりません(またはそうではありません)。
fajrian

2
@vzn:私の経験では、学者と実務家のそれぞれがバグだと考えているものの間には顕著な一致があります。また、業界の私の(元)同僚のほとんどは、「コード内のすべての単一メソッドがテストされる」ということは、それほど安心できるとは思わないでしょう。(そして、いいえ、私は投票しませんでした。ほとんどしません。)
ラドゥグリゴール

1
@vzn:別の言い方をしましたか?私は、他の人がこの答えを支持していないと思う理由を説明しようとしていました。現時点では理解できないため、この質問に答えることはできません。
ラドゥグリゴール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.