Hoareスタイルの正当性の証明中に配列を処理する方法


11

この質問に関する議論の中で、Gillesは、配列を使用するアルゴリズムの正当性の証明には範囲外の配列アクセスがないことを証明する必要があることを正しく述べています。ランタイムモデルによっては、ランタイムエラーが発生したり、配列以外の要素にアクセスしたりします。

このような正当性の証明を実行する一般的な手法の1つは(少なくとも学部の研究では、おそらく自動検証で)、Hoareロジックを使用することです。標準のルールのセットに配列に関連するものが含まれていることは知りません。それらはモナド変数に制限されているようです。

形の公理を追加することを想像できます

{0i<A.lengthP[A[i]/E]} A[i]:=E; {P}

ただし、右側の配列アクセスをどのように処理するか、つまり、あるステートメントx = Eの複雑な式一部である場合は、はっきりしません。Ex:=E

配列アクセスをHoareロジックでモデル化して、無効なアクセスがないことをプログラムの正確性を証明できるようにするにはどうすればよいですか?

答えが我々以外の文で使用される配列要素を許可しないと仮定することができるまたはいくつかの一環としてEにおけるX = Eこの表現を制限しないように。一時的な変数にいつでも必要な値を割り当てることができます。つまり、t = A [ i ]と書きます。i ft > 0 i fA [ i ] > 0 )の代わりにA[i]:=EEx:=Et:=A[i]; if(t>0)if(A[i]>0)

回答:


8

あなたの公理は実際には公理ではなく、仮説が欠けています。ホーア論理の簡単なプレゼンテーションの形式の式操作P及びPは論理式であり、Cは、コマンドです。Cが整形式であること確認する必要があります。Hoareロジックの最初の紹介でよく使用されるような単純な言語では、整形式は構文です。通常は、Cをチェックすることです。{P}C{P}PPCCC文脈自由文法に準拠し、自由変数が許可されたセット内にある可能性があります。言語に、配列要素へのアクセスなど、セマンティックな正確性を持つ構成要素が含まれている場合は、このセマンティックな正確性を表す仮説を追加する必要があります。

正式には、式やコマンドの修正を表す判断を追加できます。式に副作用がない場合、式には事後条件は不要で、事前条件のみが必要です。たとえば、{ P }などの整形式のルールを記述できます あり、コマンドでは正しい形式の式のみを許可します: {P[xE]}

{P}E wf{P0E<length(A)}A[E] wf{P}E1 wf{P}E2 wf{P}E1+E2 wf
{P[xE]}E wf{P[xE]}x:=E{P}

errorerrorError¬Error

{P[xE]}x:=E{PError}P[xE]Eerror{P[xE]}x:=E{P}

さらに別のアプローチは、プログラムが正しく終了した場合にのみ保持されるHoareトリプルを検討することです。これは、非終了プログラムの通常のアプローチです。コマンドが終了すると後条件が成立しますが、常に発生するとは限りません。実行時エラーを非終了として扱う場合、内部ですべての正確性の問題を一掃します。プログラムの正しさを何らかの形で証明する必要がありますが、そのタスクに他の形式を使用する場合は、Hoareロジックである必要はありません。

PIsSorted(A)A[i]EPA[i]PPA[A[0]1]:=A[0]A[0]=2A[1]=3A[0]=1A[1]=1A[0]A[0]AA[iE]


0

Gillesが述べたように、配列割り当ての公理があります(Gordonのノート、セクション2.1.10を参照):

{Q[AA.store(i,expr)]}A[i]=expr{Q}
A.store(i,expr)iexprA.store(i,vi)A[j]=vjA.store(j,vj).store(i,vi)

A.store(i,v)[i]vi

配列を使用したプログラムが正しいことを証明するには(「範囲外アクセスがない」)、上記の公理で十分だと思います。プログラムを考えてみましょう:

...
A[i] = 12
...

このプログラムに注釈を付けます。

...
@ {0<i<A_length}
A[i] = 12
...

ここで、A_length配列の長さを指定する変数です。次に、注釈を証明してみてください。つまり、逆に(下から上へ、Hoareの証明では「通常どおり」)修正します。上にある場合{false}、範囲外のアクセスが発生する可能性があります。それ以外の場合、取得した式は、範囲外のアクセスが不可能であるという前提条件です。(また、配列が作成されたときのようint A=int[10];に、post-conditionでそれを確実にする必要があります{A_length==10})。


公理は範囲外のアクセスをモデル化していません。長さについても言及していません。サンプルプログラムでは、どのように関係lengthしていAますか?
Gilles「SO-邪悪なことをやめなさい」

そう、公理は範囲外のアクセスをモデル化していません。まず、プログラムが正しいことを証明するために、アクセスが範囲内であることを要求する注釈を追加します。(length名前が変更されましたA_length。)次に、のような配列の「作成」公理が必要int[] a = int[length] {a_length==length}です。これで十分だと思います。
Ayrat 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.