我可以通过 z3 c++ 接口将 SMT2 文件读入求解器吗?
Can I read a SMT2 file into a solver through the z3 c++ interface?
我遇到了一个问题,即嵌入在较大系统中的 z3 代码尽管有相当长的超时,但仍未找到针对特定约束集(通过 C++ 接口添加)的解决方案。当我将约束转储到一个文件时(在调用 check() 之前使用解算器上的 to_smt2() 方法),并通过独立的 z3 可执行文件 运行 文件,它解决了系统在大约 4 秒内(返回星期六)。对于它的价值,该文件有 476,587 行长,因此有相当大的一组限制。
有没有一种方法可以使用 C++ 接口将该文件读回嵌入式求解器,替换现有约束,看看嵌入式版本是否可以从与独立求解器完全相同的起点开始求解? (本质上,我如何在求解器 class 上创建相应的 from_smt2(stream) 方法?)
当然,它们应该是与现在相同的一组约束,但是从文件中读取它们时可能会产生一些排序效果,或者我们嵌入它时引入的求解器可能存在一些细微差别,或者没有用 to_smt2() 写出来的东西。因此,如果可以的话,我想尝试回读文件,以缩小可能的差异来源。关于在调试 long-运行ning 版本时要寻找什么的建议也会有所帮助。
进一步注意:其他用户似乎遇到了类似的问题 here。与那个用户不同,我的问题使用所有位向量,唯一未知的结果是来自嵌入式代码的结果。有没有办法按照那里的建议从 C++ 接口调用 (get-info :reason-unknown) 来找出嵌入式版本出现问题的原因?
您可以使用方法"solver::reason_unknown()"来检索搜索失败的解释。
有一些方法可以将文件和字符串解析为单个表达式。
在一组断言的情况下,表达式是一个连词。
为了方便起见,将这样的方法直接添加到求解器 class 中也许是个好主意。它将是:
void from_smt2_string(char const* smt2benchmark) {
expr fml = ctx().parse_string(smt2benchmark);
add(fml);
}
因此,如果您要在求解器之外编写它 class,您需要:
expr fml = solver.ctx().parse_string(smt2benchmark);
solver.add(fml);
我遇到了一个问题,即嵌入在较大系统中的 z3 代码尽管有相当长的超时,但仍未找到针对特定约束集(通过 C++ 接口添加)的解决方案。当我将约束转储到一个文件时(在调用 check() 之前使用解算器上的 to_smt2() 方法),并通过独立的 z3 可执行文件 运行 文件,它解决了系统在大约 4 秒内(返回星期六)。对于它的价值,该文件有 476,587 行长,因此有相当大的一组限制。
有没有一种方法可以使用 C++ 接口将该文件读回嵌入式求解器,替换现有约束,看看嵌入式版本是否可以从与独立求解器完全相同的起点开始求解? (本质上,我如何在求解器 class 上创建相应的 from_smt2(stream) 方法?)
当然,它们应该是与现在相同的一组约束,但是从文件中读取它们时可能会产生一些排序效果,或者我们嵌入它时引入的求解器可能存在一些细微差别,或者没有用 to_smt2() 写出来的东西。因此,如果可以的话,我想尝试回读文件,以缩小可能的差异来源。关于在调试 long-运行ning 版本时要寻找什么的建议也会有所帮助。
进一步注意:其他用户似乎遇到了类似的问题 here。与那个用户不同,我的问题使用所有位向量,唯一未知的结果是来自嵌入式代码的结果。有没有办法按照那里的建议从 C++ 接口调用 (get-info :reason-unknown) 来找出嵌入式版本出现问题的原因?
您可以使用方法"solver::reason_unknown()"来检索搜索失败的解释。 有一些方法可以将文件和字符串解析为单个表达式。 在一组断言的情况下,表达式是一个连词。 为了方便起见,将这样的方法直接添加到求解器 class 中也许是个好主意。它将是:
void from_smt2_string(char const* smt2benchmark) {
expr fml = ctx().parse_string(smt2benchmark);
add(fml);
}
因此,如果您要在求解器之外编写它 class,您需要:
expr fml = solver.ctx().parse_string(smt2benchmark);
solver.add(fml);