Z3 c++ api 替换数组

Z3 c++ api substitution array

我正在尝试对包含数组和整数的表达式使用替换。替换后出现分段错误。

代码如下:

    context cxt;
    vector<Z3_ast> vars_ast,primed_vars_ast;

    sort Int = cxt.int_sort();
    sort Array = cxt.array_sort(Int,Int);

    expr arr =cxt.constant("arr",Array); 
    vars_ast.push_back(arr); 


    expr i =cxt.int_const("i"); 
    vars_ast.push_back(i); 


    expr test_expr = select(arr,i)==0 ;

    primed_vars_ast.push_back(cxt.constant("arr_primed",Array));
    primed_vars_ast.push_back(cxt.int_const("i_primed"));

    expr cstr_expr (cxt,
                 ast(cxt,
                  Z3_substitute(cxt,
                        ast(test_expr),
                        vars_ast.size(),
                        vars_ast.data(),
                        primed_vars_ast.data())));

但是,如果我从 ast 数组中删除变量 i,而是在表达式 test_expr = select(arr,1)==0 上测试替换,它会成功。 我错过了什么吗?

这里的问题是您混合了 C 和 C++ 代码(z3.h 和 z3++.h)。 Z3 C-API 不会为你做引用计数,所以你每次创建 Z3_astZ3_dec_ref 时都必须调用 Z3_inc_ref 每次 Z3_ast 走出 scope/use。

C++ API (z3++.h) 的主要目的是将引用计数代码抽象出来,但这仅在您不混入 C 代码时有效。经验法则是:如果一个函数被调用 'Z3_*' 那么它就是一个 C 函数,如果它是 returns 一个 Z3_ast,立即将它放入一个 expr,例如这个:

expr q(cxt, Z3_mk_select(cxt, arr, i));

在此特定示例中,我们可以将 vector<Z3_ast> 更改为 expr_vector(z3++.h 附带)。然后示例可以修改为

context cxt;
expr_vector vars_ast(cxt), primed_vars_ast(cxt);

sort Int = cxt.int_sort();
sort Array = cxt.array_sort(Int,Int);

expr arr = cxt.constant("arr",Array); 
vars_ast.push_back(arr);

expr i = cxt.int_const("i"); 
vars_ast.push_back(i); 

expr test_expr = select(arr,i)==0;

primed_vars_ast.push_back(cxt.constant("arr_primed",Array));
primed_vars_ast.push_back(cxt.int_const("i_primed"));

test_expr.substitute(vars_ast, primed_vars_ast);