Z3 软约束可以通过命名表达式实现吗?
我想知道是否可以使用命名表达式来实现软约束,而不显式地使用手动“跟踪”变量Z3 软约束可以通过命名表达式实现吗?,z3,Z3,我想知道是否可以使用命名表达式来实现软约束,而不显式地使用手动“跟踪”变量 在消息中,莱昂纳多解释了如何使用辅助布尔以手动方式实现软约束 在以下信息中: 莱昂纳多说,命名表达式本质上被视为模型查找的含义 如上面第一条消息所述,使用手动跟踪相当麻烦,因为它需要对解算器进行多次调用(事实上,在最坏的情况下可能需要调用2^n,以便在我们有n软约束时获得尽可能多的软约束满足)。 有没有可能将这两种思想结合起来,让Z3以更简单的方式实现软约束?基于这两条消息中的想法,我天真地尝试了以下方法: (set
- 在消息中,莱昂纳多解释了如何使用辅助布尔以手动方式实现软约束
- 在以下信息中: 莱昂纳多说,命名表达式本质上被视为模型查找的含义
2^n
,以便在我们有n
软约束时获得尽可能多的软约束满足)。
有没有可能将这两种思想结合起来,让Z3以更简单的方式实现软约束?基于这两条消息中的想法,我天真地尝试了以下方法:
(set-option :produce-models true)
(set-option :produce-unsat-cores true)
(assert (! false :named absurd))
(check-sat)
我希望z3会告诉我sat
,因为在一个模型中将荒谬的假设为错误的可以满足这个人为的例子;但它却产生了unsat
;这是合理的,但没有那么有用
如果您能提供任何见解,我将不胜感激;或者让我看一些关于z3如何更详细地使用命名表达式的文档。(我浏览了一下手册,但没有看到任何地方对其进行详细解释。)命名的表达式是SMT-LIB 2.0标准的一部分。
在Z3中,它们只是使用辅助布尔常量的方法的“语法糖”
在SMT-LIB 2.0标准中,命名表达式用于“跟踪”命令的断言,例如(get unsat core)
(请参阅本标准第5.1.5节)。在您的示例中,如果我们在(检查sat)
之后执行(获取unsat核心)
,我们将获得(荒谬)
。是联机示例的链接
关于软/硬约束,似乎您需要MaxSAT。Z3附带了一个示例,该示例使用两种不同的算法,使用C API和辅助布尔常量实现MaxSAT。最简单的方法就是使用以下基本思想
- 对于每个软约束
C_i
,它断言b_i意味着C_i
,其中b_i
是一个新的布尔变量
b_i
为false的赋值实际上忽略了约束C_i
- 使用形式为
AtMostK
的约束强制执行至多K
b_i
为false。
然后,我们可以使用线性搜索来找到可以满足的最大数量的软约束。我们还可以使用二进制搜索(在这种情况下,只需要调用logn
,其中N
是软约束的数量)。许多伪布尔解算器都使用了这种方法的变体
examples\maxsat
上的示例也包含了Fu和Malik建议的更智能的算法。该示例还显示了如何编码约束AtMostK
,谢谢Leonardo。。MaxSAT似乎正是我所需要的。我只是希望它能内置到Z3中,这样只需一次调用就可以通过SMT Lib接口更容易地使用它。