简体   繁体   中英

Z3 c++ api substitution array

I'm trying to use substitution on an expression containing an array and an integer. I get segmentation fault after substitution.

Here is the code:

    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())));

However, if I remove the variable i from the ast arrays, and instead test substitution on the expression test_expr = select(arr,1)==0 , it succeeds. Am I missing something?

The problem here is that you are mixing C and C++ code (z3.h and z3++.h). The Z3 C-API will not do the reference counting for you, so you have to call Z3_inc_ref everytime you create a Z3_ast and Z3_dec_ref every time a Z3_ast goes out of scope/use.

The main purpose of the C++ API (z3++.h) is to abstract the reference counting code away, but that only works for as long as you don't mix in C code. The rule of thumb is: if a function is called 'Z3_*' then it's a C function and if it returns a Z3_ast , put it into an expr immediately, for instance like this:

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

In this particular example, we can change the vector<Z3_ast> to an expr_vector (comes with z3++.h). The example can then be modified to

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM