Shambo
Shambo

Reputation: 946

collection of variables in Z3 using C++ API

I want to define a collection of variables like "x_1" ... "X_1000", using Z3 C++ API. Can this be done using a for loop? I mean something of the form :

expr x[100] ;
for( i = 0; i < 1000 ; i++)
{  sprintf(str, "x_%d", i);
   x[i] = c.bool_const(str);
}

solver s(c);

for( i = 0; i < 1000 ; i++)
   s.add(x[i] >= 1)

If not, what should be the most elegant way to achieve this?

Upvotes: 3

Views: 1742

Answers (1)

Leonardo de Moura
Leonardo de Moura

Reputation: 21475

We can't write expr x[100] because the expr class does not have a constructor of the form expr::expr(). We should use the expr_vector instead. Here is an example (I also added it to the official C++ example in the Z3 distribution).

void expr_vector_example() {
    context c;
    const unsigned N = 10;

    expr_vector x(c);

    for (unsigned i = 0; i < N; i++) { 
        std::stringstream x_name; 
        x_name << "x_" << i;
        x.push_back(c.int_const(x_name.str().c_str()));
    }

    solver s(c);
    for (unsigned i = 0; i < N; i++) {
        s.add(x[i] >= 1);
    }

    std::cout << s << "\n" << "solving...\n" << s.check() << "\n";
    model m = s.get_model();
    std::cout << "solution\n" << m;
}

UPDATE I added new C++ APIs for creating universal and existential quantifiers using expr_vector. The new APIs are already available in the unstable branch. Here is an example:

void exists_expr_vector_example() {
    std::cout << "exists expr_vector example\n";
    context c;
    const unsigned N = 10;

    expr_vector xs(c);
    expr x(c);
    expr b(c);
    b = c.bool_val(true); 

    for (unsigned i = 0; i < N; i++) { 
        std::stringstream x_name; 
        x_name << "x_" << i;
        x = c.int_const(x_name.str().c_str());
        xs.push_back(x);
        b = b && x >= 0;
    }

    expr ex(c);
    ex = exists(xs, b);
    std::cout << ex << std::endl;
}

Upvotes: 4

Related Questions