I am trying to figure out how to code quantifiers in CVC4, using the C++ interface. Here is an example I am trying to get to run, but cannot.
int main() {
SmtEngine smt(&em);
smt.setLogic("AUFLIRA"); // Set the logic
Expr three = em.mkConst(Rational(3));
Expr four = em.mkConst(Rational(4));
// make the list of bound variables in CVC4
Expr bound_var = em.mkBoundVar("x_bound", em.integerType());
vector<Expr> bound_vars;
bound_vars.push_back(bound_var);
Expr bound_var_list = em.mkExpr(kind::BOUND_VAR_LIST, bound_vars);
Expr declare = em.mkExpr(kind::EQUAL, bound_var, three); //x_bound =3
Expr check = em.mkExpr(kind::EQUAL, bound_var, four); //x_bound=4
//forall x_bound, x_bound=3, the constraint I want to declare as true
Expr expr = em.mkExpr(kind::FORALL, bound_var_list, declare);
smt.assertFormula(expr);
smt.push();
// expect to be INVALID
// I want to check that given forall x_bound, x_bound = 3
// then I ask CVC4: is it true that x_bound=4, or is it false?
std::cout << "Quantifier " << smt.query(check) << std::endl;
return 0;
}
Instead, I just get an error message:
Bound variables test
Quantifier unknown (INCOMPLETE)
But I define the quantifier as forall
. What did I do wrong?
EDIT (asked https://www.andrew.cmu.edu/user/liminjia/):
Syntax is wrong. We want to know if
(forall x, x=3) IMPLIES (forall x, x=4)
is true or not. But CVC4 does not if the above formula is valid or not, because SMT solvers are not full-fledged first-order logic theorem provers.
If you want to try something that works, try in CVC4 language:
QUERY (FORALL (x:INT): x =4);
And in C++, we have
// check that forall x, x=3 is INVALID
void cvc4BoundVar() {
std::cout << "Bound variables test" << std::endl;
SmtEngine smt(&em);
smt.setLogic("AUFLIRA"); // Set the logic
Expr three = em.mkConst(Rational(3));
Expr v_expr = em.mkBoundVar("x_bound", em.integerType());
vector<Expr> bound_vars;
bound_vars.push_back(v_expr);
Expr bound_var_list = em.mkExpr(kind::BOUND_VAR_LIST, bound_vars);
Expr declare = em.mkExpr(kind::EQUAL, v_expr, three); //x=3
Expr check = em.mkExpr(kind::EQUAL, v_expr, three);
Expr expr = em.mkExpr(kind::FORALL, bound_var_list, declare); //forall x, x=3
std::cout << "Quantifier " << smt.query(expr) << std::endl;
}