我使用Z3 C ++ api找到一个令人满意的公式,该公式对于某些布尔变量(我们称之为b0,...,bn)为真。
我有一个包含布尔变量b0,...,bn的公式,我想找到一些令人满意的公式,其中b0,...,bn的数量设置为真。
我这样做是通过最初找到b0,...,bn的一个子集,可以将其分配为true并满足我的公式,并且我逐步要求求解器找到更小的子集(即,其中一个布尔变量被翻转为假。)
当我找不到更小的子集时,我找到了我的局部最小值,即我从Z3得到了不满的结果。此时,我想访问最后一个有效的模型。
这可能吗?当“检查”的调用不满意时,Z3是否会修改模型? 如果是这样,我怎么能用C ++ api做到这一点?
非常感谢,
答案 0 :(得分:0)
如果求解器返回“sat”,则可以检索模型。模型引用求解器的状态,因此如果添加断言,状态更改和模型将不再有效,直到您检查可满足性并返回sat。 因此,每次求解器返回SAT时都可以检索模型,然后排出除最后一个模型之外的所有模型。
答案 1 :(得分:0)
正如Nikolaj所提到的,您需要在每次通话结束后跟踪模型sat
,如果您按照您概述的策略获得unsat
,则需要返回最后一个模型。
但是,可能还有另一种方法可以避免重复呼叫。您可以将问题视为优化问题而不是满意问题。您提到您拥有控制变量b0
,b1
,... bn
,因此您希望将其设置为true
的数量最小化,以获得令人满意的模型。创建一个指标,计算这些变量中的数量。类似的东西:
metric = (if b0 then 1 else 0)
+ (if b1 then 1 else 0)
+ ...
+ (if bn then 1 else 0)
然后使用Z3的优化例程来最小化metric
。我相信这只会在一个电话中为您提供所需的解决方案。
一些有用的参考资料:
这个例子特别讨论了软约束,也可能适用于你的情况:http://rise4fun.com/z3opt/tutorialcontent/guide#h25。
以下是优化程序的C ++ API参考:http://z3prover.github.io/api/html/classz3_1_1optimize.html。