我正在编写一些代码来为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));
}
答案 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;
}
}