我可以通过z3 c ++接口将SMT2文件读入解算器吗?

时间:2017-01-27 01:43:25

标签: c++ z3

我遇到了一个问题,即嵌入在较大系统中的z3代码没有找到某些约束(通过C ++接口添加)的解决方案,尽管有一些相当长的超时。当我将约束转储到文件时(在求解器上使用to_smt2()方法,就在调用check()之前),并通过独立的z3可执行文件运行该文件,它在大约4秒内解决了系统(返回sat )。对于它的价值,该文件长476,587行,因此有一个相当大的约束条件。

有没有办法可以使用C ++接口将该文件读回嵌入式求解器,替换现有的约束,看看嵌入式版本是否可以从与独立求解器完全相同的起点开始解决? (基本上,我如何在求解器类上创建相应的from_smt2(stream)方法?)

当然,它们应该是与现在相同的一组约束,但是当从文件中读取它们时可能会有一些排序效应,或者在嵌入它时引入的求解器中可能存在一些微妙的差异,或者没有用to_smt2()写出来的东西。所以,如果可以的话,我想尝试回读文件,以缩小差异的可能来源。调试长时间运行版本时要查找的内容的建议也会有所帮助。

进一步说明:看起来其他用户遇到类似问题here。与该用户不同,我的问题使用所有位向量,唯一未知的结果是来自嵌入代码的结果。有没有办法从C ++接口调用(get-info:reason-unknown),如那里所示,找出嵌入式版本出现问题的原因?

1 个答案:

答案 0 :(得分:2)

您可以使用方法" solver :: reason_unknown()"检索搜索失败的解释。 有一些方法可以将文件和字符串解析为单个表达式。 在一组断言的情况下,表达式是一个连词。 为方便起见,将这样的方法直接添加到求解器类中也许是一个好主意。它将是:

    void from_smt2_string(char const* smt2benchmark) {
        expr fml = ctx().parse_string(smt2benchmark);
        add(fml);
    }

因此,如果您要在求解器类之外编写它,则需要:

      expr fml = solver.ctx().parse_string(smt2benchmark);
      solver.add(fml);