Z3 4.0推入式和弹出式解算器
我想使用两个不同约束的解算器验证我的问题。我为此编写了一个示例程序,其中有一个变量x,我想检查它并得到Z3 4.0推入式和弹出式解算器,z3,Z3,我想使用两个不同约束的解算器验证我的问题。我为此编写了一个示例程序,其中有一个变量x,我想检查它并得到x=0和x=1的模型 我尝试在解算器中使用推和弹出。然而,我不知道如何确切地做到这一点。我已经编写了以下代码。当我尝试推送上下文并将其弹出时,会遇到崩溃。我不明白撞车的原因,但它是Seg故障。即使我按照下面的说明注释了push和pop指令,我仍然会遇到崩溃 有人能给我一些建议来解决这个问题吗 Z3_config cfg; Z3_context ctx; Z3_solver solver; Z3_
x=0
和x=1
的模型
我尝试在解算器中使用推和弹出。然而,我不知道如何确切地做到这一点。我已经编写了以下代码。当我尝试推送上下文并将其弹出时,会遇到崩溃。我不明白撞车的原因,但它是Seg故障。即使我按照下面的说明注释了push和pop指令,我仍然会遇到崩溃
有人能给我一些建议来解决这个问题吗
Z3_config cfg;
Z3_context ctx;
Z3_solver solver;
Z3_ast x, zero, one, x_eq_zero, x_eq_one;
cfg = Z3_mk_config();
ctx = Z3_mk_context(cfg);
Z3_del_config(cfg);
solver = Z3_mk_solver((Z3_context)ctx);
x = mk_int_var(ctx, "x");
zero = mk_int(ctx, 0);
one = mk_int(ctx, 1);
x_eq_zero = Z3_mk_eq(ctx, x, zero);
x_eq_one = Z3_mk_eq(ctx, x, one);
//Z3_solver_push (ctx, solver);
Z3_solver_assert(ctx, solver, x_eq_zero);
printf("Scopes : %d\n", Z3_solver_get_num_scopes((Z3_context) ctx, (Z3_solver) solver));
printf("%s \n", Z3_ast_to_string(ctx, x_eq_zero));
int result = Z3_solver_check ((Z3_context) ctx, (Z3_solver) solver);
printf("Sat Result : %d\n", result);
printf("Model : %s\n", Z3_model_to_string ((Z3_context) ctx, Z3_solver_get_model ((Z3_context) ctx, (Z3_solver) solver)));
// Z3_solver_pop (ctx, solver, 1);
// printf("Scopes : %d\n", Z3_solver_get_num_scopes((Z3_context) ctx, (Z3_solver) solver));
Z3_solver_assert(ctx, solver, x_eq_one);
result = Z3_solver_check ((Z3_context) ctx, (Z3_solver) solver);
printf("Sat Result : %d\n", result);
printf("Model : %s\n", Z3_model_to_string ((Z3_context) ctx, Z3_solver_get_model ((Z3_context) ctx, (Z3_solver) solver)));
return 0;
Z34.0中的新API具有许多新特性。例如,它引入了几个新对象:解算器、目标、策略、探测等。此外,我们还为以前的API中存在的对象(如AST和模型)引入了新的内存管理策略。新的内存管理策略基于引用计数。每个对象都有
Z3_uuinc_ref
和Z3_uudec_ref
形式的API。我们仍然支持AST和机型的旧内存管理策略。如果使用Z3_mk_context
创建Z3_context
,则为AST启用旧的内存管理策略。如果使用Z3_mk_context_rc
创建,则必须使用Z3_inc_ref
和Z3_dec_ref
来管理参考计数器。但是,新对象(解算器、目标、策略等)仅支持引用计数。我们强烈鼓励所有用户使用新的引用计数内存管理策略。因此,所有新对象仅支持此策略。此外,所有托管API(.Net、Python和OCaml)都基于引用计数策略。注意,我们提供了一个C++层之上的瘦C++层。它使用“智能指针”来“隐藏”所有引用计数调用。C++层的源代码包含在Z3分布中。
也就是说,您的程序崩溃是因为您没有增加对象的参考计数器Z3\u solver
。这是您的程序的正确版本。我基本上添加了对Z3_solver_inc_ref
和Z3_solver_dec_ref
缺少的调用。后者是避免内存泄漏所必需的。之后,我还使用C++ API来包含相同的程序。这要简单得多。在文件“代码>中提供了C++ API,其中包含Z3分布中的Z3++.H./CODE。示例包括在Examples\c++
中
Z3_config cfg;
Z3_context ctx;
Z3_solver solver;
Z3_ast x, zero, one, x_eq_zero, x_eq_one;
cfg = Z3_mk_config();
ctx = Z3_mk_context(cfg);
Z3_del_config(cfg);
solver = Z3_mk_solver((Z3_context)ctx);
Z3_solver_inc_ref(ctx, solver);
x = mk_int_var(ctx, "x");
zero = mk_int(ctx, 0);
one = mk_int(ctx, 1);
x_eq_zero = Z3_mk_eq(ctx, x, zero);
x_eq_one = Z3_mk_eq(ctx, x, one);
//Z3_solver_push (ctx, solver);
Z3_solver_assert(ctx, solver, x_eq_zero);
printf("Scopes : %d\n", Z3_solver_get_num_scopes((Z3_context) ctx, (Z3_solver) solver));
printf("%s \n", Z3_ast_to_string(ctx, x_eq_zero));
int result = Z3_solver_check ((Z3_context) ctx, (Z3_solver) solver);
printf("Sat Result : %d\n", result);
printf("Model : %s\n", Z3_model_to_string ((Z3_context) ctx, Z3_solver_get_model ((Z3_context) ctx, (Z3_solver) solver)));
// Z3_solver_pop (ctx, solver, 1);
// printf("Scopes : %d\n", Z3_solver_get_num_scopes((Z3_context) ctx, (Z3_solver) solver));
Z3_solver_assert(ctx, solver, x_eq_one);
result = Z3_solver_check ((Z3_context) ctx, (Z3_solver) solver);
printf("Sat Result : %d\n", result);
// printf("Model : %s\n", Z3_model_to_string ((Z3_context) ctx, Z3_solver_get_model ((Z3_context) ctx, (Z3_solver) solver)));
Z3_solver_dec_ref(ctx, solver);
return 0;
C++版本
context c;
solver s(c);
expr x = c.int_const("x");
expr x_eq_zero = x == 0;
expr x_eq_one = x == 1;
s.add(x_eq_zero);
std::cout << "Scopes : " << Z3_solver_get_num_scopes(c, s) << "\n";
std::cout << x_eq_zero << "\n";
std::cout << s.check() << "\n";
std::cout << s.get_model() << "\n";
s.add(x_eq_one);
std::cout << s.check() << "\n";
return 0;
context c;
s(c);
expr x=c.int_const(“x”);
expr x_eq_zero=x==0;
expr x_eq_one=x==1;
s、 加(x_等于零);
我不能感谢你的回答。还有一个疑问。它是否适用于所有对象?例如,我做了一个断言x>=0
,然后做了一个解算器检查。在那之后,我做了另一个断言y>=x
。因此,如果我希望条件是y>=x和x>=0
,那么我应该为下一次检查增加x>=0
的引用计数吗?如果我们使用C API和方法Z3_mk_context_rc
创建上下文,那么我们应该在代码引用Z3 AST时调用Z3_inc_ref
。也就是说,我们有一个局部变量或数据结构指向它。类似地,当一个指针不再指向它时,我们必须调用Z3_dec_ref
。在您的示例中,我们必须在创建后增加引用计数器x>=0
,因为我们可能会有一个局部变量指向它。请注意,当您在解算器中断言x>=0
时,Z3会增加计数器。