如何使用量词访问Z3表达式

时间:2018-04-13 15:22:13

标签: c++ z3

我想访问z3::expr。 examples目录提供了以下代码段:

void visit(expr const & e) {
    if (e.is_app()) {
        unsigned num = e.num_args();
        for (unsigned i = 0; i < num; i++) {
            visit(e.arg(i));
        }
        // do something
        // Example: print the visited expression
        func_decl f = e.decl();
        std::cout << "application of " << f.name() << ": " << e << "\n";
    }
    else if (e.is_quantifier()) {
        visit(e.body());
        // do something
    }
    else { 
        assert(e.is_var());
        // do something
    }
}

我对函数应用程序部分没问题,但是当遇到量词时我错过了一些内容。

  1. e.is_quantifier()成立时,如何获得我所拥有的量词(存在或全部)?

  2. 据我所知,Z3内部使用了De Bruijn指数,我对它们没问题。但是如何在e.is_var()为真时获取索引?

  3. 不太重要,但Z3仍然保留绑定变量的名称,即使知道De Bruijn索引在技术上使其冗余,因为如果我将表达式发送到std :: cout,则会出现变量名称。我怎么得到它?我可以假设它们是一致的,即,如果我盲目地用它的名字替换每个变量,那么变量以正确的方式绑定吗? (如果我没有弄错的话,这相当于没有变量在其使用和原始绑定站点之间再次量化的事实)

1 个答案:

答案 0 :(得分:0)

我设法编写了一些基于C API的C ++ API,从已经在Z3中实现的类似函数进行复制。

unsigned expr_get_num_bound(const z3::expr &e) {
    assert(e.is_quantifier());
    unsigned num = Z3_get_quantifier_num_bound(e.ctx(), e);
    e.check_error();
    return num;
}

z3::symbol expr_get_quantifier_bound_name(const z3::expr &e, unsigned i) {
    assert(e.is_quantifier());
    Z3_symbol sym = Z3_get_quantifier_bound_name(e.ctx(), e, i);
    e.check_error();
    return z3::symbol(e.ctx(), sym);
}

z3::sort expr_get_quantifier_bound_sort(const z3::expr &e, unsigned i) {
    assert(e.is_quantifier());
    Z3_sort sort = Z3_get_quantifier_bound_sort(e.ctx(), e, i);
    e.check_error();
    return z3::sort(e.ctx(), sort);
}

bool expr_is_quantifier_forall(const z3::expr &e) {
    assert(e.is_quantifier());
    Z3_bool is_forall = Z3_is_quantifier_forall(e.ctx(), e);
    e.check_error();
    return static_cast< bool >(is_forall);
}

unsigned expr_get_var_index(const z3::expr &e) {
    assert(e.is_var());
    unsigned idx = Z3_get_index_value(e.ctx(), e);
    e.check_error();
    return idx;
}

在我的问题中,这仍然没有给出第3点后半部分的明确答案,但它是首发。