我正在寻找相当于 get-value 的z3源API。例如,当我有以下查询时,我可以轻松指定要查看的值:
(declare-const s1 String)
(declare-const s2 String)
(assert (= 8 (str.len s1 )))
(assert (= 3 (str.indexof s1 "M" 0)))
(assert (= 3 (str.len s2 )))
(assert (= -1 (str.indexof s2 "\x00" 0)))
(check-sat)
;(get-value (s1))
(get-value (s1 s2))
我设法用(C)源API做同样的事情, 但后来我只得到整个模型(s1 和 s2)并且看起来不太可能 找到如何打印只是其中一个:
void string_example()
{
Z3_ast M;
Z3_ast s1;
Z3_ast s2;
Z3_ast x00;
Z3_ast zero;
Z3_ast three;
Z3_ast eight;
Z3_ast cond1;
Z3_ast cond2;
Z3_ast cond3;
Z3_ast cond4;
Z3_ast minusOne;
Z3_ast strlen_s1;
Z3_ast strlen_s2;
Z3_ast strchr_s1_M;
Z3_ast strchr_s2_x00;
/***************/
/* [0] Context */
/***************/
Z3_context ctx = mk_context();
/**************/
/* [1] Solver */
/**************/
Z3_solver solver = mk_solver(ctx);
/*************/
/* [2] Sorts */
/*************/
Z3_sort int_sort =Z3_mk_int_sort(ctx);
Z3_sort string_sort=Z3_mk_string_sort(ctx);
/*********************************/
/* [3] (declare-const zero Int) */
/* (declare-const eight Int) */
/*********************************/
zero =Z3_mk_int(ctx, 0,int_sort);
three =Z3_mk_int(ctx, 3,int_sort);
eight =Z3_mk_int(ctx, 8,int_sort);
minusOne=Z3_mk_int(ctx,-1,int_sort);
/*********************************/
/* [4] (declare-const s1 String) */
/* (declare-const s2 String) */
/*********************************/
s1 = Z3_mk_const(ctx,Z3_mk_string_symbol(ctx,"s1"),string_sort);
s2 = Z3_mk_const(ctx,Z3_mk_string_symbol(ctx,"s2"),string_sort);
/**********************************************/
/* [5] (assert (= (str.len someStringVar) 8)) */
/**********************************************/
strlen_s1 = Z3_mk_seq_length(ctx,s1);
cond1 = Z3_mk_eq(ctx,strlen_s1,eight);
Z3_solver_assert(ctx,solver,cond1);
/*********************************************/
/* [6] (assert (= (str.indexof s1 "M" 0) 3)) */
/*********************************************/
M = Z3_mk_string(ctx,"M");
strchr_s1_M = Z3_mk_seq_index(ctx,s1,M,zero);
cond2 = Z3_mk_eq(ctx,strchr_s1_M,three);
Z3_solver_assert(ctx,solver,cond2);
/***********************************/
/* [7] (assert (= (str.len s2) 3)) */
/***********************************/
strlen_s2 = Z3_mk_seq_length(ctx,s2);
cond3 = Z3_mk_eq(ctx,strlen_s2,three);
Z3_solver_assert(ctx,solver,cond3);
/*************************************************/
/* [8] (assert (= (str.indexof s2 "\x00" 0) -1)) */
/*************************************************/
x00 = Z3_mk_string(ctx,"\\x00");
strchr_s2_x00 = Z3_mk_seq_index(ctx,s2,x00,zero);
cond4 = Z3_mk_eq(ctx,strchr_s2_x00,minusOne);
Z3_solver_assert(ctx,solver,cond4);
/*******************/
/* [9] (check-sat) */
/*******************/
if (Z3_solver_check(ctx,solver))
{
printf("\nHere are my two strings:\n");
printf("======================= \n\n");
printf("%s\n",Z3_model_to_string(ctx,Z3_solver_get_model(ctx, solver)));
}
/**********************************/
/* [10] delete solver and context */
/**********************************/
del_solver(ctx, solver);
Z3_del_context(ctx);
}
这是输出:
Here are my two strings:
=======================
s2 -> "\x01\x10\x01"
s1 -> "\x00\x00\x00M\x00\x00\x00\x00"
编辑:
当我们添加以下代码时,我们只能提取s1:
printf("\nHere is just s1:\n");
printf("================= \n\n");
Z3_model_eval(ctx,Z3_solver_get_model(ctx, solver),s1,1,&out);
printf("%s\n",Z3_get_string(ctx,out));
当我们添加以下代码时,我们只能按名称提取s1:
printf("\nHere is just s1:\n");
printf("================= \n\n");
Z3_model_eval(ctx,Z3_solver_get_model(ctx, solver),Z3_mk_const(ctx,Z3_mk_string_symbol(ctx,"s1"),Z3_mk_string_sort(ctx)),1,&out);
printf("%s\n",Z3_get_string(ctx,out));