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_ast
和 Z3_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);
我正在尝试对包含数组和整数的表达式使用替换。替换后出现分段错误。
代码如下:
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_ast
和 Z3_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);