假设有一组公理,有没有办法简化Z3中的非布尔表达式?
例如,我想声明“a == b”,然后简化表达式 “如果(a == b,1,2)”得到“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) simplify_assuming(A4[a], Distinct(a, b, c))
这应该返回“1”,因为根据数组理论规则,假设所有索引都是不同的,Select表达式可以简化为“1”。
我试图使用“ctx-solver-simplified”策略,但它似乎只适用于布尔表达式。有没有其他方法来简化非布尔表达式,或以某种方式告诉数组重写器索引是不同的?
感谢。
答案 0 :(得分:1)
正如Nikolaj在上面的评论中所描述的那样,ctx-solver-simplify
不会在非布尔表达式下行走。另一个选择是使用策略solve-eqs
,它将使用断言的等式来重写公式的其余部分。例如,给定相等a == b
,Z3将用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
。因此,这种方法可能太脆弱,无法满足您的需求。
这是一个使用它的脚本。它也可以在线here获得。在此脚本中,我使用新谓词A4[a]
包装表达式P
,因为Z3目标是一组布尔公式。
我使用blast_distinct
将Distinct
转换为一系列不平等,并expand_select_store
将store(A, i, v)[j]
形式的术语扩展为if-then-else
形式{ {1}}。请注意,结果包含if(i == j, v, A[j])
,表示P(1)
已简化为P(A4[a])
。
1