Array select and store using the C++ API

自作多情 提交于 2019-12-06 03:34:32

Z3 has two memory management modes: push/pop and reference counting. Reference counting was introduced much later. The C API method used to create the Z3_Context defines which memory management mode will be used. The API Z3_mk_context creates a context where a push/pop policy is used. That is, AST objects are deleted when Z3_pop is invoked. Any AST object created between the matching Z3_push will be deleted. This policy is simple to use, but it may prevent your application from freeing unused memory. The API Z3_mk_context_rc creates a context where reference counting is used to reclaim memory. This is the official approach in Z3 4.x. Moreover, new objects (e.g., tactics, solvers, goals) introduced in Z3 4.x only support this approach. If you are using C++, C#, OCaml, or Python APIs. Then, it is very simple to use the new reference counting policy. On the other hand, the C API is harder to use because we have to explicitly invoke the Z3_*inc_ref and Z3_*dec_ref APIs. If we miss one of them, we can have crashes (as in your example) or memory leaks. In the C++ API, we provide several "smart pointers" that manage the reference counters automatically for us.

Your example crashes because you replaced Z3_context ctx with context ctx. The constructor of the class context uses Z3_mk_context_rc instead of Z3_context. The file example.cpp in the c++ directory demonstrates how to combine the C++ and C APIs (see function capi_example()). In this example, the C++ smart pointer are used to wrap the C objects returned by the C API.

Finally, the C++ API provided the following functions for creating array expressions:

inline expr select(expr const & a, expr const & i) {
    check_context(a, i);
    Z3_ast r = Z3_mk_select(a.ctx(), a, i);
    a.check_error();
    return expr(a.ctx(), r);
}
inline expr select(expr const & a, int i) { return select(a, a.ctx().num_val(i, a.get_sort().array_domain())); }
inline expr store(expr const & a, expr const & i, expr const & v) {
    check_context(a, i); check_context(a, v);
    Z3_ast r = Z3_mk_store(a.ctx(), a, i, v);
    a.check_error();
    return expr(a.ctx(), r);
}
inline expr store(expr const & a, int i, expr const & v) { return store(a, a.ctx().num_val(i, a.get_sort().array_domain()), v); }
inline expr store(expr const & a, expr i, int v) { return store(a, i, a.ctx().num_val(v, a.get_sort().array_range())); }
inline expr store(expr const & a, int i, int v) { 
    return store(a, a.ctx().num_val(i, a.get_sort().array_domain()), a.ctx().num_val(v, a.get_sort().array_range())); 
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!