C++ 控制Z3中的随机性

C++ 控制Z3中的随机性,c++,random,z3,C++,Random,Z3,类似于(但有点相反),如果可能的话,我确实想暴露随机性。 也就是说,我希望两个连续的查询提供不同的结果。 可能吗?这是我的密码: void oren_example() { int i; // context + solver context ctx; solver solver(ctx); // sorts sort int_sort = ctx.int_sort(); sort seq_int_sort = ctx.seq_

类似于(但有点相反),如果可能的话,我确实想暴露随机性。 也就是说,我希望两个连续的查询提供不同的结果。 可能吗?这是我的密码:

void oren_example()
{
    int i;

    // context + solver
    context ctx;
    solver solver(ctx);

    // sorts
    sort int_sort     = ctx.int_sort();
    sort seq_int_sort = ctx.seq_sort(int_sort);
    sort bool_sort    = ctx.bool_sort();

    // constants
    expr two   = ctx.int_val(2);
    expr five  = ctx.int_val(5);
    expr four  = ctx.int_val(4);
    expr three = ctx.int_val(3);

    // define State sort
    const char *names[4]={"x","A","b","n"};
    sort sorts[4]={int_sort,seq_int_sort,bool_sort,int_sort};
    func_decl_vector projs(ctx);
    sort state_sort = ctx.tuple_sort("State",4,names,sorts,projs).range();

    // define an arbitrary state sigma
    expr sigma = ctx.constant("sigma",state_sort);

    // define some predicate on the state
    func_decl init = function("init",state_sort,bool_sort);
    solver.add(forall(sigma,
        init(sigma) == (
            ((projs[0](sigma))          == two  ) &&
            ((projs[1](sigma).length()) == three) &&
            ((projs[1](sigma).nth(two)) == five ) &&
            ((projs[3](sigma))          == five ))));

    for (int k=0;k<2;k++)
    {
        // create a snapshot
        solver.push();

        // find an initial state
        solver.add(init(sigma));

        // check sat + get model
        if (solver.check() == sat)
        {
            model m = solver.get_model();
            std::cout << "x = " << m.eval(projs[0](sigma)) << "\n";
            std::cout << "A = " << m.eval(projs[1](sigma)) << "\n";
            std::cout << "b = " << m.eval(projs[2](sigma)) << "\n";
            std::cout << "n = " << m.eval(projs[3](sigma)) << "\n";

            int size = m.eval(projs[1](sigma).length()).get_numeral_int();
            std::vector<int> A;
            for (i=0;i<size;i++)
            {
                A.push_back(
                    m.eval(
                        projs[1](sigma).nth(
                            ctx.int_val(i))).get_numeral_int());
            }
            std::cout << "A = { ";
            for (i=0;i<size;i++)
            {
                std::cout << A[i] << " ";
            }
            std::cout << "}\n";
        }

        // restore snapshot
        solver.pop();
    }
}

现在发布到

这通常是通过添加约束来禁止以前的模型。请注意,除非添加新约束,否则将无法获得新的解决方案

如果您只是想在从头开始求解后依赖随机性,请尝试设置z3使用的随机种子。其中有几个:

$ z3 -pd | grep seed
    random_seed (unsigned int) random seed (default: 0)
    seed (unsigned int) random seed. (default: 0)
    spacer.random_seed (unsigned int) Random seed to be used by SMT solver (default: 0)
    random_seed (unsigned int) random seed for the smt solver (default: 0)
    random_seed (unsigned int) random seed (default: 0)
改变这些是否会给你一个明显不同的(或根本不同的)模型将取决于你的初始约束集以及哪个理论解算器起作用

从C++ API中设置这些,使用<代码> StIsPARAM< /COD>函数。以下是您设置它们的方式:

set_param("sat.random_seed", 50);
set_param("smt.random_seed", 50);

如果运行
z3-pd
,它将列出每个模块可以提供的所有设置。您可以将其转储到一个文件(
z3-pd>settings
),然后查看创建的
settings
文件,查找包含
seed
的名称,以查找存在哪些名称。请注意,您必须在实际名称前面加上它们所在的模块,如上例中的
sat
smt
。您还可以在
z3-pd
输出中找到模块名称。

我应该设置一些标志吗?我用
z3--help
查找标志。。。我不熟悉
z3-pd
。。这是什么?我添加了一个关于如何使用C/C++api实现这一点的示例。我尝试过,但正如您所怀疑的,我得到了相同的结果。。。还有别的把戏吗?我可以保留已发现状态的历史记录,并使下一个状态与所有状态不同,但这似乎非常低效……添加模型的否定是提取多个模型的常用方法。Z3不支持任何适当的随机性,即不保证解决方案的分布,即使在更改随机种子后,您也会经常得到相同的解决方案(例如,如果预处理器解决了问题,它永远不需要(伪)随机数)。
set_param("sat.random_seed", 50);
set_param("smt.random_seed", 50);