【问题标题】:Randomness in Z3 ResultsZ3 结果的随机性
【发布时间】:2013-03-31 15:44:45
【问题描述】:

我正在使用 Z3 Python 接口作为我正在编写的研究工具的一部分,当我在同一个查询上重复运行 Z3 求解器时,我注意到一些非常奇怪的行为:特别是,我似乎没有得到相同的结果每次结果,即使我在运行之前明确地重置了求解器。作为参考,这是我的代码:

import z3

with open("query.smt", "r") as smt_reader:
    query_lines = "".join(smt_reader.readlines())
    for i in xrange(3):
        solver = z3.Solver()
        solver.reset()

        queryExpr = z3.parse_smt2_string(query_lines)
        equivalences = queryExpr.children()[:-1]
        for equivalence in equivalences:
            solver.add(equivalence)

        # Obtain the Boolean variables associated with the constraints.
        constraintVars = [equivalence.children()[0] for equivalence
                          in equivalences]
        # Check the satisfiability of the query.
        querySatResult = solver.check(*constraintVars)

        print solver.model().sexpr()
        print solver.statistics()
        print ""

上面的代码三次重新创建 Z3 求解器并检查同一查询的可满足性。查询是located here

虽然上面的代码部分并不是我将如何使用 Z3 Python 接口,但问题源于一个认识,即 Z3 求解器在同一查询的代码的不同点被调用两次时,返回不同的结果.我想知道这是否是故意的,是否有任何方法可以禁用它或确保确定性。

【问题讨论】:

    标签: python z3


    【解决方案1】:

    我假设您所说的不同是指不同的模型。 如果结果从 sat 变为 unsat,那么它就是一个 bug。

    话虽如此,如果我们在同一个执行路径中两次解决同一个问题,那么 Z3 可以产生不同的模型。 Z3 将内部唯一 ID 分配给表达式。内部 ID 用于打破 Z3 使用的一些启发式方法中的联系。请注意,程序中的循环正在创建/删除表达式。因此,在每次迭代中,表示约束的表达式可能具有不同的内部 ID,因此求解器可能会产生不同的解决方案。

    请参阅以下相关问题:

    【讨论】:

    • 哦,嗯,好吧,这是有道理的。有没有办法解决这个问题?我应该以不同的方式使用 Z3 Python 界面吗?
    • 是的,实际上我所说的“不同”是指不同的模型。很抱歉有歧义。
    • 乔恩,我没有看到任何解决方法。我意识到这是一个问题。我一直在尝试修改代码以使用文件src/ast/ast_lt.cpp 中定义的表达式的总顺序来打破关系。然而,这也不是一个完美的解决方案,因为当我们简单地重命名一个变量时,我们会开始得到一个不同的解决方案。如果您有想法/建议,请随时在z3.codeplex.com/discussions 发起讨论
    • 啊,好吧。 :( 好吧,我认为我的工具现在的解决方法是记住已经运行的查询。希望这应该可以在 Z3 团队能够解决该问题之前工作。感谢您的回复!:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多