非線形演算を扱う Z3 の一部であると私が信じている部分で、パフォーマンスの問題が発生しています。これは、Z3 (バージョン 4.1) で検証すると、完了までに長い時間 (3 分程度) かかる簡単で具体的なブギーの例です。
const D: int;
function f(n: int) returns (int) { n * D }
procedure test() returns ()
{
var a, b, c: int;
var M: [int]int;
var t: int;
assume 0 < a && 1000 * a < f(1);
assume 0 < c && 1000 * c < f(1);
assume f(100) * b == a * c;
assert M[t] > 0;
}
この問題は、関数の相互作用、整数変数の範囲の仮定、および(不明な)整数値の乗算によって引き起こされるようです。最終的に主張は証明可能であってはなりません。Z3 はすぐに失敗するのではなく、どうにかして多くの用語をインスタンス化する方法を持っているようです。そのメモリ消費量はかなり急速に約 300 MB に達し、その時点で断念します。
これがバグなのか、それとも現在問題を解決しようとしている特定の方向で Z3 がいつ検索を停止すべきかについてのヒューリスティックを改善することができるのかどうか疑問に思っています。
興味深いことの 1 つは、次を使用して関数をインライン化することです。
function {:inline} f(n: int) returns (int) { n * D }
検証を非常に迅速に終了させます。
背景: これは、ベリファイア Chalice で見られる問題の最小限のテスト ケースです。そこでは、Boogie プログラムがはるかに長くなり、同様の種類の複数の仮定が含まれる可能性があります。多くの場合、検証はまったく終了していないように見えます。
何か案は?