繁体   English   中英

如何对 Z3 SMTLIB 中的值使用声明乐趣

[英]how to use declare-fun with values in Z3 SMTLIB

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

用值填充它。 我还没有在其他例子中看到这种表达式,我读它就像“确实,带有参数 3 3 的函数 myFunc 评估为 9”。 我将我的一个进行简单计算的函数转换为这种形式的“查找函数”。 巨大的性能提升!! 将此应用于另一个应该返回 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 中的最终 true ?

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

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

(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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM