我有几个SMTLIB2示例,z3通常在10毫秒内发现不满,但是,当我添加请求生成不满核心时,check-sat会持续几分钟而不返回。这种行为是期待的吗?请求不良核心不只是打开仪器记录依赖关系,并更改z3运行的程序和选项吗?有可能设置更多的选项,所以当我使用不完整的核心生成时,我会看到相同的行为,因为我在不使用它时会看到它吗?
我在Scientific Linux 6.3上使用Z3 4.3.1(稳定分支)。
示例在AUFNIRA中,但有几个不涉及实际,可能不是非线性的。
谢谢,
保罗。
答案 0 :(得分:4)
使用“答案文字”(又称假设)跟踪不满核心。 当我们启用不饱和核心提取并使用诸如
之类的断言时(assert (! (= x 10) :named a1))
Z3将在内部为名称a1
创建一个新的布尔变量,并断言
(assert (=> a1 (= x 10)))
当调用check-sat
时,它假定所有这些辅助变量都为真。也就是说,Z3试图表明这些假设是不满足的。对于可满足的实例,它将像通常一样使用模型终止。对于不可满足的实例,只要它生成仅包含这些假设的布尔变量的引理,它就会终止。引理的格式为(or (not a_i1) ... (not a_in))
,其中a_i
是假定的布尔变量的子集。
据我所知,这项技术已经由MiniSAT求解器引入。它被描述为here(第3节)。我非常喜欢它,因为它实现起来很简单,而且我们基本上可以免费获得核心代。
然而,这种方法有一些缺点。首先,一些预处理步骤不再适用。如果我们断言
(assert (= x 10))
Z3将x
替换为10
。我们说Z3正在进行“价值传播”。如果断言的格式为
(assert (=> a1 (= x 10)))
这只是一个例子,许多其他预处理步骤都会受到影响。 在求解期间,一些简化步骤也被禁用。 如果我们检查Z3源文件smt_context.cpp,我们将找到如下代码:
void context::simplify_clauses() {
// Remark: when assumptions are used m_scope_lvl >= m_search_lvl > m_base_lvl. Therefore, no simplification is performed.
if (m_scope_lvl > m_base_lvl)
return;
...
}
当使用“回答文字”/假设时,条件m_scope_lvl > m_base_lvl)
始终为真。
因此,当我们启用不良核心生成时,我们可能会真正影响性能。似乎没有什么是真正免费的:)