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.
The simplifier does not invoke the quantifier elimination procedures any longer. Quantifier elimination and many other special purpose simplification rewrites are available over tactics.
The C++ wrapper z3++.h exposes methods for creating tactic objects. You would have to create a tactic object for the "qe" tactic. THe Z3 distribution comes with a couple of samples for using the tactics from the z3++.h API. For example:
}
In your case you would want something along the lines of:
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.
expr
is 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_sort
orto_func_decl
. The signature ofto_expr
is: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.cpp
file in thec++
folder in the Z3 distribution.