【问题标题】:Too many possible configurations in z3 using scala^z3z3 中使用 scala^z3 的可能配置太多
【发布时间】:2012-01-16 20:06:18
【问题描述】:

这主要是我猜的逻辑问题……

我使用这个 smtlib 公式:

(declare-fun a () Bool)
(declare-fun b () Bool)
(declare-fun c () Bool)
(declare-fun d () Bool)
(assert (xor (and a (xor b c)) d))

这是这个结构的一个术语(至少在我看来):

    XOR
    | |
  AND d
  | |
  a XOR
    | |
    b c

我的猜测:结果集应该是这样的:

{ab, ac, d}

但它使用 scala^z3 ctx.checkAndGetAllModels():

{ab, d, ac, ad, abcd}

为什么里面有ad和abcd? 是否有可能只得到我期望的结果?

【问题讨论】:

    标签: scala logic z3 smt


    【解决方案1】:

    使用 Scala(不带 Z3)来证明实际上还有更多的约束解决方案:

    val tf = Seq(true, false)
    val allValid =
      for(a <- tf; b <- tf; c <- tf; d <- tf; 
          if((a && (b ^ c)) ^ d)) yield (
        (if(a) "a" else "") + (if(b) "b" else "") +
        (if(c) "c" else "") + (if(d) "d" else ""))
    
    allValid.mkString("{ ", ", ", " }")
    

    打印:

    { abcd, ab, ac, ad, bcd, bd, cd, d }
    

    所以除非我遗漏了什么,否则问题是,为什么它没有找到所有解决方案?现在这是那个问题的答案。 (剧透警告:“getAllModels”并没有真正获取所有模型。)首先,让我们重现您观察到的内容:

    import z3.scala._
    val ctx = new Z3Context("MODEL" -> true)
    val a = ctx.mkFreshConst("a", ctx.mkBoolSort)
    val b = ctx.mkFreshConst("b", ctx.mkBoolSort)
    val c = ctx.mkFreshConst("c", ctx.mkBoolSort)
    val d = ctx.mkFreshConst("d", ctx.mkBoolSort)
    val cstr0 = ctx.mkXor(b, c)
    val cstr1 = ctx.mkAnd(a, cstr0)
    val cstr2 = ctx.mkXor(cstr1, d)
    ctx.assertCnstr(cstr2)
    

    现在,如果我运行:ctx.checkAndGetAllModels.foreach(println(_)),我会得到:

    d!3 -> false
    a!0 -> true
    c!2 -> false
    b!1 -> true
    
    d!3 -> true    // this model is problematic
    a!0 -> false
    
    d!3 -> false
    a!0 -> true
    c!2 -> true
    b!1 -> false
    
    d!3 -> true
    a!0 -> true
    c!2 -> false
    b!1 -> false
    
    d!3 -> true
    a!0 -> true
    c!2 -> true
    b!1 -> true
    

    现在,问题在于第二个模型是一个不完整模型。 Z3 可以返回它,因为无论bc 的值是什么,都满足约束(bc无关 变量)。 checkAndGetAllModels的当前实现只是简单地否定模型以防止重复;在这种情况下,它将要求另一个模型,例如 (not (and d (not a))) 成立。这将阻止返回具有这两个值的所有其他模型。从某种意义上说,不完整模型实际上代表了四个有效的、完整的模型。

    顺便说一句,如果您将 ScalaZ3 的 DSL 与 findAll 函数一起使用会发生什么情况,当所有模型不完整时(以及在它们习惯于计算下一个)。在 DSL 的上下文中,我们可以这样做,因为我们知道出现在公式中的变量集。在这种情况下,很难猜测应该如何完成模型。一种选择是让 ScalaZ3 记住使用了哪些变量。更好的解决方案是 Z3 可以选择始终返回无关变量的值,或者可能只是列出模型中的所有无关变量。

    【讨论】:

    • 当然,欧文和你是对的。这里显示的结果是正确的。最后,我的问题是另一个问题。如果您将我的术语视为一种配置,并且所有真实的东西都会被交付,那么它就太多了;)我想要一个配置,其中:如果您选择左侧(在 XOR 中),则完整的右侧-side 应该是假的。这可以实现吗?
    • 一种方法是以这种方式增强模型中的信息: "a->!d" "d->!a" "d->!b" "d->!c"等等...但是在大型模型中,这是很多工作...
    • 我不确定我是否理解“完整的右侧”指的是什么。将您的布​​尔表达式视为一棵树,这是否意味着您希望右侧的所有 叶子 为假?还是尽可能多的?
    • 将和/或树视为模型。我希望从根到叶的路径为真,其余为假(以及尽可能多的完整路径)。这将产生我在问题中提到的结果。对不起我的问题;似乎它走错了方向。有了这些含义,就有可能创建我想要看到的结果。我希望它可以比这更容易;)
    猜你喜欢
    • 1970-01-01
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多