I would like to use Z3 for eliminating quantifiers in linear integer arithmetic formulas via C/C++ API. Consider a simple example: Exists (x) ( x <= y & y <= 2*x). A quantifier-free
formula with the same models is y >= 0.
I tried to do it this way:
context ctx;
ctx.set("ELIM_QUANTIFIERS", "true");
expr x = ctx.int_const("x");
expr y = ctx.int_const("y");
expr sub_expr = (x <= y) && (y <= 2*x);
Z3_ast qf = Z3_mk_exists_const(ctx, 0, 1, (Z3_app[]) {x},
0, {}, // patterns don't seem to make sense here.
sub_expr); //No C++ API for quantifiers :(
qf = Z3_simplify(ctx, qf);
cout << Z3_ast_to_string(ctx, qf);
what I get is
(exists ((x Int) (and (<= x y) (<= y (* 2 x))))
whereas I’d like to obtain something like
(<= 0 y)
Is there a possibility to get it with Z3?
Many thanks in advance.
Nikolaj already pointed out that tactics can be used to perform quantifier elimination. In this post, I’d like to emphasize how to safely mix the C++ and C APIs. The Z3 C++ API uses reference counting to manage the memory.
expris essentially a “smart-pointer” that manages the reference counters automatically for us. I discussed this issue in the following post: Array select and store using the C++ API.So, when we invoke a C API that returns a Z3_ast, we should wrap the result using the functions
to_expr,to_sortorto_func_decl. The signature ofto_expris:By using this function, we avoid memory leaks, and crashes (when accessing objects that have been garbage collected by Z3). Here is the complete example using
to_expr(). You can test it by copying this function in theexample.cppfile in thec++folder in the Z3 distribution.