Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Z3 4.0推入式和弹出式解算器_Z3 - Fatal编程技术网

Z3 4.0推入式和弹出式解算器

Z3 4.0推入式和弹出式解算器,z3,Z3,我想使用两个不同约束的解算器验证我的问题。我为此编写了一个示例程序,其中有一个变量x,我想检查它并得到x=0和x=1的模型 我尝试在解算器中使用推和弹出。然而,我不知道如何确切地做到这一点。我已经编写了以下代码。当我尝试推送上下文并将其弹出时,会遇到崩溃。我不明白撞车的原因,但它是Seg故障。即使我按照下面的说明注释了push和pop指令,我仍然会遇到崩溃 有人能给我一些建议来解决这个问题吗 Z3_config cfg; Z3_context ctx; Z3_solver solver; Z3_

我想使用两个不同约束的解算器验证我的问题。我为此编写了一个示例程序,其中有一个变量x,我想检查它并得到
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会增加计数器。