Z3获得最后一个有效的模型

时间:2017-03-14 16:24:13

标签: z3

我使用Z3 C ++ api找到一个令人满意的公式,该公式对于某些布尔变量(我们称之为b0,...,bn)为真。

我有一个包含布尔变量b0,...,bn的公式,我想找到一些令人满意的公式,其中b0,...,bn的数量设置为真。

我这样做是通过最初找到b0,...,bn的一个子集,可以将其分配为true并满足我的公式,并且我逐步要求求解器找到更小的子集(即,其中一个布尔变量被翻转为假。)

当我找不到更小的子集时,我找到了我的局部最小值,即我从Z3得到了不满的结果。此时,我想访问最后一个有效的模型。

这可能吗?当“检查”的调用不满意时,Z3是否会修改模型? 如果是这样,我怎么能用C ++ api做到这一点?

非常感谢,

2 个答案:

答案 0 :(得分:0)

如果求解器返回“sat”,则可以检索模型。模型引用求解器的状态,因此如果添加断言,状态更改和模型将不再有效,直到您检查可满足性并返回sat。 因此,每次求解器返回SAT时都可以检索模型,然后排出除最后一个模型之外的所有模型。

答案 1 :(得分:0)

正如Nikolaj所提到的,您需要在每次通话结束后跟踪模型sat,如果您按照您概述的策略获得unsat,则需要返回最后一个模型。

但是,可能还有另一种方法可以避免重复呼叫。您可以将问题视为优化问题而不是满意问题。您提到您拥有控制变量b0b1,... bn,因此您希望将其设置为true的数量最小化,以获得令人满意的模型。创建一个指标,计算这些变量中的数量。类似的东西:

metric = (if b0 then 1 else 0)
       + (if b1 then 1 else 0)
       + ...
       + (if bn then 1 else 0)

然后使用Z3的优化例程来最小化metric。我相信这只会在一个电话中为您提供所需的解决方案。

一些有用的参考资料: