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接口更容易地使用它。