Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Z3 quantifier support

Tags:

z3

I need a theorem prover for some simple linear arithmetic problems. However, I can't get Z3 to work even on simple problems. I'm aware that it is incomplete, however it should be able to handle this simple example:

(assert (forall ((t Int)) (= t 5)))
(check-sat)

I'm not sure if i'm overlooking something, but this should be trivial to disprove. I even tried this simpler example:

(assert (forall ((t Bool)) (= t true)))
(check-sat)

That should be solvable by making an exhaustive search, since boot only contains two values.

In both cases z3 answers with unknown. I'd like to know if i'm doing something wrong here or if not if you can recommend a theorem prover for these types of formulas.

like image 659
ThorstenT Avatar asked Nov 02 '12 16:11

ThorstenT


1 Answers

For handling this kind of quantifiers, you should use the quantifier elimination module available in Z3. Here is an example on how to use it (try online at http://rise4fun.com/Z3/3C3):

(assert (forall ((t Int)) (= t 5)))
(check-sat-using (then qe smt))

(reset)

(assert (forall ((t Bool)) (= t true)))
(check-sat-using (then qe smt))

The command check-sat-using allows us to specify an strategy to solve the problem. In the example above, I'm just using qe (quantifier elimination) and then invoking a general purpose SMT solver. Note that, for these examples, qe is sufficient.

Here is a more complicated example, where we really need to combine qe and smt (try online at: http://rise4fun.com/Z3/l3Rl )

(declare-const a Int)
(declare-const b Int)
(assert (forall ((t Int)) (=> (<= t a) (< t b))))
(check-sat-using (then qe smt))
(get-model)

EDIT Here is the same example using the C/C++ API:

void tactic_qe() {
    std::cout << "tactic example using quantifier elimination\n";
    context c;

    // Create a solver using "qe" and "smt" tactics
    solver s = 
        (tactic(c, "qe") &
         tactic(c, "smt")).mk_solver();

    expr a = c.int_const("a");
    expr b = c.int_const("b");
    expr x = c.int_const("x");
    expr f = implies(x <= a, x < b);

    // We have to use the C API directly for creating quantified formulas.
    Z3_app vars[] = {(Z3_app) x};
    expr qf = to_expr(c, Z3_mk_forall_const(c, 0, 1, vars,
                                            0, 0, // no pattern
                                            f));
    std::cout << qf << "\n";

    s.add(qf);
    std::cout << s.check() << "\n";
    std::cout << s.get_model() << "\n";
}
like image 59
Leonardo de Moura Avatar answered Sep 25 '22 23:09

Leonardo de Moura