如何调用Z3一些战术使用后枚举常量? [英] How to use enumerated constants after calling of some tactic in Z3?

查看:203
本文介绍了如何调用Z3一些战术使用后枚举常量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我的枚举类型的测试程序的源$ C ​​$ C:

Here are the source code of my testing program of enumerated types:

    Z3_symbol enum_names[3];
    Z3_func_decl enum_consts[3];
    Z3_func_decl enum_testers[3];
    enum_names[0]=Z3_mk_string_symbol(z3_cont,"a");
    enum_names[1]=Z3_mk_string_symbol(z3_cont,"b");
    enum_names[3]=Z3_mk_string_symbol(z3_cont,"c");
    Z3_symbol enum_nm = Z3_mk_string_symbol(z3_cont,"enumT");
    Z3_sort s = Z3_mk_enumeration_sort(z3_cont, enum_nm, 3, enum_names, enum_consts, enum_testers);
    z3::sort ss(z3_cont,s);
    z3::expr a = z3::expr(z3_cont,Z3_mk_app(z3_cont,enum_consts[0],0,0));
    z3::expr b = z3::expr(z3_cont,Z3_mk_app(z3_cont,enum_consts[1],0,0));
    z3::expr x =       z3::expr(z3_cont,Z3_mk_const(z3_cont,Z3_mk_string_symbol(z3_cont,"x"),s));
    z3::expr test = (x==a)&&(x==b);
    cout<<"1:"<<test<<endl;

    printf("%s\n", Z3_func_decl_to_string(z3_cont, enum_consts[0]));
    printf("%s\n", Z3_func_decl_to_string(z3_cont, enum_consts[1]));
    printf("%s\n", Z3_func_decl_to_string(z3_cont, enum_consts[2]));

    z3::tactic qe(z3_cont,"ctx-solver-simplify");
    z3::goal g(z3_cont);
    g.add(test);
    z3::expr res(z3_cont);
    z3::apply_result result_of_elimination = qe.apply(g);
    if ( result_of_elimination.size() == 1){
         z3::goal result_formula = result_of_elimination[0];
         res =  result_formula.operator[](0);
         for (int i = 1; i < result_formula.size(); ++i){
                  res = res && result_formula.operator[](i);
         }
    }
    cout<<"2:"<<res<<endl;

    printf("%s\n", Z3_func_decl_to_string(z3_cont, enum_consts[0]));
    printf("%s\n", Z3_func_decl_to_string(z3_cont, enum_consts[1]));
    printf("%s\n", Z3_func_decl_to_string(z3_cont, enum_consts[2]));

屏幕输出如下:
1:(和(= X A)(= X B))

Screen output is the following: 1:(and (= x a) (= x b))

(声明-乐趣()enumT)

(declare-fun a () enumT)

(声明乐趣B()enumT)

(declare-fun b () enumT)

(声明乐趣X()enumT)在这里,我预计C,为什么X?

(declare-fun x () enumT) Here I have expected "c", Why "x"?

2:假

(声明-乐趣()enumT)

(declare-fun a () enumT)

(声明乐趣BV()(_ BitVec 1))为什么不B?

(声明乐趣X()enumT)

(declare-fun x () enumT)

主要的问题是我应该如何调用一些战术后,在我的程序中使用枚举常量?

The main question is how I should use enumerated constants in my program after calling some tactics?

enum_consts结构被打破,Z3_mk_app(z3_cont,Z3_mk_func_decl(z3_cont,Z3_mk_string_symbol(z3_cont,一个),0,0,S),0,0)不起作用。

enum_consts structures are broken, Z3_mk_app(z3_cont,Z3_mk_func_decl(z3_cont,Z3_mk_string_symbol(z3_cont,"a"),0,0,s),0,0) doesn't work.

推荐答案

由于指向的尼古拉,你有一个错字。更重要的是,你是滥用C / C ++的API。也可以同时使用两种API。然而,使用C API的时候,我们不得不手动增加引用计数器或包装使用C ++ API中提供的C ++包装的Z3_ast值。否则,内存将被破坏。
例如,当我们调用

