正如 Nikolaj 在上面的评论中所描述的,ctx-solver-simplify
不会在非布尔表达式下行走。另一种选择是使用solve-eqs
将使用断言的等式来重写公式的其余部分的策略。例如,给定相等性a == b
,Z3 将替换每个出现的b
with a
(反之亦然)。之后,if(a == b, 1, 2)
将被重写为1
.
但是,solve-eqs
不会使用不等式,例如Distinct(a, b, c)
. 另一种选择是使用战术propagate-values
。它将每次出现的断言替换P
为true
. 同样,如果我们有一个断言not P
,它将替换所有其他出现的P
with 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))