我有一个问题要解决,可以转化为差异逻辑,而不是实现决策程序,我想使用z3来达到这个目的。 不过,我运行了几个例子,我有类似指数的运行时(即使有一个polytime决策程序)。我是z3的新手,我不知道我做错了什么。这是我正在使用的代码(c ++ api),变换这个“max”变量。
int main(int argc, char **argv) {
context c;
solver s(c, "QF_IDL");
int max = 10000;
int prev = 0;
for(int i = 1; i < max; ++i){
expr x = s.ctx().int_const(std::to_string(i).c_str());
expr y = s.ctx().int_const(std::to_string(++i).c_str());
expr pr = s.ctx().int_const(std::to_string(prev).c_str());
s.add(pr < x);
s.add(x < y);
prev = i;
}
s.add(s.ctx().int_const(std::to_string(max-1).c_str()) < s.ctx().int_const(std::to_string(0).c_str()));
clock_t begin = clock();
switch (s.check()) {
case unsat: std::cout << "UNSAT"; break;
case sat: std::cout << "SAT"; break;
case unknown: std::cout << "unknown\n"; break;
}
clock_t end = clock();
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
std::cout << "elapsed time: " << elapsed_secs;
}
非常感谢,
佩德罗
答案 0 :(得分:2)
默认情况下,Z3使用单工引擎,有时使用Floyd Marshall引擎来解决约束,即使逻辑是QF_IDL也是如此。在这种情况下,它使用单工引擎,并且对于此示例,行的大小以二次方式增长。 您可以通过在程序中插入以下内容来强制使用sparce差异逻辑解算器:
params p(c);
p.set("auto_config", false);
p.set("smt.arith.solver", (unsigned)1);
solver s(c, "QF_IDL");
s.set(p);
这将算术解算器设置为稀疏差分逻辑解算器。 它不会受到空间开销的影响。它仍需要二次时间, 或者更精确的时间与| V | | E |成比例其中| V |是数字 变量和| E |是不平等的数量。 在这种情况下,主要的时间瓶颈是大数字算术,而不是 在你的情况下是必要的我添加了对Z3的不稳定分支的更新,以便它识别仅使用小整数的场景,以便它可以使用 更高效的代表性。这需要花费大量时间来减少大约5个因素。然而,开销仍然是| V | | E |。