Scala ^ Z3:删除先前的断言

时间:2012-08-23 07:32:42

标签: scala z3

我想使用Scala ^ Z3进行增量求解。在每次迭代中,我想

a)添加公式的一部分

b)添加断言

应该为每个后续迭代保留公式,但是如果我无法实现它,我将需要删除断言,因为下一次迭代中的断言将是不同的。

那么有没有办法删除以前的陈述? Z3Context.pop()听起来有点像我需要的,但我找不到它的作用的描述..

非常感谢那里的一些帮助!

祝福, 1428162

2 个答案:

答案 0 :(得分:3)

是的,你是对的,你想要pop(删除)最后一个断言。为此,首先需要使用push保存当前的断言集。这就是Z3支持范围的方式。

通过添加公式的某些部分,我将假设您的意思是定义一个变量,其中包含一些原始大型公式的额外块,您正在进行增量检查。我还假设原始公式是子公式的大型组合。这个新公式将在推送和弹出之间保持定义(假设您保留一个引用它的变量)。

以下是z3py中大致以下伪代码示例的链接,除了在z3py脚本中我还假设公式和约束实际上是相同的东西,但也许你想要创建一些不同的约束基于子公式的那一部分:http://rise4fun.com/Z3Py/LIxW

我没有使用过Scala ^ Z3,但大致你想要做以下事情:

formula // list containing parts (sub-formulas) of original large formula
while (formulaPart = formula.removeFirst()) // remove first element of list
    Z3Context.push() // save current set of assertions

    assertion = makeConstraint( formulaPart ) // assertion based on sub-formula

    Z3Context.assertCnstr( assertion ) // add new assertion

    if !Z3Context.check() // check if assertions cannot be satisfied
        Z3Context.pop() // remove most recent assertion

以下是使用.NET API中的pop / push的示例:http://research.microsoft.com/en-us/um/redmond/projects/z3/test__managed_8cs_source.html#l00637

您也对此感兴趣:Soft/Hard constraints in Z3

答案 1 :(得分:2)

是的,ctx.pop()就是你想要的。它也可以采用参数,如ctx.pop(2),但如果省略则默认为1。直观地说,将求解器的状态恢复到“n推送前”的位置。

所以,如果你这样做:

ctx.assertCnstr(formula1)
ctx.push()

ctx.assertCnstr(extraAssertion)
ctx.check() match {
  case Some(true)  => ... // SAT
  case Some(false) => ... // UNSAT
  case None        => ... // UNKNOWN
}

ctx.pop(1)

...解决方案的状态将恢复为调用push()之前的状态。

请注意,它们的行为与Z3 C API中的等效行为完全相同,因此其中的文档也适用。

请注意,从Z3 4.0开始,不推荐在上下文中调用pushpop。现在推荐的方法是让上下文首先创建一个求解器,然后直接在求解器上使用pushpop(在Z3 4.0之前没有求解器的概念)。 Scala ^ Z3还没有赶上,但你可以预期这种变化最终会被传播。