こんにちは、自動控除と検証ハッカー!
WhyML が ACSL アノテーション付き C プログラムの証明をどのように正確に提供するかをより深く理解するために、Why3 が WhyML プログラムで行う作業を手動で「再現」し、それを SMT ロジックに変換して Z3 証明者にフィードしようとしています。
次の C フラグメントがあるとします。
const int L = 3;
int a[L] = {0};
int i = 0;
while (i < L) {
a[i] = i;
i++;
}
assert (a[1] == 1);
次のように SMT ロジックにエンコードしようとしています。
(set-logic AUFNIRA)
(define-sort _array () (Array Int Int))
(declare-const ar _array)
(declare-fun set_a_i (_array Int Int) _array)
(assert (forall ((ar0 _array) (i Int) (j Int))
(ite (< i j)
(= (set_a_i ar0 i j)
(set_a_i (store ar0 i i) (+ i 1) j))
(= (set_a_i ar0 i i) ar0) )))
(assert (= (select (set_a_i ar 0 3) 1) 1))
(check-sat)
Z3 は「不明」を返します。
これはおそらく、set_a_i 関数を指定する際に使用される数量化によるものです。しかし、それを指定する他の方法はありません。
私は次の声明を認識しています。
- 一般に、SMT ソルバーは、配列の数量化を処理できません (または悪い方法で処理します)。
- 事前条件と事後条件およびループ不変条件を指定すると、WhyML はそのようなプログラムを証明できます。
- バックエンドがZ3に設定されている場合でも、なぜMLはそのようなプログラムを証明できるので、SMTソルバー自体は問題になりません.
- WhyML は z3 smt ファイルを生成できますが、理由の 1 つは、WhyML から smt への変換が自動的に行われるため、それを理解するのは大変な労力です (たとえば、変数名を保持しません)。
WhyML、Frama-C WP プラグイン、Z3 について提供されたほぼすべての資料を読みました。また、C コードの検証に関するいくつかの論文を読みましたが、C --> SMT 変換技術に関するものは何も見つかりませんでした。
この理解を得るには、どの資料を学習すればよいですか? 命令型コードをマルチソートされた一次ロジックに変換するこの機構を説明している論文への洞察やリンクを提供していただけませんか。
コメントをいただければ幸いです。ありがとう!
がんばれ、エフゲニー。