z3中不满核心功能

时间:2012-11-23 15:15:09

标签: z3

假设我使用API​​读取SMTLIB公式:

context ctx;
...
expr F = to_expr(ctx, Z3_parse_smtlib2_file(ctx,argv[1],0,0,0,0,0,0));

表达式F是形式断言的结合:

(and (< (+ x y) 3)
     (> (- x1 x2) 0)
     (< (- x1 x2) 4)
     (not (= (- x1 x2) 1))
     (not (= (- x1 x2) 2))
     (not (= (- x1 x2) 3))) 

我想使用帖子中的以下代码片段从此连接中提取每个单独的断言:How to use z3 split clauses of unsat cores & try to find out unsat core again

    F = F.simplify();
    for (unsigned i = 0; i < F.num_args(); i++) {
        expr Ai = F.arg(i);
        // ... Do something with Ai, just printing in this example.
        std::cout << Ai << "\n";
    }

使用F.arg(i)后,原始条款(< (+ x y) 3)已更改为(not (<= 3 (+ x y)))。这是我的

a)问题:如何将条款(not (<= 3 (+ x y)))放到(< (+ x y) 3)

b)问题:我认为符号<=意味着暗示在这种情况下,并不意味着小于。我是对的吗?

c)问题:因为条款(not (<= 3 (+ x y)))模型是真还是假,我怎样才能获得x = 1, y = -1等算术值?

非常感谢任何建议。 非常感谢你。

1 个答案:

答案 0 :(得分:2)

(< (+ x y) 3)时,表达式(not (<= 3 (+ x y)))会转换为F = F.simplify()。 在您使用的代码片段中,方法simplify()用于“展平”嵌套的“和”。也就是说,公式(and (and A B) (and C (and D E)))被展平为(and A B C D E)。然后,可以使用for循环轻松遍历所有合取。但是,simplify()还将在输入公式中执行其他转换。请记住,所有转换都保持等价。也就是说,输入和输出公式在逻辑上是等价的。如果simplify()应用的转换不合适,我建议您避免使用此方法。如果您仍想遍历嵌套的“和”,则可以使用辅助todo向量。这是一个例子:

expr_vector todo(c);
todo.push_back(F);
while (!todo.empty()) {
    expr current = todo.back();
    todo.pop_back();
    if (current.decl().decl_kind() == Z3_OP_AND) {
        // it is an AND, then put children into the todo list
        for (unsigned i = 0; i < current.num_args(); i++) {
            todo.push_back(current.arg(i));
        }
    }
    else {
        // do something with current
        std::cout << current << "\n";
    }
}