如何在Z3 SMTLIB中将声明乐趣与值一起使用

时间:2018-08-19 14:23:23

标签: z3

在讨论stackoverflow和互联网以获取有关Z3的一些信息时,我遇到了一个看起来像计划问题的示例。 他们(declare-fun myFunc (Int Int) Int)及以后使用以下形式的表达式 (assert (= (myFunc 3 3) 9) ) (assert (= (myFunc 4 4) 16 )

用值填充它。在其他示例中,我还没有看到这种表达,我的读法像是“具有参数3 3的函数myFunc求值为9”。 我将执行简单计算的函数之一转换为这种形式的“ lookup-function”。巨大的性能提升! 将此应用到另一个应返回Bool的函数并不是一件容易的事。该模型向我展示了它具有以下内部形式:

; define neighbor-property by position distance, instead of row/col-distance
(declare-fun isPosNeighbor ( Int Int Int ) Bool )    ; this is later filled with values

(assert (= (isPosNeighbor 0 0 0 ) false  ) ) ; provide the default value
(assert (= (isPosNeighbor   1   0  1 ) true ) ) 
(assert (= (isPosNeighbor   1   1  2 ) true ) ) 
(assert (= (isPosNeighbor   1   3  4 ) true ) ) 
(assert (= (isPosNeighbor   1   5  6 ) true ) ) 

(assert (= (isPosNeighbor  10   0 10 ) true ) ) 
(assert (= (isPosNeighbor  10   1 11 ) true ) ) 
(assert (= (isPosNeighbor  10   2 12 ) true ) ) 
(assert (= (isPosNeighbor  10   3 13 ) true ) ) 
(assert (= (isPosNeighbor  10  12 22 ) true ) ) 

(check-sat)
(get-model)
(eval  (isPosNeighbor 33 4 1))   ; should return false

对于未给定的值,我如何强制isPosNeighbor返回false?我如何影响ite-sequence中的最终正确性?

sat 
(model (define-fun isPosNeighbor ((x!0 Int) (x!1 Int) (x!2 Int)) Bool
  (ite (and (= x!0 0) (= x!1 0) (= x!2 0)) false 
  (ite (and (= x!0 1) (= x!1 0) (= x!2 1)) true
  (ite (and (= x!0 1) (= x!1 1) (= x!2 2)) true 
  (ite (and (= x!0 1) (= x!1 7) (= x!2 8)) true 
  (ite (and (= x!0 1) (= x!1 8) (= x!2 9)) true 
  (ite (and (= x!0 10) (= x!1 0) (= x!2 10)) true 
  (ite (and (= x!0 10) (= x!1 1) (= x!2 11)) true 
  (ite (and (= x!0 10) (= x!1 2) (= x!2 12)) true 
  (ite (and (= x!0 10) (= x!1 3) (= x!2 13)) true
  (ite (and (= x!0 10) (= x!1 12) (= x!2 22)) true 
    true                ;; <<<< how to set this default-value ??
   ))))))))))) ) 

   true

1 个答案:

答案 0 :(得分:1)

可以通过如下重写输入公式来调整默认值:

(set-option :produce-models true)

(define-fun isPosNeighbor ((x!0 Int) (x!1 Int) (x!2 Int)) Bool
    (ite (or
            (and (= x!0  1) (= x!1  0) (= x!2  1))
            (and (= x!0  1) (= x!1  1) (= x!2  2))
            (and (= x!0  1) (= x!1  7) (= x!2  8))
            (and (= x!0  1) (= x!1  8) (= x!2  9))
            (and (= x!0 10) (= x!1  0) (= x!2 10))
            (and (= x!0 10) (= x!1  1) (= x!2 11)) 
            (and (= x!0 10) (= x!1  2) (= x!2 12)) 
            (and (= x!0 10) (= x!1  3) (= x!2 13))
            (and (= x!0 10) (= x!1 12) (= x!2 22)) 
        ) true false
))

(check-sat)
(get-model)

(eval  (isPosNeighbor 33 4 1))
(eval  (isPosNeighbor 0 0 0)) 
(eval  (isPosNeighbor 1 0 1))

请注意,0 0 0无需提供特殊情况。

此外,如果不知道函数的值先验,则truefalse可以替换为任意布尔表达式。

输出符合期望的行为:

~$ z3 t.smt2 
sat
(model 
)
false
false
true