将Z3模型值导入C ++

时间:2014-06-16 22:02:42

标签: c++ z3

我正在编写一些代码来为Z3生成约束,然后求解结果。我可以通过命令Z3_model_to_string(ctx,m)打印出结果,结果显示x1-> 1 x2->100,其中x1和x2都是int。我的问题是如何将这些整数值保存到C ++变量中以供将来分析?

以下是我为Z3编写的代码部分

Z3_model m;
context ctx;
Z3_ast fs;
string str = "(declare-const x1 Int) (assert (> x1 0)) (declare-const x2 Int) (assert (not (< x2 100)))" //Generated by some other function
fs  = Z3_parse_smtlib2_string(Z3_context(ctx), str, 0, 0, 0, 0, 0, 0);
Z3_assert_cnstr(Z3_context(ctx), fs);
Z3_lbool result = Z3_check_and_get_model(Z3_context(ctx), &m);
switch (result) {
case Z3_L_FALSE:
    printf("unsat\n");
    break;
case Z3_L_UNDEF:
    printf("unknown\n");
    printf("potential model:\n%s\n", Z3_model_to_string(Z3_context(ctx), m));
    break;
case Z3_L_TRUE:
    printf("sat\n%s\n", Z3_model_to_string(Z3_context(ctx), m));
    break;
}
int num_constants = Z3_get_model_num_constants(Z3_context(ctx), m);
model aaa(ctx,m);
for (i = 0; i< num_constants; i++) {
    z3::expr r = aaa.get_const_interp(aaa.get_func_decl(i));
}

1 个答案:

答案 0 :(得分:4)

拥有模型m后,可以使用类模型中的get_const_intrp和get_func_interp函数来获取它们的值。对于简单整数变量的情况,模型中应该有n常数(即常数函数),即m.num_consts() = n

expr r = m.get_const_interp(m.get_const_decl(i));

将返回模型中i - 常数的解释。对于简单整数约束的情况,结果通常是描述数值的expr,即r.is_numeral()应该为真。我们可以通过这些函数得到这些模型值的不同表示:

表示整数和其他类型:

Z3_get_numeral_string
Z3_get_numeral_decimal_string
Z3_get_numeral_int
Z3_get_numeral_uint
Z3_get_numeral_uint64
Z3_get_numeral_int64

表示真实/有理数:

Z3_get_numeral_small
Z3_get_numerator
Z3_get_denominator
Z3_get_numeral_rational_int64

其中名称的最后一部分表示将返回的对象类型。请注意,如果模型值不适合返回类型(例如,int范围内的数字太大),这些函数将返回false。如果预计所有模型值都很小,我们当然可以使用这些函数。安全(和缓慢)方式是请求一个字符串,然后将它转换为您用于应用程序的大整数表示。

注意:C ++ API只是C API之上的一个薄层,这两个API可以一起使用。许多函数只存在于C层,C ++对象(如asts和exprs)应自动转换为适合C API的指针。

以下是此特定案例的完整示例。我冒昧地用更像C ++的样式重写一些代码:

#include <string>
using namespace std;

#include <z3++.h>
using namespace z3;

void main() {
    try {        
        context ctx;        
        Z3_string str = "(declare-const x1 Int) (assert (> x1 0)) (declare-const x2 Int) (assert (not (< x2 100)))"; //Generated by some other function
        expr fs(ctx, Z3_parse_smtlib2_string(Z3_context(ctx), str, 0, 0, 0, 0, 0, 0));

        solver s(ctx);
        s.add(fs);
        check_result cr = s.check();

        model aaa(ctx, s.get_model());
        int num_constants = aaa.num_consts();
        for (int i = 0; i < num_constants; i++) {
            func_decl fd = aaa.get_const_decl(i);
            z3::expr r = aaa.get_const_interp(fd);
        }
    }
    catch (z3::exception e) {
        std::cout << e.msg() << std::endl;
    }
}