上記のコメントで説明されているように、Nikolajはctx-solver-simplify
非ブール式の下を歩きません。もう1つのオプションは、solve-eqs
表明された等式を使用して式の残りの部分を書き直す戦術を使用することです。たとえば、が等しい場合、Z3はすべての出現箇所をでa == b
置き換えます(またはその逆)。その後、に書き換えられます。b
a
if(a == b, 1, 2)
1
ただし、solve-eqs
などの不等式は使用しませんDistinct(a, b, c)
。別のオプションは、戦術を使用することpropagate-values
です。アサーションのすべての出現を。に置き換えP
ますtrue
。同様に、アサーションがある場合は、not P
他のすべてのオカレンスP
を。に置き換えfalse
ます。この戦術は、基本的にユニットブール伝播を実行しています。さらに、それは高速であることが意図されており、いかなる形式の理論的推論も適用しません。たとえば、がある場合Distinct(a, b, c)
、それはに置き換えa == b
られませんfalse
。したがって、このアプローチは、目的には脆弱すぎる可能性があります。これを使用するスクリプトを次に示します。こちらからオンラインでも入手できます。このスクリプトではA4[a]
、新しい述語を使用して式をラップしますP
Z3目標はブール式のセットであるためです。私は、を一連の不等式にblast_distinct
変換し、フォームの用語をフォームのに拡張するために使用します。結果には、がに簡略化されたことを示すが含まれていることに注意してください。Distinct
expand_select_store
store(A, i, v)[j]
if-then-else
if(i == j, v, A[j])
P(1)
P(A4[a])
1
I = BitVecSort(32)
A = Array('A', I, I)
a = BitVec('a',32)
b = BitVec('b',32)
c = BitVec('c',32)
A2 = Store(A, a, 1)
A3 = Store(A2, b, 2)
A4 = Store(A3, c, 3)
P = Function('P', I, BoolSort())
G = Goal()
G.add(P(A4[a]))
G.add(Distinct(c, b, a))
T = Then(With("simplify", blast_distinct=True, expand_select_store=True), "propagate-values")
print(T(G))