【发布时间】:2020-06-05 02:48:40
【问题描述】:
我有一个整数常量,比如说:
expr x = ctx.int_const("x");
我要做的是对 x 的各个位应用随机约束。但是,事实证明,您不能将按位运算与整数排序一起使用,而只能使用位向量。在意识到这一点之前,我最初的做法是这样的:
for(int i = 0; i < 32; i++){
int mask = 0x00000001 << i;
if(rand()%2)
solver.add((x & mask) == 0);
else
solver.add((x & mask) != 0);
}
这当然行不通,因为 Z3 会抛出异常。
在对 API 进行了一番挖掘之后,我找到了 Z3_mk_int2bv 函数,并想试试看:
for(int i = 0; i < 32; i++){
if(rand()%2)
solver.add(z3::expr(ctx(),Z3_mk_int2bv(ctx(), 32, v())).extract(i, i) == ctx().bv_val(0, 1));
else
solver.add(z3::expr(ctx(),Z3_mk_int2bv(ctx(), 32, v())).extract(i, i) != ctx().bv_val(0, 1));
}
虽然没有在上述求解器添加调用上引发任何断言,但实际求解时间突然爆炸式增长。如此之多,以至于我还没有看到实际需要多长时间。使用位向量添加类似的表达式不会对 SAT 求解器造成重大影响,据我所知,求解器的时间不到一秒。
我想知道上面的表达式是什么导致求解器性能如此糟糕地下降,是否有更好的方法?
【问题讨论】:
-
不相关:
if(rand()%2)可能略有偏差,一般来说,randsucks。考虑使用std::uniform_int_distribution<>(0,1)作为替代品。 -
@user4581301 感谢您的提示