从z3模型中仅提取一个值

时间:2018-02-21 14:42:55

标签: string z3

我正在寻找相当于 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));

1 个答案:

答案 0 :(得分:2)

最简单的方法是使用Z3_model_eval来评估您在模型下选择的任何表达式,然后打印该表达式。