【发布时间】:2018-05-30 02:44:45
【问题描述】:
我使用 Z3 和 JAVA 绑定已有 2 年了。
出于某种原因,我总是自己将 SMTLib2 代码生成为字符串,然后使用 parseSMTLib2String 构建相应的 Z3 Expr。
据我所知,每次我用这种方法输入完全相同的输入两次,我总是得到相同的模型。
但我最近决定更改并直接使用 JAVA API 并使用 ctx.mk...() 构建表达式。基本上,我不是生成字符串然后解析它,而是让 Z3 完成构建 Z3 Expr 的工作。
现在发生的情况是,当我检查求解器确实存储了完全相同的代码时,我得到了不同的模型。 我的 JAVA 代码如下所示:
static final Context context = new Context();
static final Solver solver = context.mkSolver();
public static void someFunction(){
solver.add(context.mk...()); // Add some bool expr to the solver
Status status = solver.check();
if(status == SATISFIABLE){
System.out.println(solver.getModel()); // Prints different model with same expr
}
}
我在运行时对“someFunction()”进行了不止 1 次调用,并且检查的表达式 context.mk...() 发生了变化。但是,如果我运行我的程序两次,则会检查相同的表达式序列,有时会在一次运行中为我提供不同的模型。
我尝试禁用自动配置参数并设置我自己的随机种子,但 Z3 有时仍会产生不同的模型。我只使用有界整数变量和未解释的函数。 我是否以错误的方式使用 API?
如果需要,我可以将整个 SMTLib2 代码添加到这个问题中,但它并不是很短并且包含多个求解器调用(我什至不知道它们中的哪一个会从一个执行到另一个执行产生不同的模型,我只是知道有些人这样做)。
我必须明确指出,我已阅读以下主题,但发现答案要么过时,要么(如果我理解正确的话)支持“Z3 是确定性的,应该为相同的输入生成相同的模型”:
different run time for the same code in Z3
编辑: 令人惊讶的是,使用以下代码,我似乎总是得到相同的模型,而 Z3 现在似乎是确定性的。但是,与我之前的代码相比,内存消耗是巨大的,因为我需要将上下文保留在内存中一段时间。知道我可以做些什么来以更少的内存使用实现相同的行为吗?
public static void someFunction(){
Context context = new Context();
Solver solver = context.mkSolver();
solver.add(context.mk...()); // Add some bool expr to the solver
Status status = solver.check();
if(status == SATISFIABLE){
System.out.println(solver.getModel()); // Seem to always print the same model :-)
}
}
【问题讨论】:
标签: java model z3 non-deterministic