As pointed by Nikolaj, you have a typo. More importantly, you are misusing the C/C++ APIs. It is possible to use both APIs simultaneously. However, when using the C API, we have to increment the reference counters manually, or wrap the Z3_ast values using the C++ wrappers available in the C++ API. Otherwise, the memory will be corrupted. For example, when we invoke

Z3_sort s = Z3_mk_enumeration_sort(z3_cont, enum_nm, 3, enum_names, enum_consts, enum_testers);

我们必须增加 Z3_func_decl S的引用计数器在 enum_names enum_consts 。否则,这些对象将通过垃圾收集Z3。这发生在你的榜样。这就是为什么你会得到奇怪的结果。如果我们运行的工具,如在你的例子 Valgrind的,它会报告许多内存访问违规行为。

We have to increase the reference counter of the Z3_func_decls in enum_names and enum_consts. Otherwise, these objects will be garbage collected by Z3. This happens in your example. That is why you get strange results. If we run a tool such as Valgrind in your example, it will report many memory access violations.

下面就是你们的榜样的一个固定的版本:

Here is a fixed version of your example:

using namespace z3;
...
context z3_cont;
...

Z3_symbol enum_names[3];
Z3_func_decl enum_consts[3];
Z3_func_decl enum_testers[3];
enum_names[0]=Z3_mk_string_symbol(z3_cont,"a");
enum_names[1]=Z3_mk_string_symbol(z3_cont,"b");
enum_names[2]=Z3_mk_string_symbol(z3_cont,"c");
Z3_symbol enum_nm = Z3_mk_string_symbol(z3_cont,"enumT");
sort s = to_sort(z3_cont, Z3_mk_enumeration_sort(z3_cont, enum_nm, 3, enum_names, enum_consts, enum_testers));
func_decl a_decl = to_func_decl(z3_cont, enum_consts[0]);
func_decl b_decl = to_func_decl(z3_cont, enum_consts[1]);
func_decl c_decl = to_func_decl(z3_cont, enum_consts[2]);
expr a = to_expr(z3_cont, Z3_mk_app(z3_cont, a_decl, 0, 0));
expr b = to_expr(z3_cont, Z3_mk_app(z3_cont, b_decl, 0, 0));
expr x = z3_cont.constant("x", s);
expr test = (x==a) && (x==b);
std::cout << "1: " << test << std::endl;

tactic qe(z3_cont,"ctx-solver-simplify");
goal g(z3_cont);
g.add(test);
expr res(z3_cont);
apply_result result_of_elimination = qe.apply(g);
if ( result_of_elimination.size() == 1){
    goal result_formula = result_of_elimination[0];
    res =  result_formula.operator[](0);
    for (int i = 1; i < result_formula.size(); ++i){
        res = res && result_formula.operator[](i);
    }
}
std::cout << "2: " << res << std::endl;

请注意,我使用 func_decl C ++对象包装在 enum_consts 的值。这些对象基本上是智能指针。他们自动管理引用计数我们。

Note that I'm wrapping the values in enum_consts using func_decl C++ objects. These objects are essentially smart pointers. They automatically manage the reference counters for us.

我还扩大了方法C ++ API简化列举各种创作。
的http://z3.$c$cplex.com/SourceControl/changeset/b2810592e6bb

I also extended the C++ API with a method for simplifying the creation of enumeration sorts. http://z3.codeplex.com/SourceControl/changeset/b2810592e6bb

我还包括展示如何使用这个新的API的例子。
这个扩展将在下一版本(Z3 V4.3.2)可用。
它是不稳定的(工作正在进行中)分支已经上市,也将是明天可在的
每日构建

I also included an example showing how to use this new API. This extension will be available in the next release (Z3 v4.3.2). It is already available in the unstable (working-in-progress) branch, and will be also available tomorrow in the nightly builds.

这篇关于如何调用Z3一些战术使用后枚举常量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