简体   繁体   English

将Z3模型值导入C ++

[英]Import Z3 model value to C++

I'm writing some code to generate constraints for Z3 and then solve for results. 我正在编写一些代码来生成Z3的约束,然后求解结果。 I can print out the result by the command Z3_model_to_string(ctx,m) and the result shows x1-> 1 x2->100 where x1 and x2 are both int. 我可以通过命令Z3_model_to_string(ctx,m)打印出结果,结果显示x1-> 1 x2->100 ,其中x1和x2都是int。 My question is how I can save these integer values into C++ variables for future analysis? 我的问题是如何将这些整数值保存到C ++变量中以供将来分析?

Here is the part of code I wrote for Z3 这是我为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));
}

Once you have a model m , you can use the get_const_intrp and get_func_interp functions in class model to obtain their values. 获得模型m ,可以使用类模型中的get_const_intrp和get_func_interp函数来获取它们的值。 For the case of simple integer variables there should be n constants (ie, constant functions) in the model, ie, m.num_consts() = n and 对于简单整数变量的情况,模型中应该有n常量(即常量函数),即m.num_consts() = n

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

will return the interpretation of the i -th constant in the model. 将返回模型中第i个常量的解释。 For the case of simple integer constraints, the result will usually be an expr describing a numeric value, ie, r.is_numeral() should be true. 对于简单整数约束的情况,结果通常是描述数值的expr ,即r.is_numeral()应为true。 We can get different representations of those model values through these functions: 我们可以通过以下函数获得这些模型值的不同表示:

for integers and other types: 对于整数和其他类型:

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

for real/rational numbers: 对于实数/有理数:

Z3_get_numeral_small
Z3_get_numerator
Z3_get_denominator
Z3_get_numeral_rational_int64

where the last part of the name indicates what type of object will be returned. 名称的最后一部分表示将返回什么类型的对象。 Note that these functions will return false if the model values don't fit into the return type (eg, number too large for the int range). 请注意,如果模型值不适合返回类型,则这些函数将返回false (例如,对于int范围,数字太大)。 If all model values are expected to be small, we can of course use these functions. 如果预计所有模型值都很小,我们当然可以使用这些函数。 The safe (and slow) way is to ask for a string and then convert it whatever big-integer representation you use for your application. 安全(和慢)的方法是请求一个字符串,然后将它转换为您用于应用程序的大整数表示。

Note: The C++ API is only a thin layer on top of the C API and those two APIs are meant to be used together. 注意:C ++ API只是C API之上的一个薄层,这两个API可以一起使用。 Many functions only exist on the C layer and C++ objects like asts and exprs should convert automatically into the right kind of pointers for the C API. 许多函数只存在于C层,C ++对象(如asts和exprs)应自动转换为适合C API的指针。

Here is a complete example for this particular case. 以下是此特定案例的完整示例。 I took the liberty of rewriting some of the code in a more C++ like style: 我冒昧地用更像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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM